Wie kann ich eine while-Schleife in plainTeX erstellen? Ich möchte in TeX dieselbe Funktionalität einer while-Schleife erreichen, wie sie z.B. in C Programmen möglich ist.

gefragt 17 Jun '13, 12:15

ctansearch's gravatar image

ctansearch
(ausgesetzt)
Akzeptiert-Rate: 18%

bearbeitet 22 Feb '21, 12:49

saputello's gravatar image

saputello
11.1k174365

1

Falls jemand auf diese Frage stößt, sollte er bedenken, dass es sich hier um rein plain TeX handelt. LaTeX selbst bietet mit Hilfe verschiedenster Pakete weit aus bessere und effektivere Schleifen.

(29 Jun '13, 21:57) Marco_D

Selbst für plain TeX könnte man fertige Pakete haben... wenn ich mich recht erinnere, ist z.B. das texapi Paket generic...

(29 Jun '13, 22:21) cgnieder

Erste Idee:

% !TEX pdftex
\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}

% \ifnumber{<Zahlenbeziehung>}{<wahr>}{<falsch>}:
\def\ifnumber#1{%
  \ifnum#1\relax
    \expandafter\firstoftwo
  \else
    \expandafter\secondoftwo
  \fi
}

% eine Schleife für \if-Abfragen mit der Syntax wie das oben definierte \ifnumber,
% also mit {wahr}{falsch} Argumenten, die in der Schleife weggelassen werden:
% \dowhile{<Bedingung>}{<Ausführung wenn Bedingung wahr>}
\long\def\dowhile#1#2{%
  #1{#2\dowhile{#1}{#2}}{}%
}

% test, ob's funktioniert:
\newcount\step    
\dowhile{\ifnumber{\the\step<3}}{\advance\step by 1 \the\step}

% damit \while mit derselben Syntax definieren wie in ctansearchs Antwort:
% \while[<Start>,<Obergrenze>,<Ausführung solange Zeiger kleiner Obergrenze>]
\long\def\while[#1,#2,#3]{%
  % mit der Gruppe wird die Schleife schachtelbar
  \begingroup
    \step=#1
    \dowhile
      {\ifnumber{\the\step<#2}}
      {#3\advance\step by 1 }%
  \endgroup
}

\while[0,3,4]

\while[1,5,Schritt \the\step\par]

\while[0,5,{a(\while[0,3,b]}) ]

\bye

alt text


Im LaTeX-Kernel kann man eine weitere Lösung finden:

% !TEX pdftex
\catcode`\@=11
\long\def\@gobble#1{}

% Definition von \@whilenum aus dem LaTeX-Kernel:
\long\def\@whilenum#1\do #2{%
  \ifnum #1\relax
    #2\relax\@iwhilenum{#1\relax #2\relax}%
  \fi}
\long\def\@iwhilenum#1{%
  \ifnum #1%
    \expandafter\@iwhilenum
  \else
    \expandafter\@gobble
  \fi{#1}}

\newcount\step

% Test, ob's funktioniert:
\@whilenum\the\step<3\do{\the\step \advance\step by 1 }


% \while mit derselben Syntax definieren wie in ctansearchs Antwort:
% \while[<Start>,<Obergrenze>,<Ausführung solange Zeiger kleiner Obergrenze>]
\long\def\while[#1,#2,#3]{%
  \step=#1
  \@whilenum\the\step<#2\do{#3\advance\step by 1 }%
}
\catcode`\@=12

\while[0,3,4]

\while[1,5,Schritt \the\step\par]

\bye
Permanenter link

beantwortet 17 Jun '13, 13:01

cgnieder's gravatar image

cgnieder
22.1k253463
Akzeptiert-Rate: 60%

bearbeitet 17 Mär '21, 20:07

stefan's gravatar image

stefan ♦♦
18.3k163148

Beispiel(entsp. Kommentaren korrigiert)

% !TEX pdftex
{\bf \TeX-Code}  
\vskip\baselineskip%  
\newcount\start%  
\newcount\stop%  
\def\while[#1,#2,#3]{%  
  \start=#1 %  
  \stop=#2 %  
  \def\doit{#3}%  
  \loop \ifnum\start<\the\stop \doit \advance\start by 1\repeat%  
  \start=0 \stop=0}%  
\setbox0=\hbox{Test 1}  
\setbox1=\hbox{Test 2}  
\setbox2=\hbox{Test 3}  
\while[0,3,\expandafter\box\the\start]%  
\bye%  
%
Permanenter link

beantwortet 17 Jun '13, 12:17

ctansearch's gravatar image

ctansearch
(ausgesetzt)
Akzeptiert-Rate: 18%

bearbeitet 14 Mai '21, 21:50

stefan's gravatar image

stefan ♦♦
18.3k163148

2

Nur eine Bemerkung: nach Kontrollsequenzen sind % unnötig, nach count-assignments (hier z.B. \start=#1%) sogar problematisch, weil TeX dann weitersucht bis es auf eine Nicht-Zahl trifft und dabei expandierbare Token expandiert. Besser \start=#1 %

(17 Jun '13, 12:22) cgnieder

Funktioniert gut! Wenn ich nach Clemens's Tipp in die Folgezeile mit 1 beginne, also 1\stop=#2% schreibe, compiliert es und beginnt tatsächlich dann mit 2.

(17 Jun '13, 12:31) stefan ♦♦
1

Nach \ifnum\the\start<\the\stop sollte ein \relax angefügt werden, um ein weiterscannen nach Zahlen zu verhindern: versuche \while[0,3,4] mit \def\doit{#3 #3}. Das Ergebnis ergibt keineswegs drei mal 4 4, sondern 34 mal 4

(17 Jun '13, 22:52) cgnieder
2

Die \the beim \ifnum sind unnötig. Wenn ich Counter vorliegen habe, kann ich diese mit \ifnum direkt vergleichen, ohne diese vorher mit \the "in Ziffern" zu wandeln und dann wieder einzuscannen. Ohne die \the kann man auch auf das erwähnte \relax als Abschluss der Vergleichsbedingung verzichten.

Wäre etwas anderes, wenn \start und \stop als Makros (oder als Tokenlisten) definiert wäre, aber dann könnte man \start nicht mit \advance erhöhen ...

(28 Jun '13, 21:44) bernd

@bernd Danke für den Hinweis! (Ich habe das Gefühl, ich hätte das schon mal gewusst aber wieder vergessen... :) )

(28 Jun '13, 21:47) cgnieder
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×21
×5

gestellte Frage: 17 Jun '13, 12:15

Frage wurde gesehen: 112,175 Mal

zuletzt geändert: 17 Mär '21, 20:07