我想了解通过“配对定义”和“简单定义”定义环境之间是否存在差异。
考虑
\long\def\begx#1\endx{\dosomething #1\dosomethingelse}
和
\def\begx{\dosomething\bgroup}
\def\endx{\egroup\dosomethingelse}
假设\dosomething
和\dosomethingelse
是任意标记序列。
我知道它们并不等价:事实上,在第一种情况下,参数#1
不包含在组中;而在第二种情况下,\begx
不一定需要\endx
终止,但终止就足够了\egroup
。除了这些差异之外,在定义环境时使用第一种方法比使用第二种方法有什么优势?有时我看到第一种方法,有时我看到第二种方法。但我不明白是什么让一个人选择一种方法而不是另一种方法。
编辑
我只是发现了一点不同:第一个使用之前定义的类别代码捕获参数\begx
。例如,
\def\begx{\bgroup}
\def\endx{\egroup}
\begx
\catcode`\*=\active
\def*{\relax}
\endx
是有效的,但是
\def\begx#1\endx{#1}
\begx
\catcode`\*=\active
\def*{\relax}
\endx
不是。
答案1
在第一种形式中,“环境主体”被选为宏参数,因此在执行命令之前会将整个内容标记化。这解释了 catcode 更改无效的原因。
第二种形式通常与命令前的分组一起使用,相当于 latex 环境形式的定义是
\def\begx{\begingroup\dosomething}
\def\endx{\dosomethingelse\endgroup}
另一个主要区别是嵌套,如果你想
\begx
..
\begx
..
\endx
...
\endx
然后组形式自动通过 tex 分组工作,但分隔参数形式将会中断,外部以\begx
第一个 结尾\endx
。
有时您需要将环境主体作为宏参数,因此需要一个分隔的参数形式,但具有更复杂的定义,用于检查匹配的开始结束对,如果发现不匹配的结束,则重新启动“收集”,这是 ams 对齐、tabularx 等环境或通过 latex 中的 environ 包定义的环境的基础。