Nuestras propias macros
Hoy vamos a salir de mi zona de confort y hablar sobre la creación de macros, es decir, de nuevos comandos y entornos¡Líos de nomenclatura a la vista! Dijimos hace mucho que LaTeX es un conjunto de macros para TeX. Luego hemos separado estas macros en comandos y entornos, pero un entorno no deja de ser un conjunto de comandos que afecta de forma local. Llamaremos también macro a los comandos (y por extensión entornos) que definamos nosotros, tal y como se suele hacer en el mundillo.. No soy ninguna experta en esto, pero hay un par de ideas que me parece que hay que tener claras a la hora de definir cosas en LaTeX. Básicamente voy a contar lo que me hubiera gustado que me contaran cuando empecé con esto, más que nada para no copiar de StackOverflow a ciegas.
Lo primero y más importante que tenemos que saber a la hora de jugar
con las macros en LaTeX es que tenemos dos opcionesPara ser sinceros también está \providecommand
, que
crea el comando si no existe y si no ignora la definición, pero no
tiene un primo
para los entornos.:
-
Crear un entorno o comando desde cero. Así conseguimos que LaTeX haga algo que no hacía o guardamos un conjunto de órdenes que usamos a menudo en una macro con el objetivo escribir menos. La palabra clave para esto es new.
-
Pisar un entorno o comando existente. En este caso la idea es modificar el comportamiento de cierto comando o entorno a nuestro gusto. Se conoce como renew.
El siguiente concepto en orden de importancia es que podemos (re)definir comandos en cualquier parte del documento, pero para tener todo perfectamente organizado es preferible hacerlo en el preámbulo.
Veamos entonces como crear comandos y entornos nuevos y modificar los existentes. Voy a intentar que todos los ejemplos resuelvan problemas reales, que no sean de juguete.
Escribir comandos
Han ido apareciendo comandos nuevosCuando aprendimos a escribir ecuaciones vimos un truco para no tener que escribir la palabra Ecuación a la hora de referenciar. y trucadosCuando hablamos del idioma vimos cómo modificar el nombre de las tablas. anteriormente, ¡hoy llega por fin la explicación que os debía! Primero vamos a fabricar comandos nuevecitos, luego modificaremos alguno que ya existe para que sea más divertido.
Comandos nuevos
Definir comandos nuevos en LaTeX es sencillo, solo debemos seguir la siguiente estructura:
\newcommand{COMANDO}[ARGUMENTOS]{DEFINICIÓN}
donde:
-
COMANDO
será el nombre del comando que queramos definir. Empezará por\
. Solo podemos usar letras para bautizarlo. -
ARGUMENTOS
será el número de argumentos entre 0 y 9 que le pasaremos al comando. Como veis, que un comando tenga argumentos es opcional. -
DEFINICIÓN
será donde escribiremos lo que hace el comando. Haremos referencia a los diferentes argumentos mediante#
seguida del número correspondiente.
Veamos un ejemplo. Vamos a crear un comando que nos escriba Figura X
en lugar de X
cuando hagamos referencia a cierta figura:
\newcommand{\figref}[1]{\figurename~\ref{#1}}
Analicémoslo:
-
El nombre del nuevo comando es
\figref{}
y tiene un único argumento, la etiqueta de la figura, a la que hacemos referencia gracias a nuestro viejo conocido\ref{}
. -
\figurename
es el comando que guarda el nombre de las figurasDel mismo modo, el nombre de los capítulos se guarda en\chaptername
y el de las tablas en\tablename
. Cuidado porque no todos los elementos siguen este patrón, de hecho,\sectionname
no existe.. Podríamos escribir Figura a mano, pero si cambiamos el idioma tendríamos que cambiar también la definición. De este modo LaTeX, sustituye\figurename
por el nombre de la figura según le mande el paquete de idioma. -
Usamos un espacio duro entre el nombre y el número para que LaTeX no meta en medio un salto de línea o de página.
Nuestra nueva macro se usa exactamente igual que cualquier otro comando:
\begin{figure}[H]
\includegraphics[width=0.7\textwidth]{Figuras/esquema.eps}
\caption{Esquema del proceso}
\label{fig:esquema}
\end{figure}
Como vemos en la \figref{fig:esquema}...
% Equivalente a
Como vemos en la Figura~\ref{fig:esquema}...
Un tema interesante a la hora de definir comandos es la inclusión de argumentos por defecto en la definición del mismo:
\newcommand{COMANDO}[ARGUMENTOS][DEFECTO]{DEFINICIÓN}
donde DEFECTO
es el valor que tomará el argumento opcional si
no se especifica. El argumento opcional siempre es el primero.
Un ejemplo de uso podría ser un texto matemático en el que hagamos referencia al plano real a menudo pero tal vez nos haga falta alguna vez hablar de un espacio de dimensión mayor. Para ello podemos definir un comando que nos escriba la R molona esa y que por defecto el espacio sea bidimensional, pero podamos cambiarlo opcionalmente:
\usepackage{amssymb}
\newcommand{\R}[1][2]{\mathbb{R}^{#1}}
A la hora de usarlo le pasamos el argumento opcional cuando lo necesitamos:
% Espacio bidimensional
$\R$
% Espacio tridimensional
$\R[3]$
Comandos trucados
Hemos dicho al principio que además de crear nuestros propios comandos
podemos modificar el comportamiento de alguno existente. Para ello
usamos \renewcommand
en lugar de \newcommand
con la misma
sintaxis:
\renewcommand{COMANDO}[ARGUMENTOS]{DEFINICIÓN}
donde:
-
COMANDO
será el nombre del comando que queramos modificar. -
ARGUMENTOS
será el número de argumentos, igual que antes. -
DEFINICIÓN
será la nueva definición del comando.
Como ejemplo de esta sección, vamos a usar \renewcommand
para evitar
tener que activar el modo matemático cuando escribamos fracciones. Con
este fin vamos a echar mano de \ensuremath{}
, que nos
permite usar comandos matemáticos dentro y fuera de las
ecuacionesAhora no nos vengamos
arriba y nos pongamos usar \ensuremath{}
a mansalva. Aquí
hay algunos criterios..
Como vamos a crear la nueva definición a partir del propio comando,
necesitamos guardarlo en otro sitio primero para que la definición no
sea recursiva. En este menester nos ayuda el comando \let
, que
sirve para copiar el contenido de un comando en uno nuevo:
\let\comandoNuevo=\comandoViejo
Juntando las piezas, tenemos lo siguiente:
% Guardamos la definición original
\let\oldfrac=\frac
% Modificamos \frac para que funcione fuera de ecuaciones
\renewcommand{\frac}[2]{\ensuremath{\oldfrac{#1}{#2}}}
Ahora podemos usar \frac
directamente en el texto.
Escribir entornos
¡Ya sabemos crear y cambiar comandos! Vamos a dar un paso más y hacer los mismo para los entornos.
Entornos nuevos
La sintaxis para la definición de entornos nuevos es muy similar a la
de los comandos, usando ahora \newenvironment
:
\newenvironment{ENTORNO}[ARGUMENTOS]{ANTES}{DESPUÉS}
En ANTES
escribiremos el grupo de comandos que hay que ejecutar al
iniciar el entorno y, por tanto, los que le darán el formato al mismo,
y DESPUÉS
, los que se activarán tras el texto. El resto de elementos
funciona como antes.
De esta manera, podemos definir un entorno para poner notas en el
texto. Yo he creado uno que rodea el texto de la nota con dos rayas
(\hrule
), una por debajo y una por encima, y que nos permite darle
un título, que aparecerá en negrita:
\newenvironment{nota}[1]
{\vspace{1ex}\hrule\textbf{#1}}
{\vspace{1ex}\hrule}
Este entorno nuevecito y reluciente se usa en el cuerpo del documento como cualquier otro:
\begin{nota}{¡Cuidado!}
Hay que tener en cuenta que
\end{nota}
Un tema interesante son los contadores gracias a los cuales podremos
fabricar entornos numerados. Los contadores tiene la estructura
\theELEMENTO
. Así, \thepage
contiene el número de página,
\thechapter
Uniéndolo con lo que
hemos dicho anteriormente, \thechapter
contiene el número
del capítulo, \chaptername
su nombre y
\chaptermark
el título. el número de capítulo y
\theNOMBRE
el número del elemento numerado que hayamos creado.
Para crear un contador usamos el comando \newcounter
, le damos un
nombre y, opcionalmente, le decimos dónde debe reiniciar la cuenta:
\newcounter{NOMBRE}[REINICIO]
El tema del reinicio es interesante para los documentos largos, así
podemos empezar a contar al iniciar un capítulo y hacer referencia al
elemento mediante \thechapter.\theNOMBRE
que nos escribirá el número
del capítulo seguido del número del elemento. Con el ejemplo que viene
a continuación se entenderá mejor, espero.
Luego, incrementamos el valor del contador cuando sea necesario con:
-
\stepcounter{CONTADOR}
: incrementa en uno el valor deCONTADOR
. -
\refstepcounter{CONTADOR}
: incrementa en uno el valor deCONTADOR
y nos permite usarlo en las referencias cruzadas. -
\addtocounter{CONTADOR}{NÚMERO}
: incrementaCONTADOR
en un valor que le pasemos.
Una idea que se me ocurre para hacer uso de esta funcionalidad es crear un entorno numerado para poner ejemplos en el texto cuya numeración se reinicie al cambiar de sección:
% Creamos un nuevo contador que se reinicie al cambiar de sección
\newcounter{ejemplo}[section]
% Incrementamos en uno el contador al iniciar el nuevo entorno
% Accedemos a su contenido con \theejemplo
\newenvironment{ejemplo}
{\refstepcounter{ejemplo}\vspace{1ex}\hrule\textbf{Ejemplo~\thesection.\theejemplo}}
{\vspace{1ex}\hrule}
Así, si escribimos algo de este estilo:
\section{Entorno numerado}
\begin{ejemplo}
Un primer ejemplo
\end{ejemplo}
\begin{ejemplo}
Un segundo ejemplo
\end{ejemplo}
Conseguiremos lo siguiente:
Entornos trucados
Al igual que modificábamos comandos existentes con \renewcommand
,
podemos cambiar entornos con \renewenvironment
:
\renewenvironment{ENTORNO}[ARGUMENTOS]{ANTES}{DESPUÉS}
Lo que tenemos que tener en cuenta aquí es la implementación original del entorno que vamos a cambiar. A mí me ayuda pensar en un entorno como dos comandos, uno que da inicio al formato concreto y otro que lo finaliza. Es decir, esto:
\begin{equation}
a^2 x + b x + c = 0
\end{equation}
es equivalente a:
\equation
a^2 x + b x + c = 0
\endequation
De esta manera me resulta más sencillo saber qué hay que escribir en
los argumentos ANTES
y DESPUÉS
de los que hablaba.
Para terminar con los entornos os dejo con un ejemplo complejo que monté juntando piezas de aquí y de allí para que las citas aparecieran en gris oscuro con una barrita gris clara a la izquierda. Es complicadillo y yo misma no sé si lo entiendo muy bien, pero es para que veáis un caso real:
\usepackage{framed}
% Redefinir leftbar
\renewenvironment{leftbar}[1][\hsize]
{\color{gray}
\def\FrameCommand
{{\color{lightgray}\vrule width 3pt}}
\MakeFramed{\hsize#1\advance\hsize-\width\FrameRestore}
}
{\endMakeFramed}
% Guardar entorno quote, lo forman dos comandos
\let\oldquote=\quote
\let\oldendquote=\endquote
% Barra vertical a la izquierda de la cita
\renewenvironment{quote}
{\vspace{10pt}\leftbar\vspace*{-6pt}\oldquote}
{\oldendquote\endleftbar\vspace{10pt}}
En fin, creo que la única manera de aprender a modificar entornos es modificar entornos así que no queda más remedio que practicar.
Una nota sobre TeX
En el principio de los tiempos dijimos que LaTeX es un conjunto de macros escritos en TeX (o Plain TeX) ¿recordáis? Esto provoca que LaTeX tenga algunas limitaciones a la hora de definir cosas, limitaciones que TeX, al ser de más bajo nivel, no tiene.
El comando \let
que hemos usado para guardar la definición original
de un comando que íbamos a modificar pertenece a TeX. También \def
que aparece en ejemplo de las citas personalizadas es parte de TeX y
sirve para definir comandos nuevos, al igual que \newcommand
Se pueden declarar comandos nuevos dentro de entornos
de manera similar a declararlos de manera independiente. Aquí
tenéis más información.. Os hablo de ellos porque los veréis a
menudo cuando busquéis ejemplos por ahí.
En definitiva, ¿qué hay que saber?
Diría que lo más importante es saber la diferencia entre definir
(\new
) y pisar (\renew
) un comando o entorno existente y cuándo
hay que hacer lo uno o lo otro. Tampoco está de más recordar que
escribimos tanto las definiciones como las modificaciones en el
preámbulo. Igualmente, nos viene bien saber de la existencia de
comandos de TeX como \let
y \def
que nos hacen la vida más fácil.
Para acabar, os dejo mi proceso para crear macros:
-
Escribo mi combinación de comandos en el cuerpo del documento y verifico que funciona.
-
Escribo cómo quiero que sea mi comando o entorno final y lo comparo con mi combinación de comandos.
-
Traslado la combinación al preámbulo y le doy forma según la sintaxis correspondiente.
-
Extraigo los argumentos y pienso si puedo darle un valor por defecto a alguno de ellos.
-
Pruebo si funciona.
Lo dicho, a escribir macros se aprende escribiendo macros. ¡Dadle duro!
Referencias
LaTeX example: How to create your own commands with newcommand
\newcommand
with arguments in LaTeX
Plain TeX vs. LaTeX Macros en TeXExchange
List of higher-level LaTeX commands corresponding to TeX commands en TeXExchange
What is the difference between \def and \newcommand? en TeXExchange
Anterior: También podemos presentar, Siguiente: Abramos la caja de herramientas [Contenido]