Pregunta

¿Cómo se crea un comando con argumentos opcionales en LaTeX? Algo como:

\newcommand{\sec}[2][]{
    \section*{#1
        \ifsecondargument
            and #2
        \fi}
    }
}

Entonces, puedo llamarlo así

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi
¿Fue útil?

Solución

Ejemplo de la guía :

\newcommand{\example}[2][YYY]{Mandatory arg: #2;
                                 Optional arg: #1.}

This defines \example to be a command with two arguments, 
referred to as #1 and #2 in the {<definition>}--nothing new so far. 
But by adding a second optional argument to this \newcommand 
(the [YYY]) the first argument (#1) of the newly defined 
command \example is made optional with its default value being YYY.

Thus the usage of \example is either:

   \example{BBB}
which prints:
Mandatory arg: BBB; Optional arg: YYY.
or:
   \example[XXX]{AAA}
which prints:
Mandatory arg: AAA; Optional arg: XXX.

Otros consejos

La idea general detrás de la creación de "argumentos opcionales" es definir primero un comando intermedio que escanea hacia adelante para detectar qué caracteres aparecerán a continuación en la secuencia de tokens y luego inserta las macros relevantes para procesar los argumentos que surjan según corresponda. Esto puede ser bastante tedioso (aunque no difícil) con la programación genérica de TeX. El \ @ifnextchar de LaTeX es bastante útil para tales cosas.

La mejor respuesta para su pregunta es usar el nuevo paquete xparse . Es parte de la suite de programación LaTeX3 y contiene amplias funciones para definir comandos con argumentos opcionales bastante arbitrarios.

En su ejemplo, tiene una macro \ sec que toma uno o dos argumentos entre paréntesis. Esto se implementaría usando xparse con lo siguiente:

\documentclass{article}
\usepackage{xparse}
\begin{document}
\DeclareDocumentCommand\sec{ m g }{%
    {#1%
        \IfNoValueF {#2} { and #2}%
    }%
}
(\sec{Hello})
(\sec{Hello}{Hi})
\end{document}

El argumento {m g} define los argumentos de \ sec ; m significa " argumento obligatorio " y g es " argumento entre paréntesis opcional " ;. \ IfNoValue (T) (F) se puede usar para verificar si el segundo argumento estaba realmente presente o no. Consulte la documentación para los otros tipos de argumentos opcionales que están permitidos.

¡Todo lo anterior muestra que puede ser una función agradable, flexible (o prohibir una sobrecarga) en LaTeX! (ese código TeX me parece griego)

bueno, solo para agregar mi desarrollo reciente (aunque no tan flexible), esto es lo que he usado recientemente en mi documento de tesis, con

\usepackage{ifthen}  % provides conditonals...

Inicie el comando, con el " opcional " comando configurado en blanco por defecto:

\newcommand {\figHoriz} [4] []  {

Luego hago que la macro establezca una variable temporal, \ temp {}, de manera diferente dependiendo de si el argumento opcional está en blanco o no. Esto podría extenderse a cualquier argumento aprobado.

\ifthenelse { \equal {#1} {} }  %if short caption not specified, use long caption (no slant)
    { \def\temp {\caption[#4]{\textsl{#4}}} }   % if #1 == blank
    { \def\temp {\caption[#1]{\textsl{#4}}} }   % else (not blank)

Luego ejecuto la macro usando la variable \ temp {} para los dos casos. (Aquí solo establece el título corto para que sea igual al título largo si el usuario no lo especificó).

\begin{figure}[!]
    \begin{center}
        \includegraphics[width=350 pt]{#3}
        \temp   %see above for caption etc.
        \label{#2}
    \end{center}
\end{figure}
}

En este caso, solo verifico el single, "opcional" argumento que proporciona \ newcommand {}. Si tuviera que configurarlo para, digamos, 3 '' opcional '' args, todavía tendría que enviar los 3 args en blanco ... por ejemplo.

\MyCommand {first arg} {} {} {}

lo cual es bastante tonto, lo sé, pero eso es lo más lejos que voy a llegar con LaTeX; simplemente no es tan sensato una vez que empiezo a mirar el código TeX ... Sin embargo, me gusta el método xparse del Sr. Robertson , tal vez lo intente ...

Todo lo que necesitas es lo siguiente:

\makeatletter
\def\sec#1{\def\tempa{#1}\futurelet\next\sec@i}% Save first argument
\def\sec@i{\ifx\next\bgroup\expandafter\sec@ii\else\expandafter\sec@end\fi}%Check brace
\def\sec@ii#1{\section*{\tempa\ and #1}}%Two args
\def\sec@end{\section*{\tempa}}%Single args
\makeatother

\sec{Hello}
%Output: Hello
\sec{Hello}{Hi}
%Output: Hello and Hi

Tuve un problema similar, cuando quería crear un comando, \ dx , para abreviar \; \ mathrm {d} x (es decir, poner un espacio extra antes del diferencial de la integral y tener la `` d '' vertical también). Pero también quería hacerlo lo suficientemente flexible como para incluir la variable de integración como argumento opcional. Puse el siguiente código en el preámbulo.

\usepackage{ifthen}

\newcommand{\dx}[1][]{%
   \ifthenelse{ \equal{#1}{} }
      {\ensuremath{\;\mathrm{d}x}}
      {\ensuremath{\;\mathrm{d}#1}}
}

Entonces

\begin{document}
   $\int x\dx$
   $\int t\dx[t]$
\end{document}

proporciona \ dx con argumento opcional

Aquí está mi intento, aunque no sigue exactamente tus especificaciones. No completamente probado, así que tenga cuidado.

\newcount\seccount

\def\sec{%
    \seccount0%
    \let\go\secnext\go
}

\def\secnext#1{%
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\secparse{%
    \ifx\next\bgroup
        \let\go\secparseii
    \else
        \let\go\seclast
    \fi
    \go
}

\def\secparseii#1{%
    \ifnum\seccount>0, \fi
    \advance\seccount1\relax
    \last
    \def\last{#1}%
    \futurelet\next\secparse
}

\def\seclast{\ifnum\seccount>0{} and \fi\last}%

\sec{a}{b}{c}{d}{e}
% outputs "a, b, c, d and e"

\sec{a}
% outputs "a"

\sec{a}{b}
% outputs "a and b"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top