为什么投影仪在脆弱框架中寻找 \end{frame} 时不能跳过空白?

为什么投影仪在脆弱框架中寻找 \end{frame} 时不能跳过空白?

我们都知道,在使用脆弱框架时,beamer必须小心确保\end{frame}命令恰好出现在行首。我理解为什么会出现这个问题:环境的内容必须写入文件,因此 Beamer 必须扫描所有内容,直到\end{frame}收集到必须写入的标记。

但是我不明白,也找不到任何地方,为什么\end{frame}标记序列必须正好位于行首。为什么 beamer 在寻找此标记序列时至少不能跳过行首的空格?

我认为 Beamer 无法完成这件看似简单的事情肯定有技术原因。您能总结一下这些原因吗?

答案1

用于查找帧结束的当前测试beamer设置在\beamer@processframeline

  \long\gdef\beamer@processframeline#1^^M{%
    \def\beamer@test{#1}%
    \ifx\beamer@test\beamer@stopframe%
      \let\next=\beamer@framewritten%
    \else%
      \immediate\write\beamer@verbatimfileout{#1}%
      \let\next=\beamer@processframeline%
    \fi%
    \next%
  }%

正如皮特·范奥斯特鲁姆这依赖于抓取的线的性质与“参考”的性质相同(\beamer@stopframe)。

当然,从技术上来说,这是可以解决的,只需付出额外的努力即可。例如,可以使用循环来删除抓取行开头的空格:

\documentclass{beamer}
\makeatletter
{\catcode`\^^M=12\endlinechar=-1%
  \long\gdef\beamer@processframeline#1^^M{%
    \edef\beamer@test{\beamer@spacestrip#1\beamer@stop}%
    \ifx\beamer@test\beamer@stopframe%
      \let\next=\beamer@framewritten%
    \else%
      \immediate\write\beamer@verbatimfileout{#1}%
      \let\next=\beamer@processframeline%
    \fi%
    \next%
  }%
}
\begingroup
\catcode`\ =12\relax%
\gdef\beamer@spacestrip#1{%
\ifx#1\beamer@stop\else%
\ifx#1 \expandafter\expandafter\expandafter\beamer@spacestrip%
\else%
\noexpand#1%
\expandafter\expandafter\expandafter\beamer@strip@end%
\fi%
\fi%
}%
\endgroup%
\def\beamer@strip@end#1\beamer@stop{\unexpanded{#1}}
\def\beamer@stop{\beamer@stop}
\makeatother
\begin{document}

\begin{frame}[fragile]
Hello world
 \end{frame}

\end{document}

(标签也可以被覆盖,但由于它们无法正确粘贴到网站中,所以我省略了该代码。)

目前这被视为问题 #326在 中beamer,并且取决于设计决策(应该和不应该跳过什么)将在下一个版本中修复。


请注意,以上内容确实允许对结束帧进行“嵌套”逐字演示,例如

\newenvironment{slide}
  {\begin{frame}[fragile,environment=slide]}
  {\end{frame}}

\begin{slide}{My title}
  Text.
  \begin{verbatim}
    \end{frame}
  \end{verbatim}
\end{slide}

答案2

Beamer 以脆弱(逐字)模式逐行读取帧。然后检查该行是否恰好是\end{frame},或者\end{xxxx}是否environment=xxxx给出了选项。测试使用简单的 TeX\ifx命令完成。

显然,花费额外的精力在 前面留出额外的空格是不值得的\end

相关内容