我想为环境创建简单的文本替换宏:
\def \myEnvStart {\begin{someEnvironment}[enormous list of arguments]}
\def \myEnvEnd {\end{someEnvironment}}
这不起作用:
\myEnvStart
stuff
\myEnvEnd
这有效:
\myEnvStart
stuff
\end{someEnvironment}
为什么?是否有可能以某种方式使第一个代码片段发挥作用?
答案1
一般来说,当你处理普通环境,只执行替换其对应项时,这种方法是有效的\begin
。\end
以下是一个例子:
\documentclass{article}
\usepackage[nopar]{lipsum}% Just for this example
\def\myEnvStart{\begin{center}}
\def\myEnvEnd{\end{center}}
\begin{document}
\lipsum[1]
\myEnvStart% \begin{center}
\lipsum[2]% Center this text.
\myEnvEnd% \end{center}
\lipsum[3]
\end{document}
然而,“并非所有环境都是平等的”。有些环境是以特殊方式创建的,这使得它们需要\end{<env>}
明确地查看其对应方。以下是使用环境的示例verbatim
:
\documentclass{article}
\usepackage[nopar]{lipsum}% Just for this example
\def\myEnvStart{\begin{verbatim}}
\def\myEnvEnd{\end{verbatim}}
\begin{document}
\lipsum[1]
\myEnvStart% \begin{verbatim}
\lipsum[2]% Center this text.
\myEnvEnd% \end{verbatim}
\lipsum[3]
\end{document}
当然,用 / 替换 / 会产生所需\myEnvStart
的结果:\myEnvEnd
\begin{verbatim}
\end{verbatim}
从更广泛的意义上讲,有些环境之所以以这种特殊方式编写,是因为它们的作用不仅仅是插入环境的开始/结束替换。它们可能希望捕获整个环境内容,也许是为了允许对内容进行多次处理 -tabularx
这样做,以及align
- 和朋友环境amsmath
。
它可能不一定需要进行多次处理,因为listings
lstlisting
由于类别代码发生变化,因此需要进行相同的处理(类似于我们verbatim
上面的例子)。类别代码需要在环境结束时恢复,为了正确执行此操作,某些环境会在处理之前完全吞噬其内容。
所以答案是“是”,它有效,但仅在某些情况下有效。
当然,下一个问题是是否存在解决这个问题的办法。当然有解决办法……但也只在某些情况下。例如,您可以通过自己抓取“环境”内容,然后再将其传递给“真实环境”,从而摆脱类似宏的界面。以下是第一个例子:
\long\def\myEnvStart#1\myEnvEnd{%
\begin{center}
#1
\end{center}}
宏参数文本现在包含预期的“环境结束代码” \myEnvEnd
,这意味着这#1
将是整个“环境”内容。environ
包裹提供了这种方法,尽管它需要使用\begin
/\end
对。
您不能对verbatim
类似文本(包括lstlisting
)采用上述建议的方法,因为它们会更改类别代码,因此,只能在某些情况下使用。