Tipps zum Golfen in TeX / LaTeX

28

Welche Tipps haben die Leute zum Golfen in TeX / LaTeX? Bitte posten Sie einen Tipp pro Antwort, der mindestens etwas spezifisch für TeX / LaTeX ist.


Kontext: Ich habe diese Antwort bemerkt und festgestellt , dass es für TeX / LaTeX keine Tipps gibt. Daher erstelle ich diese. Es gibt einige Überschneidungen mit den engeren Fragetipps für das Golfen in TikZ (da TikZ ein spezifisches Makropaket auf TeX / LaTeX ist): Antworten auf diese Frage werden wahrscheinlich auch dort zutreffen, aber nicht umgekehrt.

ShreevatsaR
quelle
Wie kann man eine Nicht-Programmiersprache Golf spielen?
The Great Duck
1
@TheGreatDuck Sehr schlecht :-)
ShreevatsaR
@TheGreatDuck Eigentlich TeX ist eine Programmiersprache, auch wenn es in der Regel nur als typographische ein verwendet wird .
gvgramazio

Antworten:

15

Berücksichtigen Sie statt der dokumentierten interne LaTeX-Makros

Dies ist beispielsweise \romanein dokumentiertes LaTeX-Makro, das auf LaTeX-Zählern funktioniert. Um daraus 42zu werden XLIV, müsste man so etwas benutzen

\newcounter{z}
\setcounter{z}{42}
\roman{z}

Wenn Sie stattdessen nachsehen, wie \romandas implementiert ist (verwenden Sie es \show\roman, um es interaktiv abzurufen, anstatt die Quelldateien zu lesen), können Sie feststellen, dass es in Form eines nützlichen Makros namens implementiert ist \@roman, und verwenden Sie es stattdessen direkt:

