Gepostet von
pospiech am Apr 13, 2008 in
LaTeX |
19 Kommentare
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
Der Wert wird dabei mit 0 initialisiert. Eine Veränderung erfolgt über
\setcounter{mycounter}{2} |
Den Wert erhält man als Zahl über
diese Ausgabe ist allerdings nur innerhalb der Programmierung nutzbar.
Die Textausgabe hingegen erhält man durch ein Voranstellen von
\the
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
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
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
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:
\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:
Einen Kommentar schreiben
Hallo Matthias,
super Seite! Vielleicht kannst Du noch im Abschnitt “Wahrheitswerte (boolean)” in die erste Zeile schreiben “Benötigt das Paket ifthen”. Da bin ich drüber gestolpert beim Ausprobieren.
Gruß,
Christof
Hallo,
super informativ.
Gibt es vielleicht eine Moeglichkeit 2 Textteile zu vergleichen, die auf Parametern stehen?
oder kann ich mir da irgendwie anders behelfen?
Gruss
Ich weiß nicht genau was du meinst. Aber vielleicht ist das Paket xstring was für dich. Getestet habe ich das Paket allerdings nicht.
Sehr schöne Übersicht! Zum schnellen Nachschlagen fänd ich aber noch ein Beispiel einer komplexeren IF-Bedindung sehr schön. Mir war die Existenz von \and etc. erst beim genaueren Durchlesen aufgefallen.
Die Bedeutung und der Nutzen von \string wird leider auch nicht ganz klar.
Hallo!
Sehr informativ – auch wenn ich für meine Problemstellung keine Lösung gefunden habe – vielleicht sehe ich auch “den Wald vor lauter Bäumen nicht”.
Ich beschreibe mal kurz das Problem. Ich mache einen Serienbrief – der ist fertig bis auf die letzte Logik. In der Adressdatenbank dazu sind die Informationen über Zahlungsrückstände, kein Rückstand und Überzahlungen zu finden Feld #4. In einem weiteren Feld #6 ist die Art der Mitgliedschaft Ermäßigt, Vollzahler, Ruhend. Aus diesen Informationen ist der Brieftext auszuwählen.
D.h. Überzahler bekommen die Info dass sie nichts zahlen müssen, Rückstand den Text für Rückstand, bzw. Rückstand und kein Rückstand bekommen zusätzlich die Info für den nächsten Beitrag.
Die Lösung mit jenen die nichts zahlen müssen (die Überzahler) schaffe ich nicht zu implementieren – die Verschachtelung gelingt nicht. Habt ihr da Ideen dazu? Danke
Hi,
Cool wären noch ein paar Worte zu Zeichenkettenvariablen
.
Ralf
Leider bin ich kein Experte in der LaTeX/TeX Programmierung. Der Artikel hier habe ich beim Lernen zusammengeschrieben. Daher kann ich leider auch nichts zu ‘Zeichenkettenvariablen’ verfassen, wobei ich aber auch nicht weiß was du genau meinst.
Ich hatte gerade selbst das Problem eine Art Switch-Klausel zu konstruieren, die eine Buchstabenliste in Bezug auf einen Buchstaben auswertet. Dabei bin ich auf folgende Lösung gekommen:
\documentclass{article}
\usepackage{etextools}
\begin{document}
\ifincharlist{x}{a b c}{ja}{nein}
\ifincharlist{b}{a b c}{ja}{nein}
\end{document}
P.S.: Noch besser erscheint mir das Paket “substr”. Der Name ist Programm.
http://tug.ctan.org/tex-archive/macros/latex/contrib/substr/
Hallo,
deine allg. Vorlage ist nicht schlecht! Verbessere mal die Angabe für Bilder etwas. Es hat sich in letzter Zeit einiges getan. Bsp. Caption und Hyperref – da ist es jetzt ganz einfach die Verlinkung vom Abbildungsverzeichnis aufs Bild zu gestalten. Also nicht wie davor, wo man nur auf den Bildkommentar gelandet ist, sondern das die Verlinkung oben aufs Bild zeigt.
Wenn du mir ein Beispiel oder direkt einen Patch zusendest kann ich es viel schneller einbauen, als wenn ich mir diese Informationen selber zusammensuchen muss. Zugegebenerweise bin ich nur dann selber auf einem aktuellen Stand wenn ich mich aktiv darum kümmere und dazu fehlt mir aktuell die Zeit.
Die aktuelle Version von caption hat die Nummer 3.1m (14.1.2010), und im Zusammenspiel von caption und hyperref hat sich im letzten Jahr einiges getan.
Hypcap wird nicht mehr benötigt! Den Unterschied wirst merken. Einfach \usepackage{caption} mit einbinden und freuen. So einfach ist es
\captionsetup[figure]{position=above}
hab ich doch beim letzten Post das wichtigste vergessen. sry
Hi Matthias!
Bin beim googlen zufällig auf diese Seite
http://www.pronego.com/helpdesk/knowledgebase.php?article=21
gestoßen, und irgendwie kam mir der Inhalt doch arg bekannt vor…
Und da ich auf deiner Seite keinen CC-Hinweis sehe, dachte ich dich könnte der Weg deiner Texte im Internet interessieren
Hi Matthias,
kennst Du eine Möglichkeit, um mit Latex zu rechnen:
Ich will in einem Graphen (gemäß Graphentheorie), den ich mit tikz erstellt habe, alle Knoten der Form a_i mit den Knoten der Form b_j (für j\in{i,i+1}) verbinden.
Dachte, das ginge z.B. mit
\foreach \i in {1,…,10}
\draw (\i,-3)node(a\i)[nnode]{};
\foreach \j \in {1,..,10}
\draw (\j,0)node(b\j)[nnode]{};
\foreach \i \in {1,…,9}
\foreach \j \in {\i,\i+1}
\draw (a\i)–(b\j);
Leider funktioniert das nicht, da er nicht weiß, was für ein Objekt b1+1 ist, anstatt sich zu fragen, was b2 für ein Objekt ist.
Wie kann man das bewerkstelligen, ohne alle Kanten einzeln aufschreiben zu müssen (meine tatsächliche Problemstellung ist noch wesentlich größer)?
Lars
Ich würde dir empfehlen solche Fragen auf http://tex.stackexchange.com/ zu stellen.
Also mir hat diese Seite geholfen.
Vielen Dank!
So eine Zusammenstellung habe ich schon länger gesucht, vielen Dank!
Sehr praktisch und übersichtlich. Gerade bei LaTeX-Hilfen ja nicht immer der Fall… Merci!