8

I'm trying to figure out how the verbatim environment works. In the basic LaTeX file latex.ltx I find the following definition (line 4037):

\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-}
\def\do@noligs#1{%
  \catcode`#1\active
  \begingroup
     \lccode`\~`#1\relax
     \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}}
\def\@noligs{\let\do\do@noligs \verbatim@nolig@list}

What is the purpose of the macro \do@noligs? Further, how does it work?

In the above code, I have problem understanding:

  • \lccode`\~`#1
  • why use the \lowercase control word?
  • why \endgroup after the opening brace {?
  • why \leavevmode?
  • why \kern\z@?
  • You have a lot of issues wrapped up together here: for example, the \lowercase trick is more general than just applying in this case and I think has been discussed before. – Joseph Wright May 22 '13 at 5:57
7

The 'big picture' aim here is to make sure that no ligatures are applied: for example, -- is converted to an en-dash in 'normal' circumstances as it's a ligature. The way this is done is to make the potential ligature characters 'safe' inside the verbatim environment by inserting a kern between them.

The detail you ask about is as follows. The macro \do@noligs receives one escaped character at a time, for example \-. This will have category code 'other', but to make it 'safe' the code needs to make it active. That's what the lower case business is for: much of this is a 'standard trick'. What happens is that \lowercase can be used to change the character code of a token but leave the category code unchanged. So we need some 'ready made' active character to 'transform': that's where ~ comes in. Taking the example \- The code does the following:

  • Make - an active character (\catcode`#1\active)
  • Sets up a group so the change to lower case behaviour is local
  • Makes - the lower case equivalent of ~ (\lccode`\~`#1\relax)
  • Inserts a \lowercase, which reads and therefore tokenizes its argument and substitutes the ~ by -, but does not execute it at this stage
  • Ends the group so that the case changing is returned to normal and so the definition for an active - does not need to be made globally.
  • Sets up the definition of -.

In the definition for -, the \kern\z@ is the key part as it will prevent for example -- being a ligature, as the two characters have an invisible 'barrier' between them. \leavevmode is a safety precaution, making sure that we will not be 'between paragraphs'. The latter happens if you just insert a kern directly in vertical mode (and we'd end up with a conceptually vertical kern).

The net result is that within the group created by the verbatim environment, the standard TeX ligatures do not act and the output is as expected.

  • Thanks for the great answer! What would happen if \endgroup came after e.g. \char`#1} ? – Håkon Hægland May 21 '13 at 19:46
  • What would happen if we omit "\catcode`#1\active" ? – Håkon Hægland May 21 '13 at 19:58
  • 1
    @HåkonHægland If you remove the \catcode`#1\active then the various characters are not 'active' inside the verbatim environment, and all of the work is for nothing. If you move the \endgroup then the \def is inside a group and is lost at \endgroup, and again nothing useful is achieved. – Joseph Wright May 21 '13 at 21:12
  • 1
    @HåkonHægland Escaping the characters means that TeX will look at the character itself rather than any definition, and also makes sure we are not caught out by tokens that would otherwise have a 'special' effect. It's pretty standard to escape each character when setting codes (\lccode, etc.) as it does no harm and is 'safer' than omitting it. – Joseph Wright May 22 '13 at 5:54
  • 1
    @HåkonHægland We need the \lowercase as he \def has to apply to something definable, here an active character. ~ is 'active' already, so we can rely on its catcode being suitable. The category code of a token is set when it's read, so if we omitted the \lowercase and tried to do \def#1{... with #1 equal to say - then we'd get an error as - was not active when read as #1. – Joseph Wright May 22 '13 at 5:56

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.