É possível fazer alguma mágica no TeX para obter um comando \mycmd
que 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 \unskip
o 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 \first
que olhe para frente após seu argumento para ver se uma macro \second
surge 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 csplain
formato:
\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=1
a 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 \phantomcmd
nã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 \pfantomcmd
quais 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 \active
e olhando para frente para ver se \mycmd
os 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}