Listen, Felder und Schleifen in LaTeX - Teil 3 Schleifen

in #latex7 years ago

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:
Listen_Felder_Schleifen.png

Sort:  

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