Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

(I'm aware there has been a similar question before, but this one has a twist)

I wanted a verbatim macro to use which would use an unlikely character as an end-of-verbatim -marker (unlikely as in it would be unlikely to be included in the text that would become verbatim), and looked up a couple of suggestions from Appendix D of The TeXbook, until something caught my eye:

Another approach is to keep one character untouchable. For example, it’s possible to define things so that \verbatim⟨char⟩⟨text⟩⟨char⟩ will typeset the ⟨text⟩ verbatim, where the ⟨text⟩ is not supposed to contain any occurrences of the repeated delimiter ⟨char⟩:

\def\verbatim{\begingroup\setupverbatim\doverbatim}
\def\doverbatim#1{\def\next##1#1{##1\endgroup}\next}

Now, combining this with XeTeX would allow me to use a character from the wide, wide Unicode range as the end-marker. (Based on the finding that I can do eg. \def\fi{foo}, and it works.)

Alas, adding to the above the previously mentioned macros from Appendix D:

\def\setupverbatim{\tt\def\par{\leavevmode\endgraf} \catcode`\`=\active
   \obeylines\uncatcodespecials\obeyspaces}
\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}

and trying it out (the fi -character is the Unicode fi-ligature),

\verbatim fi |\%_^foo{\it bar}
baz
fi
\bye

gives me an error about Missing $, which means there is something not working with the \verbatim macro. I just can't figure out what.

share|improve this question
add comment

3 Answers 3

up vote 3 down vote accepted

It's the space character after \verbatim.

After you change the catcode of the space character, it's not considered space anymore. Consider the output of

\def\a#1\relax{`#1'}
\def\b{\catcode`\ =12 \a}

\a \relax

\b \relax

\bye

enter image description here

Thus, your example only typesets in verbatim mode, and returns to normal after encountering the second space after .

It follows that you need to have a delimiter character immediately after \verbatim. Therefore its catcode can't be "letter", because otherwise it will be taken as a part of the control sequence name.

share|improve this answer
3  
One should note that the space after \verbatim terminates the scanning for the control sequence name, but it's not tokenized right away, because after a control sequence name TeX must enter "skipping blanks state"; therefore the space is effectively read after \verbatim has been expanded and \setupverbatim has changed the category code of the space. –  egreg Sep 16 '11 at 15:55
    
Oooh, the catcode change! I assume every char (outside the chars TeX knows) has a catcode of letter in the eyes of XeTeX, then. Thanks! –  morbusg Sep 16 '11 at 16:02
add comment

The following codes defines \verb command:

\catcode`\@=11%
\def\verb{\expandafter\verb@make\string}%
\def\verb@make#1{\begingroup\tt%
  \let\verb@delim=#1%  Save the delimiter.
  \def\verb@print##1{%
    \if##1\verb@delim% If we found the end delimiter, end the group.
      \def\verb@print{\def\verb@print{}\endgroup}%
    \else%
      ##1% Print the char
    \fi%
    \expandafter\verb@print\string% Continue reading the next char.
  }%
  \expandafter\verb@print\string% Start reading.
}%
\catcode`\@=12%

Some examples:

\verb|{$x^y{}$\abc}|

\verb!{$x^y{}$\abc}!

\verb~${x^y{}$\abc}~

All the above produces verbatim ${x^y{}$\abc}.

share|improve this answer
    
It doesn't respect spaces, though. –  egreg Jan 28 '12 at 22:06
add comment

The problem is in the space following \verbatim, as found out by Andrey. One should note that the space after \verbatim terminates the scanning for the control sequence name, but it's not tokenized right away, because after a control sequence name TeX must enter "skipping blanks state"; therefore the space is effectively read after \verbatim has been expanded and \setupverbatim has changed the category code of the space.

If you don't want to have a limitation on what characters can delimit the verbatim snippet, it's possible to improve \doverbatim:

\def\doverbatim#1{%
  \def\next{#1}%
  \ifx\next\activespacemacro
     \expandafter\doverbatim
  \else
    \def\next##1#1{##1\endgroup}%
    \expandafter\next
  \fi}
{\obeyspaces\gdef\activespacemacro{ }}

End-of-line can't be used as a delimiter (it would be possible to add another test for it). Any number of spaces can follow \verbatim.

It's curious to understand why your code gave that error, but also easy: the space after made \verbatim terminate its effect, typesetting as verbatim just the .

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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