So verwenden Sie @ifstar mit Argumenten

So verwenden Sie @ifstar mit Argumenten

Ich möchte @ifstareinen 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 \sndnamedas Argument, sondern \defder 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}

Bildbeschreibung hier eingeben

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 \emptydann 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}

verwandte Informationen