8

How to redefine \lstinline to automatically highlight or draw frames around all inline code snippets? E.g. using \bh and \eh commands from Highlight text in code listing while also keeping syntax highlighting ? (I like the tikz solution since \f[color]box doesn't work with some characters sequences in code, like ^^^)

Added:

Minimal example:

\documentclass{article}
\usepackage{listings}
% (definitions from https://tex.stackexchange.com/questions/15237/highlight-text-in-code-listing-while-also-keeping-syntax-highlighting/18890#18890 should be inserted here)

% how to redefine the \lstinline command?

% Where to insert \bh and \eh commands?

\makeatletter
% \renewcommand\lstinline[1][]{%
%     \leavevmode\bgroup % \hbox\bgroup --> \bgroup
%       \def\lst@boxpos{b}%
%       \lsthk@PreSet\lstset{flexiblecolumns,#1}%            <-- \bh can be here (before '%')
%       \lsthk@TextStyle \lsthk@Endgroup\@empty
%       \@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}%
%                          \lstinline@}                      <-- but where to place \eh ???
\makeatother

\begin{document}

The following \emph{inline} code snippet should appear
in a frame (or highlighted) if lstinline command is properly redefined above:
\lstinline´chainl1(term, "+" ^^^ Add | "-" ^^^ Sub)´

\end{document}

I.e. how to achieve that inline code snippets in the whole document will be displayed inside small frames (or highlighted) without adding anything to \lstinline|xxx| commands in the document but only via redefinition of the \lstinline command itself? Is it possible?

2
  • Welcome to TeX.SE. It is always best to compose a MWE that illustrates the problem including the \documentclass so that those trying to help don't have to recreate it. Oct 7, 2011 at 15:55
  • Peter, thank you for the hint. I added an example. Oct 7, 2011 at 16:27

1 Answer 1

7

One way to automatically apply the solutions form Highlight text in code listing while also keeping syntax highlighting around each lstinline is to redefine some of the internal macros from the listings package to include a \bh{} at the beginning of the listing and a \eh{}. To ensure that this only applies to inline listings, we use iftoggle from the etoolbox package to produce:

enter image description here

Known Issues:

  • Highlighting does not span line breaks correctly.

Code:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{atbegshi,ifthen,listings,tikz}

% change this to customize the appearance of the highlight
\tikzstyle{highlighter} = [
  yellow,
  line width = \baselineskip,
]

% enable these two lines for a more human-looking highlight
%\usetikzlibrary{decorations.pathmorphing}
%\tikzstyle{highlighter} += [decorate, decoration = random steps]

% implementation of the core highlighting logic; do not change!
\newcounter{highlight}[page]
\newcommand{\tikzhighlightanchor}[1]{\ensuremath{\vcenter{\hbox{\tikz[remember picture, overlay]{\coordinate (#1 highlight \arabic{highlight});}}}}}
\newcommand{\bh}[0]{\stepcounter{highlight}\tikzhighlightanchor{begin}}
\newcommand{\eh}[0]{\tikzhighlightanchor{end}}
\AtBeginShipout{\AtBeginShipoutUpperLeft{\ifthenelse{\value{highlight} > 0}{\tikz[remember picture, overlay]{\foreach \stroke in {1,...,\arabic{highlight}} \draw[highlighter] (begin highlight \stroke) -- (end highlight \stroke);}}{}}}
%--------------------------


\makeatletter %   Redefine macros from listings package:
\newtoggle{@InInlineListing}%
\togglefalse{@InInlineListing}%

\renewcommand\lstinline[1][]{%
    \leavevmode\bgroup\toggletrue{@InInlineListing}\bh % \hbox\bgroup --> \bgroup
      \def\lst@boxpos{b}%
      \lsthk@PreSet\lstset{flexiblecolumns,#1}%
      \lsthk@TextStyle
      \@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}%
                         \lstinline@}%

\def\lst@LeaveAllModes{%
    \ifnum\lst@mode=\lst@nomode
        \expandafter\lsthk@EndGroup\iftoggle{@InInlineListing}{\eh{}}{}%
    \else
        \expandafter\egroup\expandafter\lst@LeaveAllModes
    \fi%
    }
\makeatother


\lstset{backgroundcolor=\color{green!10}}%

\begin{document}
The following \emph{inline} code snippet should appear
in a frame (or highlighted) if lstinline command is properly redefined above:
\lstinline´chainl1(term, "+" ^^^ Add | "-" ^^^ Sub)´Now back to regular text

\bigskip
The lstlisting environment is not affected:
\begin{lstlisting}
    chainl1(term, "+" ^^^ Add | "-" ^^^ Sub)
\end{lstlisting}
\end{document}
14
  • Peter, thank you for your answer. \bh \lstinline... \eh does work, of course. What I'm trying to achieve is to redefine the \lstinline command globally to avoid changing \lstinline commands in the whole document. (It's not convenient if using LyX). Oct 7, 2011 at 16:31
  • \framebox gives errors sometimes, e.g. with ^^^ sequence, as in: \framebox{\lstinline{abc ^^^ }} results in ! Text line contains an invalid character. Oct 7, 2011 at 16:32
  • I.e. each occurence of \lstinline... in document body should result in a framed (or highlighted) code, without explicit enclosing of each \lstinline usage in \bh..\eh or other surrounding commands. Oct 7, 2011 at 16:51
  • See updated solution. Oct 7, 2011 at 19:00
  • Peter, your solution is fantastisch! Thank you very much for your efforts! Oct 7, 2011 at 20:06

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.