LaTeX3: Neue Mechanismen für die nächste Generation von Dokumenten

Seite 2: Gesteuerte Expansion

Inhaltsverzeichnis

exp13 vereinfacht das Manipulieren der Expansion. Bei "plain" TeX ist die Expansionssteuerung gewöhnungsbedürftig und schwer durchschaubar. LaTeX3 ermöglicht es nicht nur, gezielt zu expandieren, sondern auch ein besseres Verständnis für den dahinter steckenden Mechanismus von TeX zu erhalten. Hierfür existieren die Parameter N/n (No manipulation), c (csname), V/v (value), o (once), x (exhaustive) und f (full). Die Funktionsweise lässt sich anhand eines Beispiels erklären. Zunächst erfolgt die Deklaration einiger Makros:

\newcommand\eins{eins}
\newcommand\zwei{\eins, zwei}
\newcommand\drei{\eins,\zwei,drei}

Jedes Makro ist nun eine Art Kiste, deren Inhalt für LaTeX bis zur Expansion verborgen bleibt. (s. Abb. 1, links) Wenn \eins im Textmodus aufgerufen wird, wird die Kiste "ausgepackt" (s. Abb. 1, rechts). Da dieses Makro nur Text enthält, ist keine weitere Expansion möglich.

Die Bedeutung des Makros ist in einer Box verpackt (links). LaTeX erkennt die Bedeutung erst bei der Expansion (rechts) (Abb. 2).

Bei Kompilierungsprozessen ist die Ausgabe in diese Boxen nicht realisierbar. Hierfür eignet sich das expl3-Makro \tl_show:. \show existiert bereits in "plain" TeX, gibt die Bedeutung des nachfolgenden Tokens auf der Konsole aus und schreibt diese Informationen ins Log. Egal ob in TeX oder LaTeX3 sollte für die Nutzung der Debugging-Ausgaben über die Kommandozeile kompiliert werden: \tl_show:n stoppt den Compiler an der entsprechenden Stelle und zeigt den Wert seines Arguments an. Der Vorgang lässt sich anschließend mit Enter fortsetzen und mit X abbrechen.

\tl_show:n {\drei}

gibt durch den Parameter n den Inhalt der nachfolgenden Gruppe ohne Expansion aus.

Ausgabe von \tl_show:n {\drei}. Enter[ setzt den Kompiliervorgang fort (Abb. 3).

Da \tl_show:n nur als nicht expandierende Variante existiert, müssen zunächst Varianten für die Expansion mit den Parametern o, f und x erzeugt werden. Alle Varianten verhalten sich nun identisch bis auf die Handhabung des Arguments.

\ExplSyntaxOn
\cs_generate_variant:Nn \tl_show:n {o,f,x}

\tl_show:n {\drei}
\tl_show:o {\drei}
\tl_show:f {\drei}
\tl_show:x {\drei}
\ExplSyntaxOff

\cs_generate_variant erzeugt dabei zunächst Varianten des Makros \tl_show:n, sodass es auch die anderen gibt. Alle vier Varianten verhalten sich nun identisch bis auf die Handhabung des Arguments.

Die Wirkung lässt sich direkt über die Konsole beobachten: \tl_show:o erzeugt

\eins ,\zwei ,drei

Das ist bis auf das für bessere Lesbarkeit eingefügte Leerzeichen identisch zur Definition des Makros. Bei einfacher Expansion ersetzt der Compiler somit das Makro durch den Text der Deklaration. Das entspricht dem Öffnen der äußersten Box:

Das Makro \drei mit der zugehörigen ersten Expansion (Abb. 4)

\tl_show:f ergibt

eins,\zwei ,drei.

Das entspricht einer zweifachen Expansion. Allerdings ist der begrenzende Faktor dabei, dass das Makro \eins lediglich ein Mal expandierbar ist, es enthält keine weitere geschlossene Box, sondern ein freiliegendes Text-Element, das nicht weiter expandiert.

Darstellung der vollständigen Expansion (Abb. 5)

Eine vollständige Expansion wird somit beendet, wenn eines der Makros keine weitere Expansionsstufe mehr hat. In diesem Fall entspricht das Vorgehen einer zweifachen Expansion.

\tl_show:x führt hingegen eine gründliche Expansion durch. Es hat keine Begrenzung und expandiert die weiter expandierbaren Teile unabhängig vom Rest weiter. Somit ergibt es:

eins,eins,zwei,drei

Darstellung der exhaustive_exp3 (Abb. 6)

Da für die Ausgabe als letzter Schritt ohnehin eine gründliche Expansion notwendig ist, wirkt die Kontrolle darüber zunächst unnötig. Allerdings ist Expansionssteuerung für die automatisierte Verarbeitung von Daten unerlässlich: Betrachtet man die Anzahl der Kommata, fällt auf, dass \tl_show:n mit "\drei" kein einziges Komma enthält, wohingegen "eins,eins,zwei, drei" über drei verfügt. Würde man diese Token-Liste (tl) also als Komma-Liste (clist) speichern, hätte die erste Variante nur ein Element und die letzte vier.

Expansionssteuerung ist immer dann nötig, wenn der Inhalt eines Arguments möglichst keinen Einschränkungen unterliegen soll. In diesem Fall darf das einzelne Element Kommata enthalten, ohne dass es zerrissen wird.

Neben den Spezifikationsparametern für die Expansion von Makros existieren noch vier weitere Varianten, die spezielleren Mechanismen für die Arbeit mit Variablen dienen. Diese wurden mit Beispielen im zweiten Teil des LaTeX-Tutorials der iX erläutert.

Ein weiteres Feature in expl3 sind die längeren Makronamen. Das wirkt zunächst ineffizient, gestaltet den Code jedoch deutlich lesbarer und ermöglicht es, die Zuordnung von Makros durch eine feste Namensstruktur zu vereinfachen. Dadurch ist die neue Syntax nach erster Einarbeitung deutlich intuitiver und liefert zusätzlich ein einheitliches Interface für die bisherige Mischung aus TeX- und LaTeX-Befehlen.

Makro- und Variablennamen sollten immer über einen Namensteil verfügen, der dem Modul entspricht. Das Modul ist sozusagen die Ursprungsbezeichnung und erleichtert das Auffinden der Dokumentation des Makros. Das verhindert nicht nur Namenskonflikte, sondern vereinfacht zudem das Identifizieren von Datentypen bei Variablen. Das Benennen der Module erfolgt üblicherweise nach dem zugehörigen Paket oder Bundle. Bei den primitiven Makros ist es immer der Programmname. Alle durch LuaTeX eingeführten Makros beginnen beispielsweise mit \luatex_. Darüber hinaus gehören die einzelnen Datentypen zusätzlichen Modulen an. Somit setzt das Makro \int_set:Nn aus dem Integer-Modul eine Ganzzahl, wohingegen \str_set:Nn für Strings zum Einsatz kommt. Da der Variablennamen ebenfalls eine Typbezeichnung erhält, verringern sich die Fehler aufgrund von Verwechslung.

Allgemein sollten Entwickler die folgende Namensstruktur verwenden:

  • Funktionen: \<Modul>_<Funktionsname>:<Argumentenspezifikation>
  • Variablen: \<Gültigkeit>_<Modul>_<Variablenname>_<Typ>

Detaillierter sind die Namensstruktur und die Bedeutung der Argumentenspezifikation in Teil 2 des iX-Tutorials zu LaTeX geschildert.