Verbatim

Printing a single backslash in LaTeX is harder than printing an integral sign, and that is not a joke. Verbatim\verb for a fragment, the verbatim environment for a block — is the one corner of the system that only works by switching LaTeX’s own grammar off for a moment. Every rule about it that looks arbitrary follows from that: why \verb cannot cross a line break, why writing \end {verbatim} with a space in it stalls the compiler, and why putting \verb inside \section{...} or \footnote{...} fails with an error that never mentions verbatim at all. This page covers the verbatim environment and \verb, the starred forms that make spaces visible, whole-file input with \verbatiminput and \VerbatimInput, the alltt variant that keeps a few commands alive, framed and numbered blocks with fancyvrb, and how to type a lone backslash or underscore in ordinary running text.

What the verbatim environment actually switches off

Everything between \begin{verbatim} and \end{verbatim} is printed exactly as typed — line breaks and spaces included — in the typewriter font, with no package required. The mechanism is not escaping but demotion. On entering the environment, LaTeX rewrites the category code of \, {, }, $, &, #, ^, _, % and ~ all at once to “ordinary character”. A category code is the role label TeX attaches to each character as it reads the input; it decides whether that character starts a command, opens a group, or is merely ink. A backslash inside verbatim does not start a command not because commands are being ignored, but because for that moment the backslash is just a mark that happens to be shaped like a backslash.

latex
\begin{verbatim}
for i in range(3):
    print("100% & $5 \n")   # none of this is interpreted
\end{verbatim}

Implementing this is awkward for the author too, and the awkwardness is preserved in LaTeX’s own source. Inside latex.ltx, the file that defines LaTeX itself, the macro that scans for the end of a verbatim block is defined with | acting as the escape character and [ and ] acting as the braces. Inside that definition the three characters \, { and } must all be ordinary printable characters, so the language cannot express itself in its usual notation. For the length of that definition, LaTeX’s source stops being written in LaTeX. The two lines are there to read in the latex.ltx shipped with TeX Live 2024.

Two practical rules fall out of the way that ending is detected. First, the string \end{verbatim} must not appear inside the environment: LaTeX treats the moment it sees it as the end. Second, no space may sit between \end and {verbatim}. The terminator is matched character by character as a macro argument delimiter, so \end {verbatim} is not recognised at all, and TeX reads on to the end of the file before stopping with Runaway argument? followed by ! File ended while scanning use of \@xverbatim. A source formatter that tidies spacing can introduce exactly this failure. When the number of spaces matters, the starred verbatim* environment prints each one as ␣.

Choosing a delimiter for \verb, and why it cannot cross a line

To drop a short literal into the middle of a line, use \verb. Put one delimiter character immediately after \verb, then the text you want printed as-is, then the same character again — \verb|\textbf{x}|. The delimiter can be almost anything that does not occur inside the text; if | appears in the content, switch to \verb!...!, \verb+...+ or \verb/.../. Two characters are off the table. A letter will not work, because writing \verbx makes TeX read a different command name altogether. And * is unavailable, because \verb* is reserved for the starred form that prints spaces as ␣.

latex
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.

There is one more hard limit on \verb: the closing delimiter has to be on the same line. If the end of the line arrives first, compilation stops with ! LaTeX Error: \verb ended by end of line. The real cause is usually a forgotten closing delimiter, but a surprisingly common one is an editor that rewrapped or reformatted a long line and split the argument in two. For anything long, move it out of \verb and into a block environment. And if all you need is a string that tends to contain ~, #, % or _ — a URL, typically — then \url{...} from the url or hyperref package is the better fit: it is literal and it breaks the line at sensible points.

Typing a backslash or an underscore in ordinary text

For one or two characters you do not need verbatim at all. A backslash is \textbackslash and an underscore is \_. The most common accident here is that \\ is not a backslash but the line-break command: typing \\ prints nothing and breaks the line instead. $\backslash$ in math mode does produce the shape, but in the math font, so in running text \textbackslash is the right answer. A bare underscore gives ! Missing $ inserted. — to TeX _ means “subscript follows” — and escaping it as file\_name fixes it.

InputPrintsNote
\textbackslash\\\ is the line-break command, not a backslash
\__A bare _ raises ! Missing $ inserted.
\% \& \# \$% & # $Each just needs a leading \
\{ \}{ }Prints the group characters as characters
\textasciitilde~A bare ~ is an unbreakable space, not a tilde
\textasciicircum^A bare ^ means “superscript follows”

Why \verb fails inside \section, \footnote and \caption

Neither \verb nor the verbatim environment may appear inside another command’s argument. The reason is not a prohibition but plain chronology. \verb switches the category codes over just before it reads its own text. But the body of \section{...} was already converted into a list of tokens under the normal category codes at the moment \section was called. By the time \verb gets its turn, \foo has stopped being four characters to print and has become the command \foo. Verbatim cannot re-read what has already been read — that is the whole story.

The nasty part is that this failure surfaces as errors that never say the word verbatim. \section{The \verb|\foo| command} stops with ! Undefined control sequence. — because \foo really was read as a command, and no such command exists. If the content holds no special characters at all, as in \mbox{\verb|abc|}, you get the unusually helpful ! LaTeX Error: \verb illegal in argument. Block environments are harder still to read: \footnote{\begin{verbatim} ... \end{verbatim}} gives Runaway argument? followed by ! Paragraph ended before \@xverbatim was complete.; inside \parbox{5cm}{...} it becomes ! Argument of \@xverbatim has an extra }.; inside \caption{...} it becomes ! Argument of \@caption has an extra }. Every one of these is the same single cause wearing a different face.

