tikzmark、列表和 beamer 的 onlyenv

tikzmark、列表和 beamer 的 onlyenv

我发现当前tikzmark解决方案中存在此限制,用于突出显示代码行listingsbeamer当我将所有内容放入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>

相关内容