Pasar el cuerpo de un entorno arbitrario al comando enganchado

Pasar el cuerpo de un entorno arbitrario al comando enganchado

Me gustaría inyectar un comando en un entorno arbitrario que utilice el cuerpo del entorno como argumento.

Comportamiento deseado

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

Debería expandirse a

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

¿Dónde ...hay contenidos arbitrarios (posiblemente incluidos \parmensajes de correo electrónico y otros entornos y comandos)?

Caso de uso

Mi caso de uso para esta pregunta quizás extraña es el siguiente: quiero poder "preprocesar" el cuerpo del entorno con \MyMacro. En particular, \MyMacrosería un comando que a su vez invoca un comando Lua \directluaque recibiría el cuerpo del entorno como una cadena y realizaría alguna manipulación de la cadena antes de volver a colocarlo en el flujo de entrada de TeX. Como ejemplo básico:

\NewDocumentCommand{\MyMacro}{m}
  {
    \directlua
      {
        local str = "\luaescapestring{\unexpanded{#1}}"
        tex.sprint(str .. ' ~ ' .. str)
      }
  }

Aún más específicamente, todo esto comenzó porque tenía curiosidad por saber si podría implementar soporte para sintaxis "taquigráficas" (como la que se usa entypst, un programa de composición tipográfica similar a LaTeX) en modo matemático. Mis experimentos básicos arrojaron resultados sorprendentemente buenos, por lo que sentí curiosidad por saber hasta dónde podía llevar este tipo de funcionalidad en LaTeX, de ahí la generalidad de mi pregunta.

Requisitos

  • AnyEnvironmentpuede ser cualquier entorno LaTeX factible. En particular, podrá:
    • Ser definido por el usuario.
    • Estar definido por paquetes externos.
    • Estar dentro del modo matemático (por ejemplo, aligned) o activar el modo matemático en sí (por ejemplo, align).
    • Tener cualquier tipo de argumentos.
    • Puede tener asteriscos ( *) o guiones ( -) en su nombre.
    • Contener contenido literal y/o cambios de código cat.- Parece que apoyar esto sería muy difícil (según los comentarios a esta pregunta).

Enfoques

Redefiniendo el entorno

\let\oldAnyEnvironment\AnyEnvironment
\let\endoldAnyEnvironment\endAnyEnvironment
\RenewDocumentEnvironment{AnyEnvironment}{+b}
  {\oldAnyEnvironment\MyMacro{#1}}{\endoldAnyEnvironment}

Asuntos:

  • No funciona si AnyEnvironmenttiene argumentos.
  • No funciona si AnyEnvironmenttiene *(asterisco) o -(guión) en su nombre (aunque esto podría solucionarse fácilmente, he visto entornos destacados a los que se hace referencia con \<env>stary \end<env>star, y tal vez haya algo similar para los guiones).

Con ganchos

\ExplSyntaxOn
\NewDocumentCommand { \MyMacro } { m } { Argument:~#1. }
\AtBeginEnvironment { AnyEnvironment } { \MyMacro \bgroup }
\AtEndEnvironment   { AnyEnvironment } { \egroup }
\ExplSyntaxOff

Asuntos:

  • No funciona; \bgroupy \egroupno son lo correcto para este propósito (consulte tambiénArgumentos posiblemente delimitados por \bgroup y \egroup). Sin embargo, este enfoque me parece más prometedor. Intenté leer los módulos l3basicsy l3quark, ya que tenía la esperanza de poder encontrar una respuesta allí; por ejemplo, \use_none_delimit_by_q_stop:w ... \q_stopme hizo pensar que tal vez se podría usar algo similar para recolectar el cuerpo ambiental. Sin embargo, todavía no logré encontrar una solución.

Preguntas relacionadas:

Paquetes relacionados:

  • environ– Una nueva interfaz para entornos en LaTeX
    • Define \BODYy \Collect@Bodyordena
  • xparse– Un analizador de comandos de documentos genérico
    • Definiciones by +btipos de argumentos.
  • amsmath– Instalaciones matemáticas AMS para LaTeX
    • Define \collect@bodyel comando

Ejemplo básico que no funciona:

\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}

información relacionada