我想将一个命令注入到使用环境体作为参数的任意环境中。
期望的行为
\begin{AnyEnvironment}{MandatoryEnvArg}[OptionalEnvArg]
...
\end{AnyEnvironment}
应扩大到
\begin{AnyEnvironment}{MandatoryEnvArg}[OptionalEnvArg]
\MyMacro{...}
\end{AnyEnvironment}
其中...
是任意内容(可能包括\par
s和其他环境和命令)。
用例
我对这个可能有点奇怪的问题的用例如下:我希望能够使用 来“预处理”环境主体\MyMacro
。具体来说,\MyMacro
将是一个命令,它本身会调用一个 Lua 命令,该命令\directlua
将以字符串形式接收环境主体并对其进行一些字符串操作,然后再将其放回 TeX 的输入流中。作为一个基本示例:
\NewDocumentCommand{\MyMacro}{m}
{
\directlua
{
local str = "\luaescapestring{\unexpanded{#1}}"
tex.sprint(str .. ' ~ ' .. str)
}
}
更具体地说,这一切的开始是因为我很好奇我是否可以实现对“简写”语法的支持(例如在typst
(一个类似 LaTeX 的排版程序)的数学模式。我的基本实验产生了令人惊讶的好结果,所以我很好奇我可以在 LaTeX 中实现这种功能到什么程度,因此我的问题具有普遍性。
要求
AnyEnvironment
可以是任何可行的 LaTeX 环境。具体来说,它可以:- 由用户定义。
- 由外部包定义。
- 处于数学模式内(例如
aligned
),或激活数学模式本身(例如align
)。 - 有任何种类的争论。
- 其名称中可能有星号 (
*
) 或破折号 ( )。-
- 包含 verbatin 内容和/或 catcode 更改— 看来支持这一点会非常困难(根据对这个问题的评论)。
方法
重新定义环境
\let\oldAnyEnvironment\AnyEnvironment
\let\endoldAnyEnvironment\endAnyEnvironment
\RenewDocumentEnvironment{AnyEnvironment}{+b}
{\oldAnyEnvironment\MyMacro{#1}}{\endoldAnyEnvironment}
问题:
AnyEnvironment
如果有参数则不起作用AnyEnvironment
如果名称中包含*
(星号)或(破折号) ,则不起作用-
(尽管这可能很容易修复,我见过带星号的环境被用和来引用\<env>star
,\end<env>star
也许破折号也有类似的符号)。
带挂钩
\ExplSyntaxOn
\NewDocumentCommand { \MyMacro } { m } { Argument:~#1. }
\AtBeginEnvironment { AnyEnvironment } { \MyMacro \bgroup }
\AtEndEnvironment { AnyEnvironment } { \egroup }
\ExplSyntaxOff
问题:
- 不起作用;
\bgroup
并且\egroup
不适合用于此目的(另见参数可能由 \bgroup 和 \egroup 分隔)。但是,我觉得这种方法更有希望。我尝试阅读l3basics
和l3quark
模块,因为我希望在那里找到答案;例如,\use_none_delimit_by_q_stop:w ... \q_stop
让我想到也许可以使用类似的东西来收集环境体。但是,我还没有找到解决方案。
相关问题:
相关包:
environ
– LaTeX 环境的新界面- 定义
\BODY
和\Collect@Body
命令
- 定义
xparse
– 通用文档命令解析器- 定义
b
和+b
参数类型
- 定义
amsmath
– 适用于 LaTeX 的 AMS 数学工具- 定义
\collect@body
命令
- 定义
基本非工作示例:
\documentclass{article}
\ExplSyntaxOn
\makeatletter
\NewDocumentEnvironment { AnyEnvironment } {} {} {}
\NewDocumentCommand { \MyMacro } { m } { Contents: ~ #1. }
\AtBeginEnvironment { AnyEnvironment } { \MyMacro \bgroup }
\AtEndEnvironment { AnyEnvironment } { \egroup }
\makeatother
\ExplSyntaxOff
\begin{document}
\begin{AnyEnvironment}
Example.
\end{AnyEnvironment}
\end{document}