7
1

Immer wieder lese ich, dass in TeX Funktionen auf catcodes, genauer auf ihrer Änderung, basieren oder dass einige Eigenheiten von TeX auf unterschiedliche catcodes zurückzuführen sind. Ich habe aber gelegentlich auch schon lccode und uccode gesehen. Was hat es mit diesen Begriffen auf sich?

gefragt 27 Jan '14, 23:10

Speravir's gravatar image

Speravir
497139
Akzeptiert-Rate: 25%

bearbeitet 31 Jan '14, 12:09

cgnieder's gravatar image

cgnieder
22.1k253463


Jedem ASCII-Zeichen (mit XeLaTeX und LuaLaTeX vermutlich jedem Unicode-Zeichen1) ist unter anderem ein Kategorie-Code oder catcode zugeordnet. Es gibt 16 Kategoriecodes. Die folgende Tabelle listet sie auf zusammen mit LaTeX's Vorbelegung.

NummerFunktionZeichen
0Escape-Zeichen, leitet eine Befehlssequenz ein \
1Beginn einer Gruppe/eines Arguments {
2Ende einer Gruppe/eines Arguments }
3Wechsel in Mathemodus und zurück $
4Ausrichtung &
5Ende einer Zeile Return
6Parameter #
7Tiefstellung _
8Hochstellung ^
9ignoriertes Zeichen
10LeerzeichenLeerzeichen
11Buchstabea-z A-Z
12anderes Zeichenalle anderen
13aktives Zeichen ~
14Kommentar %
15ungültiges Zeichen

Die Kategoriecodes bestimmen, welches Zeichen eine Befehlssequenz einleitet, welche ein Argument beginnen und beenden, welche im Mathemodus Hoch- und Tiefstellung bedeuten usw.

Für den Anwender ist es in der Regel zweitrangig, darüber Bescheid zu wissen. Die wesentlichen Funktionen von \, {, }, $ usw kennt man ohnehin, ohne über Kategoriecodes etwas zu wissen. Wichtig ist vor allem die Unterscheidung zwischen Buchstabe und anderes Zeichen, da Befehlsnamen (die einem \ oder genauer: einem Zeichen mit Kategoriecode 0 folgen) entweder aus einer beliebigen Anzahl von Buchstaben (Kategoriecode 11) bestehen können oder aus einem Nicht-Buchstaben (Kategoriecode ungleich 11). Nach ersteren werden Leerzeichen ignoriert, nach letzteren nicht!

Open in Online-Editor
\documentclass{article}
\newcommand*\amp{\&}
\begin{document}
+\amp +\par
+\& +
\end{document}

alt text

Der Unterschied zwischen Buchstaben und Nicht-Buchstaben wird auch bei der Funktion des @ in internen Makronamen ausgenützt. Siehe dazu was machen eigentlich \makeatletter und \makeatother?. Ähnliches gilt für expl3 (die LaTeX3-Programmierkonvention), wo _ und : Buchstaben sind, Leerzeichen und Zeilenenden ignoriert werden und ~ ein normales Leerzeichen ausgibt.

Auch von Interesse ist vielleicht der Kategoriecode aktiv. Ein Zeichen, dessen Kategoriecode 13 ist, verhält sich wie eine Befehlssequenz. Man kennt hier üblicherweise ~. Der LaTeX-Kernel enthält

