Hallo! Die Frage ist verwandt mit Wie arbeite ich mit dem greektext-Befehl?

Es sollen mit der Eingabe \xalpha, \xbeta serifenlose, schräggestellte griechische Buchstaben erzeugt werden, und zwar mittels des \greektext-Befehls aus dem babel-Paket - möglichst als Schleife (ohne Schleife siehe Link).

Das muß doch ungefähr so gehen?

Open in writeLaTeX
\documentclass[varwidth, margin=5mm]{standalone}
%\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[greek,ngerman]{babel}

\usepackage{pgffor}

\foreach \GWord/\TransLetter in {alpha/a, beta/b, gamma/g}{
\newcommand*{\y\GWord}{\textsl{\greektext \TransLetter}}
}
\begin{document}
\yalpha
\end{document}

gefragt 22 Mai '14, 21:48

cis's gravatar image

cis
5.4k860167
Akzeptiert: 68%

bearbeitet 22 Mai '14, 21:48


Dein Problem ist weniger, dass Du \newcommand in einer Schleife anwendest. Dein Hauptproblem ist, dass Du \newcommand nicht korrekt anwendest. Bereits ohne Schleife funktioniert das nicht:

Open in writeLaTeX
\newcommand*{\a}{b}
\newcommand*{\y\a}{y\a}

definiert eben kein \yb, da die Argumente von \newcommand nicht expandiert werden. Auch mit einer Expansion der Argumente würde es nicht funktionieren, weil dann zwar \a funktionieren würde, aber \y nicht. Tatsächlich muss man hier eine neue code sequence über \csname …\endcsname erzeugen, also:

Open in writeLaTeX
\newcommand*{\a}{b}
\expandafter\newcommand\expandafter*\csname y\a\endcsname{y\a}

Hier wird die Ausführung (eigentlich die Expansion) von \newcommand zunächst so lange verzögert, bis * ausgeführt wurde. Dessen Ausführung wird aber so lange verzögert, bis \csname ausgeführt wurde. Dieses expandiert y\a und erzeugt aus dem Ergebnis einen Befehl (der zunächst die Bedeutung \relax erhält, wenn er noch nicht definiert ist) – im Beispiel \yb. Nachdem dies erfolgte, wird * zu * und \newcommand definiert dann dien mit \csname …\endcsname zusammengebauten Befehl als y\a.

Wenn man das auf Dein Beispiel anwendet:

Open in writeLaTeX
\documentclass[varwidth, margin=5mm]{standalone}
\usepackage[T1]{fontenc}
\usepackage[greek,ngerman]{babel}

\usepackage{pgffor}

\foreach \GWord/\TransLetter in {alpha/a, beta/b, gamma/g}{%
  \expandafter\newcommand\expandafter*\csname y\GWord\endcsname{\textsl{\greektext \TransLetter}}%
}
\begin{document}
\yalpha
\end{document}

ergibt sich ein weiteres Problem. \foreach führt die Schleife lokal, also innerhalb einer Gruppe aus. \newcommand arbeitet aber nicht von sich aus global. Damit wird \yalpha etc. zwar definiert, ist am Ende der Schleife und insbesondere beim Aufruf im Dokument aber wieder undefiniert.

Dieses zweite Problem lässt sich am einfachsten mit \gdef beheben (es gibt Tricks, um trotzdem \newcommand verwenden zu können, die jedoch ggf. auch problematisch sein können):

Open in writeLaTeX
\documentclass[varwidth, margin=5mm]{standalone}
\usepackage[T1]{fontenc}
\usepackage[greek,ngerman]{babel}

\usepackage{pgffor}

\foreach \GWord/\TransLetter in {alpha/a, beta/b, gamma/g}{%
  \expandafter\newcommand\expandafter*\csname y\GWord\endcsname{}%
  \expandafter\gdef\csname y\GWord\endcsname{\textsl{\greektext \TransLetter}}%
}
\begin{document}
\yalpha
\end{document}

\gdef ist ein global wirkendes \def, also letztlich \global\def. Es handelt sich um eine Low-Level-Anweisung, die man wie \def auch, in LaTeX nicht ohne Not verwenden sollte.

Ich habe hier eine leere Definition mit \newcommand drin gelassen. Auch wenn diese lokal bleibt, sorgt sie doch dafür, dass man nicht ohne Fehlermeldung versehentlich einen existierenden Befehl umdefiniert.

