
Mein Ziel ist es, die Beziehung zwischenZeichenbytesUndZeichentokenin Bezug auf neue Zeilenbytes. Wahrscheinlich habe ich meine Fakten nicht ganz verstanden.
Wenn TeX eine Datei mit Bytes liest, muss die Kodierung berücksichtigt werden. Davon abgesehen,
Wir können beobachten, dass eineinzelnes Zeilenumbruchzeichen-Byte(unter der Annahme von LF und CRLF) wird in ein Leerzeichen umgewandelt. Aber was passiert hinter den Kulissen? Wird ein Token mit dem Datenpaar (LF-Bytenummer, Catcode=10) erstellt?
Zwei aufeinanderfolgende Zeilenumbruch-Zeichenbyteszu einem einzigen Token mit dem Datenpaar (Leerzeichen-Byte-Nummer, Catcode 5) werden?
Wann kommt Catcode 5 „Ende der Zeile“ ins Spiel?
Ich weiß, dass LaTeX ein einfügt, \par
wenn zwei aufeinanderfolgende Zeilenenden auftreten.
Code
Ich habe versucht, Token mit Catcode 5 visuell darzustellen, bin mir aber immer noch nicht sicher, ob es \tmp
wirklich Catcode 5 wird.
\documentclass{article}
\usepackage{fontspec}% xelatex
\long\def\scan#1{#1\par\rule{\textwidth}{2pt}\par\xscan#1\relax}
\long\def\xscan{\afterassignment\xxscan\let\tmp= }
\long\def\xxscan{%
\ifx\tmp\relax\else%
\ifcat\tmp\space10 \else%
\ifcat\tmp a11 \else%
\ifcat\tmp 112 \else%...
\ifcat\tmp
5
\else%
\fi\fi\fi\fi
\expandafter\xscan
\fi}
\begin{document}
\scan{ mac::exception ==
a
}
\end{document}
Anmerkungen
- Da xelatex UTF-8-fähig ist, muss es wissen, wie 2-Byte-Zeilenenden gelesen werden.
- Code geändert von:Wie kann ich LaTeX dazu bringen, Leerzeichen in meinem Makro zu erkennen (Catcode 10)?
Antwort1
Es gibt niemals Token mit Catcode 5.
Initex richtet
\catcode`\^^M=5
Aber das wirkt ähnlich wie
\catcode`\%=14
was den Catcode 14 ergibt %
, aber es gibt keine Token mit diesem Catcode. Wenn ein Zeichen mit dem Catcode 14 gescannt wird, werden dieses Zeichen und der Rest der Zeile verworfen.
Ein Zeichen des Catcodes 5 erzeugt ein Leerzeichen und versetzt den Scanner von Tex in einen speziellen Modus, der dazu führt, dass unmittelbar folgende Zeichen des Catcodes 10 verworfen werden "Leerzeichen am Anfang einer Zeile" und ein folgendes Zeichen des Catcodes 5 als kein Leerzeichen- \par
Token gekennzeichnet wird "Leerzeile ist gleichbedeutend mit \par
"
Beachten Sie also, dass die erste neue Zeile immer ein Leerzeichen erzeugt, nachfolgende Zeilen \par
also, sodass eine leere Zeile normalerweise gleichbedeutend ist mit space\par
.
Antwort2
Charaktere haben einen Kategoriecode; siedürfengenerieren während der Tokenisierungsphase einen Charaktertoken, aber siebraucht nichtZu.
Kategoriecodes werden aus zwei Gründen verwendet: Sie werden während der Tokenisierung betrachtet (wenn TeX Text aus einer Eingabedatei oder dem Terminal aufnimmt), aber auch während der Verarbeitung der Tokenliste.
Nur Zeichen mit Kategoriecode
1 2 3 4 6 7 8 10 11 12 13
kann Zeichentoken (mit gleichem Kategoriecode) generieren bzw.
Gruppe beginnen
Gruppe beenden
Mathe Umschalttaste
Ausrichtung
Parameter
Hochstellung
Tiefstellung
Leerzeichen
Buchstabe
anderes Zeichen
aktives Zeichen
Zeichen mit dem Kategoriecode 0 5 9 14 15 werdenniemalsGenerieren Sie ein Zeichentoken mit demselben Kategoriecode: Es gibt keine Möglichkeit, dass ein Zeichentoken mit diesen Kategoriecodes im internen Tokenprozessor von TeX durchkommt:
Ein Zeichen mit dem Kategoriecode 0 löst die Bildung einer Steuersequenz aus
ein Zeichen mit Kategoriecode 9 wird ignoriert
ein Zeichen mit Kategoriecode 15 löst einen Fehler aus und wird dann ignoriert
Ein Zeichen mit dem Kategoriecode 14 weist den Tokenisierungsprozessor an, es zusammen mit allen anderen Zeichen in der Zeile zu ignorieren
Interessanter ist Kategoriecode 5, der Gegenstand Ihrer Frage ist. Wenn TeX einen findet, verwirft es alles, was in der Eingabezeile übrig bleibt, generiert einenLeerzeichenmit Zeichencode 32 und Kategoriecode 10, als ob es von Anfang an in der Zeile gestanden hätte, und versetzt den Scanner in den speziellen Zustand des Ignorierens von Leerzeichen (Kategoriecode 10), bis etwas anderes auftritt: Wenn dies ein weiteres Zeichen des Kategoriecodes 5 ist, generiert TeX ein \par
Token, andernfalls wechselt es in den Normalzustand.
Beachten Sie die Betonung aufLeerzeichenoben: Dieses Leerzeichen wird entsprechend den normalen Regeln tokenisiert, es wird also ignoriert, wenn es auf ein Steuerwort (wie \foo
) folgt, aber nicht nach einem Steuersymbol (wie \~
).
Eine Konsequenz davon ist, dass die folgenden Eingaben
\foo\baz
\foo \baz
\foo \baz
sind völlig gleichwertig. Beachten Sie, dass, wenn das Zeilenende in der letzten Eingabe eineLeerzeichen, gäbe es einen Unterschied. Aber tatsächlich einLeerzeichen(noch nicht tokenisiert) wird stattdessen generiert.
Notiz.Was oben über ignorierte Zeichen gesagt wurde, kann bei der Bildung von Steuerwörtern irreführend sein. Die Bildung eines Steuerworts beginnt mit einem Zeichen mit Kategoriecode 0, gefolgt von einem Zeichen mit Kategoriecode 11. Jedes Zeichen mit einem anderen Kategoriecode als 11 stoppt den Scanvorgang, führt zur Tokenisierung des gebildeten Steuerworts und wird erneut geprüft (auf Ignorierung, z. B. falls es Kategoriecode 9 hat).
Nachtrag zu XeTeX und LuaTeX.Wenn eine UTF-8-kodierte Datei an die Unicode-fähigen Engines weitergeleitet wird, ist es unerheblich, ob ein Zeichen in seiner UTF-8-Darstellung ein, zwei, drei oder vier Byte lang ist. Diese beiden Engines führen einen vorbereitenden Schritt durch, bei dem UTF-8-Kombinationen in Unicode-Entitäten umgewandelt werden, sodass der Tokenisierungsprozessor nur ein Zeichen sieht (mit seinem in der Initialisierungstabelle zugewiesenen Kategoriecode). Die beiden Engines können auch mit UTF-16 oder UTF-32, Little- oder Big-Endian umgehen.
Antwort3
TeX liest die Eingabe zeilenweise: Eine Eingabezeile wird gelesen und verarbeitet. Dann wird eine weitere Eingabezeile gelesen und verarbeitet. ...
Eine der ersten Aktionen, die TeX nach dem Lesen einer Eingabezeile durchführt, ist die Konvertierung der Zeichen aus dem Zeichenkodierungsschema der Computerplattform in das interne Zeichenkodierungsschema der TeX-Engine. Bei herkömmlichen TeX-Engines ist das interne Zeichenkodierungsschema ASCII, der American Standard Code for Information Interchange. Bei TeX-Engines, die auf LuaTeX oder XeTeX basieren, ist das interne Zeichenkodierungsschema Unicode, wovon ASCII eine strikte Teilmenge ist.
Danach löscht TeX alle Leerzeichen am rechten Zeilenende. Genauer: Danach löscht TeX alle Zeichen am rechten Zeilenende, deren Zeichencode 32 ist. (32 ist sowohl in ASCII als auch in Unicode die Nummer des Codepunkts des Leerzeichens.)
Dann fügt TeX am rechten Ende der Zeile ein Zeichen ein, dessen Zeichencode dem Wert des Integer-Parameters entspricht.\endlinechar
.
Normalerweise ist der Wert \endlinechar
13 und der Kategoriecode des Zeichens 13 (Rückgabezeichen) ist 5 (Zeilenende).
Dies bedeutet, dass TeX beim Erreichen des Zeilenendes während der Tokenisierung normalerweise auf ein Zeichen mit dem Kategoriecode 5 (Zeilenende) stößt.
Dann beginnt TeX mit der Tokenisierung der Zeile. Das heißt, TeX „sieht“ sich die in der Zeile enthaltenen Zeichen an und erzeugt Steuersequenz-Token und Zeichen-Token entsprechend der Kategoriecodetabelle und je nach Zustand des Lesegeräts.
Zum Zeitpunkt des Lesens und Tokenisierens der Eingabe kann sich der Leseapparat von TeX in einem von drei Zuständen befinden:
Zustände:Leerzeichen überspringen. Das Lesegerät befindet sich im Zustand S
- nach der Verarbeitung eines Zeichens aus der Eingabe, dessen Kategoriencode 10 (Leerzeichen) ist.
- nach der Verarbeitung einer Folge von zwei gleichen Zeichen des Kategoriecodes 7 (Hochstellung), gefolgt von einer Folge von zwei Zeichen, die den Zeichencode in hexadezimaler Kleinbuchstabennotation eines Zeichens bilden, dessen Kategoriecode 10 (Leerzeichen) ist.
[Beispiel: Normalerweise ist der Kategoriecode von^
7 (Hochstellung), während der Kategoriecode des Zeichens 32 (Leerzeichen; Hexadezimalzahl 20) normalerweise 10 (Leerzeichen) ist. Daher wird die Notation^^20
normalerweise so behandelt, als würde das Zeichen 32 (Leerzeichen) aus der Eingabe verarbeitet, deren Kategoriecode normalerweise 10 (Leerzeichen) ist.] - nach der Verarbeitung einer Folge von zwei gleichen Zeichen des Kategoriecodes 7 (Hochstellung), gefolgt von einem Zeichen, wobei - falls der Zeichencode des Zeichens im Bereich von 64 bis 127 liegt - der Kategoriecode des Zeichens, dessen Zeichencode durch Subtrahieren von 64 erhalten wird, 10 (Leerzeichen) ist.
[Beispiel: Da der Kategoriecode von^
normalerweise 7 (Hochstellung) und der Zeichencode von`
96 ist, während 96-64=32 und der Kategoriecode des Zeichens 32 (Leerzeichen) normalerweise 10 (Leerzeichen) ist,^^`
wird die Notation normalerweise so behandelt, als würde das Zeichen 32 (Leerzeichen) aus der Eingabe verarbeitet, deren Kategoriecode normalerweise 10 (Leerzeichen) ist.] - nach der Verarbeitung einer Folge von zwei gleichen Zeichen des Kategoriecodes 7 (Hochstellung), gefolgt von einem Zeichen, wobei – falls der Zeichencode des Zeichens im Bereich von 0 bis 63 liegt – der Kategoriecode des Zeichens, dessen Zeichencode durch Addition von 64 erhalten wird, 10 (Leerzeichen) ist.
- nach der Erzeugung eines Kontrollwort-Tokens.
- nach der Erzeugung eines Kontrollsymbol-Tokens, dessen Name aus einem Zeichen des Kategoriecodes 10 (Leerzeichen) besteht. Z. B. nach der Erzeugung des Kontrollsymbol-Tokens
\␣
(Kontrollleerzeichen).
Im Zustand S führt weder die Verarbeitung eines Zeichens mit dem Kategoriecode 10 (Leerzeichen) noch die Verarbeitung einer ^^..
-Sequenz/ <superscript-char><superscript-char>..
-Sequenz, die als gleichwertig mit einem Zeichen des Kategoriecodes 10 (Leerzeichen) angesehen wird, dazu, dass ein Token erzeugt wird und der Zustand des Lesegeräts nicht geändert wird.
Normalerweise sind das Leerzeichen (Zeichencode 32) und das horizontale Tabulatorzeichen (Zeichencode 9) die einzigen Zeichen, deren Kategoriecode 10 (Leerzeichen) ist.
Aus diesem Grund können in der Eingabe mehrere aufeinanderfolgende Leerzeichen oder horizontale Tabulatorzeichen vorkommen, die normalerweise nur ein Leerzeichen-Token ergeben, was wiederum eine horizontale Verbindung für nur ein horizontales Leerzeichen ergibt, wenn sich TeX in einem der Modi befindet, in denen Leerzeichen-Token eine horizontale Verbindung ergeben (d. h. im horizontalen Modus, im eingeschränkten horizontalen Modus, aber weder im vertikalen Modus, noch im internen vertikalen Modus, noch im Mathematikmodus, noch im Anzeigemathematikmodus).
Staat M:Mitte der Zeile. Das Lesegerät befindet sich im Zustand M
- nach der Erzeugung eines Zeichentokens, das kein Leerzeichen ist.
- nach der Erzeugung eines Steuersymbol-Tokens, dessen Name aus einem Zeichen besteht, das nicht zum Kategoriecode 10 (Leerzeichen) gehört.
Im Zustand M führt sowohl die Verarbeitung eines Zeichens mit dem Kategoriecode 10 (Leerzeichen) als auch die Verarbeitung einer ^^..
-Sequenz/ <superscript-char><superscript-char>..
-Sequenz, die als äquivalent zu einem Zeichen mit dem Kategoriecode 10 (Leerzeichen) angesehen wird, zur Erzeugung eines Leerzeichen-Tokens, d. h. eines Zeichen-Tokens mit dem Charcode 32 (Leerzeichen) und dem Catcode 10 (Leerzeichen), und zum Umschalten des Zustands des Lesegeräts in den Zustand S.
Staat N:Neue Zeile. Das Lesegerät befindet sich im Zustand N, wenn es mit dem Lesen einer weiteren Eingabezeile beginnen will. Im Zustand N führt weder die Verarbeitung eines Zeichens mit dem Kategoriecode 10 (Leerzeichen) noch die Verarbeitung einer ^^..
-Sequenz/ <superscript-char><superscript-char>..
-Sequenz, die als gleichwertig mit einem Zeichen mit dem Kategoriecode 10 (Leerzeichen) angesehen wird, zur Erzeugung eines Tokens und zur Änderung des Zustands des Lesegeräts.
Wenn TeX auf ein Zeichen des Kategoriecodes 5 (Zeilenende) stößt, während sich das Lesegerät im Zustand S befindet, erzeugt TeX überhaupt kein Token.
Wenn TeX auf ein Zeichen mit dem Kategoriecode 5 (Zeilenende) stößt, während sich das Lesegerät im Zustand M befindet, erzeugt TeX ein Leerzeichen-Token, d. h. ein Zeichen-Token mit dem Charaktercode 32 (Leerzeichen) und dem Kategorisierungscode 10 (Leerzeichen).
Wenn TeX auf ein Zeichen des Kategoriecodes 5 (Zeilenende) stößt, während sich das Lesegerät im Zustand N befindet, erzeugt TeX das Steuerwort Token \par
.
Nach dem Auftreten eines Zeichens mit dem Kategoriecode 5 (Zeilenende) wird TeX- egal in welchem Zustand sich das Lesegerät befindet -in jedem Fall alle weiteren Informationen in der aktuellen Zeile löschen und mit dem Lesen einer weiteren Eingabezeile beginnen. Dabei wird der Leseapparat von TeX in den Zustand N geschaltet.
Aufgrund des oben erwähnten \endlinechar
-Dings führt eine leere Zeile nach einer nicht leeren Zeile normalerweise dazu, dass TeX zwei aufeinanderfolgende Return-Zeichen (Zeichencode 13) verarbeitet, deren Kategoriecode 5 (Zeilenende) ist.
Beim Auftreten des ersten dieser Return-Zeichen, das sich in der nicht leeren Zeile befindet, könnte sich das Lesegerät im Zustand S oder im Zustand M befinden und daher könnte das erste Zeichen überhaupt kein Token oder ein Leerzeichen liefern.
In jedem Fall wird das Lesegerät nach dem Auftreten des ersten dieser Return-Zeichen in den Zustand N geschaltet. DaherBeim Auftreten des zweiten dieser Rückgabezeichen befindet sich das Lesegerät im Zustand N und das zweite dieser Rückgabezeichen ergibt das Steuerwort Token \par
.
Aus diesem Grund wird eine leere Zeile normalerweise wie ein „Absatzumbruch“ bzw. wie das Steuerwort-Token behandelt, \par
das normalerweise (sofern nicht neu definiert) eine Anweisung zum Umbrechen in Zeilen und zum Setzen des bis dahin gesammelten Materials als Textabsatz ist.
Das bedeutet, dass es passieren kann, dass das letzte Element innerhalb eines Absatzes ein Leerzeichen ist, das einen horizontalen Kleber ergibt. Beachten Sie, dass ein solcher horizontaler Kleber am Ende eines Absatzes von TeX normalerweise verworfen wird und Kleber entsprechend den Werten des \parfillskip
-glue-Parameters am Ende eines Absatzes angefügt wird.