Definir macros

La mejor razón para definir comandos propios en LaTeX, es decir, macros, no es ahorrar pulsaciones. Imaginemos una tesis en la que cada vector está compuesto como \mathbf{v}, cuatrocientas veces, y un director que ahora prefiere flechas. Si esos vectores se hubieran escrito \vect{v}, respaldados por un solo \newcommand, todo el cambio cabría en una línea del preámbulo; si no, son cuatrocientas correcciones cuidadosas. Una macro es el sitio donde se reserva el derecho a cambiar de opinión más tarde. Esta página parte de \newcommand y sus argumentos, aclara \renewcommand y \providecommand, explica adónde va el espacio que sigue al nombre de una macro y termina con los comandos frágiles, \protect y el moderno \NewDocumentCommand.

Definir un comando propio con \newcommand

Toda la sintaxis cabe en una línea: \newcommand{\name}{definition}. El primer argumento es el nombre deseado, el segundo lo que representa, y desde ese momento cada \name que se teclea queda sustituido por definition. Su sitio natural es el preámbulo, antes de \begin{document}. Aquí es donde rinde la historia de los vectores: el nombre \vect designa un significado, no una apariencia. Escribir «esto es un vector» en lugar de «esto va en negrita» deja la decisión —negrita o flecha encima— en un único lugar. Es el mismo trato que ya ofrece LaTeX: se escribe \section en vez de componer a mano una negrita de 14pt exactamente por esta razón.

