Imprimir una sola barra inversa en LaTeX es más difícil que imprimir un signo de integral, y no es una broma. El verbatim —\verb para un fragmento, el entorno verbatim para un bloque— es el único rincón del sistema que solo funciona apagando por un momento la gramática del propio LaTeX. De ahí se derivan todas las reglas que parecen arbitrarias: por qué \verb no puede cruzar un salto de línea, por qué escribir \end {verbatim} con un espacio dentro detiene la compilación y por qué poner \verb dentro de \section{...} o \footnote{...} falla con un error que nunca menciona el verbatim. Esta página recorre el entorno verbatim y \verb, las formas con estrella que hacen visibles los espacios, la lectura de archivos completos con \verbatiminput y \VerbatimInput, la variante alltt que mantiene vivos algunos comandos, los bloques enmarcados y numerados con fancyvrb, y cómo teclear una barra inversa o un guion bajo en el texto corriente.
Qué desactiva realmente el entorno verbatim
Todo lo que va entre \begin{verbatim} y \end{verbatim} se imprime exactamente como se escribió —saltos de línea y espacios incluidos— en fuente de máquina de escribir, sin necesidad de ningún paquete. El mecanismo no es un escape sino una degradación. Al entrar en el entorno, LaTeX reescribe de golpe el código de categoría de \, {, }, $, &, #, ^, _, % y ~ a «carácter ordinario». Un código de categoría es la etiqueta de papel que TeX asigna a cada carácter mientras lee la entrada; decide si ese carácter inicia un comando, abre un grupo o es solo tinta. Una barra inversa dentro de verbatim no inicia un comando, no porque se ignoren los comandos, sino porque en ese momento la barra inversa es solo un signo con forma de barra inversa.
\begin{verbatim}
for i in range(3):
print("100% & $5 \n") # none of this is interpreted
\end{verbatim}Implementar esto también resulta incómodo para quien lo escribe, y esa incomodidad quedó conservada en el propio código fuente de LaTeX. Dentro de latex.ltx, el archivo que define LaTeX, la macro que busca el final de un bloque verbatim está definida con | haciendo de carácter de escape y [ y ] haciendo de llaves. Dentro de esa definición los tres caracteres \, { y } deben ser caracteres imprimibles ordinarios, de modo que el lenguaje no puede expresarse allí con su notación habitual. Durante esa definición, el código fuente de LaTeX deja de estar escrito en LaTeX. Ambas líneas pueden leerse tal cual en el latex.ltx que acompaña a TeX Live 2024.
De esa manera de detectar el final se derivan dos reglas prácticas. Primera: la cadena \end{verbatim} no debe aparecer dentro del entorno; LaTeX la toma como el final en cuanto la ve. Segunda: no puede haber un espacio entre \end y {verbatim}. El terminador se compara carácter a carácter como delimitador de argumento de macro, así que \end {verbatim} no se reconoce en absoluto y TeX sigue leyendo hasta el final del archivo antes de detenerse con Runaway argument? y después ! File ended while scanning use of \@xverbatim. Un formateador de código fuente que normalice espacios provoca justamente este fallo. Cuando importa el número de espacios, el entorno con estrella verbatim* imprime cada uno como ␣.
Cómo elegir el delimitador de \verb y por qué no cruza una línea
Para insertar un fragmento literal corto en mitad de una línea se usa \verb. Se pone un carácter delimitador inmediatamente después de \verb, luego el texto que debe salir tal cual y después el mismo carácter otra vez: \verb|\textbf{x}|. El delimitador puede ser casi cualquier carácter que no aparezca dentro del texto; si el contenido lleva |, se cambia a \verb!...!, \verb+...+ o \verb/.../. Dos caracteres quedan descartados. Una letra no sirve, porque al escribir \verbx TeX lee un nombre de comando distinto. Y * no está disponible, porque \verb* está reservado para la forma con estrella que imprime los espacios como ␣.
The macro \verb|\textbf{...}| sets bold text;
a pipe in the content needs another delimiter, as in \verb!a|b!.
Count the gaps: \verb*|a b| prints the spaces as visible marks.Hay otro límite duro en \verb: el delimitador de cierre tiene que estar en la misma línea. Si llega antes el final de línea, la compilación se detiene con ! LaTeX Error: \verb ended by end of line. La causa real suele ser un delimitador de cierre olvidado, pero un caso sorprendentemente frecuente es un editor que ha reajustado o reformateado una línea larga y ha partido el argumento en dos. En cuanto el contenido se alarga, conviene sacarlo de \verb y llevarlo a un entorno de bloque. Y si lo único que hace falta es una cadena que suele contener ~, #, % o _ —una URL, típicamente—, encaja mejor \url{...} del paquete url o hyperref: es literal y además corta la línea en puntos razonables.
Teclear una barra inversa o un guion bajo en el texto corriente
Para uno o dos caracteres no hace falta verbatim. Una barra inversa se obtiene con \textbackslash y un guion bajo con \_. El accidente más habitual aquí es que \\ no es una barra inversa sino el comando de salto de línea: escribir \\ no imprime nada y corta la línea. $\backslash$ en modo matemático sí produce la forma, pero en la fuente matemática, así que en el texto corriente la respuesta correcta es \textbackslash. Un guion bajo suelto da ! Missing $ inserted. —para TeX _ anuncia un subíndice— y escaparlo como file\_name lo resuelve.
| Entrada | Imprime | Nota |
|---|---|---|
\textbackslash | \ | \\ es el salto de línea, no una barra inversa |
\_ | _ | Un _ suelto provoca ! Missing $ inserted. |
\% \& \# \$ | % & # $ | A cada uno le basta un \ delante |
\{ \} | { } | Imprime los caracteres de grupo como caracteres |
\textasciitilde | ~ | Un ~ suelto es un espacio irrompible, no una virgulilla |
\textasciicircum | ^ | Un ^ suelto anuncia un superíndice |
Por qué \verb falla dentro de \section, \footnote y \caption
Ni \verb ni el entorno verbatim pueden aparecer dentro del argumento de otro comando. La razón no es una prohibición sino simple cronología. \verb cambia los códigos de categoría justo antes de leer su propio texto. Pero el contenido de \section{...} ya se convirtió en una lista de tokens con los códigos de categoría normales en el momento en que se llamó a \section. Cuando le llega el turno a \verb, \foo ha dejado de ser cuatro caracteres que imprimir y se ha convertido en el comando \foo. Verbatim no puede releer lo que ya se leyó: ahí está todo.
Lo desagradable es que este fallo aflora como errores que nunca dicen la palabra verbatim. \section{The \verb|\foo| command} se detiene con ! Undefined control sequence., porque \foo sí se leyó como comando y ese comando no existe. Si el contenido no lleva ningún carácter especial, como en \mbox{\verb|abc|}, aparece el mensaje inusualmente útil ! LaTeX Error: \verb illegal in argument. Los entornos de bloque se leen aún peor: \footnote{\begin{verbatim} ... \end{verbatim}} da Runaway argument? seguido de ! Paragraph ended before \@xverbatim was complete.; dentro de \parbox{5cm}{...} pasa a ser ! Argument of \@xverbatim has an extra }.; y dentro de \caption{...}, ! Argument of \@caption has an extra }. Todos son la misma causa con otra cara.
Una celda de tabla, en cambio, no es un argumento. Las celdas de tabular se leen mientras TeX vigila los separadores de columna y de fila, así que \verb funciona ahí sin cambios, incluso en una columna p{4cm}. Dentro de esa misma tabla, en cambio, el tercer argumento de \multicolumn{2}{c}{...} sí es un argumento, y ahí falla. La regla que hay que recordar no es «en tablas no», sino «dentro de un argumento delimitado por llaves no».
Hay tres salidas. La primera es el paquete cprotect (Bruno Le Floch, v1.0e), cuya única razón de ser es el verbatim dentro de argumentos de macro: basta con anteponer \cprotect al comando problemático y \cprotect\section{The \verb|\foo| command} compila. Incluye \cprotEnv para proteger el \begin de un entorno. La segunda es \SaveVerb / \UseVerb de fancyvrb: guardar primero el texto verbatim con un nombre y llamar solo ese nombre dentro del argumento. La tercera es específica para notas al pie: declarando \VerbatimFootnotes de fancyvrb en el preámbulo, el verbatim funciona dentro de \footnote. Conviene saber que cambiar \verb por el \Verb de fancyvrb no ayuda: arrastra exactamente el mismo problema de cronología. Y como último recurso, escribir a mano \texttt{\textbackslash foo} es el camino más corto cuando se trata de un solo título.
% Fails: \foo was already a command token before \verb could act
% \section{The \verb|\foo| command} -> Undefined control sequence
% Workaround 1 -- cprotect
\usepackage{cprotect}
\cprotect\section{The \verb|\foo| command}
% Workaround 2 -- save it first, use it later
\usepackage{fancyvrb}
\SaveVerb{cmd}|\foo|
\section{The \UseVerb{cmd} command}
% Workaround 3 -- verbatim inside footnotes
\VerbatimFootnotesLeer un archivo entero: \verbatiminput y \VerbatimInput
Con \usepackage{verbatim} en el preámbulo y \verbatiminput{hello.py} en el cuerpo, cada línea de ese archivo externo se compone verbatim. A diferencia de copiar el código al manuscrito, al editar el archivo fuente el PDF se actualiza solo, de modo que código y documento no se separan. Si lo que se muestra es código que de verdad se ejecuta, esta es la vía más segura.
Vale la pena preguntarse por qué existe un paquete llamado verbatim junto al entorno estándar verbatim, y la respuesta no es \verbatiminput. La documentación de ese paquete, obra de Rainer Schöpf y parte del bundle Tools de LaTeX, expone el motivo sin rodeos: el entorno incorporado no puede sacar ni una línea hasta haber leído todo lo anterior a \end{verbatim} como un único argumento de macro, de modo que un listado largo puede desbordar la memoria de TeX. El paquete sustituye la implementación por una que lee y compone verbatim línea a línea —truco que su documentación atribuye a la macro \comment de AMS-TeX— y, una vez que el verbatim se puede leer línea a línea, \verbatiminput sale prácticamente de regalo. Queda un efecto secundario visible: el texto escrito en la misma línea después de \end{verbatim} lo imprime el entorno incorporado, pero la versión del paquete lo descarta en silencio. La diferencia es deliberada y está documentada.
\usepackage{verbatim}
% ...
\verbatiminput{hello.py}
\begin{comment}
This paragraph is skipped entirely -- not printed, not typeset.
\end{comment}El mismo paquete añade un entorno comment que omite todo lo que hay entre \begin{comment} y \end{comment}: no es salida literal, sino ninguna salida, cómodo para aparcar un borrador. Para un control más fino de la inclusión de archivos está \VerbatimInput[options]{filename} de fancyvrb, tema de la sección siguiente. A diferencia de \verbatiminput, admite marcos y números de línea y, con firstline=10, lastline=25, trae solo una parte del archivo, justo lo que hace falta cuando una fuente larga tiene un único pasaje relevante.
alltt: un verbatim que aún ejecuta algunos comandos
Cuando se quiere poner en negrita o en color solo una parte de un ejemplo de código, el verbatim ordinario no ofrece agarre: todos los comandos están apagados. El entorno alltt, del paquete alltt incluido en la distribución estándar de LaTeX, es la salida. alltt compone el texto monoespaciado y tal como se escribió, casi como verbatim, salvo que tres caracteres conservan su significado habitual: la barra inversa \ y las llaves { y }. El aspecto sigue siendo verbatim, pero dentro se ejecutan comandos de LaTeX.
\usepackage{alltt}
% ...
\begin{alltt}
def \textbf{greet}(name):
return "Hi, " + name \textit{# a comment}
\end{alltt}En este ejemplo el nombre de función greet sale en negrita y el comentario en cursiva, mientras el resto permanece exactamente como se escribió. El precio es claro: para imprimir los tres caracteres \, {, } como caracteres hay que escribirlos ahora \textbackslash, \{, \}, mientras que verbatim los imprime directamente. Así que alltt es un trato: cede tres caracteres de literalidad y compra el derecho a dar formato al resto. Para un énfasis ligero puesto a mano, alltt; para un texto en el que no puede moverse ni un carácter, verbatim.
Números de línea y marcos: el entorno Verbatim de fancyvrb
Ni números de línea ni marcos ofrece el verbatim incorporado. De eso se encarga el paquete fancyvrb, cuyo centro es el entorno Verbatim con V mayúscula, distinto del verbatim en minúsculas. Las opciones se pasan por entorno, como \begin{Verbatim}[numbers=left, frame=single], o se fijan para todo el documento con \fvset{numbers=left, ...} en el preámbulo. fancyvrb lo empezó en 1992 Timothy Van Zandt, autor también de PSTricks, y lo mantiene Herbert Voß desde 2000 (la copia de TeX Live 2024 es la v4.5c). Tres décadas de opciones prácticas acumuladas explican que tenga respuesta para casi todo.
| Opción | Valores típicos | Qué hace |
|---|---|---|
numbers | none / left / right | Dónde van los números, por defecto none; numbersep fija la separación |
frame | none / single / lines / leftline / topline / bottomline | Tipo de marco, por defecto none; framerule el grosor, framesep el margen |
fontsize | \small, \footnotesize, etc. | Tamaño de letra; por defecto el del cuerpo |
showspaces | true / false | Muestra los espacios; showtabs para tabulaciones, tabsize para el ancho |
firstline / lastline | enteros | Con \VerbatimInput, incluye solo una parte del archivo |
commandchars | p. ej. \\\{\} | Nombra el escape y los dos caracteres de grupo, reactivando los comandos dentro |
\usepackage{fancyvrb}
\fvset{fontsize=\small} % document-wide default
% ...
\begin{Verbatim}[numbers=left, frame=single]
def greet(name):
return "Hello, " + name
\end{Verbatim}
% only lines 10-25 of an external file, framed
\VerbatimInput[firstline=10, lastline=25, frame=lines]{server.py}Con commandchars=\\\{\}, los caracteres \, { y } vuelven a actuar dentro del texto verbatim como escape y delimitadores de grupo, de modo que se pueden incrustar comandos igual que en alltt. En lugar de repetir el mismo juego de opciones cada vez, lo idiomático es definir un entorno propio: \DefineVerbatimEnvironment{Code}{Verbatim}{numbers=left, frame=single}, y a partir de ahí basta con \begin{Code}. Con todo, cuanto hay en esta página sirve para imprimir texto tal cual; nada de ello colorea palabras clave, es decir, nada hace resaltado sintáctico. Para código fuente con color y formato están listings, que colorea solo con macros de TeX, y minted, que delega el trabajo en Pygments de Python; la página relacionada «Listados de código» compara ambos.