A table cell, on the other hand, is not an argument. Cells in tabular are read while TeX watches for the column and row separators, so \verb works there unchanged — including in a p{4cm} column. Within that same table, however, the third argument of \multicolumn{2}{c}{...} really is an argument, and it fails. So the rule to remember is not “not in tables” but “not inside a brace-delimited argument”.

There are three ways around it. The first is the cprotect package (Bruno Le Floch, v1.0e), whose whole job is verbatim in macro arguments: prefix the offending command with \cprotect and \cprotect\section{The \verb|\foo| command} compiles. It ships \cprotEnv for protecting the \begin of an environment. The second is fancyvrb’s \SaveVerb / \UseVerb: save the verbatim text under a name first, then call only that name inside the argument. The third is footnote-specific — declaring fancyvrb’s \VerbatimFootnotes in the preamble makes verbatim work inside \footnote. Note that swapping \verb for fancyvrb’s \Verb does not help; it has exactly the same timing problem. And as a last resort, spelling the name out as \texttt{\textbackslash foo} is the shortest path when it is only one heading.

latex
% 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
\VerbatimFootnotes

Reading a whole file: \verbatiminput and \VerbatimInput

Put \usepackage{verbatim} in the preamble and \verbatiminput{hello.py} in the body, and every line of that external file is typeset verbatim. Unlike copying the code into the manuscript, editing the source file updates the PDF automatically, so the code and the document never drift apart. If what you are showing is code that actually runs, this is the safest way to show it.

It is worth asking why a package called verbatim exists alongside the standard verbatim environment at all — and the answer is not \verbatiminput. The documentation of that package by Rainer Schöpf, part of LaTeX’s Tools bundle, states the motive plainly: the built-in environment cannot output a single line until it has read everything up to \end{verbatim} as one macro argument, so a long listing may overflow TeX’s memory. The package replaces the implementation with one that reads and typesets verbatim a line at a time — a trick its documentation credits to the \comment macro of AMS-TeX — and once verbatim can be read line by line, \verbatiminput essentially falls out for free. There is one visible side effect: text typed on the same line after \end{verbatim} is printed by the built-in environment but silently discarded by the package version. The difference is deliberate and documented.

document.tex
\usepackage{verbatim}
% ...
\verbatiminput{hello.py}

\begin{comment}
This paragraph is skipped entirely -- not printed, not typeset.
\end{comment}

The same package adds a comment environment that skips everything between \begin{comment} and \end{comment} — not literal output but no output, handy for parking a draft passage. For finer control over file inclusion, use \VerbatimInput[options]{filename} from fancyvrb, covered next. Unlike \verbatiminput it accepts frames and line numbers, and with firstline=10, lastline=25 it pulls in only part of a file, which is exactly what you want when a long source has one relevant passage.

alltt: verbatim that still runs a few commands

When you want to bold or colour just part of a code example, ordinary verbatim leaves you stuck: every command is switched off. The alltt environment, from the alltt package shipped with standard LaTeX, is the way out. alltt sets text monospaced and as typed much like verbatim, except that three characters keep their usual meaning: the backslash \ and the braces { and }. The result looks verbatim but still runs LaTeX commands inside.

latex
\usepackage{alltt}
% ...
\begin{alltt}
def \textbf{greet}(name):
    return "Hi, " + name   \textit{# a comment}
\end{alltt}

Here the function name greet comes out bold and the comment italic, while everything else stays exactly as typed. The price is clear: to print the three characters \, {, } as characters, you must now spell them \textbackslash, \{, \} — whereas verbatim prints them directly. So alltt is a trade: it gives up literalness for three characters and buys the right to format with the rest. Use alltt for light hand-applied emphasis, and verbatim when not a single character may move.

Line numbers and frames: the Verbatim environment of fancyvrb

Neither line numbers nor frames are available in the built-in verbatim. That job belongs to the fancyvrb package, and its centre is the capital-V Verbatim environment — a different beast from lowercase verbatim. Options go per environment as \begin{Verbatim}[numbers=left, frame=single], or become document-wide defaults via \fvset{numbers=left, ...} in the preamble. fancyvrb was started in 1992 by Timothy Van Zandt, who also wrote PSTricks, and has been maintained by Herbert Voß since 2000 (the copy in TeX Live 2024 is v4.5c). Three decades of accumulated practical options are the reason it has an answer for almost everything.

OptionTypical valuesWhat it does
numbersnone / left / rightWhere line numbers go; default none. numbersep sets the gap
framenone / single / lines / leftline / topline / bottomlineKind of frame; default none. framerule for width, framesep for padding
fontsize\small, \footnotesize, …Font size; default is the body size
showspacestrue / falseShows spaces as visible marks; showtabs for tabs, tabsize for width
firstline / lastlineintegersWith \VerbatimInput, includes only part of a file
commandcharse.g. \\\{\}Names the escape and the two group characters, re-enabling commands inside
latex
\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}

With commandchars=\\\{\}, the characters \, {, } act as the escape and group delimiters inside the verbatim text, so commands can be embedded just as in alltt. Rather than repeating the same option set every time, the idiomatic move is to define your own environment: \DefineVerbatimEnvironment{Code}{Verbatim}{numbers=left, frame=single}, after which \begin{Code} is all you write. Everything on this page, though, is about printing text as-is; none of it colours keywords, which is to say none of it does syntax highlighting. For coloured, formatted source you want listings, which highlights with TeX macros alone, or minted, which hands the job to Python’s Pygments — the related “Code listings” page compares the two.