在 beamer 中输入一行“foreach ...”(在文章中效果很好)

在 beamer 中输入一行“foreach ...”(在文章中效果很好)

我有一个问题,可以简单归结为以下几点。

首先,下面的代码可以正常工作:

\documentclass{beamer}

\usepackage{pgffor}

\begin{document}

\foreach \p in {first,second}
{
    \begin{frame}

        \p

    \end{frame}
}

\end{document}

不过,如果我把这一行改一下

\foreach \p in {first,second}

\input{forEachToBeInput.tex}

其中forEachToBeInput.tex是一个包含单行(即“ \foreach \p in {first,second}”,显然)的文件并删除frame环境,然后我开始收到一堆错误,如“ Paragraph ended before pgffor@next was complete”......

请注意,有趣的是,如果我使用文档类 Article,那么一切都很好!

提前谢谢大家!!

答案1

问题在于\input标记后面跟着其他东西,而不是直接跟着{\begin{frame}...\end{frame}}部分。

您可以使用其他答案中建议的可扩展版本来解决问题\input,但还有一种不太复杂的方法:

\begin{filecontents*}{forEachToBeInput.tex}
\foreach \p in {first,second}
\end{filecontents*}

\documentclass{beamer}
\usepackage{pgffor}

\usepackage{catchfile}

\newcommand{\foreachfromfile}[1]{%
  \begingroup
  % load the file contents in \temp
  \CatchFileDef\temp{#1}{}
  \expandafter\endgroup\temp
}

\begin{document}

\foreachfromfile{forEachToBeInput}
  {
    \begin{frame}

        \p

    \end{frame}
  }

\end{document}

由于进行了分组,因此没有\temp留下任何定义。

类似的方法只需要在文件中保存列表而不是\foreach部分内容。

\begin{filecontents*}{forEach.tex}
first,second
\end{filecontents*}

\documentclass{beamer}
\usepackage{pgffor}

\usepackage{catchfile}

\newcommand\foreachfromfile[2]{
  \CatchFileDef\foreachfromfilevariable{#2}{}%
  \foreach #1 in \foreachfromfilevariable
}

\begin{document}

\foreachfromfile\p{forEach}
  {
    \begin{frame}

        \p

    \end{frame}
  }

\end{document}

强制expl3版本:

\begin{filecontents*}{forEach.tex}
first,second
\end{filecontents*}

\documentclass{beamer}
\usepackage{xparse}

\ExplSyntaxOn
\tl_new:N \l__giulio_foreach_tl
\clist_new:N \l__giulio_foreach_clist

\NewDocumentCommand{\foreachfromfile}{m +m}
 {% #1 is the file name, #2 the actions to perform
  \tl_set_from_file:Nnn \l__giulio_foreach_tl { } { #1 }
  % normalize to a clist
  \clist_set:NV \l__giulio_foreach_clist \l__giulio_foreach_tl
  % map the clist
  \clist_map_inline:Nn \l__giulio_foreach_tl { #2 }
 }
\ExplSyntaxOff

\begin{document}

\foreachfromfile{forEach}
  {
    \begin{frame}

        #1

    \end{frame}
  }

\end{document}

如您所见,不需要伪变量。列表中的当前项仅用 表示#1

答案2

尝试这个

\documentclass{beamer}

\usepackage{filecontents}
\begin{filecontents*}{forEachToBeInput.tex}
\foreach \p in {first,second}
\end{filecontents*}

\usepackage{pgffor}

\begin{document}

\csname @@input\endcsname forEachToBeInput.tex
{
    \begin{frame}

        \p

    \end{frame}
}

\end{document}

(该filecontents包仅用于使该答案独立)


(从评论中移出)

您可以通过添加来简化上述操作

\makeatletter\let\xxinput\@@input\makeatother

到序言部分然后使用

\xxinput forEachToBeInput.tex
{
  <etc>

根据解释,宏扩展的踪迹表明,在某个阶段,TeX 将不得不扩展这个

\@addtofilelist {forEachToBeInput.tex}\filehook@atbegin {forEachToBeInput.tex}\@@input forEachToBeInput.tex<space token here>\filehook@atend {forEachToBeInput.tex}

这意味着在某个时候

\foreach \p in {first,second}\filehook@atend {forEachToBeInput.tex}

并且\foreach不喜欢这样。

\filehook@atend不是 LaTeX 内核的一部分,也不是由标准类提供的。

我招募了 Sherlock Holmes,他发现这个宏是由包提供的,filehook该包是由包加载的,sansmathaccent该包是由包加载的beamerbasefont

\ifbeamer@sansmath
  \IfFileExists{sansmathaccent.sty}
    {\RequirePackage{sansmathaccent}}
    {}
\fi

我们sansmathaccent.sty发现:

% Check to see if we are a Beamer document
\@ifpackageloaded{beamerbasefont}{%
    \def\sansmathaccent@warning{}

    % Ensure proper placement of accents with bm
    % but don't waste a mathgroup unless we will in fact use
    % bm and pureletters
    \IfFileExists{filehook.sty}{
        \RequirePackage{filehook}
        \AtBeginOfFile{bm.sty}{     
            \beamer@font@check \ifbeamer@suppressreplacements\else
            \DeclareSymbolFont{pureletters}{OT1}{mathkerncmss}{m}{sl}
            \SetSymbolFont{pureletters}{bold}{OT1}{mathkerncmss}{bx}{sl}
            \fi
        }
    }{
        \DeclareSymbolFont{pureletters}{OT1}{mathkerncmss}{m}{sl}
        \SetSymbolFont{pureletters}{bold}{OT1}{mathkerncmss}{bx}{sl}
        \PackageWarning{sansmathaccent}{Could not find 'filehooks' package: one mathgroup may be wasted}
    }

相关内容