latex
% preamble: one line decides how every vector in the document looks
\usepackage{amsmath,amssymb}
\newcommand{\vect}[1]{\mathbf{#1}}
% \newcommand{\vect}[1]{\vec{#1}}   % swap this line, the whole thesis follows

% semantic names for things you refer to constantly
\newcommand{\R}{\mathbb{R}}
\newcommand{\dd}{\mathrm{d}}

% body
\[ \vect{v} \cdot \vect{w} = \lvert \vect{v} \rvert \, \lvert \vect{w} \rvert \cos\theta \]
\[ \int_{\R} f(x) \, \dd x \]

Macros con argumentos y el argumento opcional

Para variar el contenido en cada llamada, se pone el número de argumentos entre corchetes tras el nombre y se recogen dentro de la definición como #1, #2, etc.: \newcommand{\name}[⟨nargs⟩]{... #1 #2 ...}. Solo hay un techo duro: los parámetros van de #1 a #9, nueve como máximo. Lo curioso es que pedir un décimo produce ! You already have nine parameters., y ese mensaje procede del motor TeX, no de LaTeX. El límite pertenece a la primitiva \def que hay debajo, así que \newcommand no puede aflojarlo. Necesitar más de nueve suele ser señal de que conviene rediseñar con opciones clave-valor en lugar de argumentos posicionales.

latex
% two mandatory arguments: a number and a unit
\newcommand{\unit}[2]{#1\,\mathrm{#2}}

$a = \unit{9.8}{m/s^2}$

Se puede ir un paso más allá y hacer opcional el primer argumento, con un valor por defecto. Es la forma de corchetes duplicados, \newcommand{\name}[⟨nargs⟩][⟨default⟩]{...}: #1 pasa a ser el argumento opcional y, si se omite, se sustituye por ⟨default⟩. Después se escribe \name{...} para tomar el valor por defecto o \name[x]{...} para fijar #1 en x; los argumentos obligatorios restantes se cuentan desde #2. La trampa está en el recuento: [⟨nargs⟩] es el número total de argumentos, incluido el opcional. En el ejemplo de abajo, [2][2] significa «dos argumentos, el primero opcional con valor por defecto 2».

latex
% two arguments in total; the first is optional and defaults to 2
\newcommand{\pow}[2][2]{(x + y)^{#1}_{#2}}

$\pow{n}$      % -> (x + y)^2_n
$\pow[3]{n}$   % -> (x + y)^3_n

% starred form: the argument may not contain a blank line
\newcommand*{\keyword}[1]{\textsf{#1}}

Conviene añadir dos detalles. Primero, omitir [⟨default⟩] no es lo mismo que escribir corchetes vacíos []: estos últimos dan un argumento opcional cuyo valor por defecto es la cadena vacía. Segundo, la forma con estrella \newcommand* construye una macro «corta» cuyo argumento no puede contener una línea en blanco (es decir, un \par). Parece una restricción, pero es un diagnóstico: si falta una llave de cierre, aparece ! Paragraph ended before \keyword was complete. cerca del error. Sin la estrella, TeX lee tan tranquilo el párrafo siguiente, y el de después, como parte del argumento, y el error asoma páginas más adelante. Poner * en toda macro que no deba abarcar párrafos ahorra mucho rastreo posterior.

La diferencia entre \newcommand, \renewcommand y \providecommand

Los tres toman argumentos exactamente igual; lo que cambia es cómo reaccionan ante un nombre ya ocupado. \newcommand se niega y se detiene, \renewcommand sobrescribe y \providecommand se aparta en silencio y conserva la definición existente. Así, aplicar \newcommand a un nombre existente detiene la compilación con ! LaTeX Error: Command \emph already defined., mientras que aplicar \renewcommand a uno indefinido la detiene con ! LaTeX Error: Command \foo undefined. Ambos errores forman pareja y protegen desde los dos lados: de aplastar algo por accidente y de creer que se ha aplastado algo cuando no ha cambiado nada.

Una rareza: escribir \newcommand{\endnotes}{...} se detiene con Command \endnotes already defined. aunque no exista en ninguna parte un comando con ese nombre. La segunda línea del mensaje lo delata: continúa con Or name \end... illegal, see p.192 of the manual. La comprobación de nombres dentro de latex.ltx confirma primero que el nombre está indefinido y exige además que sus tres primeras letras no sean end y que el nombre no sea relax. Como \end{itemize} funciona llamando internamente a \enditemize, permitir nombres inventados que empiecen por end rompería el emparejamiento de entornos, así que todo el prefijo está reservado. La expresión «already defined» es solo un mensaje tosco que cubre ambos casos.

ComandoAnte un nombre existenteUso principal
\newcommandSe detiene con errorCrear un comando nuevo con seguridad
\renewcommandLo sobrescribe (error si no existe)Rehacer un comando existente
\providecommandNo hace nada (mantiene la anterior)Archivos de estilo que pueden cargarse dos veces
\DeclareRobustCommandLo sobrescribe y deja nota en el logComandos robustos para argumentos móviles

El reparto práctico es nítido. \renewcommand es la puerta que dice «sustituir algo que LaTeX ya proporciona»; cambiar la viñeta de una lista con \renewcommand{\labelitemi}{--} es el caso clásico. \providecommand declara «proporciona esto si nadie más lo ha hecho», de modo que un archivo de estilo propio sobreviva a ser leído dos veces desde dos sitios distintos. En el ejemplo de abajo \vect ya existe, así que \providecommand no hace nada y la definición en negrita se mantiene. Y \DeclareRobustCommand es la estrella de la sección siguiente: no se detiene ante un nombre existente, sino que deja una línea del tipo LaTeX Info: Redefining \emph on input line 2. en el .log. Registrar la sobreescritura en vez de ejecutarla en silencio es su diferencia real con \renewcommand.

latex
% replace something the class already defines
\renewcommand{\labelitemi}{--}

% define only if nobody else did; here \vect exists, so this line is a no-op
\providecommand{\vect}[1]{\vec{#1}}

% redefine on purpose, and say so in the log
\DeclareRobustCommand{\emph}[1]{\textbf{#1}}

Por qué desaparece el espacio tras una macro y qué arregla \xspace

Un nombre de comando formado solo por letras termina en el primer carácter que no sea letra, y los espacios que siguen se engullen como marca de fin del nombre. Así, con \newcommand{\lab}{Knuth Lab} en el preámbulo, teclear \lab was founded. imprime «Knuth Labwas founded.» El espacio no se ha esfumado: TeX lo consumió para averiguar dónde acaba el nombre \lab. La excepción es reveladora: \$ de conserva su espacio y compone «$ de». \$ es un símbolo de control de un solo carácter no alfabético; su nombre queda completo tras ese carácter y no hay motivo para leer más allá. La trampa, por tanto, afecta solo a los nombres de comando escritos con letras.

latex
\usepackage{xspace}
\newcommand{\lab}{Knuth Lab}
\newcommand{\labx}{Knuth Lab\xspace}

\lab was founded.     % -> Knuth Labwas founded.
\lab{} was founded.   % -> Knuth Lab was founded.
\lab\ was founded.    % -> Knuth Lab was founded.
\labx was founded.    % -> Knuth Lab was founded.
\labx, and a comma.   % -> Knuth Lab, and a comma.

Hay tres remedios. El habitual es un par de llaves vacío, \lab{}, que marca dónde acaba el nombre; luego el espacio de control \lab\ ; y en tercer lugar \xspace, del paquete xspace. Lo ingenioso de \xspace es que no añade el espacio sin más: primero echa un vistazo al siguiente token. La lista de excepciones de xspace.sty incluye , . ' / ? ; : ! ~ - ) y las llaves de cierre, además de \footnote y similares; delante de ninguno de ellos se inserta espacio. Por eso \labx, and compone correctamente «Knuth Lab, and». El paquete forma parte del lote tools de LaTeX y lo escribió originalmente David Carlisle; \xspaceaddexceptions permite ampliar la lista. Conviene conocer el precio: \xspace es un truco de anticipación, innecesario en macros con argumentos (que acaban en } de todos modos) y a veces sorprendente dentro del argumento de otra macro. En caso de duda, {} es la más segura de las tres.

Comandos frágiles, argumentos móviles, \protect y \DeclareRobustCommand

Una macro propia puede romperse de golpe dentro de un título de sección o de un pie de figura. La causa es el argumento móvil. El texto de \section{...} no solo se compone en el cuerpo: también se escribe en el archivo .aux para el índice y se pasa a la cabecera. El mismo contenido «se mueve» a otros lugares. \caption{...}, \thanks{...} y las expresiones @{...} de tabular y array se comportan igual. Un comando cuyo código pierde el sentido al expandirse en el momento de escribirse se llama comando frágil; el que sobrevive intacto a esa escritura es un comando robusto.

El remedio clásico es \protect, colocado justo antes de un comando frágil para decir «no lo expandas aquí: escríbelo tal cual». Protege exactamente un comando por vez. Hay, no obstante, buenas noticias: desde la versión de LaTeX de octubre de 2019, muchísimos comandos antes frágiles se volvieron robustos. El cambio consta en LaTeX News 30, sección «Making more user commands robust», y llegó hasta \begin y \end, de modo que hoy caben entornos enteros dentro de un título. El irreductible es \verb: puesto en un título de sección, la compilación se detiene con ! LaTeX Error: \verb illegal in argument. (arrastrando casi siempre ! Paragraph ended before \@sect was complete.). A ese \protect no lo salva, así que en un título o un pie lo práctico es reescribirlo como \texttt{...}.

latex
% \verb cannot go here at all -- rewrite it
\section{The \texttt{\textbackslash par} primitive}

% a macro that is robust from the start, even though \ifmmode is fragile
\DeclareRobustCommand{\seq}[2][n]{%
  \ifmmode #2_{1}\ldots #2_{#1}\else\textbf{??}\fi
}
\section{Sequences $\seq{x}$}   % works without \protect

Para las macros propias, definirlas robustas desde el principio con \DeclareRobustCommand es más fiable que acordarse de \protect cada vez. Los argumentos se escriben igual que con \newcommand y, aunque el cuerpo mezcle código frágil como \ifmmode, el comando resultante sobrevive a un argumento móvil. El \seq de arriba es el ejemplo del propio clsguide de LaTeX, escrito para demostrar justamente esto. El precio es una ligera pérdida de eficiencia, así que no hace falta volver robusta una macro que jamás aparecerá en un título o un pie. La única pregunta útil es si la macro puede acabar alguna vez en el índice.

\NewDocumentCommand: la forma moderna de definir

\newcommand solo sabe construir una forma: como mucho un argumento opcional entre corchetes, seguido de los obligatorios. \NewDocumentCommand{\name}{⟨arg-spec⟩}{...} derriba ese techo. En lugar de un número de argumentos se le pasa una especificación de argumentos (arg-spec): una cadena de letras que nombra el tipo de cada uno. Empezó siendo una función del paquete xparse, pero la versión del 1 de octubre de 2020 la incorporó al núcleo de LaTeX (módulo ltcmd), así que hoy funciona sin \usepackage{xparse}. LaTeX News 32 deja constancia del traslado.

EspecificadorSignificadoCómo llega al cuerpo
mArgumento obligatorioUn #1 corriente, etc.
oArgumento opcional [...]Marcador de «sin valor» si falta
O{default}Opcional, con valor por defectoEl valor por defecto si falta
sEstrella * opcionalSe comprueba con \IfBooleanTF

Aquí está su ventaja decisiva sobre \newcommand: admite varios argumentos opcionales y trata las variantes con estrella como una función de pleno derecho. Al escribir s, #1 llega como un booleano que indica si había estrella, y se ramifica con \IfBooleanTF{#1}{con estrella}{sin estrella}. Cambiar el prefijo entre New, Renew, Provide y Declare da los equivalentes de \newcommand, \renewcommand, \providecommand y la sobreescritura incondicional. Para código nuevo, esta interfaz puede ser la opción por defecto, aunque \newcommand ni ha desaparecido ni ha envejecido y sigue siendo perfecto para una definición corta de uno o dos argumentos.

latex
% s = optional star, m = mandatory argument
\NewDocumentCommand{\diff}{s m}{%
  \IfBooleanTF{#1}%
    {\frac{\mathrm{d}}{\mathrm{d}#2}}%   starred: d/dx
    {\mathrm{d}#2}%                      plain:   dx
}

$\diff{x}$    % -> dx
$\diff*{x}$   % -> d/dx

% O{...} gives an optional argument with a default
\NewDocumentCommand{\note}{O{note} m}{\textbf{#1:} #2}

Nombrar macros sin colisiones y dónde guardar las definiciones

La mejor herramienta contra las colisiones de nombres es el propio \newcommand. Sobrescribir de entrada con \renewcommand o \def no revela nunca qué se ha destruido; definir primero con \newcommand hace saltar un already defined que avisa al instante de que el nombre está ocupado. Por eso mismo conviene no aplastar a la ligera comandos del núcleo o de paquetes con \renewcommand. Para los nombres propios, evita los demasiado cortos y prefiere un prefijo propio del proyecto (\myR, \bookTitle). Los nombres cortos de operadores matemáticos están especialmente ocupados —\ker, \deg, \arg, \Re—, así que si se quiere \R, merece la pena una prueba con \newcommand.

Demasiadas macros hacen tan ilegible el texto como demasiado pocas. Una abreviatura extrema como \newcommand{\x}{\xi} es un cifrado para el yo de dentro de seis meses y para un coautor. Reserva las macros para lo que se repite a menudo, es probable que cambie en bloque o merece un nombre por su significado; el resto se lee mejor escrito directamente. La prueba es sencilla: ¿se entiende el nombre de un vistazo? \vect sí; \x no.

Queda la cuestión del emplazamiento. Para un solo artículo basta el preámbulo; pero un libro repartido en un archivo por capítulo, o varios artículos que comparten una misma notación, se gestionan mejor si las definiciones viven en un archivo propio cargado con \usepackage. Hay un pequeño extra: dentro de un .sty o un .cls, @ cuenta como letra, así que nombres internos como \mybook@vecfont funcionan sin escribir \makeatletter. Como un nombre que contiene @ no puede invocarse desde el cuerpo del documento, se obtiene una distinción por el nombre entre los comandos públicos y los privados. Hacer lo mismo en un preámbulo obliga a encerrar el código entre \makeatletter y \makeatother, una ocasión más de equivocarse.

latex
% ---- mynotation.sty --------------------------------------------
\ProvidesPackage{mynotation}[2024/01/01 shared notation]
\RequirePackage{amsmath,amssymb}

% private: the @ makes it uncallable from the document body
\newcommand{\mynot@vecfont}[1]{\mathbf{#1}}

% public
\newcommand{\vect}[1]{\mynot@vecfont{#1}}
\newcommand{\R}{\mathbb{R}}

% ---- thesis.tex ------------------------------------------------
% \usepackage{mynotation}