
在這答案egreg使用了宏\DeclareTextSymbol
,\DeclareTextCommandDefault
而\UndeclareTextCommand
我之前(但沒有成功)嘗試過簡單的\newcommand
或\let
。
有人可以詳細說明這些命令的正確使用以及與標準的差異等\newcommand
嗎?
答案1
某些命令能夠根據目前的輸出編碼選擇其操作。
最簡單的例子就是重音。人們希望\"
當輸出編碼(可用字形與其在字體中的位置之間的對應關係)為 OT1 或 T1 時表現有所不同。
在第一種情況下,\"u
將由重音符號和字元組成輸出,使用 T1 它將直接排版預組合字元(當考慮連字符時,這種差異非常重要)。
\DeclareTextSymbol
因此,可以使用或類似的函數來定義命令,而不是維護命令列表來在切換編碼時更改定義。
我們來看一下\textborn
。它在基礎 LaTeX 中未定義,但textcomp
提供了它的定義:
% textcomp.sty, line 225
\DeclareTextCommandDefault{\textborn}{\tc@check@symbol2\textborn}
知道替換文字應該做什麼並不重要,但這定義\textborn
為
\?-cmd \textborn \?\textborn
(三個標記,最後一個是單個標記,其擴展是上面的替換文本\tc@check@symbol2\textborn
,可以透過執行存取\csname ?\string\textborn\endcsname
)。
ts1enc.def
稍後載入時,因為textcomp.sty
隱式呼叫\usepackage[TS1]{inputenc}
),LaTeX 會發現
\DeclareTextSymbol{\textborn}{TS1}{98}
這將執行與之前類似的技巧,定義\textborn
為
\TS1-cmd \textborn \TS1\textborn
(又是三個標記)。這是最重要的部分。像這樣的命令是如何運作的?
在擴充 時\textborn
,如果 LaTeX 位於需要排版字元的位置,則會根據 TS1 檢查目前輸出編碼。如果是,則僅使用目前字體的字形編號 98;否則開啟一個群組,將編碼切換為 TS1,排版字元 98 並關閉該群組。
這樣的命令始終是健壯的,這意味著如果在移動參數中找到它,它會在涉及寫入操作時自行產生而不是擴展。
這應該可以解釋你在做時的困惑
\let\oldtextborn\textborn
在加載之前,然後看到和kpfonts
產生的輸出之間沒有區別。該套件不會重新定義,而是根據所選字體系列名稱將新字體與 TS1 編碼相關聯。所以和仍然是一樣的。\textborn
\oldtextborn
kpfonts
\textborn
\oldtextborn
\textborn
為了定義\textborn
使用cmr
家庭,必須小心,因為像這樣的策略
\let\oldtextborn\textborn
\renewcommand\textborn{{\fontfamily{cmr}\selectfont\oldtextborn}}
不保證安全。例如,如果\textborn
出現在移動參數中,例如在節標題或說明中,則該.aux
檔案將包含
\@writefile{toc}{\contentsline {section}{\numberline {1}{\fontfamily {cmr}\selectfont {\fontfamily {cmr}\selectfont \textborn }}}{1}}
該命令似乎被擴展了幾次。在其他情況下,這甚至可能導致無限循環。
涉及的策略\UndeclareTextCommand
肯定更安全。