PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : \@for in LaTeX/TeX



Spindoctor
09-09-2010, 03:25
Letzte Frage \@for dem Schlafengehen ;)

Bin (mehr zufällig) auf den Befehl \@for gestoßen.

Damit kann ich sowas machen:



\def\vara{Peter,Hans,Joachim}
\makeatletter
\@for\men:=\vara {%
\men%
}
% Output: PeterHansJoachim


Soweit so gut.

Was ich gern machen möchte ist folgendes:




\def\vara{Peter,Hans,Joachim}
\def\varb{Susi,Helene,Bettina}
\makeatletter
\@for\men:=\vara \women:=\varb{%
\men + \women,%
}
% Output: Peter + Susi,Hans + Helene,Joachim + Bettina


Geht das irgendwie, über 2 Variablen iterieren kann?

Danke!

u_fischer
09-09-2010, 11:48
Da musst du zwei \@for-Schleifen benutzen:


\documentclass{scrartcl}


\begin{document}

\def\vara{Peter,Hans,Joachim,Achim}
\def\varb{Susi,Helene,Bettina}
\makeatletter
\newcounter{myloop}
\setcounter{myloop}{0}
\@for\women:=\varb \do{%
\stepcounter{myloop}%
\expandafter\edef\csname women\the\value{myloop}\endcsname{\women}}

\setcounter{myloop}{0}
\@for\men:=\vara \do{%
\stepcounter{myloop}%
\men + \csname women\the\value{myloop}\endcsname, }%


\end{document}

Spindoctor
09-09-2010, 12:21
wow!

das ist ja cool!

kannst du mir erklären was da passiert? Versteh das irgendwie noch nicht...

u_fischer
09-09-2010, 12:48
In der ersten Schleife gehe ich durch die Womenliste und erzeuge Befehle \women1, \women2, \women3 ... und in der zweiten Liste benutze ich bei Mann1 halt noch den Befehl \women1 usw.

Spindoctor
09-09-2010, 12:54
ah, ok, verstehs schon fast (bis auf die Befehle, die sind mir noch ziemlich fremd ;-))

Danke!

Spindoctor
09-09-2010, 20:26
noch eine letzte frage dazu: was hats mit "expandieren" auf sich, bzw. was heißt das. Hab mich noch nie um expandierende Kommandos gekümmert und auf einmal scheints total wichtig?

Was ist das, das expandieren von Kommandos?

Schweinebacke
09-09-2010, 20:51
TeX ist eine Makrosprache, das bedeutet, dass man keine Prozeduren oder Funktionen definiert, die ausgeführt werden, sondern es werden Makros definiert. Diese Makros werden dann expandiert. Das bedeutet, dass ein Makro durch seine Definition ersetzt wird (einstufige Expansion wie bei \expandafter). Bei der Vollständigen Expansion wird das dann für die Makros in der Definition ebenfalls gemacht, bis nur noch sogenannte Primitive übrig sind. Primitive sind die Basisbefehle von TeX, die nicht weiter expandiert werden können. TeX expandiert bei verschiedenen Gelegenheiten, beispielsweise bei \edef, \expandafter, beim Zusammenbauen des Inhalts eines Box-Registers, bei der Ausgabe in eine Datei ...

Spindoctor
09-09-2010, 21:09
ok, glaub ich versteh das ungefähr.

In TeX können also z.b. keine Variablen definiert werden, sondern - wie du sagst - nur Makros. wenn ich das Makro \foo1 ausführen will, muss ich also sicherstellen, dass ich es auch exakt mit dem Code \foo1 aufrufe - es geht nicht mit \def \bar{1} und nachher \foo\bar. Um diesen Effekt trotzdem zu erzielen, muss ich sicherstellen, dass \foo\bar zuerst ausgeführt (also expandiert) wird, bevor das ganze Dokument übersetzt wird.

Damit ist expandieren vergleichbar mit \eval() in JavaScript.

Versteh ich das richtig?

