# simple REPL output formatting (xstring and special characters)

I want to copy/paste REPL transcripts into an environment and get minimal highlighting of the input.

Expected result:

\begin{repl}
> foo
bar
> baz < quux
fnord
\end{repl}


should produce something like

>foo
bar
>baz < quux
fnord

(i.e. verbatim-like environment, user input is bold, all output (including the prompt >) is normal.)

I thought this should be easy to do with fancyvrb and xstring, however the best thing I could get working still has problems:

\documentclass{article}
\usepackage{fancyvrb}
\usepackage{xstring}
\usepackage{tgcursor} % default fixed font doesn't bold(?)
\renewcommand{\FancyVerbFormatLine}[1]{%
\IfBeginWith{#1}{!}{> \textbf{\StrGobbleLeft{#1}{2}}}{#1}
}
\begin{document}
\begin{Verbatim}
! foo
bar
! baz < quux
fnord
\end{Verbatim}
\end{document}


outputs

>foo
bar
>baz ␣quux
fnord

0. Is this completely the wrong approach or generally going in the right direction? (If wrong: Ignore the following questions and just suggest a better way.)

1. \IfBeginWith will not compare >, so this example uses ! and replaces it in the output. (This affects all common prompt characters (>, #, \$, %). I looked through the xstring documentation and while §3.1.* states that # and % might be problematic, from my reading > should be fine.)

➜ Can this be fixed / made to work with > (and possibly the others as well)?

2. < mis-behaves in the input. It produces a warning

! Undefined control sequence.
<->\leavevmode \kern \z@ \char \<


and depending on other unknown factors may or may not produce the correct character in the output PDF. (It prints fine in my "full" document (still produces the warning), but the MWE above turns it into a ␣. I tried adding some likely candidate packages… no idea what's "fixing" this.) Changing \FancyVerbFormatLine to

\IfBeginWith{\detokenize{#1}}{!}{\textbf{#1}}{#1}


gets rid of the warning, so this is again xstring-related.

➜ What's going wrong here and how do I fix it?

3. (non-essential) While fancyvrb allows to define custom verbatim environments with \DefineVerbatimEnvironment, \FancyVerbFormatLine seems to affect all variants.

➜ Is there an easy way to make that affect only my custom verbatim environment? (If there's only a hard way, that's not worth the effort.)

• Welcome to TeX - LaTeX! Have you looked at the listings package? – Andrew Swann May 21 '17 at 11:07
• @AndrewSwann Yes, I'm aware of the various listing and program output packages – they generally do too much (I don't want line numbers, no (accidental) highlighting, no program execution, no …) and yet they're still inflexible. In the case of listings, \lstset{basicstyle=\ttfamily,morecomment=[l][keywordstyle]{> }} gets me roughly what I have now, but it also highlights the prompt (which I want to avoid). With listings I see no way to improve on that and get what I want, with my approach from above I know that it's possible, I just get problems with "special" characters. – nobody May 21 '17 at 13:05

Apparently xstring has problems with removing the space (which however is not really needed.

\documentclass{article}
\usepackage{fancyvrb}
\usepackage{xparse}
\usepackage{tgcursor} % default fixed font has no bold

\ExplSyntaxOn
\RenewDocumentCommand{\FancyVerbFormatLine}{m}
{
\str_if_eq_x:nnTF { \tl_head:n { #1 } } { > }
{ > \bfseries \tl_tail:n { #1 } }
{ #1 }
}
\ExplSyntaxOff

\begin{document}

\begin{Verbatim}
> foo
bar
> baz < quux >> foo
fnord
\end{Verbatim}

\end{document}


Note you can use >, which you can't with xstring because in a Verbatim environment > is active; the \str_if_eq:nnTF comparison is category code agnostic.

If you need to use the standard Verbatim command (and even if you don't), a different environment can be used:

\documentclass{article}
\usepackage{fancyvrb}
\usepackage{xparse}
\usepackage{tgcursor} % default fixed font has no bold

\newenvironment{shell}
{\VerbatimEnvironment
\let\FancyVerbFormatLine\shellformatline
\Verbatim}
{\endVerbatim}

\ExplSyntaxOn
\NewDocumentCommand{\shellformatline}{m}
{
\str_if_eq_x:nnTF { \tl_head:n { #1 } } { > }
{ > \bfseries \tl_tail:n { #1 } }
{ #1 }
}
\ExplSyntaxOff

\begin{document}

\begin{shell}
> foo
bar
> baz < quux >> foo
fnord
\end{shell}

\end{document}
`