我正在考虑一个带有右侧注释的投影仪演示文稿。为了在注释和它们所指的内容之间建立更好的联系,我修改了命令\notes
(使用zref
's savepos),使注释文本打印在与文本出现的同一垂直位置。因此,将命令直接放在框架中并不总是可行的\notes
,但有时它需要出现在不同的环境中。
这是为了激励,在大多数情况下效果很好。但是,请考虑这个 MWE:
\documentclass{beamer}
\usepackage{amsmath,pgfpages}
\setbeameroption{show notes on second screen=right}
\newcounter{notecounter}
\begin{document}
\begin{frame}
\begin{align*}
a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}\\} \\
b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}\\}
\end{align*}
\end{frame}
\end{document}
这没有任何重新定义,只是使用我当然内部使用的普通 beamer 命令。注释页面将输出以下内容:
这是第一条注释:0
这是第二条注释 1
这是第一条注释:2
这是第二篇笔记 3
由于某种原因,注释在多行数学环境中出现时会重复出现(更糟糕的是,多次展开)(使用 和 进行测试align
,gather
带星号和不带星号)。但这似乎不是一个根本问题,您可能\note
根本不会在数学模式下使用,因为它适用于\[ \]
和equation
。
有没有办法可以解决这个问题,当我改变对齐定义时它会完全弄乱我的间距\note
?
编辑:应 samcarter 的要求,我提供了一个包含部分代码的 MWE,用于提供对齐的注释。这非常简单,原始代码还包含错误放置的超链接的修复、合并比例框等,但这与显示问题无关。可能,tikzmark
会使定位算法更优雅。由于我通常使用tikz
,这对我来说不是一个缺点;但是,我认为实现只能从表面上解决问题:对齐可能是正确的(并且tikz
会给出两次使用相同名称的警告),但两个相同的注释会打印在彼此的顶部。
\documentclass{beamer}
\usepackage{amsmath,pgfpages,zref-user,zref-savepos}
\setbeameroption{show notes on second screen=right}
\setbeamertemplate{note page}[plain]
\newcounter{notecounter}
\makeatletter
\let\oldnote\note
\newcounter{pposes}
\newcounter{poses}
\AtBeginNote{%
\setcounter{poses}{0}%
}
\AtEndNote{%
\setcounter{poses}{0}%
\stepcounter{pposes}%
}
\renewcommand<>{\note}[1]{%
\only#2{%
\stepcounter{poses}%
\vbox to 0pt{%
\edef\l{p\the\value{pposes}-\the\value{poses}}%
\zsaveposy{\l}%
\zrefused{\l}%
\oldnote{%
\stepcounter{poses}%
\edef\l{p\the\value{pposes}-\the\value{poses}}%
\zref@ifrefundefined{\l}{}{%
\parbox[l][0pt][t]{0pt}{%
\hfuzz=\maxdimen%
\parbox{\textwidth}{%
\vspace{\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
#1%
}%
}%
}%
}%
}%
}%
}
\begin{document}
\begin{frame}
\begin{align*}
a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
\end{align*}
Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
\end{frame}
\end{document}
请注意,这样一来,问题就发生了变化:现在不是音符可见两次(因为宏没有找到第二次出现的相关位置),而是在 -environment\note
之后使用该命令align
,首先给出未打印的重复音符。因此,此 MWE 生成正确对齐的前两个音符,然后再次生成第一个音符,该音符未与“问题”的位置对齐。重复的第二个音符和实际的第三个音符根本没有显示。
答案1
这个问题是由于align
环境需要在实际打印任何内容之前执行一些测量和计算而引起的。为此,它首先必须排版框寄存器中的所有内容,这些内容不会打印,只会进行测量。之后所有内容都会再次排版,这一次是真实的。
此过程的结果是,在align
环境内进行的任何分配都会执行两次,这就是您遇到的情况。
(注意:测量完成后,所有 LaTeX 计数器都会重置,因此在环境内\setcounter
可以\stepcounter
按预期工作align
。)
规避此问题的一种方法是使用条件\ifmeasuring@
,在执行这些测量时将其设置为 true。以下内容来自amsmath
文档:
\ifmeasuring@
所有显示环境都会排版两次 - 一次是在“测量”阶段,然后再次在“生产”阶段;\ifmeasuring@
将用于确定我们处于哪种情况,以便我们采取适当的措施。
因此,您可以重新定义,\note
以便它在测量阶段不执行任何操作,如下所示:
\documentclass{beamer}
\usepackage{amsmath,pgfpages}
\makeatletter
\let\originalnote\note
\renewcommand<>\note[2][]{\ifmeasuring@\else\originalnote#3[#1]{#2}\fi}
\makeatother
\setbeameroption{show notes on second screen=right}
\newcounter{notecounter}
\begin{document}
\begin{frame}
\begin{align*}
a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}\\} \\
b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}\\}
\end{align*}
\end{frame}
\end{document}
答案2
由于某种原因,其中的代码align*
被执行了两次。因此,前两个注释也被定义了两次。注释的标签分别为 p0-1、p0-2、p0-1、p0-2 和 p0-3(请注意重复的标签)。Beamer 现在已存储了 5 个注释。在排版注释页面时,您的代码会尝试使用标签 p0-1 到 p0-5 来表示存储的注释。当然,最后两个是未知的。
您的代码存储的位置是正确的。但现在,第三个存储的音符是第一个的副本。这是用第三个真实音符的位置设置的。其他音符没有给出,因为现在使用的标签是未定义的。
一种可能的解决方案是阻止第一次执行注释(我也尝试阻止第二次执行,但没有成功)。这里使用(ma 表示数学对齐)完成此操作,仅当标志为\manote
时才执行。标志设置为(需要包)。不幸的是,无法使用重置,因为此时已经太晚了。因此,标志的设置方式有两种:a)使用(内部设置标志)作为最后一个注释或 b)在最后一个之后使用,但在环境中。\note
\ifexecutenote
true
false
\AtBeginEnvironment
etoolbox
\AtEndEnvironment
\lmanote
\executemanotes
\manote
\AtBeginEnvironment{someenv}{\global\executemanotefalse}
对于每个其他环境,您必须在序言中添加一行。
我保留了一些(注释掉的)调试代码,因为它对于弄清楚发生了什么非常有用。如果您的完整代码出现一些问题,它可能会有所帮助。代码将一些信息写入日志文件。
\documentclass{beamer}
\usepackage{amsmath,pgfpages,zref-user,zref-savepos}
\usepackage{etoolbox} % <---- new
\setbeameroption{show notes on second screen=right}
\setbeamertemplate{note page}[plain]
\newcounter{notecounter}
\makeatletter
\let\oldnote\note
\newcounter{pposes}
\newcounter{poses}
\AtBeginNote{%
\setcounter{poses}{0}%
}
\AtEndNote{%
\setcounter{poses}{0}%
\stepcounter{pposes}%
}
\renewcommand<>{\note}[1]{%
\only#2{%
\stepcounter{poses}%
\vbox to 0pt{%
\edef\l{p\the\value{pposes}-\the\value{poses}}%
% \typeout{XXXXXXXXXXXXXXXXXXXX label: \l}%
\zsaveposy{\l}%
\zrefused{\l}%
% \typeout{AAAAAAAAAAAAAAAAAAAA pos: \the\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
\oldnote{%
\stepcounter{poses}%
\edef\l{p\the\value{pposes}-\the\value{poses}}%
% \typeout{YYYYYYYYYYYYYYYYYYYY label: \l}%
\zref@ifrefundefined{\l}{%
% \typeout{ZZZZZZZZZZZZZZZZZZZZ label undefined: \l}%
}{%
% \typeout{ZZZZZZZZZZZZZZZZZZZZ label defined: \l}%
\parbox[l][0pt][t]{0pt}{%
\hfuzz=\maxdimen%
\parbox{\textwidth}{%
\vspace{\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
% \typeout{BBBBBBBBBBBBBBBBBBBB pos: \the\dimexpr\paperheight - \zposy{\l}sp - 6mm}%
#1%
}%
}%
}%
}%
}%
}%
}
%-------------------------------------------------------------------------------
\newif\ifexecutemanote
\newcommand<>{\manote}[1]{%
\ifexecutemanote
\note#2{#1}%
\fi
}
\newcommand<>{\lmanote}[1]{%
\manote#2{#1}%
\global\executemanotetrue
}
\newcommand*{\executemanotes}{\global\executemanotetrue}
\AtBeginEnvironment{align*}{\global\executemanotefalse}
%-------------------------------------------------------------------------------
\begin{document}
\begin{frame}
\begin{align*}
a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
\end{align*}
Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
% \typeout{EEEEEEEEEEEEEEEEEEEE: with note}
\end{frame}
% \typeout{EEEEEEEEEEEEEEEEEEEE: 1. frame end}
\begin{frame}
\begin{align*}
a & = 1 \manote{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
b & = 2 \lmanote{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
\end{align*}
or
\begin{align*}
a & = 1 \manote{This is the third note: \arabic{notecounter}\stepcounter{notecounter}} \\
b & = 2 \manote{This is the fourth note \arabic{notecounter}\stepcounter{notecounter}}
\executemanotes
\end{align*}
Problem \note{This is the fifth note: \arabic{notecounter}\stepcounter{notecounter}}
% \typeout{EEEEEEEEEEEEEEEEEEEE: with tablenote}
\end{frame}
% \typeout{EEEEEEEEEEEEEEEEEEEE: 2. frame end}
\begin{frame}
\begin{tabular}{cc}
a & = 1 \note{This is the first note: \arabic{notecounter}\stepcounter{notecounter}} \\
b & = 2 \note{This is the second note \arabic{notecounter}\stepcounter{notecounter}}
\end{tabular}
Problem \note{This is the third note: \arabic{notecounter}\stepcounter{notecounter}}
% \typeout{EEEEEEEEEEEEEEEEEEEE: with tabular}
\end{frame}
% \typeout{EEEEEEEEEEEEEEEEEEEE: 3. frame end}
\end{document}