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!

2
  • 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, 2014 at 20:10
  • I'd recommend trying tcolorbox
    – egreg
    Apr 15, 2014 at 20:37

2 Answers 2

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}
2
  • Thanks. That is much simpler than whatever I had come up with. Your solution does add quite some extra blank space before and after the environment, though. (Trying to figure out why right now.) Apr 15, 2014 at 20:50
  • Found it. It was the skipabove and skipbelow settings of mdframed. Apr 15, 2014 at 20:52
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

0

You must log in to answer this question.

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