\newcommand: Usar un parámetro como predeterminado para el otro

\newcommand: Usar un parámetro como predeterminado para el otro

Me gustaría definir una macro que tome dos argumentos, uno de los cuales es opcional. Si no se proporciona, entonces debería tomar el otro como valor predeterminado.

Desafortunadamente,

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

no funciona, tampoco

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

¿Alguien sabe cómo hacer esto?

Respuesta1

Buenas noticias: puedes hacerlo muy fácilmente con 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}

El especificador de argumento O{...}toma como argumento qué sustituir de forma predeterminada cuando el argumento en sí no aparece en el momento de la llamada. Bien puede ser un token de parámetro que hace referencia a otro argumento.

ingrese la descripción de la imagen aquí

Respuesta2

Puedes usarxparsecondicionar fácilmente si un argumento opcional estaba presente o no, y proporcionar la combinación adecuada a otra función (auxiliar). He aquí un ejemplo:

ingrese la descripción de la imagen aquí

\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}

Una versión ligeramente diferente de esto surge del uso de \caption, donde puede proporcionar un argumento opcional para LoT/LoF, pero si no lo hace, se envían los argumentos obligatorios (de manera similar para unidades seccionales con argumentos opcionales destinados a ToC). ). Esto utiliza elnúcleo'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}

Respuesta3

Este es un intento de agregar protección como ocurre con otras macros que procesan argumentos opcionales:

%%\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}

ingrese la descripción de la imagen aquí

información relacionada