将任意环境的主体传递给挂钩命令

将任意环境的主体传递给挂钩命令

我想将一个命令注入到使用环境体作为参数的任意环境中。

期望的行为

\begin{AnyEnvironment}{MandatoryEnvArg}[OptionalEnvArg]
  ...
\end{AnyEnvironment}

应扩大到

\begin{AnyEnvironment}{MandatoryEnvArg}[OptionalEnvArg]
  \MyMacro{...}
\end{AnyEnvironment}

其中...是任意内容(可能包括\pars和其他环境和命令)。

用例

我对这个可能有点奇怪的问题的用例如下:我希望能够使用 来“预处理”环境主体\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 分隔)。但是,我觉得这种方法更有希望。我尝试阅读l3basicsl3quark模块,因为我希望在那里找到答案;例如,\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}

相关内容