%3F.png)
Welche Token verwendet TeX nicht als unbegrenzte Argumente (es sei denn, sie sind zwischen einem expliziten Zeichentoken des Kategoriecodes 1 und einem expliziten Zeichentoken des Kategoriecodes 2 verschachtelt)?
Im vorletzten gefährlichen Biegungs-Absatz vor Übung 20.4 des TeXbooks findet sich der Satz:
Nachdem Sie ' ' gesagt haben
\def\row#1#2{...}
, dürfen Sie Leerzeichen zwischen die Argumente setzen (z. B. '\row x n
'), da TeX keineEinzelplätzeals unbegrenzte Argumente.
Im Absatz zum doppelten Dangeorus-Bend vor Übung 20.5 des TeXbooks finden Sie den Satz:
Sie fragen sich, wie TeX feststellt, wo ein Argument endet. Antwort:[...]Unmittelbar folgt ein nicht begrenzter Parameter in der⟨Parametertext⟩durch ein Parametertoken oder es steht ganz am Ende des Parametertextes; in diesem Fall ist das entsprechende Argument das nächsteNicht leeres Token, es sei denn, das Token ist „
{
“. In diesem Fall ist das Argument die gesamte{...}
folgende Gruppe.
Im TeXbook habe ich weder für die Begriffe „einzelnes Leerzeichen“ noch für „nicht leeres Token“ genaue Definitionen gefunden.
Bitte zählen Sie alle Token auf, die TeX nicht als undelimitierte Argumente verwendet (es sei denn, sie sind zwischen einem expliziten Zeichentoken des Kategoriecodes 1 und einem expliziten Zeichentoken des Kategoriecodes 2 verschachtelt).
Mittlerweile habe ich herausgefunden, dass TeX keine expliziten Zeichen-Token der Kategoriecodes 10 und 32 als unbegrenzte Argumente verwendet. Sie müssen sich darauf konzentrieren, was TeX als \macro
zweites Argument verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A B
\show\macrob
\bye
Implizite Zeichen-Token der Kategoriecodes 10 und 32 werden als nicht begrenzte Makroargumente verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\X=13
\uppercase{\let\space= } %
\uppercase{\letX= } %
\macro A\space B
\show\macrob
\macro AXB
\show\macrob
\bye
Explizite lustige Leerzeichen werden als nicht begrenzte Makroargumente verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\uccode`\ =`\a
\uppercase{\macro A B}%
\show\macrob
\bye
Implizite lustige Leerzeichen werden als nicht begrenzte Makroargumente verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\def\letcs#1#2{\let#1= #2}%
\catcode`\X=13
\uccode`\ =`\a
\uppercase{\letcs\space{ }}%
\uppercase{\letcsX{ }}%
\macro A\space B
\show\macrob
\macro AXB
\show\macrob
\bye
Implizite/explizite Zeichen-Token der Kategoriecodes 12 und 32 werden als nicht begrenzte Makroargumente verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\ =12\relax%
\let\space= %
\macro{A} {B}%
\show\macrob
\macro{A}\space{B}%
\show\macrob
\bye
Die Kontrolltaste + Leertaste wird als nicht begrenztes Makroargument verwendet:
\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A\ B
\show\macrob
\bye
Ich habe also ein paar Fälle getestet, aber das Testen von Randfällen führt weder zu einer präzisen Definition des Begriffs „einzelnes Leerzeichen“ noch zu einer präzisen Definition des Begriffs „nicht leeres Token“. ;-)
Mit anderen Worten: Ich weiß nicht genau, welche Token TeX nicht als unbegrenzte Argumente verwendet (es sei denn, sie sind zwischen einem Zeichentoken des Kategoriecodes 1 und einem Zeichentoken des Kategoriecodes 2 verschachtelt).
Es scheint, die Menge⟨Leerzeichen⟩ist nicht gleich „einzelnes Leerzeichen“/„nicht leeres Token“:
Im TeXbook heißt es in Kapitel 24: Zusammenfassung des vertikalen Modus:
Die Quantität⟨Leerzeichen⟩, das in der Syntax von verwendet wurde⟨optionale Leerzeichen⟩steht oben für ein explizites oder implizites Leerzeichen. Mit anderen Worten bezeichnet es entweder ein Zeichentoken der Kategorie 10 oder eine Steuersequenz oder ein aktives Zeichen, dessen aktuelle Bedeutung durch
\let
oder gleich einem solchen Token gemacht wurde\futurelet
.
Die erwähnte "Steuersequenz oder aktives Zeichen", subsumierbar unter⟨Leerzeichen⟩, wird als nicht begrenztes Makroargument verwendet – die Beispiele oben zeigen es –, während „einzelnes Leerzeichen“/„nicht leeres Token“ nicht als nicht begrenztes Makroargument verwendet wird.
Wahrscheinlich ist "einzelnes Leerzeichen"/"nicht leeres Token" eine strikte Teilmenge von⟨Leerzeichen⟩?
Wenn ja, welche Teilmenge davon genau?
Antwort1
Der Stil des TeXbooks besteht oft darin, etwas Richtiges zu sagen, aber nicht die ganze Wahrheit.
Es gibt keine formale Definition eines „einzelnen Leerzeichens“, da dies nicht erforderlich ist.
Wenn Sie es tatsächlich versuchen,
\begingroup\def\\{\global\let\spacetoken= }\\ \endgroup
\def\foo#1#2{(First is #1)(Second is #2)}
\foo AB
\foo A B
\edef\two{\space\space}
\expandafter\foo\expandafter A\two B
\foo A\spacetoken B
\bye
Sie erhalten drei Instanzen von
(Erstes ist A)(Zweites ist B)
und die letzte Zeile erzeugt stattdessen
(Erstes ist A)(Zweites ist)B
Der \expandafter
Trick besteht darin, mehrere Leerzeichen zwischen A
und einzufügen B
. Sie sehen also, dass die nächste Übung „korrekter“ ist: TeX überspringt alleexplizitLeerzeichen-Token bei der Suche nach einem nicht begrenzten Argument.
Das letzte Beispiel zeigt, dassimplizitLeerzeichen werden nicht übersprungen. Die erste Zeile des Codes ist aus Übung 24.6 entlehnt, um \spacetoken
ein implizites Leerzeichen zu erstellen, da man nicht einfach so vorgehen kann wie in \let\bgroup={
. Wenn Sie hinzufügen, \show\spacetoken
erhalten Sie
> \spacetoken=blank space .
aber das istnichtwird ignoriert, wenn nach einem nicht begrenzten Argument gesucht wird.
Ein explizites Leerzeichen-Token ist ein Zeichen-Token mit dem Kategoriecode 10 (Leerzeichen oder Tabulator, bei normaler Einstellung; bei Interesse finden Sie später weitere Einzelheiten). Bei normaler Einstellung kann dies durch ein Leerzeichen oder einen Tabulator in der Eingabe oder durch ein beliebiges Zeichen generiert werden, dem zum Zeitpunkt der Tokenisierung der Eingabe der Kategoriecode 10 zugewiesen wird.
Aber die Sache hat einen Haken. Es gibt immer einen!
Man muss berücksichtigen, dass TeX Zeichen mit Kategoriecode 10 aufnimmt und ihnen unabhängig von ihrem ursprünglichen Zeichencode den Zeichencode 32 zuweist. Tabulatoren unterscheiden sich also nicht von Leerzeichen, da sieSinddas Gleiche gilt, sobald die Tokenisierung durchgeführt wurde.
Also, was ist das Problem mit
\uccode` =`x \uppercase{\foo A B}
das den komischen Raum nicht ignoriert? Es ist in der Tat anders als
\catcode`*=10 \foo A*B
das das Sternchen ignoriert, da es den Kategoriecode 10 hat.
Tatsache ist, dass Zeichen mit dem Kategoriecode 10normalisiertden Zeichencode 32 habenwährend der Tokenisierung. Wenn jedoch \uppercase
angewendet wird, wurde die Tokenisierung bereits durchgeführt und das Leerzeichen hat den Zeichencode 32. Aber danach \uppercase
wird das Zeichen zu x
10 , was nicht länger ignoriert werden kann, weil es nicht den Zeichencode 32 hat.
Daher ist die Antwort, dass nur Zeichen mit dem Zeichencode 32 und dem Kategoriecode 10 ignoriert werden, zwar richtig, jedoch irreführend, wenn die Normalisierung nicht berücksichtigt wird.
Antwort2
tex.web hat
begin if cur_tok=space_token then
um die ignorierten Token zu überspringen, space_token
wobei
@d space_token=@'5040 {$2^8\cdot|spacer|+|" "|$}
Antwort3
Folgen expliziter Zeichen-Token des Zeichencodes 32 und der Kategorie 10 (Leerzeichen) sind die einzigen Dinge, die TeX überspringt, während es nach dem Beginn eines nicht begrenzten Arguments „sucht“.
Die Quantität⟨Leerzeichen⟩ist in der Tat nicht gleichbedeutend mit „einzelnes Leerzeichen“/„nicht leeres Token“ im Sinne der von Ihnen zitierten TeXbook-Absätze:
Die Quantität⟨ein optionales Leerzeichen⟩ist definiert als:
⟨ein optionales Leerzeichen⟩→⟨Leerzeichen⟩|⟨leer⟩
Wo auch immer⟨ein optionales Leerzeichen⟩ist zulässig, das kann auch ein implizites Leerzeichen-Token sein.
Siehe beispielsweise
\lowercase{\let\sptoken = } %
\edef\result{\number1234 }
\show\result
\edef\result{\number1234\sptoken}
\show\result
\let\result\sptoken\sptoken=\sptoken\TeX
\bye
(Hier \lowercase
wird nichts weiter getan, als die Klammern zu entfernen. Auf diese Weise erhält man zwei explizite Leerzeichen-Token mit dem Zeichencode 32 hinter "=". Das erste wird verworfen, da bei \let
-Zuweisungen ein Leerzeichen hinter "=" optional ist. Das zweite wird nicht verworfen, sondern ist das Token, dessen Bedeutung zugewiesen wird \sptoken
.)
\sptoken
ist ein implizites Leerzeichen-Token.
Es wird bei der -Auswertung von TeX \number
wie ein explizites Leerzeichen-Token verworfen.
Es wird auch wie jedes andere⟨optionales Leerzeichen⟩während der Ausführung der zweiten \let
-Zuweisung.
Aber TeX würde nicht springen, \sptoken
während es nach dem Anfang eines nicht begrenzten Arguments „sucht“.
Dieses Beispiel beweist also, dass die Menge⟨Leerzeichen⟩ist nicht gleichbedeutend mit „einzelnes Leerzeichen“/„nicht leeres Token“ im Sinne der von Ihnen zitierten TeXbook-Absätze.
Übrigens:
Ihre Frage konzentriert sich darauf, wie TeX Token behandelt, während nach dem Anfang eines nicht begrenzten Arguments gesucht wird.
Ihre Frage bezieht sich auf eine Verarbeitungsphase, in der die Tokenisierung bereits abgeschlossen ist.
Dennoch ist eine Tatsache im Zusammenhang mit dem Prozess der Tokenisierung von .tex-Eingaben erwähnenswert:
Wenn TeX beim Tokenisieren von .tex-Eingaben auf ein Zeichen mit dem Kategoriecode 10 (Leerzeichen) stößt, während sich das Lesegerät im Zustand M (Zeilenmitte) befindet, hängt TeX ein explizites Zeichentoken der Kategorie 10 (Leerzeichen) und des Zeichencodes 32 an den Token-Stream an. Das heißt, das resultierende Token hat den Zeichencode 32, unabhängig von der Nummer, die der Codepunkt des Zeichens der betreffenden Eingabe hat.
Beispielsweise ist dem horizontalen Tabulator – der horizontale Tabulator hat in ASCII die Codepunktnummer 9 – normalerweise auch der Kategoriecode 10 zugewiesen. Daher ergibt die Tokenisierung eines horizontalen Tabulators normalerweise ein explizites Zeichentoken der Kategorie 10 (Leerzeichen) und des Zeichencodes 32. D. h. genau das Token, das von TeX übersprungen wird, während nach dem Anfang eines nicht abgegrenzten Arguments „gesucht“ wird.