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