Open in Online-Editor
\catcode`\~=13
\def~{\nobreakspace{}}

Grundsätzlich kann der Kategoriecode jedes Zeichens zu jeder Zeit geändert werden. Das verwenden z.B. die Befehle und Umgebungen für Verbatim-Text, die es ja ermöglichen, auch die Zeichen, die nicht Buchstabe oder anderes Zeichen sind, direkt auszugeben. Die Vorbelegung wird soweit ich weiß1 teilweise vom Format und teilweise vom Kernel vorgenommen.

Der vorige Absatz stimmt nicht ganz: sobald ein Zeichen als Argument eines Befehls gelesen wurde, ist sein Kategoriecode fixiert. Daher müssen Befehle wie \verb auch erst die betreffenden Kategoriecodes ändern (man findet hier im LaTeX-Kernel die Anweisung \let\do\@makeother \dospecials) und dann einen weiteren Befehl aufrufen, der jetzt die Zeichen mit neuem Kategoriecode tatsächlich als Argument bekommt (im Fall von \verb selbst passiert das tatsächlich nicht, die Zeichen werden gar nicht als Argument gelesen, es gibt aber andere Beispiele).

Die gerade erwähnte Fixierung in Argumenten von Befehlen ist übrigens der Grund, warum man Befehle wie \verb nicht in Argumenten von Befehlen einsetzen kann. Es gibt keine Möglichkeit, die Fixierung der Kategoriecodes zu verhindern. Mit e-TeXs \scantokens gibt es allerdings die Möglichkeit, die Zeichen erneut „einzulesen“. Mit TeXs \string oder e-TeXs detokenize kann man Zeichen nachträglich noch Kategoriecode 12 zuweisen.

Der folgende Code zeigt jetzt noch ein Beispiel aus dem Kernel (Teil der Definition der verbatim-Umgebung), bei dem in einer Gruppe \, { und } zu anderen Zeichen werden und |, [ und ] temporär ihre Rolle übernehmen.

Open in Online-Editor
\begingroup \catcode `|=0 \catcode `[= 1
\catcode`]=2 \catcode `\{=12 \catcode `\}=12
\catcode`\\=12 |gdef|@xverbatim#1\end{verbatim}[#1|end[verbatim]]
|gdef|@sxverbatim#1\end{verbatim*}[#1|end[verbatim*]]
|endgroup

Meine Erfahrung und mein Wissen über \lccode und \uccode hält sich sehr in Grenzen: ich musste mich bislang noch nicht näher damit befassen. Sie bestimmen, was in den Argumenten von \lowercase und \uppercase passiert. Die Zeichen a--z haben lccode = Zeichencode, die Zeichen A--Z uccode = Zeichencode, Großbuchstaben haben den lccode der Kleinbuchstaben und die den uccode der Großbuchstaben. Andere Zeichen haben jeweils den Wert Null. Zum Beispiel hat »a« den Zeichencode 97, den lccode 97 und den uccode 65, »A« hingegen hat Zeichencode 65, lccode 97 und uccode 65. \uppercase und \lowercase gehen nun durch die Zeichen in ihrem Argument und ersetzen sie (wenn der lcode bzw uccode nicht Null ist) durch das Zeichen des entsprechenden lccodes bzw uccodes. Dabei ändert sich der Kategoriecode des Zeichens nicht.

Open in Online-Editor
\documentclass{article}

\usepackage{array}

\newcommand*\zeichen[1]{%
  -- #1 --\par
  Zeichencode: \number`#1 \par
  uccode: \the\uccode`#1 \par
  lccode: \the\lccode`#1 \par
  Kategoriecode: \the\catcode`#1 \par
}

\begin{document}

\catcode`\A=12

\begin{tabular}{*2{p{.33\linewidth}}}
  \zeichen{a} &
  \zeichen{A} \\
  \lowercase{\zeichen{A}} &  % wie \zeichen{a}, auch der Kategoriecode stimmt
  \uppercase{\zeichen{a}} % wie \zeichen{A}, auch der Kategoriecode stimmt
\end{tabular}

\end{document}

alt text

Als Anwendung ist mir vor allem der „\lowercase-Trick“ bekannt, den man anwenden kann, um einem Zeichen eine Definition zu geben, wenn es aktiv ist:

Open in Online-Editor
\documentclass{article}
\usepackage{xcolor}

\begingroup\lccode`~=`.
  \lowercase{\endgroup\def~}#1{\color{red}{#1}}

