Comando TeX com argumento ANTES do comando

Comando TeX com argumento ANTES do comando

É possível fazer alguma mágica no TeX para obter um comando \mycmdque leva um argumentoanteso comando e umapós. Então, algo como <arg1>\mycmd<arg2>. tentei

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

{foo}\mycmd{bar}

\end{document}

mas obviamente falhou. Não posso dizer que esperava que funcionasse, de qualquer maneira.

Responder1

O problema foi examinado sob um ponto de vista diferente emÉ possível um comando com um argumento antes e depois do comando?mas a situação é diferente: o objeto que deveria ser colocado antes ou depois do comando principal é ele próprio uma macro.

Não é possível ter uma macro que “olhe para trás”. TeX é estritamente “primeiro a entrar, primeiro a sair”, após a expansão macro. Além disso, ele tokeniza a entrada somente quando necessário para fornecer argumentos para macros ou primitivas.

Após a expansão da macro, restam apenas tokens não expansíveis e eles são executados na ordem em que são encontrados e removidos. Então, em uma situação como

{abc}\macro{def}

a {abc}peça já desapareceu quando \macroé examinada. Rastros dele podem permanecer em algumas das listas internas, então, por exemplo, o TeX é capaz de executar \unskipo que realmente é um comando que, após a execução, remove o último nó da lista atual, desde que seja cola (há detalhes complicados , mas isso é basicamente a verdade).

Um comando queparecefazer o que você quer é \over. No entanto, esta não é uma macro, mas sim uma primitiva.

Seu trabalho é realizado no nível das listas internas: quando o TeX encontra \over, ele o executa, pois não é expansível. A execução consiste em armazenar o que estiver na lista matemática atual em um local especial e seguir em frente. Quando o final da lista matemática atual é encontrado, o TeX usa ela e a parte armazenada para construir umFraturaátomo com a sublista principal como numerador e a sublista final como denominador. Mas nada disto acontece ao nível da expansão macroeconómica.

Vocêpodetenha uma macro \firstque olhe para frente após seu argumento para ver se uma macro \secondsurge e então tome as decisões apropriadas sobre o que fazer.

Mesmo o LuaTeX não pode fazer isso, a menos que você modifique o processador da macro, porque ele pode examinar e gerenciar todos os tipos de nós na lista atual, enquanto as habilidades do TeX são mais limitadas (apenas penalidades, colas, kerns e caixas e não em todas as situações ).

Responder2

Sua exigênciaé possívelpor exemplo com encTeX. Experimente o seguinte 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

Quando \mubytein=1a entrada especial é ativada: O \phantomcmdé inserido antes de cada ocorrência do {caractere. Isso é feito antes do token e da expansão do processador. Mas há uma exceção: se a {sequência de controle imediatamente seguinte for tokenizada pelo processador de token, então \phantomcmdnão será inserido. Portanto, ambos os exemplos funcionam: \normalcmd{hello}e {foo}\cmd{bar}. O segundo funciona internamente como:

\phantomcmd{foo}\mycmd{bar}

e isso é expandido conforme desejado. Mas esta técnica é muito frágil, porque cada ocorrência que {não ocorre imediatamente após a sequência de controle é automaticamente precedida por \phantomcmd(quando \mybytein=1). Por exemplo, isso trava:

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

Observe a diferença entre este e o exemplo anterior: o espaço imediatamente após \normalcmd.

Se você não tem medo dessa fragilidade, pode definir \pfantomcmdquais processos são os diversos \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

Responder3

Em comentário do OP, foi mencionado que a aplicação era de citações pré-determinadas anteriores a uma carta caligráfica. Como eu disse na minha resposta ao comentário, talvez haja alguma esperança se o problema puder ser mais restrito. Por exemplo, se <arg1>é sempre (e apenas) um único glifo de um conjunto limitado de possibilidades de catcode 12, então você pode alcançar o resultado desejado criando esses glifos \activee olhando para frente para ver se \mycmdos segue ou não.

Esta abordagem poderia ser usada a menos que as <arg1>possibilidades fossem necessárias dentro de outras macros, como o período, .por exemplo, não funcionaria bem para <arg1>, uma vez que é frequentemente usada para especificar dimensões através de um ponto decimal.

No MWE, <arg1>\mycmd<arg2>imprimirá um Huge \fbox{<arg1><arg2>}. Eu o configurei apenas para interceptar aspas duplas ou um ponto de interrogação para <arg1>, embora outros <arg1>glifos do catcode 12 possam ser adicionados.

EDITADO para ignorar chamadas com valores "ilegais" 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}

insira a descrição da imagem aqui

informação relacionada