Als letzter Fehler in Deinem Beispiel bleibt, dass \TransLetter dann undefiniert ist. Dieses Problem resultiert wieder daher, dass hier bei der Definition nichts expandiert wird. Tatsächlich hättest Du gerne eine teilweise Expansion. Das könnte man nun mit \xdef lösen, einem global arbeitenden \edef (\edef expandiert den Körper der Definition zunächst):

Open in writeLaTeX
\documentclass[varwidth, margin=5mm]{standalone}
\usepackage[T1]{fontenc}
\usepackage[greek,ngerman]{babel}

\usepackage{pgffor}

\foreach \GWord/\TransLetter in {alpha/a, beta/b, gamma/g}{%
  \expandafter\newcommand\expandafter*\csname y\GWord\endcsname{}%
  \expandafter\xdef\csname y\GWord\endcsname{\noexpand\textsl{\noexpand\greektext \TransLetter}}%
}
\begin{document}
\yalpha
\end{document}

Die \noexpand sorgen hier dafür, dass \textsl und \greektext nicht bereits bei der Definition, sondern erst bei der Verwendung von \yalpha etc. expandiert werden.

Man kann sich aber auch einen Hilfs-Befehl definieren, und benötigt dann nur noch wenige \expandafter und kein \xdef:

Open in writeLaTeX
\documentclass[varwidth, margin=5mm]{standalone}
\usepackage[T1]{fontenc}
\usepackage[greek,ngerman]{babel}

\usepackage{pgffor}

\newcommand*{\gdefgreekletter}[2]{%
  \gdef#1{\textsl{\greektext #2}}%
}

\foreach \GWord/\TransLetter in {alpha/a, beta/b, gamma/g}{%
  \expandafter\newcommand\expandafter*\csname y\GWord\endcsname{}%
  \expandafter\gdefgreekletter\csname y\GWord\expandafter\endcsname\TransLetter
}
\begin{document}
\yalpha
\end{document}

Wie hier die \expandafter zusammenwirken, sei als Übung empfohlen. Am besten an einem Beispiel durchspielen!

Fazit: Das ganze ist also weniger ein Problem der Schleife an sich als eine Frage, wie man einerseits bei der Bildung des Namens eines neuen Befehls diesen durch Expansion anderer Befehle bilden kann und andererseits den Inhalt des Makros bereits bei der Definition teilweise expandieren kann. Die Anwendung auf eine Schleife bringt dann nur einen kleinen, zusätzlichen Aspekt, nämlich, wie man innerhalb einer Gruppe eine Definition vornehmen kann, die sich außerhalb der Gruppe oder global auswirkt.

Als letztes sei lediglich erwähnt, dass man auch die e-TeX-Erweiterung \unexpanded, verwenden könnte, um bei \xdef Teile der Definition nicht zu expandieren. Es gibt weitere Tricks, die hier jedoch zu weit führen würden. Der LaTeX-Kernel selbst ist eine Fundgrube solcher Tricks.

Permanenter link

beantwortet 23 Mai '14, 02:35

Bes's gravatar image

Bes
1411516

bearbeitet 23 Mai '14, 03:00

Ja, also danke erstmal. Daß der TransLetter nichts mit dem Problem zu tun hat, glaube ich Dir gern. Für mich mich ist dieses "a/b" nur eine Notation, die ich bei TikZ oft verwende, z.B. "1.57/pi/2" mit dem Ziel: Schreibe pi/2 an die Stelle von 1.57. Wenn das jetzt hier aus irgendeinem Grund nicht geht, bin offengestanden ratlos.

(23 Mai '14, 02:45) cis
1

@cis Da war ich ein wenig zu schnell. Die Expansion von \TransLetter hat gewissermaßen schon etwas mit dem Problem zu tun. Ich habe das deshalb noch ergänzt.

(23 Mai '14, 02:50) Bes
(23 Mai '14, 04:59) cis
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Aktuelle Buch-Infos

LaTeX Cookbook

LaTeX Beginners Guide

Limitierter Rabatt ebook
50% Coupon code tDRet6Y

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üge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×12
×9
×2

Frage gestellt: 22 Mai '14, 21:48

Frage wurde angeschaut: 2,278 Mal

Zuletzt aktualisiert: 23 Mai '14, 04:59