Warum wird das Zeichen, das diesem makrodefinierenden Makro folgt, verschlungen?

Warum wird das Zeichen, das diesem makrodefinierenden Makro folgt, verschlungen?

Ich habe den folgenden einfachen Tex-Code:

\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp\xx a b c
\tempii\tempii

Ich erwarte die folgende Ausgabe: a b c ABCABC

Aber ich sehe tatsächlich Folgendes: b c ABCaABCa

Warum wird das „a“ in die Definition von \tempii hineingeklaut?

Antwort1

Ich denke immer noch darüber nach, warum das so ist, aber diese Überarbeitung (die Folgendes umfasst \xx) gibt Ihnen, was Sie wollen.

Ich denke, die Antwort ist, dass \temp\xx a b cdas Leerzeichen nach \xxaus der Sicht des TeX-Parsers überhaupt kein Leerzeichen ist, sondern lediglich das Ende des Makronamens anzeigt \xx. Wenn Sie beispielsweise einfach \xx Aeine Zeile allein einfügen, werden Sie sehen, dass sie als ABCAohne Leerzeichen ausgegeben wird. Der Parser saugt also das nachfolgende „A“ als mit verbunden auf \xx. Man könnte auch , verwenden \temp\xx{} a b c, um dem Parser mitzuteilen, dass das Leerzeichen ein Trennzeichen ist und nicht nur das nächste Zeichen nach \xx.

\documentclass{article}
\begin{document}
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp{\xx} a b c
\tempii\tempii
\end{document}

Antwort2

Der Übersichtlichkeit halber werde ich Leerzeichen-Token mit kennzeichnen , da sie in der Diskussion sehr wichtig sind. Leerzeichen in den folgenden Codebeispielen sollten ignoriert werden.

Der Parametertext von \tempist

#1•

während der Ersatztext

\def\tempii{#1}

Ihr Anruf \tempist

\temp\xx a•b•c•\tempii\tempii

Beachten Sie, dass danach \xxein Leerzeichen nur zur Abgrenzung des Makros folgt; es istnichtein Leerzeichen: es ist nichts, weil TeX Leerzeichen nach Kontrollzeichen immer ignoriert.Wörter(nicht kontrollierenSymbole). Das Leerzeichen danach cstammt vom Zeilenende in Ihrem Code.

Die folgenden Token \tempwerden (ohne Erweiterung) durchsucht, um eine Übereinstimmung mit dem Parametertext zu finden, wobei das Argument durch ein Leerzeichen getrennt ist, sodass #1es endet \xx aund der nächste Zustand des Eingabestroms ist

\def\tempii{\xx a}b•c•\tempii\tempii

Nun führt TeX die Definition aus und entfernt sie aus dem Eingabestrom:

b•c•\tempii\tempii

und der Teil b•c•wird an die Satzphase übergeben. Nach der Erweiterung der beiden Kopien von \tempiiist dies gleichbedeutend mit dem Eintippen von

b•c•\xx a\xx a

oder

b•c•ABCaABCa

und das ist genau das, was Sie bekommen haben.

\?Wenn Sie stattdessen verwendet hätten, \xxwären die letzten beiden Zeilen umgewandelt worden in

\temp\?•a•b•c•\tempii\tempii

weil \?es sich um ein Steuersymbol handelt und TeX Leerzeichen danach nicht ignoriert. In diesem Fall wäre das Ergebnis

a•b•c•ABCABC

Beachten Sie, dass

\expandafter\temp\xx a•b•c
\tempii\tempii

würde das gleiche Ergebnis liefern, denn nach der Aktion von \expandafterTeX würde präsentiert werden mit

\temp ABCa•b•c

(natürlich dieselbe Konvention für Leerzeichen wie zuvor). Sie erhalten dasselbe Ergebnis wie mit \?statt \xxmit

\expandafter\temp\expandafter\xx\space a•b•c

denn dann würde TeX präsentiert werden mit

\temp\xx•a•b•c

Tatsächlich werden Leerzeichen nach Steuerwörtern nur während des Tokenisierungsprozesses ignoriert.

verwandte Informationen