Programmieren in TeX / LaTeX

Eine umfassende Dokumentation zur Programmierung von LaTeX Klassen und Paketen gibt es leider nicht. In den Anfängen kommt man zwar mit dem LaTeX Begleiter und dem clsguide.pdf in das Thema hinein, hat dann aber nicht zum Anschließen. Häufig wird man bei dem Thema auf das TeXBook verwiesen welches TeX und PlainTeX in aller Ausführlichkeit erklärt aber ganz offensichtlich alle LaTeX Befehle auslässt die einem die Programmierung erheblich vereinfachen können bzw. notwendig zur LaTeX Klassen und Paket Programmierung sind. Im Folgenden versuche ich meine Erkenntnisse (vielleicht in einer Serie) hier darzustellen.

Für die TeX Kommandoes empfehle ich ebenfalls in diese Liste zu schauen: TeX Primitive Control Sequences.

Variablen von TeX / LaTeX

Es gibt Zählervariablen (int), Längenvariablen (float) und Wahrheitswerte (bool) sowie Makros die Strings und Befehle enthalten können. Eine Klassische Einteilung in int, float, bool, string gibt es nicht.

Zählervariablen (counter)

Counter speichern Integer Werte. Die Deklaration erfolgt über
\newcounter{mycounter}
Der Wert wird dabei mit 0 initialisiert. Eine Veränderung erfolgt über
\setcounter{mycounter}{2}
Den Wert erhält man als Zahl über
\value{mycounter}
diese Ausgabe ist allerdings nur innerhalb der Programmierung nutzbar. Die Textausgabe hingegen erhält man durch ein Voranstellen von \the
\themycounter
möchte man die Ausgabe in einer bestimmten Notation ist dies möglich durch
\arabic{mycnt}  % Wert von mycounter als Textstring in arabischen Ziffern
\roman{mycnt}  % Wert von mycounter als Textstring in römischen Ziffern
von diesen Notationen gibt es weitere die hier nicht aufgeführt sind. Zur Rechnung stehen Counter nicht direkt zur Verfügung. Man kann sie jedoch einstellen und erhöhen:
\setcounter{mycounter}{2}     % mycounter = 2
\addtocounter{mycounter}{4}  % mycounter = 6
\addtocounter{mycounter}{\value{othercounter}}
Eine Erhöhung speziell um 1 erfolgt über
\stepcounter{mycounter} % Zähler um 1 inkrementieren

Längenvariablen (length)

Die Längenvariablen entsprechen Flieskommazahlen (float) in eine gewöhnlichen Programmiersprache. Diese Längen werden in Abhängigkeit einer Maßeinheit (mm, cm, pt. . . ) abgespeichert. Die Definition und Zuweisung erfolgt analog zu den countern
\newlength{\mylen} %Deklaration
\setlength{\mylen}{<NeueLänge>} %Zuweisung
\addtolength{\mylen}{<ZusatzLänge>} % Operator
Längen können auch variabel sein:
\setlength{\mylen}{<NeueLänge>plus <P> minus <M>}
Die Textausgabe erhält man durch ein Voranstellen von \the
\the\mylen
Die Ausgabe zwischen Countern und Längen ist somit unterschiedlich
\newcounter{mycounter}
\themycounter
\newlength{\mylength}
\the\mylength
Die jeweiligen TeX Äquivalente werden jedoch beide mit \the vorgestellt ausgegeben.
\newcount\mycounter
\the\mycounter
\newskip\mylength
\the\mylength
Eine interessante Funktion in diesem Zusammenhang ist \settowidth welche die Länge eines Textes vermisst und in einem Längenregister speichert.
\settowidth{\mylen}{Text} % misst die Breite von "Text"

Wahrheitswerte (boolean)

Die Wahrheitswerte entsprechen boolschen Variablen in eine gewöhnlichen Programmiersprache. Hierfür wird das Paket ifthen benötigt. Die Definition und Zuweisung erfolgt analog zu den Countern und Längen
\newboolean{boolvar} %Deklaration
\setboolean{boolvar}{false} %Zuweisung
Eine Abfrage des Werten erfolgt über
\boolean{boolvar}
welcher z.B. bei if Abfragen genutzt wird
\ifthenelse{\boolean{boolvar}}{}{}

Rechnen innerhalb von TeX

  • \advance
    \advance<Numerische Variable> by <Zahl>
  • \divide
    \divide<Numerische Variable> by <Zahl>
  • \multiply
    \multiply<Numerische Variable> by <Zahl>

If Abfrage

