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