8

I am, once again, trying to achieve what seems like a trivial goal. I want to use \newenvironment to define a verbatim environment with a background color. I need to define my own environment because I need to run extra commands when opening the environment.

Here's what I have so far:

\newenvironment{response}{%
  % here, run extra commands, mostly related to \tikzmark and other extra legwork
  \verbatim
}{
  \endverbatim
}

This works fine. I tried the following to add a background color.

  • Define a background color for FancyVrb (Background color for fancyvrb), but then if I put \begin{Verbatim} and \end{Verbatim} in lieu of \verbatim and \endverbatim, this no longer works,
  • Playing myself with \color@setgroup and \color@endroup but these do not seem to be exposed by the xcolor package.
  • Using an lrbox, but again, any pair of \begin{foo} and \end{foo} that go across the environment are rejected (possibly because of \verbatim?)

I'm quite puzzled now and would love to have any pointers. Thanks!

UPDATE: the first comment has the solution, namely my failing to use \VerbatimEnvironment!

  • 1
    For fancyvrb, you need to use \VerbatimEnvironment before the \begin{Verbatim}. That tells fancyvrb to detect the name of the current environment, and look for the end of that environment, rather than looking for a literal \end{Verbatim}. – G. Poore Apr 15 '14 at 20:10
  • I'd recommend trying tcolorbox – egreg Apr 15 '14 at 20:37

2 Answers2

6

For fancyvrb, you need to use \VerbatimEnvironment before the \begin{Verbatim}. That tells fancyvrb to detect the name of the current environment, and look for the end of that environment, rather than looking for a literal \end{Verbatim}.

You will probably want to use a proper framing package to provide the background color...that way you won't have to worry about coming up with your own solutions for pagebreaks and will have access to a lot more features. You may want to take a look at mdframed or tcolorbox. An example with mdframed is below. tcolorbox has built-in solutions for a lot of use cases; one of those might give you most or all of what you need.

\documentclass{article}

\usepackage{fancyvrb}
\usepackage{mdframed}
\usepackage{xcolor}

\newenvironment{response}%
  {\VerbatimEnvironment
    \begin{mdframed}[backgroundcolor=green]
    \begin{Verbatim}}
  {\end{Verbatim}%
    \end{mdframed}}

\begin{document}

\begin{response}
<Text>
\end{response}

\end{document}
G. Poore
  • 12,417
2

First, here is a solution that uses only the xcolor package and the standard verbatim environment. But it is not a new environment, per se, and so does not directly answer the OP's question (for that, see below).

\documentclass{article}
\usepackage{xcolor}
\fboxrule=1pt
\begin{document}
\setbox0=\hbox{\begin{minipage}{3in}
\color{red!90}
\begin{verbatim}
\verbatim <Text>
Here
%$#@&^* \macros
\end{verbatim}
\end{minipage}}
\fcolorbox{cyan}{blue!10}{\box0}
\end{document}

enter image description here


To create an environment as desired by the OP, I adapted color into the syntax employed by the verbatimbox package, and created the cverbbox environment, which stores your verbatim content in a user-named box that is exactly as wide as the content (plus boxsep and boxrule). It comes with an optional argument and 4 mandatory arguments:

\begin{cverbbox}[options]{boxname}{text color}{box color}{frame color}
...
\end{cverbbox}

where the options are the same as already work in verbatimbox environments (in this MWE, I used the option to make the verbatim \tiny and added a bullet before each row). It uses \fboxsep and \fboxrule in the standard manner to set frame offset and rule thickness.

\documentclass{article}
\usepackage{xcolor}
\usepackage{verbatimbox}
\makeatletter
\newenvironment{cverbbox}[5][]{%
  \setcounter{VerbboxLineNo}{0}%
  \def\verbatim@processline{%
% THE FIRST #1 ACCOUNTS FOR NON-PRINTING COMMANDS; THE SECOND #1 IS FOR
% PRINTED OPTIONAL MATERIAL
    {\addtocounter{VerbboxLineNo}{1}%
    #1\setbox0=\hbox{#1\the\verbatim@line}%
    \hsize=\wd0 \the\verbatim@line\par}}%
  \@minipagetrue%
  \@tempswatrue%
  \global\edef\sv@name{\@macro@name{#2}}%
  \global\edef\cverbboxColor{#4}%
  \global\edef\cverbboxFColor{#5}%
  \@ifundefined{\sv@name content}{%
    \expandafter\newsavebox\expandafter{\csname\sv@name content\endcsname}%
  }%
  \expandafter\global\expandafter\edef\csname\sv@name\endcsname{\usebox{%
  \csname\sv@name content\endcsname}}%
  \setbox0=\vbox\bgroup\color{#3} \verbatim
}
{%
  \endverbatim%
  \unskip\setbox0=\lastbox %
  \egroup%
  \setbox1=\hbox{%
    \colorbox{\cverbboxColor}{\box0}}%
  \global\sbox{\csname\sv@name content\endcsname}%
    {\fboxsep=\fboxrule\colorbox{\cverbboxFColor}{\box1}}%
}
\makeatother
\fboxrule=1pt\fboxsep=3pt\relax
\begin{document}
\begin{cverbbox}[\tiny\textcolor{black}{$\bullet$}]{\mycvbox}{red!80}{blue!10}{cyan}
\verbatim <Text>
Here
%$#@&^* \macros
xa
\end{cverbbox}
x\fbox{a}\mycvbox\fbox{b}x
\end{document}

enter image description here