如何使用带参数的 @ifstar

如何使用带参数的 @ifstar

我想使用@ifstar来定义一个命令,其非星号版本将值存储在变量中,而其星号版本从变量中读取值。我尝试了以下操作。它不会产生错误,但也不会打印值。

\def\sndname#1{\@ifstar\@sndname{\def\@sndname{#1}}}
\sndname{Hello U2}
\sndname*

我知道我可以使用这种模式,但是有没有办法将其作为一行代码来完成?

\def\foo{\@ifstar\@foo\@@foo}
\def\@foo#1{...}
\def\@@foo#1{...}

答案1

\documentclass{article}
\makeatletter
\def\sndname{\@ifstar\@sndname{\def\@sndname}}
\makeatother
\begin{document}
Set it \sndname{Hello U2}and use it \sndname*.
\end{document}

诀窍在于,不\sndname读取参数而是读取\def内部参数\sndname

答案2

您滥用了 LaTeX 语法准则。命令的 * 版本通常应具有与标准版本相同的强制参数。

您可以改用可选参数:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\sndname}{o}
 {
  \IfNoValueTF{#1}
    {\tl_use:N \l_cocomore_sndname_tl}
    {\tl_set:Nn \l_cocomore_sndname_tl { #1 }}
 }
\tl_new:N \l_cocomore_sndname_tl
\ExplSyntaxOff

\begin{document}

\sndname[Hello U2]
\sndname

\end{document}

在此处输入图片描述

然而,更好的方法是使用不同的命令来设置变量和使用它。

答案3

对@egreg 的答案的补充,我同意它有更好的语法,但没有xparse。注释版本是命令的 TeX 样式定义,未注释版本是 LaTeX 样式定义。在 LaTeX 定义中,可选参数只能采用默认值,此处设置为\empty,然后可以在代码中检查。只要没有加载,它就应该可以工作\empty。使用时命令周围的点只是为了检查没有添加额外的空格。(实际上,LaTeX 版本可能可以看作是一行,但这样更易读:-)

\documentclass{article}
%%%% TeX style definition
% \makeatletter
% \def\sndname{\@ifnextchar[\opt@sndname\@sndnamevar}
% \def\opt@sndname[#1]{\def\@sndnamevar{#1}}
% \makeatother

%%%% LaTeX style definition
\newcommand\sndname[1][\empty]{%
  \ifx#1\empty
    \sndnamevar
  \else
    \def\sndnamevar{#1}%
  \fi}

%%%% Load with nothing (just in case \sndname is used before loaded)
\sndname[]
%%%%
\begin{document}
Load: .\sndname[Name of snd].

Print: .\sndname.

\end{document}

相关内容