8

When I try to do the following:

\documentclass{article}
\begin{document}
 Hello \verb{foo}.                                                                                                     
\end{document}                                                                                                        

i.e. use braces as a delimiter for \verb I get the following error:

! LaTeX Error: \verb ended by end of line.

Is there a reason why you have to use | or + or some other delimiter? The documentation I found online suggests any delimiter (other than *) should work. But curly braces don't seem to work.

user28291
  • 155
  • 2
    TeXnically speaking, { and } are not delimiters. They have a different catcode. If they are converted to active chars then things are bound to break. – percusse Apr 01 '13 at 17:00
  • @percusse: You don't need to define { and } to be active to use them as delimiters. For example, in ConTeXt, you may use \type{...} for verbatim text. Of course, LaTeX like \type|..| or \type+...+ also works. Ditto for ConTeXt packages like filter and vim module that work with verbatim text. – Aditya Apr 01 '13 at 17:03
  • @Aditya I might be wrong but I think verb defines the next char to be active to collect the content in between. Baaah I meant the \dospecials – percusse Apr 01 '13 at 17:05
  • @percusse: I haven't looked to LaTeX's definition, but ConTeXt does not make a character active. Basically, it grabs the next char, checks if it is \bgroup; if so uses one definition, else uses 2nd definition. See, for example, this implementation in t-filter. – Aditya Apr 01 '13 at 17:10
  • As @Aditya says, you can set up to grab verbatim material in braces: xparse does this as the v-type argument. – Joseph Wright Apr 01 '13 at 17:28
  • @JosephWright thanks for the pointer to xparse and the v argument. Ultimately, I'd like to define my own command that can grab verbatim text between braces. – user28291 Apr 01 '13 at 18:16

2 Answers2

8

Here's the relevant code from latex.ltx

\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi
  \bgroup
    \verb@eol@error \let\do\@makeother \dospecials
    \verbatim@font\@noligs
    \@ifstar\@sverb\@verb}

The \verb command doesn't have any argument; it does some preliminary work and then hands control to \@verb or \@sverb (the latter if it was called as \verb*.

\def\@verb{\@vobeyspaces \frenchspacing \@sverb}

Here we see that \@verb simply makes the space active (already defined to expand to \space) and sets \frenchspacing for keeping all spaces equal; then it calls \@sverb

\def\@sverb#1{%
  \catcode`#1\active
  \lccode`\~`#1%
  \gdef\verb@balance@group{\verb@egroup
     \@latex@error{\noexpand\verb illegal in command argument}\@ehc}%
  \aftergroup\verb@balance@group
  \lowercase{\let~\verb@egroup}}

Now \@sverb reads the first token (the delimiter) and makes it active. Then it defines a check macro for getting out of troubles in case \verb is called as the argument to a command.

Finally it defines the active delimiter to be \verb@egroup; upon finding and expanding it, all the special settings for verbatim mode will be undone.

Thus \verb{xyz{ is legal (try it) but \verb{xyz} isn't. The code might be changed to take care of \verb{xyz}; however, one of the main points of \verb is allowing unbalanced braces in the verbatim text, so there's not so much to gain with that.

egreg
  • 1,121,712
  • Thanks! I guess I wanted \verb to behave like a standard latex command. Obviously { and } are different characters. I never thought that you might want to have unbalanced braces. – user28291 Apr 01 '13 at 18:14
4

You have to use matching "delimiters". And, in this instance, { does not match }. \verb grabs the first (non-* character) and makes it active, in order to match it with the same character at the of the verbatim content, thereby defining a scope over which the verbatim protocol acts.

The choice between using * or not is based on the fact that LaTeX sometimes provides a starred variant of a command. In terms of \verb, this is also the case as it executes \@ifstar (from latex.ltx):

\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi
  \bgroup
    \verb@eol@error \let\do\@makeother \dospecials
    \verbatim@font\@noligs
    \@ifstar\@sverb\@verb}

The listings package provides a similar verbatim-style macro using lstlistings (for the environment) and \lstinline (for the in-line usage). From the listings documentation (section 4.2 Typesetting listings, p 25) it notes that you have to provide the <character>...<same character> pattern:

\lstinline[<key=value list>]<character><source code><same character>

Only recently has an "experimental" \lstinline[..]{...} been provided. However, for similar reasons and making the coding behind it more complicated, using it in the traditional sense should be adequate.

Werner
  • 603,163