\newenvironment{strange}{\catcode`\.=13 }{}

\begin{document}

.foo
\begin{strange}
.foo
\end{strange}

\end{document}

alt text

Man nützt hier aus, dass ~ bereits aktiv ist. Dann setzt man temporär den \lccode von ~ gleich dem des Zeichens, dem man eine Definition geben möchte. Innerhalb von \lowercase wird dann ~ wie eine aktive Version des gewünschten Zeichens behandelt, so dass man ihm eine Definition zuweisen kann. Da das alles in einer Gruppe geschieht, ist das Zeichen hinterher nicht aktiv und ~ hat seinen ursprünglichen \lccode wieder. Macht man nun später das betreffende Zeichen aktiv (gibt ihm also Kategoriecode 13), dann hat es die hier gegebene Definition.

\lowercase „behandelt“ die Zeichen in seinem Argument, bevor die Anweisungen in seinem Argument ausgeführt werden. Man vermeidet damit, dass man die Definition global machen muss, da man die Gruppe schließen kann, bevor man die Definition vornimmt.


  1. Vielleicht kann das jemand bestätigen/verneinen?
Permanenter link

beantwortet 28 Jan '14, 11:59

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 01 Okt '15, 14:54

Der Absatz mit verbatim klingt etwas wirr. Der Catcode eines Zeichen liegt unverrückbar fest, sobald TeX das Zeichen gelesen hat - egal aus welchen Grund. Da die Argumente eines Befehls gelesen werden, bevor der Befehl ausgeführt wird, kann ein Befehl die catcodes seiner (echten) Argumente nicht ändern. Wenn er das trotzdem will, muss er sie noch mal einlesen z.B. mit \scantokens. \verb geht einen anderen Weg: es ist nicht als Befehl mit Argument definiert, sondern ändert erst diverse \catcodes (u.a. mit \dospecials) und schaut dann nach vorne und fangt an zu sammeln.

(29 Jan '14, 09:03) Ulrike Fischer

@Ulrike ich hab den Teil etwas überarbeitet. Ist er so besser?

(29 Jan '14, 09:30) cgnieder

@Clemens Sollte ich das etwa zu früh als beantwortet akzeptiert (und upgevote)t haben? ;-) Das wird ja von Tag zu Tag besser!

(30 Jan '14, 22:48) Speravir

@Speravir ich hab noch mal ein bisschen was zu den lc- und uccodes nachgelesen und dachte, ich geb das gleich mal weiter :)

(30 Jan '14, 23:02) cgnieder
2

Zu Fußnote 1: Jedes Zeichen wird einer Kategorie zugeordnet, egal ob nun ASCII oder Unicode. Hauptsache, es ist dem zugrundeliegenden TeX-System bekannt, ansonsten gibt es in der Ausgabe wirre Zeichen oder eben einen Fehler.

(02 Feb '14, 14:52) Herbert

@Herbert Danke! Das hatte ich vermutet

(02 Feb '14, 14:58) cgnieder

@Clemens Im letzten Codeblock, sollte es nicht besser heißen: \lowercase{\endgroup\def~}{\color{red}}? (\color besitzt nur ein Argument, den Farbnamen.)

(25 Okt '19, 12:41) AlexG
1

@AlexG ich wollte mit Sicherheit \textcolor{red}{#1} schreiben…

(25 Okt '19, 13:46) cgnieder
Ergebnis 5 von 8 show 3 more comments

Ein Beispiel für catcode-Spielereien, wobei ich die ersten Zeilen mit einem Kommentar versehen habe, damit der Einstieg etwas leichter ist ... Mit tex/xetex/luatex/etex/... laufen lassen. Der Autor steht unten rechts im Ei.

Open in Online-Editor
\let~\catcode   % Das aktive Zeichen ~ ist jetzt identisch zu \catcode
~`z0        % Zeichen z bekommt den catcode 0, wird also \
~`'01       % \catcode`'01, Hochkomma wird zu {
~`,02       % \catcode`,02, Komma wird zu }
~`406       % \catcode`406, 4 wird zu #
~`@11       % \catcode`@11, @ wird zum normalen Buchstaben
~`=13       % \catcode`=13, = wird aktiv
zdef=41'    % \def=#1{
~`4113      %   \catcode`#1 13
zgdef,=$$41'    %   \gdef}=$
~`4113
zcountdef,=++41'
                   ~`4113zlet,=AA'B!d6l;8p/Pa5Nr.eq3Ei[
              DSm@|H9c]o1M?TgJk-CF2*tnIj7Rf,=""'2d-NDDRIeMj|Nir
            -n-;.g./pjkCm1Bg;J7R3Ie!kmEae9djCEe6t8Dt@lpdCcM?or8m8
          rat]F3i.1m;[5M*agFiotMTml7a/Rd/pMe/|lB5-jca*iCIc!??9n.g!/
        mq2etc8MfSj8rmko-SSStB21plt?et5tNNT?BliPqi51Je8l|[-p.n.9/Tp[H
       a9[gkcTk[d/!ie5]F!iT[ri|kPDPHdaNrBp[Tp!.ra1j;.i8fd851i?BoS5||2m
      iE.F|Mq*.EcPq*-rB812?[C|MnCHnke|D13o|l3Rt/73p-[lf-/C3|kHan[Sqi!E2
     ltCiJEa*@]22dNng8RrpnoBk5DtH*9cH!rRdiEj|3tiBrPBBHEn8l|.e5593o3JPp;g
    i1pkS]Dp52SilElS-mt8l.2kgD]!ac]n-JPDReD@[JP?lNT6N-dEPNnNpIkNH/1@gNFCd
   e869SNnfCf9]*|6ni8BPeD7M519rq-;T3IPSt*6-F@@BP68D?-|/5DN?e5Hp3[BBHNk31|H
  9ge.maeERBqTc3tp@pNIpDtEqMeS.pe5FmHJ.-eDmpmC.8P;g1!1/[PDt/JDH1Bl]@1qmlPiJ
  N*PacC?1md;!!NE/k.S99I98gqpcn9c8NaEao[!1!kJfm99adfi1jp*/5Dea-R-1d8;I?|gPl
 ][ai-;8kgHlJ?cS3S-ic;ceE.EJn|nke2;Sa1!FIoadp1EBCig*[//9|55DJ.cqDB@6lERPP5-q
 cC.go-n3fE5;7-9faJf8Fo]gcEHa6.midi@f-/CHNHe/R7p|dqp|@do-q2qB3NEalCold3?*8B6
 D1jFq7-Ek@.icJ]l|F@-]n-HprI@pJNBCccN*;NR5lk.!5!M?M*ID;e@7ce/!Ef[ggt5jiHP/]N
 F-p1e[ESmS@g-kc;/p29[HE/MSnClCkMtn1ppHJ*g[f@Ilak6DeJM..o.;?P/19I-?!BE*]a!lq
 /an?5D7l9M]98d2M32|DJ2?5r|5Be|aa1J]|]Mn]TTqa?.k[ki2qrlfoHc@E;8R9Djime;J]M5S
 NiS;S[FPe91Ht-FR|aN..m6n99SeP7tT8qoRqecn97gHE/E!om?9]E9dPDTB*Pdt[dolk/kRj9o
 ]/RH9NfD8Rq2ra/2/N[H5J.aI3SkadJpfRDFT/mr]ECdPm|TTJDe1.;9.!mk-a.qCorTm*DfDp?
 Eqk2cI!JfNojFTPt@fSeCpaI!6C;TSd!|T?fFoNgJ@p|R8|aRHf16NPlrkiTnDgBdJ;Nn6D*ocn
  kC8?r2TgF?68PDF7aN*9.68|1gg31.B-k3-I;5]2kRplq..]j|Eq5JmeE7iSI;;fp/25|/-gE
  -Tdqf;D*S6RFg9@|n*mRJS?9orI/HNJiT|o!8,=[[',+]][$CC0C0$TT1T25+&&zadvance+*
   *zmultiply+//zdivide+##zifnum[[+))zfi+((zifx+||zelse[[+>>zexpandafter+;
    ;zxdef[[+::zgdef[[=z}}4142'>;zcsname41zendcsname'42,,[[=z{{41'zcsname
     41zendcsname,[[=!!41';]']41,,+z\\zthe[[=PP4142$'}41'\C,&C1:A'42,,=V
      V'>PA$(A]|>V),V=GG'TC/C10*C10&T-C/C10!'\T,,[=DD414243'>C{'43,*C50
       >T{'42,&CT*C50>T{'41,&CTGGGGGzfutureletAV,=YY41',:V'(A$>Y|>D),!
        3!.>D"$$RR2R38$YY3Y-R&Y1$XX5[[=SS4142$'41:]'42,,=OO'>S]$,[[=Q
          Q41'T41*T41&CT,=HH'C0QXQYC-CQR,=BB'#X<RH#C<0P|O)&X1>B),=L
            L'#Y<RX-Rzhbox'B,&Y2>L),=PP'zhskip0.5em,zvbox'zttL,[:
              Y41',;A'bYryYge,=::41i'>{>'A,,~`412:stephen.hicks
                 3.14159265358979323846264338327950288419716
                    9399375105820974944592307816406286208
                        99862803482534211706798214808
                                   kthxbai
\bye
Permanenter link

beantwortet 02 Feb '14, 15:11

Herbert's gravatar image

Herbert
5.1k34
Akzeptiert-Rate: 31%

bearbeitet 01 Okt '15, 19:44

1

Ja, so wird die Frage erst in vollem Umfang abgerundet! PIn beeindruckt. Aber weil Du angefangen hast, setze ich noch zwei Links hier rein: xii.tex von David Carlisle (wird außerdem sowohl mit MiKTeX als auch TeX Live mitgeliefert) und xcix.tex von Enrico Gregorio. („Autor steht unten rechts“ ist leider etwas missverständlich, vgl. deshalb http://permalink.gmane.org/gmane.comp.tex.texhax/15416 .)

(03 Feb '14, 01:49) Speravir

OK, wenn ich die Originalquelle bei tug.org denn gefunden hätte. Der zweite Link ist ja im ersten angegeben. Man sieht zwar nur dort den Kreis, allerdings muss ich dazu den Webseitenstil abschalten.

(03 Feb '14, 18:29) Speravir

du siehst doch durch den gmane-Link, dass es eigentlich die texhax-Mailingliste ist.

(03 Feb '14, 19:33) Herbert

Jetzt ja, aber auch dann hätte ich nicht ohne Weiteres die originale Quelle gefunden.

(04 Feb '14, 16:42) Speravir
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×22
×2

gestellte Frage: 27 Jan '14, 23:10

Frage wurde gesehen: 16,898 Mal

zuletzt geändert: 25 Okt '19, 13:46