我如何突出显示源代码中的某些行?

我如何突出显示源代码中的某些行?

我正在准备一个演示文稿(使用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包裹,这会linebackgroundcolorlistings界面添加一个键。在下面,我将此键与命令一起使用\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}

相关内容