我突然意识到,括号中的标题beamer
是可选的!请帮我理解这一点。通常,可选参数用方括号提供。正如我在 MWE 的幻灯片 1 中展示的那样,可选参数可能很挑剔,如果可选参数本身包含可选[]
数据,就会搞砸。(请注意,在 MWE 中,\xyz
是一个忽略其可选参数并仅输出强制参数的宏。)
beamerframe
标题不会遇到这些问题,并且可以处理包含[]
选项的参数。
然而,当frame
省略了包含标题时,如我的 MWE 幻灯片 2 所示,后面的文本首字母frame
不会被视为 1 个字母的标题。因此frame
能够区分包含标题{title}
和generic slide text
。本质上,标题上的括号充当可选参数分隔符。
在我的 MWE 的第 3 张幻灯片中,我给出了\meaning
,这可能有助于解开如何使用花括号项目作为可选参数的\frame
谜团。beamer
我是否遗漏了一些简单的东西?请帮助我了解这是如何工作的。
\documentclass{beamer}
\usepackage[T1]{fontenc}
\newcommand\xyz[2][]{#2}
\begin{document}
\begin{frame}{title is in braces, but optional! \xyz[\xyz{DOES~NOT}]{WORKS}}
Here is text after title.
Optional arguments can be tricky. For example,
take \textbackslash xyz macro:
.\xyz{WORKS with no optional argument}.
.\xyz[\xyz{DOES~NOT}]{WORKS with optional argument}.
.\xyz[\xyz[ignoreme]{DOES~NOT}]{WORK when optional argument has []}.
\bigskip
The problem is an optional argument within an optional argument.
But that problem did not apply to the title (where an optional argument
was processed).
\end{frame}
\begin{frame}
Here is text after no title is specified.
Note that the ``H'' was not taken as a title,
implying that the title, within braces, is optional.
\bigskip
\textbf{How does this work?!}
The title is an optional argument in curly braces,
not square brackets. It can process optional arguments within the title.
\end{frame}
\begin{frame}
Help me to understand this, if this is where the magic is:
\bigskip
\meaning\frame
\end{frame}
\end{document}
答案1
归根结底,这是一个设计决定。要了解发生了什么,我们需要了解技术细节。
当 Leslie Lamport 编写 LaTeX 时,他认为对于用户来说,区分可选参数和强制参数是一件“好事”。他通过使用{
...}
对表示强制参数,使用[
...]
对表示可选参数来实现这一点。但是,其他编写 LaTeX 代码的人可以使用其他约定。
在 LaTeX 中,字符[
和]
的 TeX 类别代码为“其他”。与 和 相对{
,}
它们分别是“开始组”和“结束组”。TeX 在抓取{
...内部的参数}
(LaTeX 强制参数)时会进行括号匹配,因为“开始”/“结束”组标记的规则很明确:它们必须平衡。另一方面,TeX 不会对[
...执行此]
操作,因为它们只是“其他”标记。LaTeX2e 使用一些前瞻代码(查找[
)和所谓的分隔参数来实现可选参数
\def\foo[#1]{% Code here
当 TeX 以这种方式查找被标记包围的参数时,它会以“懒惰”的方式进行。因此
\foo[[bar]]
[bar
将抓住#1
并留下第二个]
“悬垂”。
可以添加额外的代码来匹配[
...]
标记:xparse
这样做。当 LaTeX2e 发布时,“成本”(代码行)太高,不切实际,但现在完全可以接受。因此,使用生成的命令xparse
不会出现嵌套方括号的问题。
在这种beamer
情况下,Till Tantau 使用了一些前瞻代码,{
而不是[
。这样做稍微有点棘手,但如果命令不需要“可扩展”,那么它是相当可行的。逐字幻灯片存在一些小问题(前瞻有点麻烦!),但除此之外,不喜欢 Till 方法的原因是,阅读代码时根本不清楚需要哪些参数。
答案2
这只是一个提示,但在基本 LaTeX 中,使用同一种括号表示不同含义的机制是众所周知的。在
\begin{picture}(a,b)(c,d)
(a,b)
是强制的,(c,d)
是可选的。诀窍如下:
\long\gdef\picture#1{\pictur@#1}
\gdef\pictur@(#1){%
\@ifnextchar({\@picture(#1)}{\@picture(#1)(0,0)}}
中的构造beamerbaseframe.sty
类似:
\def\beamer@checkframetitle{\@ifnextchar\bgroup\beamer@inlineframetitle{}}
\def\beamer@inlineframetitle#1{%
\@ifnextchar\bgroup{\frametitle{#1}\framesubtitle}{\frametitle{#1}\relax}%
但(
被 取代\bgroup
。