脆弱的 \end{frame} 破壞投影機後的評論

脆弱的 \end{frame} 破壞投影機後的評論

今天我花了比我願意承認的更多的時間來被程式碼中的註解打敗...

我試圖在簡報中逐字插入一些內容,但收到此錯誤:

Runaway argument?
! File ended while scanning use of \next.

然後,將整個事情簡化為 MWE,我得到了:

\documentclass{beamer}

\begin{document}

\begin{frame}[fragile]
Hello :)
\end{frame}% NO :(

\end{document}

並且錯誤仍然存在。

然後,當我在整個事情成功後刪除評論時\end{frame}

有人能解釋一下這裡發生了什麼事嗎?


免責聲明:不,我不需要那裡的評論:P

答案1

在深入研究了beamer的內部結構之後,我發現答案是,正如egreg 指出的那樣,逐字處理器。

對於[fragile]幀,beamer使用其逐字處理器,位於beamerbaseverbatim.sty. Beamer 有一個簡潔的逐字處理器:

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

處理器是一個定界宏,它將讀取回車符(換行符)之前的所有內容。讀取的內容儲存在其中\beamer@test並與其進行比較\beamer@stopframe,大多數情況下定義為:

\xdef\beamer@stopframe{\string\\end\string\{frame\string\}}

它擴展為確切的字串\ e n d { f r a m e }

處理器比較\beamer@test\beamer@stopframe如果不同,則將 的內容\beamer@test寫入\beamer@verbatimfileout(.vrb 檔案),\next巨集將\let成為處理器,並遞歸呼叫自身繼續讀取。否則,如果\beamer@test是 string \end{frame},則處理器正常退出。

發生錯誤的原因是處理器不會忽略註釋(在逐字上下文中可能需要它們!),因此處理器\end{frame}與進行比較\end{frame}% NO :(,這顯然會失敗,並繼續讀取過去的內容\end{frame}

現在可能發生兩件事:

首先,這是最後一幀,因此處理器永遠不會找到匹配\end{frame},並且! File ended while scanning use of \next.會出現錯誤並且編譯停止。

其次,更痛苦的是,還有另一個框架,其中將包含處理器正在尋找的機器人 \end{frame}。但在本例中,\next將是\letto \beamer@framewritten,它本質上是將 .vrb 檔案的內容讀回框架。但內容會是這樣的:

Hello :)
\end{frame}% NO :(
\begin{frame}
Hello again!

這會讓事情變得瘋狂:)

長話短說

孩子請記住,使用[fragile]框架時,\end{frame} 必須成為僅有的行中的事情。不允許前導空格和註釋(尾隨空格被 TeX 吞噬)。

正如 samcarter 在她的評論中指出的那樣,Beamer 的當前版本允許領先尾隨空格和製表符。\beamer@strip@whitespace在與 比較之前,巨集將吃掉空格和製表符\beamer@stopframe

相關內容