如何重新定义\lstinline
自动突出显示或绘制所有内联代码片段周围的框架?例如使用\bh
和\eh
命令突出显示代码列表中的文本,同时保持语法突出显示?(我喜欢 tikz 解决方案,因为\f[color]box
它不适用于代码中的某些字符序列,例如^^^
)
添加:
最小示例:
\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}
即如何实现整个文档中的内联代码片段将显示在小框架内(或突出显示),而无需向\lstinline|xxx|
文档中的命令添加任何内容,而只需重新定义\lstinline
命令本身?可能吗?
答案1
自动应用解决方案表单的一种方法突出显示代码列表中的文本,同时保持语法突出显示围绕每个的方法lstinline
是重新定义包中的一些内部宏,以在列表开头listings
包含一个和一个。为了确保这仅适用于内联列表,我们使用包中的宏来生成:\bh{}
\eh{}
iftoggle
etoolbox
已知的问题:
- 突出显示不能正确跨越换行符。
代码:
\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}