Passe o corpo do ambiente arbitrário para o comando viciado

Passe o corpo do ambiente arbitrário para o comando viciado

Gostaria de injetar um comando em um ambiente arbitrário que use o corpo do ambiente como argumento.

Comportamento desejado

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

Deveria expandir para

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

Onde ...estão conteúdos arbitrários (possivelmente incluindo \parprogramas e outros ambientes e comandos).

Caso de uso

Meu caso de uso para esta pergunta talvez estranha é o seguinte: quero ser capaz de "pré-processar" o corpo do ambiente com \MyMacro. Em particular, \MyMacroseria um comando que invoca um comando Lua \directluaque receberia o corpo do ambiente como uma string e realizaria alguma manipulação de string nele antes de colocá-lo de volta no fluxo de entrada do TeX. Como exemplo básico:

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

Ainda mais especificamente, tudo isso começou porque eu estava curioso para saber se poderia implementar suporte para sintaxes "abreviadas" (como a usada emtypst, um programa de composição tipo LaTeX) em modo matemático. Meus experimentos básicos produziram resultados surpreendentemente bons, então fiquei curioso para saber até onde poderia levar esse tipo de funcionalidade no LaTeX, daí a generalidade da minha pergunta.

Requisitos

  • AnyEnvironmentpode ser qualquer ambiente LaTeX viável. Em particular, pode:
    • Seja definido pelo usuário.
    • Ser definido por pacotes externos.
    • Esteja dentro do modo matemático (por exemplo, aligned) ou ative o próprio modo matemático (por exemplo, align).
    • Tenha qualquer tipo de argumento.
    • Pode conter asteriscos ( *) ou travessões ( -) em seu nome.
    • Contém conteúdo textual e/ou alterações de código de gato— Parece que apoiar isso seria muito difícil (conforme comentários a esta pergunta).

Abordagens

Redefinindo o ambiente

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

Problemas:

  • Não funciona se AnyEnvironmenttiver argumentos
  • Não funciona se AnyEnvironmenttiver *(asterisco) ou -(traço) em seu nome (embora isso possa ser facilmente corrigível, vi ambientes marcados com estrela serem referidos por \<env>stare \end<env>stare talvez haja algo semelhante para travessões).

Com ganchos

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

Problemas:

  • Não funciona; \bgroupe \egroupnão são a coisa certa para usar para esse propósito (veja tambémArgumentos possivelmente delimitados por \bgroup e \egroup). No entanto, essa abordagem parece mais promissora para mim. Tentei ler os módulos l3basicse l3quark, pois tinha esperança de encontrar uma resposta lá; por exemplo, \use_none_delimit_by_q_stop:w ... \q_stopme fez pensar que talvez algo semelhante pudesse ser usado para coletar o corpo do ambiente. Porém, ainda não consegui encontrar uma solução.

Perguntas relacionadas:

Pacotes relacionados:

  • environ– Uma nova interface para ambientes em LaTeX
    • Define \BODYe \Collect@Bodycomanda
  • xparse– Um analisador de comando de documento genérico
    • Define be +btipos de argumentos
  • amsmath– Instalações matemáticas AMS para LaTeX
    • Define \collect@bodyo comando

Exemplo básico não funcional:

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

informação relacionada