13

I'm curious as to how verbatim is implemented internally in TeX. I am mostly familiar with the basics of TeX's inner mechanics (catcodes, and what not), but I'm just curious about this command.

  • If you're in a hurry before someone answers: see texdoc source2e for the implementation (with documentation) of the verbatim environment. It's just 3 pages and a bit. – ShreevatsaR Jan 30 '18 at 21:10
  • 1
    I think you might want to elaborate a bit whether you mean 'How verbatim-like environments may be implemented in general' or 'How a specific \verbatim command works'. The two answers posted at present take different lines on what you mean in this regard: the tex-core suggests you mean the very general case but it's not entirely clear to me. – Joseph Wright Jan 31 '18 at 9:54
13

For example

\beginverbatim
 verbatim text & $ #
 in more    lines... 
\endverbatim

can be implemented as

\def\beginverbatim{\par
   \begingroup
      ... set all special catcodes to other
      ... set space as active and define it as \space
      ... set ^^M as active and define it as \par
      \beginverbatimA
}
\def\beginverbatimA #1<tricky of \endverbatim separator>{%
    #1%
    \endgroup % restores normal catcodes
}

Of course, this is only pseudocode. We need to define \beginverbatimA with parameter #1 separated by \endverbatim where this separator uses \ as normal character with catcode "other". It needs some "tricky" code. For example, like this:

\let\ea=\expandafter
\ea\def\ea\beginverbatimA\ea#\ea1\string\endverbatim{%
    #1\endgroup
}

The main idea is presented here, not the whole implementation.

Edit: A LaTeX-notice: second answer here specializes to LaTeX but one thing is missed there: how the \@xverbatim works and how it is implemented. This is analogue to \endverbatimA mentioned in my answer, but the separator of #1 parameter must be \end{verbatim} where not only \ but above that the { and } must have catcode "other". This can be done, for example by:

\let\ea=\expandafter
\edef\tmp{\string\end\string{verbatim\string}}
\ea\def\ea\@xverbatim\ea#\ea1\tmp{#1\end{verbatim}}

but you can see in latex.ltx that another approach was used here.

20

Let's begin with an excerpt from latex.ltx (the LaTeX "kernel"):

\def\verbatim{\@verbatim \frenchspacing\@vobeyspaces \@xverbatim}
\def\endverbatim{\if@newlist \leavevmode\fi\endtrivlist}
\def\verbatim@font{\normalfont\ttfamily}

The instruction \@verbatim does most of the heavy lifting. It is defined as follows (also in latex.ltx, right before \def\verbatim...):

\def\@verbatim{\trivlist \item\relax
  \if@minipage\else\vskip\parskip\fi
  \leftskip\@totalleftmargin\rightskip\z@skip
  \parindent\z@\parfillskip\@flushglue\parskip\z@skip
  \@@par
  \language\l@nohyphenation
  \@tempswafalse
  \def\par{%
    \if@tempswa
      \leavevmode \null \@@par\penalty\interlinepenalty
    \else
      \@tempswatrue
      \ifhmode\@@par\penalty\interlinepenalty\fi
    \fi}%
  \let\do\@makeother \dospecials
  \obeylines \verbatim@font \@noligs
  \everypar \expandafter{\the\everypar \unpenalty}%
}

There's a lot going on, isn't there? The most important instructions are as follows. First, LaTeX enters a trivlist environment (which will be terminated by \endtrivlist, at the end of \endverbatim). Unless we're in a minipage environment, a vertical skip in the amount of \parskip is performed. After executing a paragraph break (via \@@par) and suppressing all hyphenation, \par is redefined locally. The single most important set of instructions is let\do\@makeother \dospecials. They set the catcodes of \ (space), \ (backslash), {, }, $, &, #, ^, _, %, and ~ to "other" (12). Essentially, all TeX-special characters are not special inside a verbatim environment. Next, TeX is instructed to obey line breaks, switch the font to monospaced (aka "teletype" or tt), and activate some characters in order to break ligatures such as << for «. The standard paragraph-builder penalty for line breaks is unset. Wow -- we've made it to the end of the \@verbatim code block.

Next, \frenchspacing (a plain-TeX command that's replicated in the LaTeX kernel) ensures that no extra space is inserted after punctuation marks. In comparison, the chores handled by \endverbatim are nearly trivial: The most important instruction is \endtrivlist, which closes the trivlist environment that was opened at the start of \@verbatim.

The trivlist environment is a very important tool in LaTeX. It occurs quite a few times in latex.ltx. For example, the center, flushleft, flushright environments are all set up as trivlists, and the list environment employs trivlist internally. The enumerate, itemize, and description environments employ list environments internally and thus, ultimately, trivlist environments as well.

  • 1
    The question was not LaTeX specific but this answer is LaTeX specific. IMHO, it is better (almost everytime) to do the implementation from scratch than to be inspired by LaTeX code. – wipet Jan 31 '18 at 7:16
  • @wipet - It’s true that I interpreted the question about how verbatim works to be related to the LaTeX environment called verbatim. If that’s not what the OP had in mind, I trust I’ll get a comment to that effect. – Mico Jan 31 '18 at 7:51
  • 4
    \@noligs is not about ff, fi and so on. Its job is to activate some characters in order to break ligatures such as ?` for ¿ or << for «. – egreg Jan 31 '18 at 9:55
  • @egreg - I stand corrected! I'll edit the passage in question to incorporate your information. – Mico Jan 31 '18 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.