更新部分命令以在环境中包装整个部分

更新部分命令以在环境中包装整个部分

我正在尝试编写一个 beamer 模板潘多克.为此我需要转换

\section{Text 1}
Some text.

\begin{frame}[fragile]{Text 1}
Some text.
\end{frame}

有没有办法在 LaTeX 中做到这一点,例如使用\renewcommand?我不介意对生成的 LaTeX 文件进行多次解析。

这个问题似乎在寻找类似的解决方案,但我感兴趣的问题并没有真正得到解答。

编辑

对 like的重新定义\section(伪代码)

def \section{$title}:
    static has_preceeding_section = False

    has_preceeding_section = True

    if not has_preceeding_section:
        return \begin{frame}[fragile]{$title}
    else:
        return \end{frame}\begin{frame}[fragile}{$title}

    finally:
        return \end{frame}

对我的用例来说就足够了。如何在 LaTeX 中实现上述伪代码?

答案1

我有一种解决方案,但我不确定它有多强大。在这种特殊情况下,这可能是可以的,因为 LaTeX 文件是从 创建的pandoc,因此输出中不太可能有任何“偷偷摸摸的宏”。特别是,我预计不会有人试图在文档中间更改 catcodes。此外,诸如\section命令和\end{document}命令之类的东西将位于它们自己的行上。

这个想法是,当我们得到一个\section时,我们就开始吞噬行。每次我们得到一个新行时,我们都会测试第一个标记以查看它是\section命令还是一个\end。如果它是\end,我们会测试它是否是\end{document}。如果其中一个(最终)测试为真,那么我们就会停止吞噬行并将我们迄今为止吞噬的内容放入框架中(以部分标题作为框架标题)。如果其中一个为假,那么我们就会返回到吞噬行。

请注意,我们可以通过将其放入脆弱框架中来处理 catcode 内容。

以下是代码,附带示例文档:

\documentclass{beamer}

\makeatletter

\long\def\ge@addto@macro#1#2{%
  \begingroup
  \toks@\expandafter\expandafter\expandafter{\expandafter#1#2}%
  \xdef#1{\the\toks@}%
  \endgroup}

\let\sec@this=\@empty
\def\sec@document{document}

\long\gdef\sec@line#1\par{%
  \g@addto@macro\sec@this{#1\par}%
  \futurelet\sec@next\sec@linestart}%

\def\sec@linestart{%
  \let\sec@do@next=\sec@line
  \ifx\sec@next\section
  \let\sec@do@next=\sec@new
  \else
  \ifx\sec@next\end
  \let\sec@do@next=\sec@test@end
  \fi
  \fi
  \sec@do@next}

\def\sec@new{%
  \def\sec@frame{}%
  \ifx\sec@this\@empty
  \else
  \g@addto@macro\sec@frame{\begin{frame}}%
  \ge@addto@macro\sec@frame\sec@title
  \ge@addto@macro\sec@frame\sec@this
  \g@addto@macro\sec@frame{\par\end{frame}}%
  \fi
  \let\sec@title=\@empty
  \let\sec@this=\@empty
  \sec@frame
  }

\def\sec@test@end\end#1{%
  \def\sec@test{#1}%
  \ifx\sec@test\sec@document
  \message{got here}%
  \let\sec@do@next=\sec@new
  \else
  \let\sec@do@next=\sec@line
  \fi
  \sec@do@next\end{#1}}

\renewcommand{\section}[1]{\message{Called with #1}\def\sec@title{{#1}}\sec@line}

\makeatother

\usepackage{lipsum}

\begin{document}

\section{Introduction}

\lipsum[1]

\section{Main Part}

\lipsum[1]

\section{Main Theorem}

\begin{theorem}[Euclid]
There is no largest prime.
\end{theorem}

\begin{proof}
We start by noting that a number is prime if and only if no prime less than it divides it.

\begin{enumerate}[<+->]
\item Suppose that there were a largest prime.
\item Then the number of primes would be finite; label them (in order) as \(p_1, \dotsc, p_n\).
\item Consider \(q = p_1 \cdot p_2 \cdots p_n + 1\).
\item Then \(p_j \not| q\) so \(q\) is not divisible by any prime less than it.
\item Hence \(q\) is prime.
\item But \(q > p_n\) so \(q\) is not prime.
\end{enumerate}
\end{proof}

\section{Conclusion}

\lipsum[1]

\end{document}

我把theoremproof放进去以表明它适用于非文档端。该lipsum包用于为其他框架提供一些虚拟文本。

请注意,对技术细节感兴趣的人:我查看了和,environbeamer了解如何收集大量“东西”,但两者都是通过收集到下一个 来工作的\end。我们需要能够同时查找\end{document}\section{Section Title}。我看不出有任何方法可以使用相同的机制来做到这一点,所以不得不逐行吞咽。如果有更好的方法,我很想知道。

相关内容