
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 \par
mensajes 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, \MyMacro
sería un comando que a su vez invoca un comando Lua \directlua
que 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
AnyEnvironment
puede 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
AnyEnvironment
tiene argumentos. - No funciona si
AnyEnvironment
tiene*
(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>star
y\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;
\bgroup
y\egroup
no 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ódulosl3basics
yl3quark
, ya que tenía la esperanza de poder encontrar una respuesta allí; por ejemplo,\use_none_delimit_by_q_stop:w ... \q_stop
me 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
\BODY
y\Collect@Body
ordena
- Define
xparse
– Un analizador de comandos de documentos genérico- Definiciones
b
y+b
tipos de argumentos.
- Definiciones
amsmath
– Instalaciones matemáticas AMS para LaTeX- Define
\collect@body
el comando
- Define
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}