如何使覆盖在 lstlisting 环境中仍然有效?

如何使覆盖在 lstlisting 环境中仍然有效?

问题

我想使用覆盖逐步解释 C# 编程语言beamer.cls。但它不起作用,如下图所示。

如何解决这个问题呢?


代码片段

\documentclass[dvipsnames,cmyk]{beamer}

\usepackage{listings}

\begin{document}

\defverbatim[colored]\Lst{%
\begin{lstlisting}[language={[Sharp]C}]
using System;
public delegate void Foo(object o);
\uncover<1>{public class Foo}
\uncover<2>{\{}
\uncover<3>{public static void Main()}
\end{lstlisting}}

\begin{frame}{MyListing}
\Lst
\end{frame}

\end{document}

答案1

使用semiverbatim环境,在这种情况下会更加灵活。下面是我前段时间做的一个例子:

\documentclass{beamer}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}

\begin{document}
\begin{frame}[fragile]{Matrixoperationen}{Benutzung von \texttt{semiverbatim}}
\setbeamercolor{alerted text}{fg=blue}
\setbeamerfont{alerted text}{series=\bfseries,family=\ttfamily}
\begin{semiverbatim} \small
\uncover<1->{\alert<0>{\alert<6>{sub \color{red}matrix_row2vector} \{}}
\uncover<2->{\alert<2>{  my $m = shift;    my($rows,$cols) = ($m->[1],$m->[2]);}}
\uncover<2->{\alert<2>{  my $r = shift;   # optional, which column from matrix}}
\uncover<2->{\alert<2>{  croak "Error: matrix hasn't 3D rows" unless ($colsRun also:>{}>3);}}
\uncover<3->{\alert<3>{  if ( defined $r ) \{}}
\uncover<3->{\alert<3>{    croak "Error: matrix hasn't that row" unless ($r < $rows);}}
\uncover<3->{\alert<3>{  \}}}
\uncover<4->{\alert<4>{  else \{}}
\uncover<4->{\alert<4>{    croak "Error: matrix is not a 3D row matrix"}}
\uncover<4->{\alert<4>{           unless ($rowsRun also: >>  1);}}
\uncover<5->{\alert<5>{    $r = 0;}}
\uncover<4->{\alert<4>{  \}}}
\uncover<6->{\alert<6>{  return Math::VectorReal->%
\alert<6>{\color{red}new(@\{$m->[0][$r]\})};}}
\uncover<1->{\alert<1>{\}}}
\end{semiverbatim}

\visible<6>{Beachte den Gebrauch von \alert{\color{red}\texttt{shift}}.}
\end{frame}
\end{document}

如果你有很多 TeX 代码需要展示,那么可以定义类似

\def\Lcs#1{\textbackslash#1}

那么编写类似 \Lcs{newpage} 的内容就更容易了。

答案2

尽管专家已经接受了semiverbatimHerbert 的(经常给出的)“使用”答案,但我还是想提出我的listings在这里提出我的唯一解决方案 – 针对像 Tobi 这样不想放弃语法着色和该listings软件包所有其他酷炫功能的人。

首先要做的(类似于 Herbert 的解决方案)是不要使用 beamer 的\defverbatim,而是使用选项将列表嵌入框架内[fragile]。(的重点\defverbatim是内容得到扩展 \begin{frame},因此覆盖规范不起作用。)

然后,诀窍就是使用moredelim样式选项listings将覆盖命令注入到列表中:

\documentclass[dvipsnames,cmyk]{beamer}
\usepackage{listings}
\lstloadlanguages{[Sharp]{C}}

\lstdefinestyle{base}{
  language=[Sharp]{C},
  moredelim=**[is][\only<+>{\color{red}}]{@}{@},
}

\begin{document}

\begin{frame}[fragile]{MyListing 1}
  \begin{lstlisting}[style=base, gobble=4]
    using System;
    public delegate void Foo(object o);
    @public class Foo@
    @{@ 
    @  public static void Main()@
    @}@
  \end{lstlisting}
\end{frame}
\end{document}

请注意,我使用的\only\uncover\moredelim**,因为应用了给出的格式此外对当前行的所有其他格式,这意味着\uncover这里基本上没有效果。

为了不仅实现当前行的突出显示,还实现剩余部分的“变暗”(如 Tobi 的解决方案),我们必须对列表样式进行更多尝试。我们的想法是使用一种样式(base)使列表“变暗”,并在命令(使用)中将另一种样式( highlight)应用于其顶部以删除当前行的“变暗”。这适用于所有样式元素,但是,因此我们在命令中手动应用“非变暗”版本(这里是):\moredelim\lstsetbasicstylebasicstyle\color{black}moredelim

\lstdefinestyle{highlight}{
  keywordstyle=\color{red},
  commentstyle=\color{green},
}
\lstdefinestyle{base}{
  language=[Sharp]{C},
  basicstyle=\color{black!40},
  keywordstyle=\color{red!40},
  commentstyle=\color{green!40},
  moredelim=**[is][\only<+>{\color{black}\lstset{style=highlight}}]{@}{@},
}

\begin{frame}[fragile]{MyListing 2}
  \begin{lstlisting}[style=base, gobble=4]
    using System;
    public delegate void Foo(object o);
    @public class Foo@
    @{@ 
    @  public static void Main()@
    @}@
  \end{lstlisting}
\end{frame}

在此处输入图片描述

答案3

根据要求,我的回答是关于使用带有半透明覆盖的 TikZ 。

代码

\documentclass[handout]{beamer}

% basic packages
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}

% load TikZ to draw the heighlighting areas
\usepackage{tikz}
    \usetikzlibrary{fit,calc,decorations.pathreplacing}
    \newcommand{\tikzref}[1]{% to define an anchor
        \tikz[remember picture]{%
            \coordinate (#1) at (0,0.5ex);%
        }%
    }
    \tikzset{
       transp/.style={
          fill opacity=0.75,fill=white, inner sep=1.5mm,
       },
       reverseclip/.style={
          insert path={(current page.north east) --
            (current page.south east) --
            (current page.south west) --
            (current page.north west) --
            (current page.north east)},
       },
    }

% use listings to show an example how to heighlight code
\usepackage{listings}
    \lstloadlanguages{[LaTeX]TeX}
    \lstset{% 
        language=[LaTeX]TeX, 
        basicstyle=\ttfamily,
        keywordstyle={},
        escapechar={§},% needed to set tikz anchors in listings
    }


\begin{document}

% EXAMPLE A
\begin{frame}{Heighlighting parts of an equation}
% 1.  Set the equation as usual. Add anchors with \tikzmark at the beginning and
%     end of the formular, named bmath and emath in this example, and at the
%     beginning and end of the part you want to heighlight, named bfrac and efrac.
\[
    \tikzref{bmath}f(x) =
        \left(2x^4 + \tikzref{bfrac}\frac{3x^3}{4m}\tikzref{efrac}+
        7x+\pi\right)\cdot\frac{\alpha}{2\gamma\varepsilon_0}\tikzref{emath}
\]
% 2.  Add the code to highlight
% 2.1 The {tikzpicture} shouldn't take space on the frame but 'overlay' it and
%     we make the \tikzref anchors acessible via 'remember picture'.
\begin{tikzpicture}[overlay, remember picture]
% 2.2 Draw the frame around the part that should be heighlighted, i.e. not coverd
%     by the semi-transparent overlay. This path has the 'clip' option meaning
%     that all following path are clipped by that.
    \path [clip] % [A, see Notes]
        ($(bfrac) - (0,5mm)$) -- %
        ($(efrac) - (0,5mm)$) -- %
        ($(efrac) + (0,5mm)$) -- %
        ($(bfrac) + (0,5mm)$) --%
        cycle
         [reverseclip];
% 2.3 Add the semi-transparent overlay to cover the whole equation.
    \node [transp,fit={($(bmath)+(0,5mm)$) ($(emath)-(0,5mm)$)}] {};
\end{tikzpicture}
\end{frame}

% EXAMPLE B
\begin{frame}[fragile]{Heighlighting parts of a code example}
% 1.  Set the code environment as usual and add \tikzref anchors. Here § is used
%     to escape from vermatim back to LaTeX.
    \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
        §\tikzref{z1}§\documentclass[ngerman,11pt]{scrartcl}
        \usepackage[T1]{fontenc}
        \usepackage[latin1]{inputenc}
        \usepackage{babel}
        §\tikzref{z5}§\usepa§\tikzref{pkgcmd}§ckage{list§\tikzref{pkg}§ings}§\tikzref{lst}§
        §\tikzref{z6}§    \lstset{basicstyle=\ttfamily}§\tikzref{lstset}§
        §\tikzref{z7}§    \lstMakeShortInline|§\tikzref{svrb}§
        §\tikzref{z8}§\begin{document}
        Eine \emph{Auszeichnung} und 
        §\tikzref{bvrb}§|verb§\tikzref{verb}§atim|-Text§\tikzref{evrb}§ enthält.
        \dots und eine {unbedeutende Gruppe}.
        % Kommentare erscheinen nicht in der Ausgabe§\tikzref{txt}§
        §\tikzref{z15}§\end{document}
    \end{lstlisting}
% 2.  Add the {tikzpicture} to draw the heiglighting (see example A).
    \begin{tikzpicture}[overlay, remember picture]
        % clipping:
        \begin{scope}% [B, see Notes]
            % cut out 1
            \path [clip] let \p1=(z5), \p2=(z7), \p3=(lstset) in%
                ($(z8) + (0,1ex)$) %
                -- ++(\x3-\x1,0) %
                -- ++($(0,0) + (0,2ex) + (0,\y1-\y2)$)
                -- ++(\x1-\x3,0) %
                -- cycle [reverseclip];
            % cut out 2
            \path [clip] %
                ($(bvrb) - (0,1ex)$) %
                -- ($(evrb) - (0,1ex) $) %
                -- ($(evrb) + (0,1ex) $) %
                -- ($(bvrb) + (0,1ex)$) %
                -- cycle [reverseclip];
            % clip everything without cutted areas
            \node [transp,fit=(z1) (z15) (txt)] {};
        \end{scope}
% 3.  Add some additional text annotations using 'nodes' and the \tikzref anchors.
        \def\ddx{0.15}\def\ddy{1ex}\def\dx{0.7}
        \draw<2-> [<-] ($(lst) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {load};
        \draw<3-> [<-] ($(lstset) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {mono font};
        \draw<4-> [<-] ($(svrb) + (\ddx,0)$) -- +(\dx,0) node [right, anchor=mid west] {short verb};
        \draw<5-> [<-] ($(verb) + (0,-\ddy)$) |- +(0.3,-0.5) node [right, anchor=mid west] {example};
    \end{tikzpicture}
\end{frame}

\end{document}

输出

输出


笔记

  • 为了获得带有一些剪切区域的半透明覆盖层,我将一个节点放置在框架的整个相关部分上方并进行剪辑。所需的reveseclip-Option 由 Jake 在如何在 TikZ 中反转“剪辑”选择?

  • 在设计这个例子的时候,我发现绘制剪切路径的方向[A]是相关的,所以如果不起作用,请尝试顺时针(逆时针)绘制路径。

  • 请注意,TikZ 需要运行两次 (pdf)LaTEX 才能获得正确的位置。

  • 在某些情况下[B]{scope}将剪辑限制在不受影响的其他绘图范围内似乎是个好主意。

  • 一个问题可能是我们需要用 污染原始列表代码§\tikzref{…}§。也许有人知道如何自动导出调整后的列表?

相关内容