\catcode`@11
\@roman{42}

\catcode`@11ist die golfige Schreibweise \makeatletter(Clean Way in LaTeX) oder \catcode`\@=11(Clean Way in Plain TeX). Es wird zu Beginn nur einmal benötigt, danach können Sie Makronamen verwenden, die enthalten @.

ShreevatsaR
quelle
13

~kann als Makro verwendet werden (wie auch andere aktive Charaktere)

Beispiel

Vor:

\def\a{...some definition...} ... use \a...

Nach:

\def~{...some definition...} ... use ~...

Erläuterung : Im Allgemeinen sind Makros in TeX „Steuersequenzen“: Sie können \somethingoder definieren \a. Sie können aber noch kürzer werden, indem Sie einen aktiven Charakter verwenden. Das einzige aktive Zeichen, das standardmäßig vorhanden ist (in TeX / LaTeX), ist ~(verwendet für "Krawatten", dh definiert als \penalty \@M \in TeX (eine Strafe von 10000, gefolgt von einem Leerzeichen) und als \nobreakspace {}in LaTeX). Aber nichts hindert Sie daran, es für den von Ihnen gewünschten Zweck neu zu definieren.

Weiter : Sie können dasselbe mit jedem anderen Zeichen tun, indem Sie dessen Katcode auf \active(13) setzen. Zum Beispiel machen Zhat einen aktiven Charakter ein „Kosten“ von 12 Bytes \catcode`Z13. Dann können Sie einfach Züberall anstelle eines Makros wie verwenden \z. Bei einigen Zeichen, die mit einer bestimmten Bedeutung beginnen, funktioniert der direkte Backtick-Ansatz nicht und Sie benötigen ein weiteres Zeichen: \catcode`\Z13oder \catcode90=13.

ShreevatsaR
quelle
9

\def kann festen Mustern entsprechen

Angenommen, Sie hatten \def\a #1 #2 {...some definition here...}. Wenn Sie es dann auf eine Zeichenfolge wie aufrufen, können \a Act42, Scene26die Argumente innerhalb des Makros wie # 1 <- Act42,, # 2 <- zugewiesen werden , Scene26und dann müssen Sie einige weitere Arbeiten ausführen, um die relevanten Teile zu extrahieren. Stattdessen könnte man direkt schreiben

\def\a Act#1, Scene#2 {...some definition here...}

und dann aufrufen, als \a Act42, Scene26würde direkt # 1 <- 42und # 2 <- gesetzt 26.

(Dies ist im Grunde die Definition von \def, aber es ist leicht zu vergessen, da dies in LaTeX normalerweise nicht der Fall ist und Argumente lieber übergeben werden, {}als wären es Funktionsaufrufe.)

ShreevatsaR
quelle
8

Wahl zwischen TeX und LaTeX

Darüber lässt sich viel sagen, aber vergleichen Sie kurz gesagt ein typisches einfaches TeX-Dokument, das "Hallo" druckt, mit einem typischen LaTeX-Dokument für dasselbe:

Hello
\bye

gegen

\documentclass{article}
\begin{document}
Hello
\end{document}

Die "Kosten" von LaTeX (Wrt-Code Golf) liegen auf der Hand. Der "Vorteil" ist natürlich, dass LaTeX eine Bibliothek mit vielen vorgefertigten Makros und Paketen enthält, von denen einige für die jeweilige Aufgabe nützlich sein können.

ShreevatsaR
quelle
Ich war fest in der Verwendung von LaTeX verhaftet, weil \@Roman(es würde eine Menge Bytes kosten, wenn Großbuchstaben im Klartext verwendet würden) - aber einfaches TeX war oft kürzer.
Chris H
8

\input ... ist kürzer als \usepackage{...}

Zum Beispiel können Sie schreiben

\input color

anstatt

\usepackage{color}

Das sind 6 Bytes weniger.

Tödlich
quelle
8
Es ist jedoch sinnvoll, darauf hinzuweisen, dass dies mit \usepackagezunehmender Anzahl der enthaltenen Pakete effizienter wird. Da Sie mehr als ein Paket mit nur einer \usepackageAnweisung verwenden können, aber \inputfür jedes Paket eine benötigen , ist \usepackagedie Option " Wenn Sie 3 oder mehr Pakete verwenden" die bessere.
Weizen-Assistent
7

Wenn Sie LaTeX verwenden, verwenden Sie eine kurzedocumentclass (Idee von Chris H )

Anstatt mit dem Typischen zu beginnen

\documentclass{article}

Man kann kürzere Dokumentenklassen wie bookoder sogar wählen

\documentclass{ecv}

oder

\documentclass{tui}
ShreevatsaR
quelle
Sie sollten daran denken, innerhalb der Spezifikationen der Frage zu bleiben, articlestandardmäßig nummeriert seine Seiten, dies kann als zusätzliche Ausgabe angesehen werden. Vielleicht ist eine Meta-Frage, um zu bestimmen, welche Dokumentenklassen erlaubt sein sollen.
Weizen-Assistent
@ WheatWizard Guter Punkt. Ich denke, es kann an der individuellen Frage liegen, ob Seitenzahlen als zusätzliche Ausgabe gelten.
ShreevatsaR
Ich denke, eine minimale Klasse wäre eine gute Idee - ein einzelner Buchstabe und keine Seitennummerierung
Chris H
Ich habe eine zusammengestellt, g.clsdie nur article.clsmit ist, \pagenumbering{gobble}aber da der Github unten ist, kann ich es vorerst nicht aufstellen
Chris H
g.cls
Chris H
7

Das Erstellen einer Umgebung mit dem Namen myenvironmentgeneriert die Befehle \myenvironmentund \endmyenvironment. Diese werden intern verwendet, um die Umgebung zu starten und zu beenden. In einigen Fällen können sie als Verknüpfungen verwendet werden. Zum Beispiel anstelle von

\begin{itemize}
\item abc
\end{itemize}

man kann tun

\itemize
\item abc
\enditemize

Nicht unterstützt, nicht zuverlässig, funktioniert nicht in allen Fällen, auf eigene Gefahr usw. usw.

Ian Thompson
quelle
Willkommen auf der Seite!
DJMcMayhem
3
Sie können oft \itemize{...}noch mehr sparen.
Weizen-Assistent
4

\usepackage{packagea,packageb,packagec} funktioniert, solange Sie keine Optionen an die Pakete übergeben.

Chris H
quelle
4

Führen Sie die Zeilen zusammen. Zeilenumbrüche werden in LaTeX / TeX im Vergleich zu vielen Langformsprachen selten benötigt.

Chris H
quelle
3

Einige Makros, für deren Argumente möglicherweise geschweifte Klammern erforderlich sind, tun dies tatsächlich nicht, insbesondere, wenn sie in einem anderen Makro mit #1-style-Argumenten verwendet werden.

Die meisten Makros benötigen nur geschweifte Klammern, wenn das Argument mehr als ein Token (Zeichen oder Kontrollsequenz) enthält.

\mymacro1          % equivalent to \mymacro{1}
\mymacro{12}       % equivalent to \mymacro{12}
\mymacro a         % equivalent to \mymacro{a}
\mymacro{ab}       % equivalent to \mymacro{ab}
\mymacro\foo       % equivalent to \mymacro{\foo}
\mymacro{\foo x}   % equivalent to \mymacro{\foo x}
Chris H
quelle
3

Wenn Sie dasselbe Makro mit einem langen Namen mehrmals verwenden müssen, können Sie \leteinen kürzeren Alias ​​definieren.

\let\a\mymacrowithalongname
\a{foo}\a{bar}\a{qux}

Dies spart zwei Bytes \def\a{\mymacrowithalongname}, wenn Sie nicht mehrere Token in der Definition benötigen.

Anstelle eines Makronamens können Sie ein aktives Zeichen zum Speichern von Backslashes verwenden.

Beachten Sie, dass \letdies nicht nur mit Makronamen funktioniert, sondern auch mit integrierten Grundelementen. Wenn Sie zum Beispiel viele \ifnum ... \fiKonstrukte in Ihrem Code verwenden, können Sie durch das Definieren \let\i\ifnumund Verwenden von \i ... \fiein paar Bytes sparen. Dies funktioniert auch für \letsich selbst: \let\l\let.

Gilles 'SO - hör auf böse zu sein'
quelle
3

Verwenden Sie lokale {... }Gruppen mit Bedacht

Wie in dieser Antwort hervorgehoben , können aktive Zeichen wie ~als Makroname verwendet werden. Leider ~ist dies standardmäßig das einzige aktive Zeichen, und das Ändern des Catcodes für ein anderes Zeichen ist teuer: \catcode`!13dauert 12 Byte. Wenn die neue Makrodefinition nur in einer kleinen Region Ihres Codes benötigt wird, können lokale Gruppen eine Lösung sein.

