2

I'd like to be able to use inline verbatim text with the following features:

  1. Line breaks, as provided for example by package spverbatim, command \spverb;
  2. Colored font, as provide by package color;
  3. Highlighting (text with colored background), like soul's package \hl command.

By "inline" I mean that the verbatim part is within the normal text (not an environment with its own paragraph), and by "verbatim" I mean that special symbols like \, _ etc are not be interpreted by LaTeX.

What I'd like to achieve looks like this (using blue as font color and grey as highlighting color), but it should allow a line break if the verbatim part requires one.

enter image description here

I have tried packages color, newverbs, spverbatim and soul, but I haven't been able to combine all the above features. The closest I've got is:

  • Tweaking spverbatim's definition of spverb to include colored font. That way I get features 1 and 2, but not 3:

    \gdef\myVerb{%
      \bgroup
      \color{fgColor}%
      \let\spverb@ve=\verb@egroup
      \def\verb@egroup{\spverb@ve\egroup}%
      \def\@xobeysp{\mbox{}\space}%
      \verb
    }
    

    Apparently \myVerb defined this way can't be chained with soul's package hl to use \hl{\myVerb{verbatim text}} (LaTeX complains LaTeX Error: \verb illegal in command argument.). Is there any way to combine them? For example, is there something analogous to \hl that can be added after \color{fgColor} in the code above to achieve highlighting?

  • Using the newverbs package to define

    \newverbcommand{\myVerb}
    {\color{fgColor}\begin{lrbox}{\verbbox}}
    {\end{lrbox}\colorbox{bgColor}{\usebox{\verbbox}}}
    

    This produces the font colored in fgColor and the highlighting with bgColor, so I get 2 and 3; but not 1: it doesn't allow line breaks. I guess that's because of lrbox or \colorbox, but I don't know how to modify this to allow line breaks. Is there any way to do it?

  • I can of course use

    \newcommand{\myVerb}[1]{{\ttfamily\color{fgcolor}{\hl{#1}}}}
    

    with hl as per soul package. With this I get 1, 2 and 3 but it's not verbatim, so I have to escape all special characters.

So, is there any way to achieve what I want? Either by solving what's missing in any of the above approaches, or by using a different approach? Perhaps there's a package that supports all the features I want off the shelf?

2

While not exactly what the OP asks, it may suffice. First, it uses \detokenize, not verbatim, which means 1) that braces {} must be balanced, 2) that the % symbol is still interpreted as a comment, 3) that a space is inserted after all detokenized macro names, and 4) Hash marks # are doubled in number.

Also, I just \allowbreak between words, using the \fboxsep of the colorbox to create the interword spaces.

EDITED to use \ttfamily for the \mytokens macro.

EDITED to fix line height, since the combination of a \strut and \fboxsep blew the allowed baselineskip budget.

Originally, I was not using interword space but allowed the \fboxsep to suffice. But this caused margin issues, as nothing could stretch. So, upon RE-EDIT, I insert a space of 0pt minus \fboxsep between words, which seems to allow enough compression to address the margin issues, while still leaving enough space between words (otherwise 2\fboxsep).

