TeX-Befehl mit Argument VOR dem Befehl

TeX-Befehl mit Argument VOR dem Befehl

Ist es möglich, mit etwas TeX-Magie einen Befehl zu erhalten \mycmd, der ein Argument akzeptiert?Vorder Befehl und einenachher. Also so etwas wie <arg1>\mycmd<arg2>. Ich habe es versucht

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

{foo}\mycmd{bar}

\end{document}

aber offensichtlich fehlgeschlagen. Ich kann jedenfalls nicht sagen, dass ich erwartet hätte, dass es funktionieren würde.

Antwort1

Das Problem wurde unter einem anderen Gesichtspunkt untersucht inIst ein Befehl mit einem Argument vor und nach dem Befehl möglich?Die Situation ist jedoch anders: Das Objekt, das vor oder nach dem Hauptbefehl platziert werden sollte, ist selbst ein Makro.

Es ist nicht möglich, ein Makro zu haben, das „rückwärts schaut“. TeX ist nach der Makroerweiterung strikt „First In, First Out“. Darüber hinaus tokenisiert es die Eingabe nur, wenn sie für die Bereitstellung von Argumenten für Makros oder Primitive erforderlich ist.

Nach der Makroerweiterung bleiben nur nicht erweiterbare Token übrig und diese werden in der Reihenfolge ausgeführt, in der sie gefunden werden, und entfernt sie. In einer Situation wie

{abc}\macro{def}

der {abc}Teil ist bereits verschwunden, wenn \macrountersucht wird. Spuren davon können in einigen der internen Listen verbleiben, so dass TeX beispielsweise ausführen kann, \unskipwas tatsächlich ein Befehl ist, der bei der Ausführung den letzten Knoten aus der aktuellen Liste entfernt, vorausgesetzt, es handelt sich um einen Kleber (es gibt haarige Details, aber das ist im Grunde die Wahrheit).

Ein Befehl, derscheintzu tun, was Sie wollen, ist \over. Dies ist jedoch kein Makro, sondern ein Primitiv.

Seine Arbeit wird auf der Ebene der internen Listen ausgeführt: Wenn TeX findet \over, führt es es aus, da es nicht erweiterbar ist. Die Ausführung besteht darin, alles, was in der aktuellen mathematischen Liste steht, an einem speziellen Ort zu speichern und weiterzumachen. Wenn das Ende der aktuellen mathematischen Liste gefunden wird, verwendet TeX es und den gespeicherten Teil, um einFracAtom mit der Kopf-Unterliste als Zähler und der Schwanz-Unterliste als Nenner. Aber nichts davon passiert auf der Ebene der Makroerweiterung.

DudürfenHaben Sie ein Makro \first, das nach seinem Argument vorausschaut, um zu sehen, ob ein Makro \secondvorbeikommt, und treffen Sie dann entsprechende Entscheidungen darüber, was zu tun ist.

Sogar LuaTeX kann dies nicht, es sei denn, Sie ändern den Makroprozessor, weil es alle Knotentypen in der aktuellen Liste untersuchen und verwalten kann, während die Fähigkeiten von TeX eingeschränkter sind (nur Strafen, Kleber, Kerns und Boxen und nicht in jeder Situation).

Antwort2

Ihr Bedarfist möglichzum Beispiel mit encTeX. Versuchen Sie den folgenden nach csplainFormat kompilierten Code:

\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

Wenn \mubytein=1die spezielle Eingabe aktiviert ist: Das \phantomcmdwird vor jedem Vorkommen des {Zeichens eingefügt. Dies geschieht vor dem Token- und Expand-Prozessor. Es gibt jedoch eine Ausnahme: Wenn das {unmittelbar nach der vom Token-Prozessor tokenisierten Steuersequenz folgt, \phantomcmdwird das nicht eingefügt. Daher funktionieren beide Beispiele: \normalcmd{hello}und {foo}\cmd{bar}. Das zweite funktioniert intern wie folgt:

\phantomcmd{foo}\mycmd{bar}

und dies wird nach Wunsch erweitert. Diese Technik ist jedoch sehr fragil, da jedem Vorkommen von {which nicht unmittelbar nach der Steuersequenz automatisch \phantomcmd(when \mybytein=1) vorangestellt wird. Dies stürzt beispielsweise ab:

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

Beachten Sie den Unterschied zwischen diesem und dem vorherigen Beispiel: das Leerzeichen unmittelbar nach \normalcmd.

Wenn Sie sich von dieser Fragilität nicht abschrecken lassen, können Sie definieren, \pfantomcmdwelche Prozesse die verschiedenen \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

Antwort3

In einem Kommentar des OP wurde erwähnt, dass es sich bei der Anwendung um die Vorgabe von Anführungszeichen vor einem kalligraphischen Buchstaben handelte. Wie ich in meiner Antwort auf den Kommentar sagte, besteht vielleicht Hoffnung, wenn das Problem stärker eingegrenzt werden kann. Wenn beispielsweise <arg1>immer (und nur) ein einzelnes Glyph aus einer begrenzten Anzahl von Catcode-12-Möglichkeiten ist, können Sie Ihr gewünschtes Ergebnis erzielen, indem Sie diese Glyphen erstellen \activeund vorausschauen lassen, um zu sehen, ob \mycmdihnen folgt oder nicht.

Dieser Ansatz kann verwendet werden, sofern die <arg1>Möglichkeiten nicht innerhalb anderer Makros benötigt werden. Der Punkt .beispielsweise würde für nicht gut funktionieren <arg1>, da er häufig verwendet wird, um Abmessungen über einen Dezimalpunkt anzugeben.

Im MWE <arg1>\mycmd<arg2>wird ein riesiges ausgegeben \fbox{<arg1><arg2>}. Ich habe es nur so eingerichtet, dass ein doppeltes Anführungszeichen oder ein Fragezeichen für abgefangen wird <arg1>, obwohl andere Catcode-12- <arg1>Glyphen hinzugefügt werden könnten.

BEARBEITET, um Anrufe mit „ungültigen“ Werten zu ignorieren <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}

Bildbeschreibung hier eingeben

verwandte Informationen