Wenn TeX eine neue lokale Gruppe betritt, die von geöffnet wurde {, erstellt es eine neue Gruppierungsebene auf dem internen Speicherstapel. Dies bedeutet, dass alle aktuellen Makros und Register gespeichert werden. Änderungen an ihnen (sofern nicht ausdrücklich als markiert \global) sind nur noch aktiv, bis die Gruppe durch geschlossen wird }. Dies bedeutet, dass ~innerhalb einer Gruppe neu definiert und dort mit der neuen Definition verwendet werden kann. Die alte Definition wird nach Beendigung der Gruppe automatisch wiederhergestellt.

Hier ist ein Beispiel:

\def~{abc}
~ -- {\def~{123}~} -- ~

Dies gibt aus

abc - 123 - abc

Ein interessanter Nebeneffekt dieses Gruppierungsmechanismus ist, dass die alten Werte in der Gruppe noch verfügbar sind, bis sie dort geändert werden. Stellen Sie sich zur Veranschaulichung vor, wir möchten eine Anzahl von Zeichen basierend auf dem Wert eines Zählers drucken, sie mit Leerzeichen bis zu einer festen Länge auffüllen und mit dem ursprünglichen Zählerwert fortfahren. Dies könnte folgendermaßen erreicht werden:

\newcount\x
\x=3
Print a char \the\x\ times,
{\x=-\x \advance\x 10 pad with \the\x\ spaces,}
and go on with x=\the\x.

welche Ausgänge

Drucken Sie ein Zeichen dreimal, füllen Sie es mit 7 Leerzeichen auf und fahren Sie mit x = 3 fort.

Dieses Gruppierungsverhalten ist besonders wichtig, wenn Sie die Standardmakros von TeX für das \loop ... \repeatVerschachteln von Schleifen verwenden möchten . Diese Makros definieren interne Befehle und verwenden diese, um die weitere Vorgehensweise zu bestimmen. Wenn Sie sie verschachteln, ohne die innere Schleife in geschweifte Klammern zu setzen, werden die internen Befehle durcheinander gebracht und es kommt zu unerwartetem Verhalten.

Siracusa
quelle
1

Die Weiterentwicklung von Zählern, wie z

\advance\u by 1
\multiply\u by 3
\divide\u by 2

auch arbeiten als

\advance\u1        % \u = \u + 1
\advance\u-1       % \u = \u - 1
\multiply\u3       % \u = \u * 3
\multiply\u\u      % \u = \u * \u
\divide\u2         % \u = \u / 2

Das gleiche Prinzip gilt auch für die Initialisierung:

\newcount\u\u1

setzt den Zähler auf 1.

Beachten Sie, dass diese ein Leerzeichen (Zeilenumbruch oder Leerzeichen) nach sich ziehen müssen (oder a \relax, aber das gleiche gilt für Leerzeichen), damit der nächste Befehl nicht ignoriert wird. Beispielsweise,

\u1\the\u

druckt NICHT \ u, ignoriert aber den \theBefehl.

Simon Klaver
quelle
1

\enddocumentstatt \end{document}speichert zwei Zeichen

sheß
quelle
Scheint nicht zu Arbeit \begin{document}=> \documentobwohl
Shess