我想使用@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}