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, 08:16

Student's gravatar image

Student
4702577103
Akzeptiert: 96%

bearbeitet 31 Aug '13, 11:49

saputello's gravatar image

saputello
18.4k22352


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, 08:30

Clemens's gravatar image

Clemens
19.0k112960

bearbeitet 31 Aug '13, 11: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, 08:27

esdd's gravatar image

esdd
14.2k53251

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, 13:25

ctansearch's gravatar image

ctansearch
(inaktiv)

bearbeitet 02 Sep '13, 02:55

saputello's gravatar image

saputello
18.4k22352

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:

×45
×15

Frage gestellt: 31 Aug '13, 08:16

Frage wurde angeschaut: 3,658 Mal

Zuletzt aktualisiert: 02 Sep '13, 02:55