TeX kennt die Struktur
\if
...
\else
...
\fi
wobei es eine größere Anzahl von vordefinierten If-Abragen gibt
\ifundefined
\ifnum
\ifodd
\ifdim
\iftrue
\iffalse
\ifx
...
Hier einige Beispiel dazu
  • Test ob der Wert eines Counter \count0 kleiner ist als 100
    \ifnum\count0<100
    ...
    \else ... \fi
  • Vergleich zweier Integerwerte
    % Alles TeX und kein LaTeX Code!
    \newcount\WertA
    \newcount\WertB
    \WertA=20
    \WertB=\WertA
    \ifnum\WertA=\WertB
    	Werte stimmen überein
    \fi
  • Vergleich von Dimensionswerten (Längen): \ifdim
    \newlength{\firstlen} 
    \newlength{\secondlen} 
    \settowidth{\firstlen}{Text} % misst die Breite von "Text"
    \settowidth{\secondlen}{anderer Text} % misst die Breite von "anderer Text"
    \ifdim\firstlen=\secondlen
    	Werte sind gleich und haben die Länge \thefirstlen
    \else
    	Werte sind ungleich
    \fi
    Latex kennt das Kommando \lengthtest{1pt < 2pt} was dem \ifdim entspricht.
  • Testen ob eine Makro definiert ist (eine Definition als \relax reicht dafür aus)
    \ifundefined{TeX} 
    	true text 
    \else 
    	false text 
    \fi
    hierfür gibt es allerdings noch weitere Möglichkeiten, siehe dazu auch Existenz von Paketen prüfen
  • Testen von 'Gleichheit' zweier Makros ohne Sie zu expandieren: \ifx. Hier ein Beispiel aus dem TeXBook
    \def\a{\c} 
    \def\b{\d}
    \def\c{\e} 
    \def\d{\e} 
    \def\e{A}
    \ifx\c\d
    	 wahr
    \fi
    \ifx\a\b
    	 nicht wahr
    \fi
    Die Frage wann das Ergebnis true zurückgibt ist komplex und wird vom TeXBook wie folgt beschrieben
    The condition is true if (a) the two tokens are not macros, and they both represent the same (character code, category code) pair or the same TEX primitive or the same \font or \chardef or \countdef, etc.; or if (b) the two tokens are macros, and they both have the same status with respect to \long and \outer, and they both have the same parameters and “top level” expansion.
LaTeX bietet zum Testen von If Abfragen noch die Befehle \equal {\Makro }{ ABC }, \and, \or, \not sowie zum Schachteln von Bedingungen die Klammern , \( und , \).

Weitere Möglichkeiten zu If-Anweisungen sind hier dargestellt:

\ifcase Anweisung

Diese Abfrage ist vergleichbar mit einer switch Anweisung. Sie hat die Syntax
\ifcase\number 
         text for case 0 
\or 
         text for case 1 
\or
         ...
\or
          text for case n
 \else 
         text for all other cases 
\fi
Hierbei wird über die Zahlen von \number die Anweisung ausgewählt.

TeX Funktionen

Nur eine Auswahl...
  • \string
    gibt ein folgendes Kommando inklusive dem Backspace aus
  • \relax
    Donald Knuth schreibt dazu das es TeX sagt:"do nothing." Darüber hinaus führt es dazu dass Makros die auf darauffolgende Tokens agieren mit diesem Befehl keine weiteren Token aktzeptieren.

LaTeX Funktionen

Nur eine Auswahl...
  • \g@addto@macro
    Hängt weitere Befehle an ein bestehendes Makro an
    \g@addto@macro{\<macroname>}{<Zus. Befehle>}

Schleifen

\whiledo (nur LaTex)

Benötigt das Paket ifthen. Im Beispiel wird zusätzlich das Paket pifont benötigt.
\newcounter{ctra}
\setcounter{ctra}{1}
\whiledo {\value{ctra} < 7}%
{%
\thectra {\large \ding{111}}%
\stepcounter {ctra}%
}
Ausgabe:
\newcounter{ctra}\setcounter{ctra}{1}\whiledo {\value{ctra} < 7}{\thectra {\large \ding{111}}\stepcounter {ctra}}

\loop (TeX)

\loop
	\ifnum\n>0 % Abbruchbedingung (\if ohne \fi)
...
\repeat

For Schleife (LaTeX)

Das forloop Paket stellt eine for Schleife zur Verfügung.
\newcounter{ct}
\forloop{ct}{1}{\value{ct} < 5}%
{%
	\arabic{ct}
}
Ausgabe:
 \newcommand{\forloop}[5][1]{%    \setcounter{#2}{#3}    \ifthenelse{#4}{%       #5\addtocounter{#2}{#1}       \forloop[#1]{#2}{\value{#2}}{#4}{#5}% 	}{} }% \newcounter{ct} \forloop{ct}{1}{\value{ct} < 5} {\arabic{ct}}