Listen, Felder und Schleifen in LaTeX - Teil 3 Schleifen
Wie schon zuvor bei den 'Setter- und Getter-Makros' für die Listen und Felder, so belasse ich den Makro für die "ForTeX"-Schleife in der Präambel.
Auch in diesem Fall gibt es ein Vorbild, welches ich jedoch an TeX-Zähler (daher Zähler-Initialisierung mit \newcount ) anpasste und um die Möglichkeit der Rückwärtszählung verbesserte.
Da ich es für angebrachter halte, Erklärungen neben die entsprechenden Programmzeilen zu platzieren, so verweise ich auf die durch ein voranstehendes % gekennzeichneten Kommentarzeilen.
Allgemein beruht diese Schleife darauf, dass sie sich rekursiv selbst aufruft, solange die Zählerbedingungen dies erlauben.
Im ausführendem Document-Teil werden die Schleifenmöglichkeiten auf Herz und Nieren getestet.
Zu beachten ist, dass die in der ForTeX-Schleife eingestellte Zählervariable immer mit einem vorangestellten '\
' geschrieben werden muss, also z.B.: \ForTeX{\Z}{1}{9}[1}{Hallo\\}
Dann sollte eigentlich alles richtig funktionieren.
Ich wünsche viel Spaß und Erfolg beim Probieren und Nutzen und freue mich über Kritiken!
% Fortsetzung von Teil1 und Teil2 :
\def\ForTeX#1#2#3#4#5% Definition des Schleifen-Makros ForTeX
{% ForTeX und nicht loop, um Kollision mit TeX-Syntax zu vermeiden.
% Übergabe-Parameter:
% #1=Zählername #2=Startwert #3=Endwert #4=Zählschrittweite #5=AusführungsCode
% Angelehnt an BASIC-Syntax:
% FOR ZählerVariable[#1] = StartWert[#2] TO EndWert[#3] STEP Zählschrittweite[#4] DO
% Schleifeninneres/AusführungsCode[#5]
% END FOR
%
\ifdefined #1\relax% Wenn #1 definiert ist, dann nichts tun ...
\else\newcount #1% ... sonst Zähler (in #1) definieren
\fi%
#1=#2 % ZählerVariable (in #1) wird Startwert (in #2) zugewiesen.
% Voraussetzung ist, dass diese Zählervariable zuvor (vor der Schleife) bereits ...
% ... definiert wurde mit \newcount\<Zählervariable>
\ifnum #1<#3 % IF [#1] < [#3] THEN ...
\ifnum #4>0 %
#5% Ausführungs-Code
\advance #1 by #4 % Verändere Wert von ZählerVariable (#1) um Zählschrittweite (#4).
\ForTeX{#1}{\the#1}{#3}{#4}{#5}% Rekursiver Aufruf, doch mit ...
% ... \the#1 (gibt Wert von ZählerVariable aus) anstelle des ursprünglichen Startwertes.
% Sonst würde die Schleife ewig neu aufgerufen und es würde einen Stack-Überlauf geben.
\fi% END IF von Prüfung auf Zählschrittweite > 0 [\ifnum #4 > 0]
\else%
% \ifnum fragt auf kleiner (<) ab, nicht auf kleiner und gleich (<=).
% Deshalb mit einer extra Gleich-Abfrage klären, ob Endwert erreicht ist:
\ifnum #1=#3 % IF [#1] == [#3] THEN ...
#5% AusführungsCode ein letztes Mal ausführen.
\else% Warum jetzt noch ELSE? Etwas vergessen?
% JA! Was ist, wenn der Startwert größer sein sollte als der Endwert UND ...
% ... der Zählschrittwert <0 ??? All das muss hier noch geprüft werden:
\ifnum #4<0 % Zählschrittwert kleiner Null?
\ifnum #1>#3 %
#5%
\advance #1 by #4 % Ändere Zählerwert (#1) um Zählschrittweite (#4).
\ForTeX{#1}{\the#1}{#3}{#4}{#5}% Rekursiver Aufruf, gleiches Spiel
\fi% Ende der Rückwärts-Zählung
\fi% Ende der Prüfung auf negative Zählschrittweite
\fi% END IF von \ifnum im ELSE-Zweig Gleichheitsprüfung
\fi% END IF ... Ende der Aufwärts-Zählung
}
% Aufrufsyntax:
% \ForTeX{\<Zählername>}{<Startwert>}{<Endwert>}{<Zählschrittweite>}{<Ausführungscode>}
% Wichtig ist, den Zähler immer mit vorangestelltem \ zu schreiben!
\begin{document}
\sf% Die Serifen-Schrift ist gruselig! Daher Umschaltung auf Serifen-frei
%
%
\newcount\ZaehlerX% Tex-Zähler wird initialisiert ... obligatorisch!
%
% Füllung einer Liste mit Werten, dafür wird ein Hilfszähler benötigt:
\newcount\ZaehlerY% Hilfzaehler ZaehlerY als Zwischenwertspeicher
%
\ForTeX{\ZaehlerX}{1}{9}{1}%
{%
\ZaehlerY = \the\ZaehlerX%
\multiply\ZaehlerY by 10 % Multiplikation von \ZaehlerX mit 10 würde ZaehlerX ändern.
% \ZaehlerX darf nämlich selbst wegen der Schleifensteuerung nicht beeinflusst werden!
\ListeEin{MeineListe}{\the\ZaehlerX}{\the\ZaehlerY}% Eingabe in Listen-Feld
}%
\ListeEin{MeineListe}{0}{9}% Spaßeshalber speichert Element 0 die Anzahl der Listen-Elemente.
% (Muss nicht sein, denn Element 0 kann verwendet werden wie alle andern auch ... nur als Gag.)
%
%
% Ausgabe der zuvor gefüllten Liste, die Anzahl der Listenelemente wird aus Element 0 entnommen:
\ForTeX{\ZaehlerX}{1}{\ListeAus{MeineListe}{0}}{1}%
{%
\ListeAus{MeineListe}{\the\ZaehlerX}%
\ifnum \the\ZaehlerX < \ListeAus{MeineListe}{0} % Zähler noch nicht beim letzten Element?
\,---\,% Wenn nein, dann Trennstrich, ...
\else\\% ... sonst neue Zeile.
\fi%
}%
%
%
\vskip10pt%
%
% Abschließend noch zwei Schleifen-Crashtests:
Crashtest: Wenn alles in Ordnung ist, dann sollte hier nur iO! stehen: %
i%
\ForTeX{\ZaehlerX}{0}{4}{-1}{ha ha}% Wenn alles iO ist, dann sollten diese beiden ...
O%
\ForTeX{\ZaehlerX}{7}{2}{1}{hu hu}% ... Schleifen hier gar nicht ausgeführt werden.
!\\[10pt]%
%
%
%
% Zählschrittweite > 1 testen:
Vorwärts +2 : \ForTeX{\ZaehlerX}{2}{8}{2}{\the\ZaehlerX\ifnum\the\ZaehlerX < 8 ..\fi}% 2+4+6+8
\hskip2cm%
Rückwärts -3 : \ForTeX{\ZaehlerX}{9}{3}{-3}{\the\ZaehlerX\ifnum\the\ZaehlerX > 3 ..\fi}% 9+6+3
%
%
%
\vskip1cm%
%
% Und als Krönung zwei ineinander verschachtelte XY-Schleifen ... z.B. für ein 2dim-Feld:
% Eingabe in Feld bzw. 2D-Array:
\ForTeX{\ZaehlerY}{0}{9}{1}% Äußere Y-Schleife von 0 bis 9 in 1er-Schritten:
{%
\ForTeX{\ZaehlerX}{0}{9}{1}% Innere X-Schleife von 0 bis 9 in 1er-Schritten:
{%
\FeldEin{MeinFeld}{\the\ZaehlerY}{\the\ZaehlerX}%
{%
(\the\ZaehlerY\,:\,\the\ZaehlerX)% Listen und Felder dürfen auch Zeichenketten speichern.
}%
}% Ende der inneren X-Schleife
}% Ende der äußeren Y-Schleife
%
% Ausgabe aus Feld bzw. 2D-Array:
\ForTeX{\ZaehlerY}{0}{9}{1}% Äußere Y-Schleife von 0 bis 9 in 1er-Schritten:
{%
\ForTeX{\ZaehlerX}{0}{9}{1}% Innere X-Schleife von 0 bis 9 in 1er-Schritten:
{%
\FeldAus{MeinFeld}{\the\ZaehlerX}{\the\ZaehlerY}\hskip10pt%
% Die Listen und Felder können auch Zeichenketten enthalten.
}% Ende der inneren X-Schleife
\vskip15pt%
}% Ende der äußeren Y-Schleife
%
% Das Beispiel mit der Schleifenverschachtelung hätte von der Darstellung her natürlich auch ganz ohne ...
% ... Feld-bzw. Array-Variablen funktioniert und wirkt so gesehen umständlich.
% Es geht hierbei nur darum, zu zeigen, dass das Konzept funktioniert.
%
%
% Fazit: Mit LaTeX (und etwas TeX) geht weit mehr als man denkt - auch ohne Lua, GnuPlot, Perl oder Python!
\end{document}
Die zu erwartende Ausgabe habe ich hier als Format-unabhängigen Ausschnitt dargestellt:
Wer kein TeXLive ode MiKTeX oder vergleichbares installiert hat bzw. installieren möchte, kann dieses auch online ausprobieren:
http://latex.informatik.uni-halle.de/latex-online/latex.php