如何在不进行分组的情况下在宏中收集 LaTeX 环境的内容?

如何在不进行分组的情况下在宏中收集 LaTeX 环境的内容?

关于为什么我需要这样做,说来话长,但请耐心听完。我有一个相当复杂的自定义类,它要求文档以命令开头:

\coverandabstract{Abstract text goes here}

这样做的目的是布置一个(一列)封面,基本上是一个自定义的 maketitle,然后切换到第二页具有不同页面尺寸的两列布局,从跨越两列的摘要开始。

现在,我希望能够用 Markdown 起草文档并通过 Pandoc 转换为此类(和其他格式)。表示摘要的最跨格式方式是使用 blockquote,它会转换为 quote 环境。

\begin{quote}
Abstract text goes here
\end{quote}

所以我需要做的是找到一种方法将第一个(也是唯一第一个)引用环境转换为命令\coverandabstract

现在,实现此目的的一种方法是使用 environ 包:

\usepackage{environ}
\let\oldquote=\quote
\let\endoldquote=\endquote
\makeatletter
\renewenvironment{quote}%
  {\Collect@Body\coverandabstract}%
  {\let\quote=\oldquote
   \let\endquote=\endoldquote}
\makeatother

问题在于该类基于回忆录,而更改页面布局意味着使用\checkandfixthelayout。如果在环境中调用,则无法正常工作,可能是分组的结果。这意味着上述技术破坏了文档其余部分的布局。

那么有没有办法将环境的内容传递给命令,而不将其包装在 TeX 组中?

答案1

如果你坚持,environ你可以使用\aftergroup

在此处输入图片描述

\documentclass{article}

\def\coverandabstract#1{\twocolumn[#1]}

\usepackage{environ}
\let\oldquote=\quote
\let\endoldquote=\endquote
\let\quote\relax
\let\endquote\relax

\NewEnviron{quote}%
  {\global\let\tmp\BODY\aftergroup\docoverandabstract}



\def\docoverandabstract{%
  \let\quote=\oldquote
  \let\endquote=\endoldquote
  \coverandabstract{\tmp}}

\begin{document}


\begin{quote}
Abstract text Abstract text Abstract text 
Abstract text Abstract text Abstract text 
Abstract text Abstract text Abstract text 
\end{quote}

\texttt{\meaning\quote}

a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a


\end{document}

答案2

我会说

\let\oldquote\quote
\let\oldendquote\endquote
%% the following to please environ
\let\quote\relax
\let\endquote\relax

\NewEnviron{quote}{%
  \xdef\dolatercoverandabstract{%
    \noexpand\coverandabstract{\unexpanded\expandafter{\BODY}}%
    \unexpanded{\let\quote\oldquote\let\endquote\oldendquote}%
  }\aftergroup\dolatercoverandabstract}

如果没有\unexpanded,新环境的定义quote应该是

\NewEnviron{quote}{%
  \expandafter\gdef\expandafter\dolater\expandafter{%
    \expandafter\coverandabstract\expandafter{\BODY}%
    \let\quote\oldquote\let\endquote\oldendquote
  }\aftergroup\dolater}

答案3

经过大量的思考和失败的实验后,我终于想出了一个可行的办法。

\let\oldquote=\quote
\let\endoldquote=\endquote
\makeatletter
\def\quote#1\end{%
  \end{quote}%
  \coverandabstract{#1}%
  \let\quote=\oldquote
  \let\endquote=\endoldquote
  \@gobble}
\makeatother

前两行保存了引用环境的正常定义。

(重新)定义的作用是使 的效果无效\begin{quote},然后提取\begin{quote}和 之间的所有内容\end(这意味着不在此环境中使用其他环境,但这没问题。)然后它会立即关闭 quote 环境,让我们回到顶层。然后我可以将收集的内容放入命令中\coverandabstract(现在按预期运行),并将 quote 环境恢复为其原始定义。

这只会留下一个多余的{quote}标记供 TeX 解析(来自\end{quote}),所以我用 将其删除\@gobble(因此是\makeatletter\makeatother)。

相关内容