Überarbeitungsverlauf[Zurück]
Klicke auf Einblenden/Ausblenden von Überarbeitungen 4

17 Mai '14, 18:40

cgnieder's gravatar image

cgnieder
22.1k253463

Versuch einer Eigenantwort nach Recherchen... verschiedenen Recherchen (und inzwischen auch eigener Anwendung)... ---------- Grundsätzlich scheint es für die `\romannumeral`-Expansion (oder f-Expansion) drei Einsätze zu geben: 1. Entfernen von führenden Leerzeichen. 2. Volles Expandieren (von links) auf expandierbare Art, d.h., in einem `\edef` o.ä. anwendbar. [Auch von Nutzen, wenn man nicht weiß, wie viele Expansionen bötigt werden und wie lang eine `\expandafter`-Kette sein müsste][1]. 3. Bilden einer Schleife. **Punkte 2.** und **3.** scheinen häufiger eingesetzt zu werden als der erste Punkt. Für **Punkt 1.** habe ich quasi keine Hinweise gefunden, dass es tatsächlich in der Praxis angewendet wird, abgesehen von dem [einen][2] oder [anderen][3] Post von Heiko Oberdiek auf TeX.sx. Das Prinzip ist einfach (hier steht · für eine beliebige Anzahl Leerzeichen): \romannumeral·<num>·\relax und \romannumeral<num>\relax sind äquivalent: nach [Befehlssequenzen werden Leerzeichen sowieso ignoriert][4] und das Leerzeichen nach `<num>` (mehrere Leerzeichen verhalten sich wie eines) wird von `\romannumeral` (wie auch von anderen TeX Primitiven, die nach Zahlen suchen) verwendet, um das Ende der Zahl festzustellen, und dann weggeworfen. Beispiel: \documentclass{article} \begin{document} \makeatletter \long\def\trim@left#1{\romannumeral-`\q#1} \def\foo{ foo } !\trim@left{\foo}! \end{document} **Punkt 2.** scheint öfter verwendet zu werden, um expandierbar Makros zu expandieren. Wenn man z.B. aufmerksam auf TeX.sx sucht, findet man dafür immer wieder Beispiele. Auch in Paketen wird es angewendet, etwa dem [`trimspaces`][5]-Paket. Im wesentlichen definiert es einen Befehl `\trim@spaces` wie folgt: \catcode`\Q=3 \newcommand\trim@spaces[1]{% \romannumeral-`\q\trim@trim@\noexpand#1Q Q% } \long\def\trim@trim@#1 Q{\trim@trim@@#1Q} \long\def\trim@trim@@#1Q#2{#1} \catcode`\Q=11 `\romannumeral` expandiert von links, d.h., wie wenn man eine genügende Menge `\expandafter`s verwendet hätte. Es wird also zunächst `\trim@trim@` expandiert, was rechts die Leerzeichen entfernt, dann wird `\trim@trim@@` expandiert, was das zweite `Q`<sub>3</sub> entfernt, dann wird `\noexpand` expandiert, was schließlich linke Leerzeichen entfernt, da sie hinter `\noexpand` ignoriert werden<sup>1</sup>. Da es reicht, `\romannumeral` zu expandieren, um den gesamten Mechanismus zu starten und zu Ende zu bringen, kann das Paket nun zum Beispiel recht einfach einen Befehl definieren, das die Leerzeichen entfernt, den Rest aber unexpandiert zurücklässt: \newcommand\trim@spaces@noexp[1]{% \unexpanded\expandafter\expandafter\expandafter{\trim@spaces{#1}}% } **Punkt 3.** wird zum Beispiel in den `\xx_case:` Funktionen von expl3 ausgenützt, [Joseph Wright hat das hier ganz gut erklärt][6]. Auch das Paket [`multiexpand`][7] nützt die gleiche Methode. Hier wird ausgenützt, dass `\romannumeral` auf der Suche nach einer Zahl und folgendem Leerzeichen weiterexpandiert, aber aufhört, wenn es das gefunden hat. Hier wird eine `0` mit folgendem Leerzeichen gefüttert, um aus der Schleife auszubrechen. Im folgenden Beispiel (der Definition von `\MultiExpand` aus eben genanntem Paket) macht das das Makro `\ME@endroman`. Gleichzeitig braucht der schleifende Befehl (kann man das so sagen?) selbst _nur eine Expansion_! Im Beispiel unten bedeutet das, dass zweifache Expansion von `\MultiExpand` (damit `\romannumeral` getriggert wird) die achtfache (!) Expansion von `\a` liefert: \documentclass{article} \begin{document} \makeatletter \def\ME@use#1{#1}% \def\MultiExpand{\romannumeral\multiexpand}% \edef\ME@endroman#1{0\noexpand\expandafter\space}% \long\def\multiexpand#1{% \ifnum#1<2 \expandafter\ME@endroman \else \expandafter\ME@use \fi {% \expandafter\multiexpand \expandafter{\number\numexpr#1-1\expandafter}% }% }% \def\a{\b} \def\b{\c} \def\c{\d} \def\d{\e} \def\d{\f} \def\e{\f} \def\f{\g} \def\g{\h} \def\h{\i} \def\i{\j} \def\j{k} \expandafter\expandafter\expandafter\def \expandafter\expandafter\expandafter\x \expandafter\expandafter\expandafter{\MultiExpand{8}\a} \show\x % ->\j ->\i . \end{document} ---------- Ich selber habe mir inzwischen angewöhnt, sie für **Punkt 2.** 2.**, die *expandierbare Expansion*, einzusetzen. ---------- 1. Ich hoffe, diese Analyse ist korrekt. Auch hier bitte ich um eventuelle Berichtigung. [1]: http://www.texdev.net/2011/07/05/expansion-using-romannumeral/ [2]: http://tex.stackexchange.com/a/73180/5049 [3]: http://tex.stackexchange.com/a/94190/5049 [4]: http://texwelt.de/wissen/fragen/17 [5]: http://www.ctan.org/pkg/trimspaces [6]: http://tex.stackexchange.com/a/121395/5049 [7]: http://www.ctan.org/pkg/multiexpand
Klicke auf Einblenden/Ausblenden von Überarbeitungen 3

