
Ich möchte @ifstar
einen Befehl definieren, dessen Nicht-Star-Version einen Wert in einer Variablen speichert und dessen Star-Version den Wert aus der Variablen liest. Ich habe Folgendes versucht. Es erzeugt keinen Fehler, druckt den Wert aber auch nicht aus.
\def\sndname#1{\@ifstar\@sndname{\def\@sndname{#1}}}
\sndname{Hello U2}
\sndname*
Ich weiß, dass ich dieses Muster verwenden kann, aber gibt es eine Möglichkeit, es als Einzeiler zu verwenden?
\def\foo{\@ifstar\@foo\@@foo}
\def\@foo#1{...}
\def\@@foo#1{...}
Antwort1
\documentclass{article}
\makeatletter
\def\sndname{\@ifstar\@sndname{\def\@sndname}}
\makeatother
\begin{document}
Set it \sndname{Hello U2}and use it \sndname*.
\end{document}
Der Trick besteht darin, dass nicht \sndname
das Argument, sondern \def
der Inhalt gelesen wird \sndname
.
Antwort2
Sie missachten die Syntaxrichtlinien von LaTeX. Die *-Version eines Befehls sollte grundsätzlich dieselben obligatorischen Argumente haben wie die Standardversion.
Sie können stattdessen ein optionales Argument verwenden:
\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}
Ein besserer Ansatz wäre jedoch, unterschiedliche Befehle zum Festlegen und Verwenden der Variablen zu verwenden.
Antwort3
Eine Ergänzung zu @egregs Antwort, die meiner Meinung nach eine bessere Syntax hat, aber ohne xparse
. Die kommentierte Version ist eine TeX-Definition des Befehls und die unkommentierte eine LaTeX-Definition. In der LaTeX-Definition kann das optionale Argument nur einen Standardwert annehmen, der hier auf gesetzt ist und \empty
dann im Code überprüft werden kann. Es sollte funktionieren, solange es nicht mit geladen wird \empty
. Die Punkte um die Befehle dienen bei Verwendung nur dazu, zu überprüfen, dass keine zusätzlichen Leerzeichen hinzugefügt werden. (Eigentlich kann die LaTeX-Version wahrscheinlich als Einzeiler angesehen werden, aber so ist sie besser lesbar:-)
\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}