Schweinebacke
09-09-2010, 21:54
Ja und nein. Wenn Du ein Makro \foo1 ausführen willst, gibt es schon einmal das Problem, dass Makronamen nur aus Letter-Token bestehen können. LaTeX würde in Wirklichkeit \foo ausführen. Aber auch ein Makro \fooA kannst Du nicht ausführen, indem Du \foo\bar schreibst und \bar als A definiert ist. Dann ist nämlich \ noch immer kein Letter-Token. Genau dafür hat TeX aber ein eigenes Primitiv \csname mit dem zugehörigen \endcsname (funktioniert auch mit plainTeX, nicht nur mit LaTeX):
\expandafter\def\csname foo1\endcsname{funktioniert}
\def\bar{1}
\expandafter\show\csname foo\bar\endcsname Hier haben wir eine weitere Gelegenheit, bei der TeX expandiert: Alle Makros zwischen \csname und \endcsname werden expandiert und anschließend wird ein neuer Makroname gebildet.

\show zeigt übrigens im Terminal bzw. der Log-Datei die Definition des Makros und wartet dann auf eine Eingabe (mit »x« wird TeX beendet). Das \expandafter ist hier vor \show notwendig, weil wir nicht die Definition von \csname, sondern die Definition von \foo1 wissen wollen.

u_fischer
10-09-2010, 09:50
noch eine letzte frage dazu: was hats mit "expandieren" auf sich, bzw. was heißt das.


\documentclass{article}
\def\Wert{A}
\def\BefehlEins{\Wert} %\Wert nicht expandiert
\edef\BefehlZwei{\Wert} %\Wert voll expandiert


\begin{document}
\BefehlEins, \BefehlZwei

\def\Wert{B}

\BefehlEins, \BefehlZwei

\end{document}

Spindoctor
10-09-2010, 10:47
so ähnlich hab ichs eh verstanden :)

danke!

voss
10-09-2010, 12:56
Ja und nein. Wenn Du ein Makro \foo1 ausführen willst, gibt es schon einmal das Problem, dass Makronamen nur aus Letter-Token bestehen können. LaTeX würde in Wirklichkeit \foo ausführen. Aber auch ein Makro \fooA kannst Du nicht ausführen, indem Du \foo\bar schreibst und \bar als A definiert ist. Dann ist nämlich \ noch immer kein Letter-Token. Genau dafür hat TeX aber ein eigenes Primitiv \csname mit dem zugehörigen \endcsname (funktioniert auch mit plainTeX, nicht nur mit LaTeX):
\expandafter\def\csname foo1\endcsname{funktioniert}
\def\bar{1}
\expandafter\show\csname foo\bar\endcsname Hier haben wir eine weitere Gelegenheit, bei der TeX expandiert: Alle Makros zwischen \csname und \endcsname werden expandiert und anschließend wird ein neuer Makroname gebildet.


\documentclass{minimal}

\begin{document}

\makeatletter
\@namedef{foo1}{funktioniert}
\@nameuse{foo1}

\def\bar{2}
\@namedef{foo1\bar}{funktioniert auch}
\@nameuse{foo12}
\end{document}

Herbert

Schweinebacke
10-09-2010, 13:28
Und, was willst Du uns damit sagen? \@namedef und \@nameuse sind in latex.ltx wie folgt definiert:
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
\def\@nameuse#1{\csname #1\endcsname} Das ist also nichts anderes als die von mir gezeigte Funktion von \csname...\endcsname mit dem Nachteil, dass man den catcode von @ ändern muss, weshalb Du ein \makeatletter brauchst, und dass es LaTeX benötigt. Expansion ist aber eine Grundprinzip von TeX und nichts, was LaTeX dazu erfindet. Daher habe ich auch versucht, es an TeX zu erklären.

voss
10-09-2010, 13:54
Und, was willst Du uns damit sagen? \@namedef und \@nameuse sind in latex.ltx wie folgt definiert:
\def\@namedef#1{\expandafter\def\csname #1\endcsname}
\def\@nameuse#1{\csname #1\endcsname} Das ist also nichts anderes als die von mir gezeigte Funktion von \csname...\endcsname mit dem Nachteil, dass man den catcode von @ ändern muss, weshalb Du ein \makeatletter brauchst, und dass es LaTeX benötigt. Expansion ist aber eine Grundprinzip von TeX und nichts, was LaTeX dazu erfindet. Daher habe ich auch versucht, es an TeX zu erklären.

es ging nur um Varianten, wenn man tippfaul ist. Und in Paketen
verwendet, braucht man auch nicht das \makeatletter

Herbert