La lunotipia. Tipografía digital, TeX y cafeína

Definir un comando con opciones fijas en LaTeX

El caso es el siguiente. Queremos definir en LATEX un comando que ejecute una acción por defecto, pero que pueda realizar otras si le aplicamos una serie de opciones predefinidas. De tal suerte que:

  1. \micomando: la acción por defecto;
  2. \micomando[valor1]: la acción asociada al valor 1
  3. \micomando[valor2]: la acción asociada al valor 2
  4. Etc.

Hay muchas formas de hacer esto en LATEX, pero aquí daremos cuenta de tres, empezando la que resulta más idiomática a LATEX2ε.

Mediante \nameuse y \namedef

Partamos de que definimos nuestro comando (por el uso de la arroba debemos encerrarlo todo entre sendas \makeatletter y \makeatother), con la opción por defecto:

% empezamos \makeatletter
\makeatletter

\newcommand\micomando[1][defecto]{%
  \@nameuse{#1}}

Sólo nos quedaría ir definiendo las distintas opciones mediante \namedef, empezando por la opción por defecto:

\@namedef{defecto}{%
  Esta es la opción por defecto}

Y siguiendo por las otras opciones definidas:

\@namedef{valor1}{%
  Esta es la opción asociada al valor 1}

\@namedef{valor2}{%
  Esta es la opción asociada al valor 2}

% cerramos el grupo \makeatletter...\makeatother
\makeatother

Podemos compilar ya nuestro comando con las tres opciones:

\begin{document}

\micomando

\micomando[valor1]

\micomando[valor2]

\end{document}

Y obtendremos el resultado esperado:

opciones1.png

Mediante los paquetes xparse y etoolbox

El paquete xparse, perteneciente al proyecto LATEX 3, pero usable perfectamente en LATEX2ε, nos proporciona una interfaz novedosa y clara para poder definir comandos a muy alto nivel en nuestros documentos de LATEX. Por su parte, del paquete etoolbox nos viene como anillo al dedo el comando \ifstrequal para comparar dos cadenas de texto (primero y segundo argumento), que serán las opciones del comando que queremos definir. El tercer argumento, que sería lo que devolviese si las dos cadenas no fuesen iguales, lo dejaremos vacío. Es decir, que no ejecutará nada en ese caso.

Comenzamos, pues, definiendo el documento y cargando los paquetes:

\documentclass{article}
\usepackage{xparse}
\usepackage{etoolbox}

Y declaramos nuestro nuevo comando, esta vez mediante la sintaxis de xparse (véase el manual, para más información). Definimos un único argumento opcional; si el valor del argumento opcional es falso (no tiene valor verdadero) se aplica el valor defecto, pero si es verdadero (no tiene valor falso) se aplican los tres condicionales que comparan la cadena del argumento opcional con los valores prefijados:

\DeclareDocumentCommand\micomando{ o }{%
  \IfNoValueTF{#1}
  {Este sigue siendo, amigos, el valor por defecto}
  {\ifstrequal{#1}{valor1}{Nada cambia: vuelve a ser el valor 1}{}
    \ifstrequal{#1}{valor2}{Ídem para el valor 2}{}
    \ifstrequal{#1}{valor3}{Y el valor 3 no se aparta de lo esperable}{}
  }
}

Ya sólo nos queda compilarlo:

\begin{document}

\micomando

\micomando[valor1]

\micomando[valor2]

\micomando[valor3]

\end{document}

Y aquí nuestro resultado:

opciones2.png

De nuevo mediante xparse, pero usando ahora la sintaxis de LaTeX 3 para comparar cadenas

Es decir, en lugar de etoolbox usaremos aquí el comando \str_if_eq:nnTF. Iniciamos nuestro documento:

\documentclass{article}
\usepackage{xparse}

Primero, definimos una macro, para simplificar (ojo, hay que encerrarla entre \ExplSyntaxOn Y \ExplSyntaxOff para que se tenga en cuenta la sintaxis de las funciones de expl3)

\ExplSyntaxOn
\cs_new_eq:NN \compara \str_if_eq:nnTF
\ExplSyntaxOff

Y volvemos a definir nuestro comando con xparse:

\DeclareDocumentCommand\micomando{ o }{%
  \IfNoValueTF{#1}
  {Sin novedad: el valor por defecto}
  {\compara{#1}{valor1}{Y otra vez y por tercera, el valor 1}{}
    \compara{#1}{valor2}{Y el valor 2}{}
    \compara{#1}{valor3}{¡Y el valor 3!}{}
  }
}

Y volvemos a compilar:

\begin{document}

\micomando

\micomando[valor1]

\micomando[valor2]

\micomando[valor3]

\end{document}

Con nuestro resultado esperable:

opciones3.png

Publicado: 05/11/20

Última actualización: 16/08/23


Índice general

Acerca de...

Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.

© Juan Manuel Macías
Creado con esmero en
GNU Emacs