I also rearranged the \grayspace and allowbreak, upon RE-EDIT, so that a linebreak would not occur before trailing punctuation.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xcolor}
\newcommand\mytokens[1]{\mytokenshelp#1 \relax\relax}
\def\mytokenshelp#1 #2\relax{\allowbreak\grayspace\tokenscolor{#1}\ifx\relax#2\else
 \mytokenshelp#2\relax\fi}
\newcommand\tokenscolor[1]{\colorbox{gray!20}{\textcolor{blue}{%
  \ttfamily\mystrut\smash{\detokenize{#1}}}}}
\def\mystrut{\rule[\dimexpr-\dp\strutbox+\fboxsep]{0pt}{%
 \dimexpr\normalbaselineskip-2\fboxsep}}
\def\grayspace{\hspace{0pt minus \fboxsep}}
\begin{document}
Here is my leading text
\mytokens{Fie Fi Fo Fum, I smell the $#@*& blood of an \Englishman.
I will continue this text to observe the margins. 
Fie Fi Fo Fum, I smell the \textbf{blood} of an Englishman.}
and my trailing text. And here is more text to find where the margin end
really should be.

Standard MATLAB formats are allowed, such as \mytokens{1.2}, \mytokens{-.2i},
\mytokens{1.}, \mytokens{-1.2e3}, \mytokens{+.2E-3j}.  \mytokens{i} and 
\mytokens{j} denote...
\end{document}

enter image description here

  • Thanks! This seems to do what I need, except that my verbatim text may contain non-balanced {}. It may also contain \, which produce an extra space if I understood correctly; but that's less of an issue for me – Luis Mendo Oct 19 '15 at 15:21
  • Hm, it looks like the # gets duplicated... Do you think my first approach could be modified to include something next to \color{fgColor} to realize the gray background in addition to the colored font? – Luis Mendo Oct 21 '15 at 0:07
  • @LuisMendo Apparently, the double # seems to be a function of \detokenize, of which I had been previously unaware. I will have to add that as item 4 in the 1st paragraph list. As to your other question, I am not sure how to do that, but I will give it more thought. – Steven B. Segletes Oct 21 '15 at 1:13
  • I ended up writing a program to transform for example \myVerb+abc$\+ into \myVerb{abc\$\textbackslash } (that is, escape characters and use {} as delimiters). That way I can dispose of verbatim and use \newcommand{\myVerb}[1]{{\ttfamily\color{fgcolor}{\hl{#1}}}} (the third "solution" in my question). Not ideal but it works; I only need to pass my program on the tex file to do the transformation prior to compiling. So I no longer need a solution. However, I'm leaving the question here in case someone can solve the problem; I think it would be interesting to have an actual solution – Luis Mendo Oct 24 '15 at 1:06
  • @LuisMendo I'm glad you found a workaround. If so inclined, you can always post your approach as an answer to your own question. – Steven B. Segletes Oct 24 '15 at 1:09
1

As I mentioned in comments to Steven's answer, I ended up writing a program to transform for example

\myVerb+abc$\+

into

\myVerb{abc\$\textbackslash }

that is, escape characters and use {} as delimiters. That way I can dispose of verbatim and use

\newcommand{\myVerb}[1]{{\ttfamily\color{fgcolor}{\hl{#1}}}}

i.e. the third "solution" in my question. It's not ideal but it works; I only need to run my program on the tex file to do the transformation prior to compiling.

I wrote the program as the following Matlab function.

function convert_myVerb(fileName)

% Converts \myVerb+...+ or \myVerb|...| into: \myVerb{...} with escaped characters

fid = fopen(fileName);
s = fread(fid);
fclose(fid);
s = char(s.');
ind = regexp(s, '(?<=\\myVerb).');
unique(s(ind)); % characters found after "\myVerb", as a check. I only used + and |
[ini, fin] = regexp(s, '\\myVerb([+|]).*?\1'); % all matching substrings
if isempty(ini)
    disp('Nothing needs to be converted. Converted file not written')
else
    disp([num2str(numel(fin)) ' substrings identified for conversion'])
    y = s(1:ini(1)-1); % output. Initiallize
    % \# \$ \% \& \textbackslash{} \textasciicircum {}\_ \{ \} \textasciitilde{}
    ini(end+1) = numel(s)+1;
    for n = 1:numel(fin)
        t = regexprep(s(ini(n)+6:fin(n)-1), '\\', '\\textbackslash '); % This has
        % to go first, so that it won't convert \ introduced to escape other
        % characters. No {} here, because they would get converted into \{\} later
        t = regexprep(t, '[#$%&_{}]', '\\$0');
        t = regexprep(t, '\^', '\\textasciicircum{}');
        t = regexprep(t, '~', '\\textasciitilde{}');
        t = ['\myVerb{' t '}'];
        y = [y t s(fin(n)+1:ini(n+1)-1)];
    end
    fid = fopen(fileName, 'w');
    count = fwrite(fid, y);
    fclose(fid);
    if count
        disp('Converted file successfully written')
    end
end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.