我发现当前tikzmark
解决方案中存在此限制,用于突出显示代码行listings
。beamer
当我将所有内容放入onlyenv
环境中时,似乎未设置或未找到标记。示例:
\documentclass{beamer}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{tikzmark,fit}
\usetikzmarklibrary{listings}
\newcommand{\showmark}[2]{%
\tikz[remember picture,overlay]{\draw[red,thick] ({pic cs:line-#1-#2-first}) -- ({pic cs:line-#1-#2-end});}%
}
\begin{document}
\begin{frame}[fragile]
\begin{onlyenv}<1>
\showmark{first}{2}
\begin{lstlisting}[name=first]
Listing
In first slide
\end{lstlisting}
\end{onlyenv}
\begin{onlyenv}<2>
\showmark{second}{2}
\begin{lstlisting}[name=second]
Listing
In second slide
\end{lstlisting}
\end{onlyenv}
\end{frame}
\end{document}
我在第一张幻灯片中看到了一条红线,但在第二张幻灯片中却看不到。有没有(简单的)解决方法可以解决这个问题?还是我做错了什么?
PS.\showmark
宏只是一种快速展示问题的方法。
答案1
由于您没有重新启动行的值,第二个清单中的第二行实际上是第四行;要么重新启动行,要么使用适当的值:
\documentclass{beamer}
\usepackage{tikz}
\usepackage{listings}
\usetikzlibrary{tikzmark,fit}
\usetikzmarklibrary{listings}
\newcommand{\showmark}[2]{%
\tikz[remember picture,overlay]{\draw[red,thick] ({pic cs:line-#1-#2-first}) -- ({pic cs:line-#1-#2-end});}%
}
\begin{document}
\begin{frame}[fragile]
\begin{onlyenv}<1>
\showmark{aaa}{2}
\begin{lstlisting}[name=aaa]
Listing
In first slide
\end{lstlisting}
\end{onlyenv}
\begin{onlyenv}<2>
\showmark{second}{4}
\begin{lstlisting}[name=second]
Listing
In second slide
\end{lstlisting}
\end{onlyenv}
\end{frame}
\end{document}
在正常情况下,使用\resetcounteronoverlays
(或\resetcountonoverlays
用于 TeX 计数器)可以防止计数器踩到覆盖层;但是,当该name=<name>
选项用于列表时,行号的值存储在其中,\lstno@<name>
这是一个宏而不是计数器,因此\resetbeameronoverlays
不起作用,并且没有本机方法可以防止不良行为。可以手动将计数器设置为适当的值,或明确设置适当的数字firstnumber
,如下所示:
\documentclass{beamer}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{listings}
\usetikzlibrary{tikzmark,fit}
\usetikzmarklibrary{listings}
\newcommand{\showmark}[2]{%
\tikz[remember picture,overlay]{\draw[red,thick] ({pic cs:line-#1-#2-first}) -- ({pic cs:line-#1-#2-end});}%
}
\resetcounteronoverlays{lstnumber}
\begin{document}
\begin{frame}[fragile]
\begin{onlyenv}<1>
\showmark{first}{2}
\begin{lstlisting}[name=first]
Listing
In first slide
\end{lstlisting}
\end{onlyenv}
\begin{onlyenv}<2>
\showmark{second}{2}
\begin{lstlisting}[name=second,firstnumber=1]
Listing
In second slide
\end{lstlisting}
\end{onlyenv}
\end{frame}
\end{document}
或者
\documentclass{beamer}
\usepackage{tikz}
\usepackage{etoolbox}
\usepackage{listings}
\usetikzlibrary{tikzmark,fit}
\usetikzmarklibrary{listings}
\newcommand{\showmark}[2]{%
\tikz[remember picture,overlay]{\draw[red,thick] ({pic cs:line-#1-#2-first}) -- ({pic cs:line-#1-#2-end});}%
}
\resetcounteronoverlays{lstnumber}
\begin{document}
\begin{frame}[fragile]
\begin{onlyenv}<1>
\showmark{first}{2}
\begin{lstlisting}[name=first]
Listing
In first slide
\end{lstlisting}
\end{onlyenv}
\makeatletter
\def\lstno@second{1}
makeatother
\begin{onlyenv}<2>
\showmark{second}{2}
\begin{lstlisting}[name=second]
Listing
In second slide
\end{lstlisting}
\end{onlyenv}
\end{frame}
\end{document}
与此问题相关的是使用行号、“name”和“beamer”覆盖时出现列表问题。我最初想过手动重置\lst@firstnumber
,但安德鲁·斯旺解释他的回答,还是考虑一下吧\lstno@<name>
。