17 Mai '14, 18:25

cgnieder's gravatar image

cgnieder
22.1k253463

<sub>Versuch einer Eigenantwort.</sub> Eigenantwort nach Recherchen... ---------- Grundsätzlich scheint es für die `\romannumeral`-Expansion (oder f-Expansion) drei Einsätze zu geben: 1. Entfernen von führenden Leerzeichen. 2. Volles Expandieren (von links) auf expandierbare Art, d.h., in einem `\edef` o.ä. anwendbar. [Auch von Nutzen, wenn man nicht weiß, wie viele Expansionen bötigt werden und wie lang eine `\expandafter`-Kette sein müsste][1]. 3. Bilden einer Schleife. Punkte 2. **Punkte 2.** und 3. **3.** scheinen häufiger eingesetzt zu werden als der erste Punkt. Für **Punkt 1.** habe ich quasi keine Hinweise gefunden, dass es tatsächlich in der Praxis angewendet wird, abgesehen von dem [einen][2] oder [anderen][3] Post von Heiko Oberdiek auf TeX.sx. Das Prinzip ist einfach (hier steht · für eine beliebige Anzahl Leerzeichen): \romannumeral·<num>·\relax und \romannumeral<num>\relax sind äquivalent: nach [Befehlssequenzen werden Leerzeichen sowieso ignoriert][4] und das Leerzeichen nach `<num>` (mehrere Leerzeichen verhalten sich wie eines) wird von `\romannumeral` (wie auch von anderen TeX Primitiven, die nach Zahlen suchen) verwendet, um das Ende der Zahl festzustellen, und dann weggeworfen. Beispiel: \documentclass{article} \begin{document} \makeatletter \long\def\trim@left#1{\romannumeral-`\q#1} \def\foo{ foo } !\trim@left{\foo}! \end{document} **Punkt 2.** scheint öfter verwendet zu werden, um expandierbar Makros zu expandieren. Wenn man z.B. aufmerksam auf TeX.sx sucht, findet man dafür immer wieder Beispiele. Auch in Paketen wird es angewendet, etwa dem [`trimspaces`][5]-Paket. Im wesentlichen definiert es einen Befehl `\trim@spaces` wie folgt: \catcode`\Q=3 \newcommand\trim@spaces[1]{% \romannumeral-`\q\trim@trim@\noexpand#1Q Q% } \long\def\trim@trim@#1 Q{\trim@trim@@#1Q} \long\def\trim@trim@@#1Q#2{#1} \catcode`\Q=11 `\romannumeral` expandiert von links<sup>1</sup>, links, d.h., wie wenn man eine genügende Menge `\expandafter`s verwendet hätte. Es wird also zunächst `\trim@trim@` expandiert, was rechts die Leerzeichen entfernt, dann wird `\trim@trim@@` expandiert, was das zweite `Q`<sub>3</sub> entfernt, dann wird `\noexpand` expandiert, was schließlich linke Leerzeichen entfernt, da sie hinter `\noexpand` ignoriert werden<sup>2</sup>. werden<sup>1</sup>. Da es reicht, `\romannumeral` zu expandieren, um den gesamten Mechanismus zu starten und zu Ende zu bringen, kann das Paket nun zum Beispiel recht einfach einen Befehl definieren, das die Leerzeichen entfernt, den Rest aber unexpandiert zurücklässt: \newcommand\trim@spaces@noexp[1]{% \unexpanded\expandafter\expandafter\expandafter{\trim@spaces{#1}}% } **Punkt 3.** wird zum Beispiel in den `\xx_case:` Funktionen von expl3 ausgenützt, [Joseph Wright hat das hier ganz gut erklärt][6]. Auch das Paket [`multiexpand`][7] nützt die gleiche Methode. Hier wird ausgenützt, dass `\romannumeral` auf der Suche nach einer Zahl und folgendem Leerzeichen weiterexpandiert, aber aufhört, wenn es das gefunden hat. Hier wird eine `0` mit folgendem Leerzeichen gefüttert, um aus der Schleife auszubrechen. Im folgenden Beispiel (der Definition von `\MultiExpand` aus eben genanntem Paket) macht das das Makro `\ME@endroman`. Gleichzeitig braucht der schleifende Befehl (kann man das so sagen?) selbst _nur eine Expansion_! Im Beispiel unten bedeutet das, dass zweifache Expansion von `\MultiExpand` (damit `\romannumeral` getriggert wird) die vierfache achtfache (!) Expansion von `\a` liefert: \documentclass{article} \begin{document} \makeatletter \def\ME@use#1{#1}% \def\MultiExpand{\romannumeral\multiexpand}% \edef\ME@endroman#1{0\noexpand\expandafter\space}% \long\def\multiexpand#1{% \ifnum#1<2 \expandafter\ME@endroman \else \expandafter\ME@use \fi {% \expandafter\multiexpand \expandafter{\number\numexpr#1-1\expandafter}% }% }% \def\a{\b} \def\b{\c} \def\c{\d} \def\d{\e} \def\e{f} \def\d{\f} \def\f{\g} \def\g{\h} \def\h{\i} \def\i{\j} \def\j{k} \expandafter\expandafter\expandafter\def \expandafter\expandafter\expandafter\x \expandafter\expandafter\expandafter{\MultiExpand{4}\a} \expandafter\expandafter\expandafter{\MultiExpand{8}\a} \show\x % ->\e ->\j . \end{document} ---------- Ich selber habe mir inzwischen angewöhnt, sie für **Punkt 2.** einzusetzen. ---------- 1. Man möge mich bitte korrigieren, wenn das nicht stimmt. 2. Ich hoffe, diese Analyse ist korrekt. Auch hier bitte ich um eventuelle Berichtigung. [1]: http://www.texdev.net/2011/07/05/expansion-using-romannumeral/ [2]: http://tex.stackexchange.com/a/73180/5049 [3]: http://tex.stackexchange.com/a/94190/5049 [4]: http://texwelt.de/wissen/fragen/17 [5]: http://www.ctan.org/pkg/trimspaces [6]: http://tex.stackexchange.com/a/121395/5049 [7]: http://www.ctan.org/pkg/multiexpand
Klicke auf Einblenden/Ausblenden von Überarbeitungen 2
Rechtschreibfehler korrigiert

04 Aug '13, 21:02

cgnieder's gravatar image

cgnieder
22.1k253463

Klicke auf Einblenden/Ausblenden von Überarbeitungen 1

04 Aug '13, 20:30

cgnieder's gravatar image

cgnieder
22.1k253463

Willkommen, erstes Mal hier? Schau mal unter FAQ!

×