# Verbatim environment with correct tab handling and special characters

I'm looking for an environment similar to Verbatim which will allow me to say something like the following code (which uses indentation instead of spaces):

\documentclass{article}

\usepackage{fancyvrb}
\usepackage[margin=1in]{geometry}

\begin{document}
\begin{enumerate}
\item We first set \texttt{x} to infinity if it is positive:
\begin{Verbatim}
if x > 0:
x = \infty
\end{Verbatim}
\end{enumerate}
\end{document}


and get back exactly the following, in terms of the indentation, the escaping of all symbols (like \infty), etc.

The problem with Verbatim is that it requires me to un-indent the body with respect to the rest of the code, which makes my source code ugly. (I also can't use verbatim because it forces me to use spaces.) Furthermore, I can't figure out how to embed special symbols in it, either.

Is there some environment that fixes these problems with a not-too-difficult syntax for inserting special symbols and math into the code? (Ideally, I would want \ and $ to be the escape characters, but anything that isn't too difficult to type will do.) - The indentation is done with tabs, I guess. But you can also indent with spaces (in the fancyvrb documentation you can BTW find this remark: “using tabs is in fact a rather old-fashioned style of coding”). In fancyvrb there’s an option gobble, with that you can suppress a certain amount of spaces or even tabs (max. 9 chars). Note also the options obeytabsand tabsize. I am surprised, too, that you didn’t get an error message while compiling your MWE. Normally you should have to define commandchars first. – Speravir Mar 21 '12 at 3:27 Actually the shown image can not be produced with the code of the MWE! – Speravir Mar 21 '12 at 17:59 I added an answer, where I show you something of that, what I’ve wriiten in my first comment. – Speravir Mar 21 '12 at 23:03 @Mehrad: please see my updated answer with a new solution solving the tabs issue. – Gonzalo Medina Mar 21 '12 at 23:35 ## 5 Answers # UPDATE Martin Scharrer's lstautogobble package takes care of the tabs issue using the listings package; for the other issues, you can and the mathescape=true, and escapeinside options; a little example: \documentclass{article} \usepackage{listings} \usepackage{lstautogobble} \lstset{basicstyle=\ttfamily, mathescape=true, escapeinside=||, autogobble} \begin{document} \begin{enumerate} \item We first set \texttt{x} to infinity if it is positive: \begin{lstlisting} if$x > 0$:$x = \infty$if x > 0: x =$\infty$\end{lstlisting} \end{enumerate} \end{document}  The file lstautogobble.sty can be found in this answer to How to automatically skip leading white spaces in listings - Is there any way to make it look like TTY text, the way verbatim and Verbatim do? – Mehrdad Mar 21 '12 at 3:12 @Mehrdad: sure; see my updated answer. – Gonzalo Medina Mar 21 '12 at 11:26 Gonzalo, that's bad: I already had upvoted your answer and then your edit is so much better, but I can’t upvote twice :-) … – Speravir Mar 22 '12 at 0:18 @Speravir: no problem and thank you. Most of the credit, if not all, goes to Martin and his package ;-) – Gonzalo Medina Mar 22 '12 at 0:23 This is freaking amazing. Thanks so much to both you and Martin!! :) – Mehrdad Mar 22 '12 at 0:45 This counts the spaces used to indent the first line and removes that many spaces from all lines. \documentclass{article} \usepackage{fancyvrb} \usepackage[margin=1in]{geometry} \makeatletter \def\zzz{\FV@Space} \def\hmm#1{% \let\zz=#1% \ifx\zz\zzz \toks@\expandafter{\the\toks@#1}% \expandafter\hmm \else \expandafter\hmmb \fi} \def\hmmb#1\relax{% \expandafter\gdef\expandafter\hmmc\the\toks@{}} \def\FancyVerbFormatLine#1{% \gdef\FancyVerbFormatLine##1{\hmmc##1}% \toks@{}% \hmm#1\relax\relax \hmmc#1} \begin{document} \begin{enumerate} \item We first set \texttt{x} to infinity if it is positive: \begin{Verbatim}[commandchars=\\\{\}] if x > 0: x = $$\infty$$ \end{Verbatim} \end{enumerate} \end{document}  - Let me show the opportunities in an answer (it’s obviously too long for a another comment): As I pointed out in my comment, you can indent also with spaces, which is in my opinion the better variant, because it’s much better predictable. But, see my example code: \documentclass{article} \usepackage{fancyvrb} % Let us first define a custom Verbatim environment, that saves us a lot of writing \DefineVerbatimEnvironment{VerbatimTest}{Verbatim}% {showspaces,showtabs,commandchars=\\\{\}}% showspaces and showtabs only for visualizing \begin{document} Remember, options showspaces'' and showtabs'' are active. \begin{enumerate} \item First, no change, indenting with spaces (using the \$ sign would
require an additional definition, see fancyvrb manual, section
"Catcode characters").

