Anzeige:
Ergebnis 1 bis 14 von 14

Thema: \@for in LaTeX/TeX

  1. #1
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338

    \@for in LaTeX/TeX

    Letzte Frage \@for dem Schlafengehen

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

    Damit kann ich sowas machen:

    Code:
    \def\vara{Peter,Hans,Joachim}
    \makeatletter
    \@for\men:=\vara {%
        \men%
    }
    % Output: PeterHansJoachim
    Soweit so gut.

    Was ich gern machen möchte ist folgendes:


    Code:
    \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!

  2. #2
    Registrierter Benutzer
    Registriert seit
    19.05.2009
    Beiträge
    4.045
    Da musst du zwei \@for-Schleifen benutzen:

    Code:
    \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}

  3. #3
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338
    wow!

    das ist ja cool!

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

  4. #4
    Registrierter Benutzer
    Registriert seit
    19.05.2009
    Beiträge
    4.045
    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.

  5. #5
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338
    ah, ok, verstehs schon fast (bis auf die Befehle, die sind mir noch ziemlich fremd ;-))

    Danke!

  6. #6
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338
    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?

  7. #7
    Registrierter Benutzer
    Registriert seit
    31.03.2010
    Beiträge
    1.039
    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 ...

  8. #8
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338
    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?

  9. #9
    Registrierter Benutzer
    Registriert seit
    31.03.2010
    Beiträge
    1.039
    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):
    Code:
    \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.

  10. #10
    Registrierter Benutzer
    Registriert seit
    19.05.2009
    Beiträge
    4.045
    noch eine letzte frage dazu: was hats mit "expandieren" auf sich, bzw. was heißt das.
    Code:
    \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}

  11. #11
    Registrierter Benutzer
    Registriert seit
    09.06.2007
    Beiträge
    338
    so ähnlich hab ichs eh verstanden

    danke!

  12. #12
    Registrierter Benutzer Avatar von voss
    Registriert seit
    10.04.2005
    Beiträge
    5.045
    Zitat Zitat von Schweinebacke Beitrag anzeigen
    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):
    Code:
    \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.
    Code:
    \documentclass{minimal}
    
    \begin{document}
    
    \makeatletter
    \@namedef{foo1}{funktioniert}
    \@nameuse{foo1}
    
    \def\bar{2}
    \@namedef{foo1\bar}{funktioniert auch}
    \@nameuse{foo12}
    \end{document}
    Herbert

  13. #13
    Registrierter Benutzer
    Registriert seit
    31.03.2010
    Beiträge
    1.039
    Und, was willst Du uns damit sagen? \@namedef und \@nameuse sind in latex.ltx wie folgt definiert:
    Code:
    \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.

  14. #14
    Registrierter Benutzer Avatar von voss
    Registriert seit
    10.04.2005
    Beiträge
    5.045
    Zitat Zitat von Schweinebacke Beitrag anzeigen
    Und, was willst Du uns damit sagen? \@namedef und \@nameuse sind in latex.ltx wie folgt definiert:
    Code:
    \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

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •