kann mir jemand Futurelet erkläreninnerhalbUmgebungen ausrichten?
Beispiel:
Der Befehl \A sollte ein „A“ ergeben, wenn das nächste Zeichen ein { ist, ein „B“, wenn es ein & ist und ein „C“ in allen anderen Fällen.
\gdef\A{\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
und im Fall von normalem Text oder Inline-Mathematik funktioniert es ganz gut:
\A{a},\A&,\A a % -> "A,B,C"
$\A{a}$,$\A&$,$\A a$ % -> "A,B,C"
Abersobald ich es in einer align*-Umgebung (amsmath) verwende, tritt ein „Unvollständiger \ifx“-Fehler auf:
\begin{align*} \A{a},\A&,\A a \end{align*}% --> error.
Kann mir das jemand erklären? Danke!
Chris
PS: Es gibt noch mehr Dinge über Futurelet in einer Align-Umgebung, die ich nicht verstehe: Wenn wir
\gdef\A{\futurelet\thesymbol\alpha}
\gdef\D#1{\detokenize{#1}}
Dann
\begin{align*}
\D&,\A a % -> "&,alpha a" (okay)
\A a,\D{&} % -> "alpha a,&" (okay)
\A a,\D& % -> error: "Argument of D has an extra }." (???)
\end{align*}
Antwort1
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}
wenn TeX das sieht, &
tauscht es den Rest der Vorlage gegen das aus, \halign
wie in Latex-Case durch usw. angegeben c
r
, sodass \ifx
die ersten beiden Token der Vorlage verglichen werden (wahrscheinlich \unskip
und \hfil
dann wird die Zelle (und damit die Gruppe) beendet, wenn etwas schief geht.
Wenn Sie sich ausblenden möchten, &
während Sie eine Gruppe vor dem Futurelet starten und nach dem Test beenden, benötigen Sie die
{\ifnum0=`}
...
\ifnum0=`{\fi}
Formular, das in jedem tabellarischen Code vorkommt.
Dadurch entstehen A, B, C, was meiner Meinung nach das beabsichtigte Ergebnis ist.
\documentclass{article}
\usepackage{amsmath}
\gdef\A{{\ifnum0=`}\fi\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi \ifnum0=`{\fi}}
\begin{document}
\begin{align*} \A{a},\A&,\A a \end{align*}
\end{document}
Beachten Sie für Ihr zweites Beispiel, dass &
eine Gruppe beendet wird.
a,\D&
ist wie {\D}
und beide geben den gleichen Fehler aus:
! Argument of \D has an extra }.
<inserted text>
\par
l.15 {\D}
Dort ist nicht ganz klar, was die Lösung ist, da nicht klar ist, was Sie {\D}
tun möchten.
Antwort2
Ich kann nicht mit Davids Verständnis von TeX-Code mithalten, daher werde ich nicht versuchen, Ihre Makros zu reparieren (meiner Meinung nach ist das, was Sie tun, jedoch grundsätzlich unklug). Sein Kommentar zu „wenn TeX das sieht &
“ kann jedoch wie folgt erweitert werden. Beim Scannen einer Ausrichtung verhält sich TeX auf eine Weise, die etwas im Widerspruch zu dem mentalen Modell steht, das die meisten Benutzer (selbst erfahrene und sachkundige Benutzer) von ihrer Ausführung haben. Wirvorstellendass TeX immer eines von drei Dingen macht:
Scannen der Eingabe, um die Zeichen in Token zu zerlegen und so Nahrung für den „Mund“ des Makroparsers bereitzustellen;
Makros erweitern;
Ausführen nicht erweiterbarer Token: entweder Programmieranweisungen wie
\def
oder\hbox
oder direkte Satzbefehle wie Zeichen.
Bei diesem Modell erwartet jeder, dass innerhalb einer Ausrichtung (die TeX-Grundelemente \halign
oder \valign
) das Tabulatorzeichen &
seine Aktion unter Punkt 3 ausführt: Ausführung. Dies ist jedoch nicht wirklich der Fall; tatsächlich „bemerkt“ TeX Tabulatorzeichen in Punkt 1! Wenn TeXjemals gelesenein Et-Zeichen (oder eine gleichwertige Zeichenkategorie) beendet sofort die aktuelle Zelle, schließt eine Gruppe, fügt den „ v
Teil“ der Vorlage ein und so weiter.
(Bearbeiten:Ich habe nur überflogen errorlog.pdf
(das heißt texdoc errorlog
) und den relevanten Kommentar aus einer Debugging-Sitzung am 18. März 1978 gefunden:
Machen Sie die Routine „get next“ so, dass sie Intercept-
&
und\cr
Tokens enthält. Ich dachte, ich könnte einfach „&
and“\cr
inbig_switch
[also in den Magen von TeX, nicht in die Augen] einfügen; das war ein großer Fehler.
Dies ist ein interessanter Teileinblick in die Gründe, die Knuth zu der oben beschriebenen, anscheinend bizarren Verhaltenswahl dieser Array-Token veranlasst haben, und zugleich eine Bestätigung dafür, dass es sich tatsächlich um dieses Verhalten handelt.)
Die Ausnahme besteht natürlich darin, wenn sich TeX innerhalb einer unvollendeten Klammerngruppe befindet (und \begingroup
diese Gruppe muss mit tatsächlichen Klammern beginnen, nicht mit impliziten oder ). Dies führt zu Davids {\ifnum0=
}`-Konstruktion, die erweiterbar einer öffnenden Klammer entspricht, ohne dass innerhalb einer Makrodefinition, in der sie platziert werden könnte, tatsächlich ungleichmäßige Klammern erstellt werden.
Das Ergebnis dieser seltsamen Parsing-Regel ist, dass man sehr vorsichtig sein muss, was von einem Makro in einer Tabellenzelle gelesen wird oder was von einer Umgebung umschlossen wird. Makros wie Ihres, die ihr Argument effektiv durch Zuweisung und nicht durch Makroargument-Parsing lesen, sind noch prekärer, da ohne die erforderlichen Klammern der Tabulator, der gelesen werden könnte,nichtgeschützt werden. Tabellenkompatible Umgebungen schließen das \ifnum
Ding ein, um alle Tabulatorzeichen zu schützen, die darin vorkommen können; einfachere Umgebungen werden auf mehrere Zellen aufgeteilt und schlagen daher wahrscheinlich fehl.