\begin{VerbatimTest}
if x > 0:
x = $$\infty$$
\end{VerbatimTest}

\item Second, gobbling 8 space chars (up to nine are possible).

\begin{VerbatimTest}[gobble=8]
if x > 0:
x = $$\infty$$
\end{VerbatimTest}

\item From now on indenting with tabs, first line for comparising indented
with spaces, note that by default one tab stands for 8 (!) characters.

\begin{VerbatimTest}
First line indented with spaces
if x > 0:
x = $$\infty$$
\end{VerbatimTest}

\item Now gobbling one character (here one space or one tab).

\begin{VerbatimTest}[gobble=1]
First line indented with spaces
if x > 0:
x = $$\infty$$
\end{VerbatimTest}

\item You can define with tabsize'', how many spaces are represented by
one tab (here 1 tab = 4 spaces).

\begin{VerbatimTest}[tabsize=4]
First line indented with spaces
if x > 0:
x = $$\infty$$
\end{VerbatimTest}

\item Last in combination: tabsize=4'' and gobble=1''.

\begin{VerbatimTest}[tabsize=4,gobble=1]
First line indented with spaces
if x > 0:
x = $$\infty$$
\end{VerbatimTest}
\end{enumerate}

\end{document}


The output looks as follows:

-
Yeah I was looking for something automatic (I don't want to change the gobble values every time I indent/unindent), but +1 anyway I guess. –  Mehrdad Mar 21 '12 at 23:25
@Mehrdad: You can of course give the option gobble with a global value in the preamble definition, too. If somewhere in the document you need a different gobble, you can add it there, and this overwrites the global definition then. –  Speravir Mar 21 '12 at 23:40

In order to allow indenting the code as pleases to you, TeX generally ignore spaces at the beginning of a line.

This poses a "chicken and egg" problem: when \begin{Verbatim} is sensed, the spaces that precede it have already been thrown out and TeX can't know how many it should discard at the beginning of verbatim lines unless you tell it (there's a gobble option to the Verbatim environment provided by fancyvrb). Only inside the Verbatim environment spaces at the beginning of a line are not ignored, because they are significant.

I'm not saying that the general problem is not solvable, but a solution requires a different reading of the input (for example maintaining a count of how many spaces are thrown out at the beginning of the line), which is simply not possible in TeX, but might be realized in LuaTeX.

I don't think that indenting code as you do is "nice": to the contrary, I never do that in normal text, but only in macro definitions. It's a matter of opinion, of course. Unfortunately, you have to live with "ugly" code when you need verbatim material, or pass explicitly the indentation level with the gobble option.

-
Whoa, so you never indent your code like that? How do you match opening/closing tags then? (Isn't it painful?) –  Mehrdad Mar 21 '12 at 11:00
@Mehrdad Is balancing environments painful? No. :) –  egreg Mar 21 '12 at 12:18

Use alltt.sty file and then use \begin{alltt} for math use $$ Example: \documentclass{article} \usepackage{fancyvrb} \usepackage[margin=1in]{geometry} \usepackage{alltt} \begin{document} \begin{enumerate} \item We first set \texttt{x} to infinity if it is positive: \begin{alltt} if \(x > 0$$:
$$x = \infty$$
\end{alltt}
\end{enumerate}

\end{document}


and also use:

\begin{enumerate}
\item We first set \texttt{x} to infinity if it is positive:
\begin{Verbatim}[commandchars=\\\{\}, codes={\catcode$=3\catcode^=7}] if$x>0$:$x=\infty\$
\end{Verbatim}
\end{enumerate}

-
Thanks but that doesn't fix the space issue. –  Mehrdad Mar 21 '12 at 5:19