指令前帶有參數的 TeX 指令

指令前帶有參數的 TeX 指令

\mycmd是否可以使用一些 TeX 魔法來獲取帶有一個參數的命令命令和一然後。所以類似的東西<arg1>\mycmd<arg2>。我試過

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

{foo}\mycmd{bar}

\end{document}

但顯然失敗了。無論如何,我不能說我期望它會起作用。

答案1

這個問題已經從不同的角度進行了研究指令前後是否可以帶有參數?但情況有所不同:要放置在主命令之前或之後的物件本身就是一個巨集。

不可能有一個「向後看」的巨集。 TeX 在巨集擴展之後是嚴格的「先進先出」。此外,它僅在需要為巨集或原語提供參數時才對輸入進行標記。

巨集展開後,僅保留不可展開的標記,它們會依照找到的順序執行並刪除它們。所以在這樣的情況下

{abc}\macro{def}

當檢查時該{abc}部分已經消失。\macro它的痕跡可以保留在某些內部列表中,因此,例如,TeX 能夠執行\unskip一個命令,該命令在執行時從當前列表中刪除最後一個節點,前提是它是粘合的(有一些毛茸茸的細節) ,但這基本上是事實)。

一個命令似乎做你想做的事\over。然而,這不是一個宏,而是一個原語。

它的工作是在內部清單層級執行的:當 TeX 找到 時\over,它會執行它,因為它是不可擴展的。執行過程包括將當前數學清單中的所有內容儲存在一個特殊的位置並繼續。當找到當前數學列表的末尾時,TeX 使用它和儲存的部分來建立一個壓裂原子,頭子列表作為分子,尾子列表作為分母。但在宏觀擴張層面,這一切都沒有發生。

有一個宏\first,在其參數之後向前查看宏是否\second出現,然後就要做什麼做出適當的決定。

即使是LuaTeX 也做不到,除非你修改巨集處理器,因為它可以檢查和管理目前清單中的所有類型的節點,而TeX 的能力則更加有限(只有懲罰、黏合、緊縮和框框,而不是在所有情況下) )。

答案2

您的要求是可能的例如 encTeX。嘗試按格式編譯以下程式碼csplain

\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

\mubytein=1啟動特殊輸入時:在\phantomcmd每次出現的{字元之前插入 。這是在令牌和擴展處理器之前完成的。但有一個例外:如果{緊接在由標記處理器標記的控制序列之後,則\phantomcmd不會插入 。所以這兩個例子都有效:\normalcmd{hello}{foo}\cmd{bar}。第二個內部運作原理如下:

\phantomcmd{foo}\mycmd{bar}

並且可以根據需要進行擴展。但這種技巧非常脆弱,因為每次出現時{都不是緊接在控制序列之後,而是自動前面加上\phantomcmd(when \mybytein=1)。例如這會崩潰:

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

請注意此範例與上一個範例之間的差異:緊接著 後的空格\normalcmd

如果您不害怕這種脆弱性,您可以定義\pfantomcmd哪些進程\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

答案3

在OP發表的評論中,提到該應用程式是在書法信件之前預先確定的引用之一。正如我在評論回覆中所說,如果問題能得到更多限制,也許還有一些希望。例如,如果<arg1>始終(且僅)來自一組有限的 catcode 12 可能性中的單個字形,那麼您可以透過製作這些字形來實現所需的結果\active,並使其向前看是否\mycmd遵循它們。

<arg1>除非其他巨集內部需要這種可能性,否則可以使用這種方法,例如句點.,對於 來說效果不佳<arg1>,因為它經常用於透過小數點指定尺寸。

在MWE中,<arg1>\mycmd<arg2>會印出一個Huge \fbox{<arg1><arg2>}。我僅將其設定為攔截 的雙引號或問號,但可以添加<arg1>其他 catcode 12字形。<arg1>

編輯以忽略具有“非法”值的呼叫<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}

在此輸入影像描述

相關內容