23

Why is it not possible to define a new environment that extends a verbatim environment? Consider, e.g.:

\documentclass{article}
\newenvironment{myverbatim}{\tiny\begin{verbatim}}{\end{verbatim}}
\begin{document}
\begin{myverbatim}
  test
\end{myverbatim}
\end{document}

Compiling with pdflatex gives the error:

Runaway argument?
^^M  test^^M\end{myverbatim}^^M\end{document}^^M^^M
! File ended while scanning use of \@xverbatim.
<inserted text> 
                \par

(A motivation for this question can be found here: "Format a verbatim paragraph". From which it should be clear that I cannot use the listings or fancyvrb packages)

It would be nice with a basic and perhaps more detailed explanation (for this particular case and the reason for the error message) than what is given in, for instance, this discussion: "Why doesn’t verbatim work within...", and if there could be workarounds for simple cases like the one in this example..

Edit1:

Based on the answers so far, I feel that I need to be more precise about my case: I am trying to get the following code to work somehow (Confer with "Format a verbatim paragraph" for more details)

\documentclass{article}
\makeatletter
\begingroup
  \catcode`|=0
  \catcode`[=1
  \catcode`]=2
  \catcode`\{=12
  \catcode`\}=12
  \catcode`\\=12
  |gdef|myvr@xverbatim#1\end{myverbA}[#1|end[myverbA]]
|endgroup
\newenvironment{myverbA}{%
  \let\@xverbatim=\myvr@xverbatim
  \verbatim
}{%
}
\makeatother
\newenvironment{myverbB}{\tiny\begin{myverbA}}{\end{myverbA}}
\begin{document}
\begin{myverbB}
  test
\end{myverbB}
\end{document}

Edit2:

Based on egreg's answer, I tried the following:

\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\begingroup
  \catcode`|=0
  \catcode`[=1
  \catcode`]=2
  \catcode`\{=12
  \catcode`\}=12
  \catcode`\\=12
  |gdef|myvr@xverbatim#1\end{myverbA}[#1|end[myverbA]]
|endgroup
\newenvironment{myverbA}{%
  \let\@xverbatim=\myvr@xverbatim
  \verbatim
}{%
}
\newenvironment{myverbB}
  {\preto\verbatim@font{\tiny}
   \myverbA}
  {\endmyverbA}
\makeatother
\begin{document}
\begin{myverbB}
  test
\end{myverbB}
\end{document}

which produces the error:

Runaway argument?
^^M  test^^M\end{myverbB}^^M\end{document}^^M^^M
! File ended while scanning use of \@xverbatim.
<inserted text> 
                \par 
3

4 Answers 4

16

The main problem with using your definition of myverbatim can be defined in terms of a combination of scope and macro replacement. That is, something that starts with

\begin{<some-env>}

is expected to end with

\end{<some-env>}

If it doesn't, there's a problem, since the scope is not clearly defined. In your case, you start it with

\begin{myverbatim}

which is internally replaced with (removing the font change to \tiny for now)

\begin{verbatim}

Now, since you're in the verbatim environment (that is, a successful call was made to \begin{verbatim}), LaTeX starts gobbling up contents and printing them as-is until it arrives at a single line of code that resembles

\end{verbatim}

That's just how the verbatim environment works. It it looking for the stopping point. However, this never happens since the replacement of \end{myverbatim} (in your code) to \end{verbatim} (as per your definition) never occurs within the verbatim environment; verbatim doesn't perform the replacement of macros with their definitions. As such, TeX just keeps on scanning, producing what is considered a "Runaway argument" error.

Taking the above into account, a broad view on the replacement leaves your MWE to resemble (I've added a comment):

\documentclass{article}
\newenvironment{myverbatim}{\tiny\begin{verbatim}}{\end{verbatim}}
\begin{document}
\tiny\begin{verbatim}% Replacement text for \begin{myverbatim}
  test
\end{myverbatim}% No replacement since you're in the verbatim environment
\end{document}

Clearly the above doesn't start and end with the same environment.

If you want to have more flexibility with verbatim, use the verbatim package which allows you to do the following:

enter image description here

\documentclass{article}
\usepackage{verbatim}% http://ctan.org/pkg/verbatim
\newenvironment{myverbatim}%
  {\endgraf\tiny\verbatim}%
  {\endverbatim}
\begin{document}
Some text before.
\begin{myverbatim}
test
test
\end{myverbatim}
Some text after.
\end{document}

The verbatim package is a means to obtain your desired solution, just like fancyvrb and listings would be. Of course, a more rudimentary implementation (specific to your case) would be to merely change the font used by verbatim - stored in the macro \verbatim@font:

\makeatletter
\renewcommand{\verbatim@font}{\tiny\ttfamily}
\makeatother

Sure you can just precede the verbatim environment with \tiny and it will work just as well, but \verbatim@font is called within the verbatim environment, and therefore is constrained to only function there, not outside of it.

2
  • Thanks for the nice reply! How can I use your suggestion for my case? See "Edit" section at the end of my question. If I write \newenvironment{myverB}{\endgraf\tiny\myverbA}% {\endmyverbA} I get the error \begin{myverbB} ended by \end{document} May 16, 2013 at 17:51
  • @HåkonHægland: I guess egreg's answer addresses your this concern...
    – Werner
    May 16, 2013 at 18:55
13

It doesn't work because after

\documentclass{article}
\newenvironment{myverbatim}{\tiny\begin{verbatim}}{\end{verbatim}}
\begin{document}
\begin{myverbatim}
  test

\ is no longer an escape character it acts verbatim just typestting a \. so this:

\end{myverbatim}

is not a command to end the environment, it is just more text, and so is this:

\end{document}

and TeX hits the end of file and things have gone wrong.

A normal verbatim ends because it looks especially for the string \end{verbatim} and stops. That string is not in your document.

The verbatim and fancyvrb packages give facilities for defining verbatim-like environments.

2
  • You say the string \end{verbatim} is not in my document. But I used it in the definition of myverbatim.. May 17, 2013 at 4:08
  • Sorry, I see that my question has been answered by Werner May 17, 2013 at 4:12
7

The problem is the timing where the \tiny command is issued. It can't go before \verbatim without a preceding \par, but it can't go after it either.

So you have to change the definition of \verbatim@font:

\documentclass{article}
\usepackage{verbatim,etoolbox}
\makeatletter
\newenvironment{myverbA}
  {\verbatim}
  {\endverbatim}
\newenvironment{myverbB}
  {\preto\verbatim@font{\tiny}
   \myverbA}
  {\endmyverbA}
\makeatother

\usepackage{lipsum}

\begin{document}
\lipsum*[3]% no \par is issued
\begin{myverbB}
  test
\end{myverbB}
\lipsum*[3]
\begin{myverbA}
another test
\end{myverbA}
\end{document}

enter image description here

You may also want to look at the fancyvrb package:

\documentclass{article}
\usepackage{fancyvrb}
\newenvironment{myverbA}
  {\Verbatim}
  {\endVerbatim}
\newenvironment{myverbB}
  {\myverbA[fontsize=\tiny]}
  {\endmyverbA}

\usepackage{lipsum}

\begin{document}
\lipsum*[3]% no \par is issued
\begin{myverbB}
  test
\end{myverbB}
\lipsum*[3]
\begin{myverbA}
another test
\end{myverbA}
\end{document}
3
  • Thank you for the clear answer! I tried to implement your solution, see end of my question.. May 16, 2013 at 19:12
  • @HåkonHægland Where, in my solution, do you find catcode settings? Why should you want to follow that complicated route?
    – egreg
    May 16, 2013 at 20:31
  • @HåkonHægland Now I see more clearly the matter. No, you can't define a verbatim environment in terms of another one if you follow your route, so all you can do is defining myverbB in the same way you define myverbA and adding the redefinition of \verbatim@font.
    – egreg
    May 16, 2013 at 21:50
3

An answer can be found here Command for special text with reserved LaTeX symbols or, if you don't mind the result in boxes (I mean LaTeX box, not a bordered box), you can use the verbatimbox package with an optional argument:

\documentclass{article}
\usepackage{verbatimbox}
\begin{document}
\begin{verbbox}[\tiny]
This is tiny \verbatim
\end{verbbox}
\theverbbox
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .