Comando TeX con argumento ANTES del comando

Comando TeX con argumento ANTES del comando

¿Es posible hacer algo de magia TeX para obtener un comando \mycmdque requiera un argumento?antesel comando y unodespués. Entonces algo así como <arg1>\mycmd<arg2>. Lo intenté

\documentclass{memoir}
\def#1\mycmd#2{Hello World of #1 and #2}
\begon{document}

{foo}\mycmd{bar}

\end{document}

pero obviamente falló. De todos modos, no puedo decir que esperaba que funcionara.

Respuesta1

El problema ha sido examinado desde un punto de vista diferente en¿Es posible un comando con un argumento antes y después del comando?pero la situación es diferente: el objeto que se iba a colocar antes o después del comando principal es en sí mismo una macro.

No es posible tener una macro que “mira hacia atrás”. TeX es estrictamente “el primero en entrar, el primero en salir”, después de la macroexpansión. Además, tokeniza la entrada sólo cuando es necesario para proporcionar argumentos a macros o primitivas.

Después de la macro expansión, solo quedan tokens no expandibles y se ejecutan en el orden en que se encuentran y se eliminan. Entonces en una situación como

{abc}\macro{def}

la {abc}pieza ya no está cuando \macrose examina. Su rastro puede quedar en algunas de las listas internas, así, por ejemplo, TeX es capaz de ejecutar \unskiplo que en realidad es un comando que, al ejecutarse, elimina el último nodo de la lista actual, siempre que esté pegado (hay detalles complicados). , pero esto es básicamente la verdad).

Un comando queparecehacer lo que quieres es \over. Sin embargo, esto no es una macro, sino una primitiva.

Su trabajo se realiza a nivel de las listas internas: cuando TeX encuentra \over, lo ejecuta, porque no es expandible. La ejecución consiste en almacenar lo que esté en la lista matemática actual en un lugar especial y continuar. Cuando se encuentra el final de la lista matemática actual, TeX lo usa y la parte almacenada para construir unafracturaátomo con la sublista principal como numerador y la sublista final como denominador. Pero nada de esto sucede a nivel de expansión macroeconómica.

podertener una macro \firstque mira hacia adelante después de su argumento para ver si \secondaparece una macro y luego tomar las decisiones apropiadas sobre qué hacer.

Incluso LuaTeX no puede hacerlo, a menos que modifique el macroprocesador, porque puede examinar y administrar todos los tipos de nodos en la lista actual, mientras que las capacidades de TeX son más limitadas (solo penalizaciones, pegamentos, kerns y cajas y no en todas las situaciones). ).

Respuesta2

Su requisitoes posiblepor ejemplo con encTeX. Pruebe el siguiente código compilado por csplainformato:

\mubyte \phantomcmd #1 {\endmubyte

\mubytein=0
\def\phantomcmd#1\mycmd#2{1=#1, 2=#2}
\def\mycmd{my}
\def\normalcmd#1{normal=#1}

\mubytein=1

\normalcmd{hello}    % gives: normal=hello 
...{foo}\mycmd{bar}  % gives: ...1=foo, 2=bar

\bye

Cuando \mubytein=1se activa la entrada especial: \phantomcmdse inserta antes de cada aparición del {carácter. Esto se hace antes del token y del procesador expandido. Pero hay una excepción: si la {secuencia de control sigue inmediatamente a la tokenizada por el procesador de tokens, entonces \phantomcmdno se inserta. Entonces ambos ejemplos funcionan: \normalcmd{hello}y {foo}\cmd{bar}. El segundo funciona internamente como:

\phantomcmd{foo}\mycmd{bar}

y esto se amplía según se desee. Pero esta técnica es muy frágil, porque cada aparición que {no ocurre inmediatamente después de la secuencia de control, está precedida automáticamente por \phantomcmd(cuando \mybytein=1). Por ejemplo, esto falla:

\normalcmd {hello}   % this is transformed to \normalcmd\phantomcmd{hello}
bb {foo}\mycmd{bar}  % 

Note la diferencia entre este y el ejemplo anterior: el espacio inmediatamente después \normalcmd.

Si no temes esta fragilidad, puedes definir \pfantomcmdqué procesos se realizan entre los distintos \mycmds:

\mubyte \phantomcmd #1 {\endmubyte
\mubytein=0
\def\phantomcmd#1{\def\tmp{#1}}
\def\mycmdA#1{I am A. before: \tmp, after: #1}
\def\mycmdB#1{I am B. before: \tmp, after: #1}
\mubytein=1
... {a}\mycmdA{b} ... {x}\mycmdB{y}
\bye

Respuesta3

En un comentario realizado por el OP, se mencionó que la aplicación era una de citas predeterminadas previas a una letra caligráfica. Como dije en la respuesta de mi comentario, tal vez haya alguna esperanza si el problema puede limitarse más. Por ejemplo, si <arg1>siempre (y solo) hay un solo glifo de un conjunto limitado de 12 posibilidades de catcode, entonces podría lograr el resultado deseado creando esos glifos \activey hacer que mire hacia adelante para ver si \mycmdlos sigue o no.

Este enfoque podría usarse a menos que <arg1>se necesitaran las posibilidades dentro de otras macros, como el período, .por ejemplo, no funcionaría bien <arg1>, ya que se usa frecuentemente para especificar dimensiones mediante un punto decimal.

En el MWE, <arg1>\mycmd<arg2>se imprimirá un enorme \fbox{<arg1><arg2>}. Solo lo tengo configurado para interceptar una comilla doble o un signo de interrogación , aunque se podrían agregar <arg1>otros glifos catcode 12 .<arg1>

EDITADO para ignorar llamadas con valores "ilegales" de <arg1>.

\documentclass{article}
\let\precommand\relax
\let\mycmd\relax
\def\testnext#1#2{\ifx#1\mycmd\myactualcmd\precommand{#2}\else\precommand#1#2\fi}
\def\myactualcmd#1#2{\if#1\precommand\fbox{\Huge#1#2}\else#1#2\fi}
\let\svquote"
\catcode`"=\active
\def"{\let\precommand\svquote\testnext}
\let\svqmark?
\catcode`?=\active
\def?{\let\precommand\svqmark\testnext}

\begin{document}
Is this is a "test"\textbf{?}  This is a "\mycmd{BIG} test?\mycmd{!}

Here mycmd is used with illegal precommand =\mycmd{which} is ignored.
\end{document}

ingrese la descripción de la imagen aquí

información relacionada