\newcommand: Einen Parameter als Standard für den anderen verwenden

\newcommand: Einen Parameter als Standard für den anderen verwenden

Ich möchte ein Makro definieren, das zwei Argumente annimmt, von denen eines optional ist. Wenn es nicht angegeben ist, soll das andere als Standardwert verwendet werden.

Bedauerlicherweise,

\newcommand{\mycommand}[2][#1]{ ... }

funktioniert nicht, auch nicht

\newcommand{\mycommand}[2][#2]{ ... }

Weiß jemand, wie das geht?

Antwort1

Die gute Nachricht ist, dass dies ganz einfach ist mit xparse:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand{\foo}{O{#2}m}{%
  Optional=``#1'', mandatory=``#2''\par
}
\NewDocumentCommand{\oof}{mO{#1}}{%
  Mandatory=``#1'', optional=``#2''\par
}

\begin{document}

\foo{x}

\foo[y]{x}

\oof{x}

\oof{x}[y]

\end{document}

Der Argumentspezifizierer O{...}verwendet als Argument, was als Standard ersetzt werden soll, wenn das Argument selbst zum Aufrufzeitpunkt nicht erscheint. Dies kann durchaus ein Parametertoken sein, das auf ein anderes Argument verweist.

Bildbeschreibung hier eingeben

Antwort2

Sie könnenxparseum einfach davon abhängig zu machen, ob ein optionales Argument vorhanden war oder nicht, und die entsprechende Kombination einer anderen (Hilfs-)Funktion zu übergeben. Hier ist ein Beispiel:

Bildbeschreibung hier eingeben

\documentclass{article}

\usepackage{xparse}

\newcommand{\printthis}[2]{%
  Optional: #1; Mandatory: #2%
}

\NewDocumentCommand{\mycommand}{o m}{%
  \IfValueTF{#1}
    {\printthis{#1}{#2}}% \mycommand[..]{...}
    {\printthis{#2}{#2}}% \mycommand{...}
}

\begin{document}

\mycommand{first}

\mycommand[first]{second}

\end{document}

Eine leicht abgewandelte Version davon ergibt sich aus der Verwendung von \caption, wobei Sie ein optionales Argument für das LoT/LoF angeben können, aber wenn Sie dies nicht tun, werden stattdessen die obligatorischen Argumente gesendet (ähnlich für Sektionseinheiten mit optionalen Argumenten, die für das ToC bestimmt sind). Dies verwendet dasKernel'S \@dblarg:

\documentclass{article}

\newcommand{\printthis}[2][]{%
  Optional: #1; Mandatory: #2%
}

\makeatletter
\newcommand{\mycommand}{%
  \@dblarg\printthis
}
\makeatother

\begin{document}

\mycommand{first}

\mycommand[first]{second}

\end{document}

Antwort3

Dies ist ein Versuch, Schutz hinzuzufügen, wie bei anderen Makros, die optionale Argumente verarbeiten:

%%\errorcontextlines=1000
\documentclass[a4paper]{article}

\makeatletter
\newcommand\makefirstmandatorytheoptional[1]{%
  \expandafter\innermakefirstmandatorytheoptional
  \expandafter{\csname\string#1\endcsname}{#1}%
}%
\newcommand\innermakefirstmandatorytheoptional[2]{%
  \def#2{%
    \ifx\protect\@typeset@protect
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    {\kernel@ifnextchar[{#1}{\@dblarg{#1}}}%
    {\protect#2}%
  }%
}%
\newcommand\mycommand[2][dummyoptional]{%
  This is taken for the optional argument: #1.\\
  This is taken for the mandatory argument: #2.
}%
\makefirstmandatorytheoptional{\mycommand}%
\makeatother

\parindent=0ex
\parskip=\medskipamount

\begin{document}

No optional argument given---\verb|\mycommand{A}|:

\mycommand{A}

Optional argument "B" given---\verb|\mycommand[B]{A}|:

\mycommand[B]{A}

\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen