3

This is a follow-up question to How can I use `\renewcommand` to wrap `\colorbox` around `\Verb`?

I have TeX files which contain code like:

\Verb|print("Hello World", end="")|

The \Verb content should have a background color. However, I cannot modify the body of the TeX files - only the preamble. The solution with the newverbs package from the question linked above works fine with this.

It doesn't work for \Verb[commandchars=\\\{\}], though, like:

\Verb[commandchars=\\\{\}]|print("Hello World", end="")|

MCVE:

\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{xcolor}
\usepackage{fancyvrb}

\usepackage{newverbs}
\renewcommand{\Verb}{\collectverb{\colorbox{lightgray}}}

\begin{document}

This works: \Verb|print("Hello World", end="")|

%This doesn't work: \Verb[commandchars=\\\{\}]|print("Hello World", end="")|

\end{document}

1 Answer 1

5

The approach suggested in your previous question is incompatible with fancyvrb's key-value system. When you do \renewcommand{\Verb}{...}, this command will no longer belong to fancyvrb.

I suggest a different approach: We redefine \FVC@Verb (the underlying macro in \Verb) and add a \FV@CMD around it, so we can change, with a key, the meaning of \FV@CMD and wrap the verbatim content with whatever we want. Boiling it down simply we will do:

\FV@CMD{<verbatim stuff>}

which is exactly what the \collectverb approach was doing.

First we make sure that \FV@CMD exists:

\let\FV@CMD\relax

then we make a key that will change its value:

\define@key{FV}{wrapwith}[\relax]{\def\FV@CMD{#1}}

and finally we incorporate that to the \FVC@Verb macro:

\begingroup
\catcode`\^^M=\active%
\gdef\FVC@Verb#1{%
  \begingroup%
    \FV@UseKeyValues%
    \FV@FormattingPrep%
    \FV@CatCodes%
    \outer\def^^M{}%
    \catcode`#1=12%
    \def\@tempa{\def\FancyVerbGetVerb####1####2}%
    \expandafter\@tempa\string#1{\mbox{\FV@CMD{##2}}\endgroup}%
    \FancyVerbGetVerb\FV@EOL}%          ^^^^^^^   ^ Added this
\endgroup

Then all we have to do is to redefine \FV@CMD to \colorbox{lightgray}:

\fvset{wrapwith=\colorbox{lightgray}}

This will have global effect, so you can use it in the preamble as you need. But if you use as argument to a \Verb command it will work as well, but will have local effect only.

Full code:

\documentclass[12pt]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage{xcolor}
\usepackage{fancyvrb}

\makeatletter
\let\FV@CMD\relax
\define@key{FV}{wrapwith}[\relax]{\def\FV@CMD{#1}}
\begingroup
\catcode`\^^M=\active%
\gdef\FVC@Verb#1{%
  \begingroup%
    \FV@UseKeyValues%
    \FV@FormattingPrep%
    \FV@CatCodes%
    \outer\def^^M{}%
    \catcode`#1=12%
    \def\@tempa{\def\FancyVerbGetVerb####1####2}%
    \expandafter\@tempa\string#1{\mbox{\FV@CMD{##2}}\endgroup}%
    \FancyVerbGetVerb\FV@EOL}%
\endgroup
\makeatother

\fvset{wrapwith=\colorbox{lightgray}}

\begin{document}

This works: \Verb|print("Hello World", end="")|

This does work: \Verb[commandchars=\\\{\}]|print("Hello World", end="")|

\end{document}

You must log in to answer this question.

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