我正在准备一个演示文稿(使用beamer
),我需要包含许多源代码片段。对于包括源代码,我可能会使用listings
包。(我知道也有minted
包,但它在我的发行版存储库中不可用,因此安装起来会困难得多,也烦人)。
但是...在源代码中间,我想突出显示一些行,因为我想显示我添加、删除或更改了哪些行(与上一个代码片段相比)。我该怎么做?
此外,也许我可能想突出显示某一行中的某些单词,而不是整行。
(我所说的“突出显示”是指任何不同的风格:可能是背景变化、字体粗细变化、颜色变化……)
答案1
你可以在列表中使用任何你想要的 (All)TeX 宏,只需将其括在转义括号内即可,
(*@ \textcolor{blue}{code} @*)
这有趣的眼睛是您按如下方式定义转义符:
\lstset{escapeinside={(*@}{@*)}}
为了突出显示soul
包提供了一个很好的突出显示宏\hl
,请在以下最小中尝试它
\documentclass{article}
\usepackage{soul,listings,xcolor}
\lstnewenvironment{teX}[1][]
{\lstset{language=[LaTeX]TeX}\lstset{escapeinside={(*@}{@*)},
numbers=left,numberstyle=\normalsize,stepnumber=1,numbersep=5pt,
breaklines=true,
%firstnumber=last,
%frame=tblr,
framesep=5pt,
basicstyle=\normalsize\ttfamily,
showstringspaces=false,
keywordstyle=\itshape\color{blue},
%identifierstyle=\ttfamily,
stringstyle=\color{maroon},
commentstyle=\color{black},
rulecolor=\color{black},
xleftmargin=0pt,
xrightmargin=0pt,
aboveskip=\medskipamount,
belowskip=\medskipamount,
backgroundcolor=\color{white}, #1
}}
{}
\begin{document}
\begin{teX}
\test{this is some code}
(*@ \textcolor{blue}{code} @*)
(*@ \hl{yellow code} @*)
\end{teX}
\end{document}
我通常使用“列表”设置环境,但您也可以使用任何其他代码样式。
另一个有用的技巧是使用“列表”设置来强调宏,如下所示:
\gdef\emphasis#1{\lstset{emph={begin,end,#1},
emphstyle={\itshape\ttfamily\textcolor{blue}}}}
\gdef\hlemphasis#1{\lstset{emph={begin,end,#1},
emphstyle={\hl{blue}}}}
这样你就可以强调关键词。
答案2
以下是我结合投影仪叠加规范突出显示列表中的完整行或行范围/集的方法。
突出显示本身由 Martin Scharrer 完成lstlinebgrd
包裹,这会linebackgroundcolor
向listings
界面添加一个键。在下面,我将此键与命令一起使用\btLstHL<overlay spec>{line range list}
,以便我们仅在某些行上设置颜色,并且仅当给定的<overlay spec>
匹配时才设置颜色:
\begin{lstlisting}[
linebackgroundcolor={%
\btLstHL<1>{1-3}% on slide 1, highlight lines 1-3
\btLstHL<2>{6,9}% on slide 2, highlight lines 6 and 9
\btLstHL<3>{7}%
\btLstHL<4>{8}%
}]
/**
* Prints Hello World.
**/
#include <stdio.h>
int main(void) {
printf("Hello World!");
return 0;
}
\end{lstlisting}
我们得到以下结果:
完整代码:
\documentclass[dvipsnames,cmyk]{beamer}
\usepackage{pgf, pgffor}
\usepackage{listings}
\usepackage{lstlinebgrd} % see http://www.ctan.org/pkg/lstaddons
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \btIfInRange{number}{range list}{TRUE}{FALSE}
%
% Test in int number <number> is element of a (comma separated) list of ranges
% (such as: {1,3-5,7,10-12,14}) and processes <TRUE> or <FALSE> respectively
\newcount\bt@rangea
\newcount\bt@rangeb
\newcommand\btIfInRange[2]{%
\global\let\bt@inrange\@secondoftwo%
\edef\bt@rangelist{#2}%
\foreach \range in \bt@rangelist {%
\afterassignment\bt@getrangeb%
\bt@rangea=0\range\relax%
\pgfmathtruncatemacro\result{ ( #1 >= \bt@rangea) && (#1 <= \bt@rangeb) }%
\ifnum\result=1\relax%
\breakforeach%
\global\let\bt@inrange\@firstoftwo%
\fi%
}%
\bt@inrange%
}
\newcommand\bt@getrangeb{%
\@ifnextchar\relax%
{\bt@rangeb=\bt@rangea}%
{\@getrangeb}%
}
\def\@getrangeb-#1\relax{%
\ifx\relax#1\relax%
\bt@rangeb=100000% \maxdimen is too large for pgfmath
\else%
\bt@rangeb=#1\relax%
\fi%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \btLstHL<overlay spec>{range list}
%
% TODO BUG: \btLstHL commands can not yet be accumulated if more than one overlay spec match.
%
\newcommand<>{\btLstHL}[1]{%
\only#2{\btIfInRange{\value{lstnumber}}{#1}{\color{orange!30}\def\lst@linebgrdcmd{\color@block}}{\def\lst@linebgrdcmd####1####2####3{}}}%
}%
\makeatother
\begin{document}
\begin{frame}[fragile]{MyListing}
\lstset{language=C, numbers=left}
\begin{lstlisting}[
gobble=4,
linebackgroundcolor={%
\btLstHL<1>{1-3}%
\btLstHL<2>{6,9}%
\btLstHL<3>{7}%
\btLstHL<4>{8}%
}]
/**
* Prints Hello World.
**/
#include <stdio.h>
int main(void) {
printf("Hello World!");
return 0;
}
\end{lstlisting}
\end{frame}
\end{document}
答案3
以下是突出显示部分行的解决方案。它是我在以下建议的方法的组合:
基本上,我使用列表选项moredelim=**
来定义分隔符,然后将这些样式应用于所有其他格式,以便保留语法格式。
为了不局限于分隔符样式的标准字体命令,我使用 lrbox 来获取当前组的内容。生成的框包含列表的(语法格式的)输出,可用于实现更花哨的突出显示样式。
在示例代码中,命令的实现\btHL
使用 TikZ 将 lrbox 排版为 TikZ 节点。此外,可以在可选参数(例如\btHL<1->[fill=red!20,draw=red]
)中给出 tikzpicture 和节点的 beamer 叠加规范和 TikZ/PGF 选项,这提供了非常灵活的高亮器。
(注意:当在某些列表参数中使用可选参数时,整个\btHL[<key>=<value>,...]
命令必须放入花括号中,以免混淆列表键=值解析器。)
该\btHL
命令也可以在普通文本中使用。但是,它不能跨换行符使用。
\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage{beramono}
\usepackage{listings}
\lstset{
basicstyle=\scriptsize\ttfamily,language=[LaTeX]Tex,breaklines=true,
breakautoindent=true,breakindent=2ex,
}
\lstMakeShortInline{!}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}
\tikzset{onslide/.code args={<#1>#2}{%
\only<#1>{\pgfkeysalso{#2}} % \pgfkeysalso doesn't change the path
}}
\makeatletter
\newenvironment<>{btHighlight}[1][]
{\begin{onlyenv}#2\begingroup\tikzset{bt@Highlight@par/.style={#1}}\begin{lrbox}{\@tempboxa}}
{\end{lrbox}\bt@HL@box[bt@Highlight@par]{\@tempboxa}\endgroup\end{onlyenv}}
\newcommand<>\btHL[1][]{%
\only#2{\begin{btHighlight}[#1]\bgroup\aftergroup\bt@HL@endenv}%
}
\def\bt@HL@endenv{%
\end{btHighlight}%
\egroup
}
\newcommand{\bt@HL@box}[2][]{%
\tikz[#1]{%
\pgfpathrectangle{\pgfpoint{1pt}{0pt}}{\pgfpoint{\wd #2}{\ht #2}}%
\pgfusepath{use as bounding box}%
\node[anchor=base west, fill=orange!30,outer sep=0pt,inner xsep=1pt, inner ysep=0pt, rounded corners=3pt, minimum height=\ht\strutbox+1pt,#1]{\raisebox{1pt}{\strut}\strut\usebox{#2}};
}%
}
\makeatother
\begin{document}
\begin{frame}[fragile]{Highlighting single elements in listings}
\scriptsize !\btHL<overlay spec>[tikz key=val list]! highlights till the end of a group (no line breaks, though). Hence, it can be used as a ordinary font command with listings:
\par
\bigskip
\lstset{language=C, gobble=4}
\begin{lstlisting}[
moredelim={**[is][\btHL<1>]{@1}{@}},
moredelim={**[is][{\btHL<2>}]{@2}{@}}
]
#include @2<stdio.h>@
int @1main@(void) {
@2printf("Hello World!")@;
return 0;
}
\end{lstlisting}
\end{frame}
\begin{frame}[fragile]{Highlighting single elements in listings}
\scriptsize !\btHL<overlay spec>[tikz key=val list]! actually draws the content inside a TikZ node, so you can play with named nodes and other options:
\par
\bigskip
\begin{lstlisting}[language=C, gobble=4, numbers=left,
moredelim={**[is][{%
\btHL[name=X, remember picture, onslide=<2->{fill=red!50}]%
}]{@}{@}},
]
@int main (void)@ {
printf("Hello World!");
return 0;
}
\end{lstlisting}
% main() is typset into the node (X):
\tikz[remember picture, overlay]{
\path<2> node[red, above right=3mm of X](L){This is the entry point};
\draw<2>[->, red, shorten >=5pt] (L.west)--(X);
}
\end{frame}
\end{document}
答案4
我喜欢这种简单回答。
1)在 \begin{document} 之前输入:
\usepackage{color}
2)在您的列表中使用如下颜色框:
\begin{lstlisting}[escapechar=!]
...not highlighted... !\colorbox{yellow}{...**HIGHLIGHTED**...}! ...not highlighted...
\end{lstlisting}