
Ich spiele derzeit mit Makros herum (bin ziemlich neu) und mir scheint etwas ziemlich Grundlegendes zu LaTeX/TeX-Makros zu fehlen:
\def\car{Yes}
\def\iszero#1{
\ifnum#1=0{
\let \car = Yes
}
\else{
\let \car = No
}
\car
}
\iszero{1}
Gibt zurück: Ja.
Ich habe mich gefragt, warum dies passiert und wie ich verhindern kann, dass LaTeX es vorzeitig \car
durch seinen aktuellen Wert ersetzt.
Antwort1
Sie wollen
\def\car{Yes}
\def\iszero#1{%
\ifnum#1=0 % Terminate number with a space
\def\car{Yes}%
\else
\def\car{No}%
\fi
}
\iszero{1}
Sie verwenden ein primitives TeX-Konditional, daher sind die beiden ZweigenichtStellen in Klammern: stattdessen werden die durch das Ende der Bedingung, die \else
und die abgegrenzt \fi
. Das \let
Grundelement kann nur verwendet werden, um einem Token den Wert eines zweiten zuzuweisen: Sie können es nicht verwenden, um ein Makro zu definieren, das benötigt \def
.
Antwort2
Die Syntax für TeX-Bedingungsanweisungen verwendet keine Klammern für die True- und False-Zweige.
Verhält sich auch \let
anders als Sie zu denken scheinen: \let\foo=<token>
macht \foo
(fast) äquivalent zu <token>
. Im Fall von
\let\car = Yes
das Token Y
würde zugewiesen \car
und es
gedruckt (wenn im nicht übersprungenen Zweig); dasselbe für \let\car = No
.
Sie sollten \def
stattdessen verwenden. Es gibt jedoch bessere Möglichkeiten, für die kein erforderlich ist \car
.
Unter der Annahme von einfachem TeX,
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}
\def\iszero#1{%
\ifnum#1=0
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
{Yes}{No}%
}
würde funktionieren: Der \expandafter
Trick entfernt die Reste des bedingten Textes und lässt entweder „ \firstoftwo{Yes}{No}
oder“ \secondoftwo{Yes}{No}
im Eingabestrom zurück.
Dies kann verallgemeinert werden
\def\IfIsZeroTF#1{%
\ifnum#1=0
\expandafter\firstoftwo
\else
\expandafter\secondoftwo
\fi
}
genannt werden wie
\IfIsZeroTF{1}{Yes}{No}
Antwort3
Alternativ platzieren Sie den Vergleich innerhalb der Definition von \car
.
%\def\car{Yes}%% Not needed for this example
\def\iszero#1{%
\edef\car{%
\ifnum#1=0
Yes%
\else
No%
\fi
}}
False: \iszero{1}\car
True: \iszero{0}\car
Ich verwende \edef
zum Abrufen nur Yes
oder No
in \car
. Bei \def
Verwendung besteht das Risiko, dass die Eingabe vor der Auswertung geändert wird, z. B. wenn die Eingabe ein Zähler ist.