Ich möchte innerhalb eines Makros ein weiteres Makro definieren, dessen Namen durch einen Parameter bestimmt wird.

Mit \newcommand habe ich es soweit geschafft:

\documentclass{article}
\newcommand{\erzeuge}[2]{%
  \newcommand{#1}{#2}}
\begin{document}
\erzeuge{\autor}{Name}
\autor
\end{document}

Jedoch möchte ich nicht einen Makronamen mit Backslash übergeben, sondern nur den Namen als Text, also z.B. \erzeuge{autor}{Name}. Kriegt man das auch hin?

gefragt 31 Aug '13, 14:16

Student's gravatar image

Student
5807779104
Akzeptiert-Rate: 82%

bearbeitet 31 Aug '13, 17:49

saputello's gravatar image

saputello
11.1k154365


Du kannst \@namedef{<befehlsname>}{<definition>} verwenden, das vom LaTeX-Kernel bereitgestellt wird. Allerdings hat es ein @ im Namen, weswegen man \makeatletter und \makeatother einsetzen muss. Außerdem testet es nicht, ob ein Makro bereits definiert ist, was \newcommand ja macht. Hier wäre eine Möglichkeit, die \@ifdefinable verwendet (den Test, der auch von \newcommand durchgeführt wird):

\makeatletter
\newcommand{\erzeuge}[2]{%
  \expandafter\@ifdefinable\csname#1\endcsname
    {\@namedef{#1}{#2}}%
  }
\makeatother

Einfacher wäre aber vielleicht, den Befehlsnamen mit \csname ...\endcsname zu erzeugen und dann von \newcommand definieren zu lassen:

\newcommand{\erzeuge}[2]{%
  \expandafter\newcommand\csname#1\endcsname{#2}}

Wenn kein Absatz in der Definition vorkommen wird, wäre es übrigens von Vorteil

\newcommand*{\erzeuge}[2]{ ... }

zu verwenden.

Das etoolbox Paket stellt übrigens eine ganze Reihe zu \@namedef ähnlicher Befehle bereit (\csdef wäre das direkte Äquivalent).

\csname bla\endcsname ist nach einer Expansion gleichbedeutend mit dem Aufruf \bla mit dem Unterschied, dass \bla die Bedeutung \relax bekommt, wenn es vorher nicht definiert war. Damit kann also kein undefined control sequence Fehler passieren. \@namedef{bla} ist eine Hülle für \expandafter\def\csname bla\endcsname.

Permanenter link

beantwortet 31 Aug '13, 14:30

cgnieder's gravatar image

cgnieder
22.1k243463
Akzeptiert-Rate: 60%

bearbeitet 31 Aug '13, 17:36

Mit Hilfe von \expandafter funktioniert es, wenn im ersten Argument der neue Makroname ohne Backslash angegeben wird:

\documentclass{scrartcl}
\newcommand{\erzeuge}[2]{\expandafter\newcommand\expandafter{\csname #1\endcsname}{#2}} 
\begin{document}
  \erzeuge{autor}{Name}
  \autor
\end{document}
Permanenter link

beantwortet 31 Aug '13, 14:27

esdd's gravatar image

esdd
17.7k254256
Akzeptiert-Rate: 62%

Eine Kombination aus dieser und der Frage »Wie kann ich ein Makro redefinieren, falls existent, sonst definieren?« und der Antwort von esdd ergibt die Möglichkeit, zwei Fliegen mit einer Klappe zu schlagen:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{longtable}
\newcommand{\ram}[2]{\expandafter\newcommand\expandafter{\csname
    ram#1\endcsname}{#2}} 
\newcommand{\rom}[2]{\expandafter\newcommand\expandafter{\csname
    rom#1\endcsname}{#2}} 
\begin{document}
\ram{firstname}{Fritz}
\ram{lastname}{Becker}
\ram{date}{12.09.72}
\ram{dog}{Fluffy}
\ram{table}{\begin{longtable}{p{2cm}p{2cm}p{2cm}p{2cm}}\ramfirstname&\ramlastname&\ramdate&\ramdog \\\end{longtable}}

\rom{firstname}{Franz}
\rom{lastname}{Schaefer}
\rom{date}{13.05.75}
\rom{dog}{Rascal}

\ramfirstname  \\
\ramlastname \\
\ramdate \\
\ramdog \\
\ramtable
\romfirstname  \\
\romlastname \\
\romdate \\
\romdog \\
\rom{table}{\begin{longtable}{p{2cm}p{2cm}p{2cm}p{2cm}}\romfirstname&\romlastname&\romdate&\romdog
    \\\end{longtable}}
\romtable
\end{document}
Permanenter link

beantwortet 01 Sep '13, 19:25

ctansearch's gravatar image

ctansearch
(ausgesetzt)
Akzeptiert-Rate: 18%

bearbeitet 02 Sep '13, 08:55

saputello's gravatar image

saputello
11.1k154365

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:

×52
×18

gestellte Frage: 31 Aug '13, 14:16

Frage wurde gesehen: 12,549 Mal

zuletzt geändert: 02 Sep '13, 08:55