在重新定義LaTeX環境的時候,為何很少用到 patchcmd 一類的命令?
我看到很多重新定義 environment 的時候都是直接裸寫其開頭結尾,我比較好奇為什麼很少人使用 etoolbox或者 xpatch 之類的包來修改以代替重寫。
一、出現得太晚。
etoolbox 是 2007 年才向 CTAN 發布的(Google 網上論壇)。而 xpatch 作為 etoolbox 的加強版,則要晚至 2012 年(Google 網上論壇)。
我們常用常見的宏包,最多一兩百個,多是 2007 年以前就已經誕生了的。舊宏包當然不可能用得上新工具。而即使是舊宏包要更新,沒有特殊需要也不會重寫沒有問題的代碼。
對舊命令大量補丁的一個常見例子就是 footmisc 包。看版權聲明就知道,這個包發佈於 1995 年,比 etoolbox 早 12 年,甚至早於 eTeX 本身的成熟。所以,footmisc 在做代碼補丁時很謹慎(使用了 CheckCommand),代碼質量也相當不錯,但不依賴 eTeX 相關技術。
二、不少人不知道。
很多開發者都不知道有這種東西,當然,出現得晚也是造成了解人少的原因之一。
別不相信,你知道有 etoolbox,就八成不知道有在 Plain TeX 下能用的同類宏包 texapi。
關於這種問題,更明顯的例子是在複雜宏編程中很常見的循環遍歷。作為 etoolbox 和 LaTeX3 的推崇者肯定喜歡 forcsvlist、forlistloop 或是 ool_while_do:nn、 l_map_inline:nn 之類的東西,你可能還知道繪圖包中使用的 pgffor、multido,但你未必知道 forloop、forarray,以及 texapi 中的循環功能。——但要說實話,更多的老派開發者用的最多的則還是 Plain TeX 內核的 loop
epeat,LaTeX2e 內核的 @for 和 @tfor,甚至自己手寫的循環。
三、避免增加依賴。
etoolbox 是在 eTeX 擴展的基礎上產生的,LaTeX3 上的 xpatch 更是。儘管現如今不支持 eTeX 擴展的引擎幾近消失,不過區區幾年前不支持 eTeX 的引擎也還相當常見。依賴 etoolbox、xpatch 的結果就是這個宏包不能用在不支持 eTeX 的引擎上。當然在今天,對 eTeX 的依賴越來越不成問題了,從 LaTeX 新內核到各個新宏包都利用了 eTeX 擴展。
宏包本身的依賴則更重要些。宏包作者通常不希望自己的宏包有太多依賴項,能少一個依賴,在一些受限環境下部署就能方便一點。例如 TeX Live 的 basic 安裝就不包含 etoolbox(但有 eTeX)。
四、需要的功能太簡單。patchcmd 的邏輯並不簡單,它裡面有一個搜索替換的過程,實現得也很技巧。但實際中更常用的僅僅是在原有的命令前面或後面增加一點代碼,即只需要 etoolbox 中的 preto、appto。所以常見的使用也僅僅是類似這樣:
letxxx@save@foofoo
deffoo{before xxx@save@foo after}
同樣是一兩行代碼解決問題,為這種簡單功能增加一個上千行的宏包依賴,就不划算了。
而如果真的需要 patchcmd 那樣在代碼中間替換掉一段東西,用 etoolbox 就相對划算了,因為重抄一遍原有命令的定義可能非常長,而自己實現 patchcmd 的邏輯則很麻煩。
又例如,我在寫 diagbox 的時候需要在內部使用 appto 的功能完成選項附加,我就沒有依賴 etoolbox,而是直接把 appto 的定義展開使用了。
其實在原有宏後面附加內容,這個用法非常常見。LaTeX2e 內核有不依賴 eTeX 的命令 g@addto@macro,在完成這一工作上也足夠使用。
五、單靠補丁不夠用。
etoolbox 的 patchcmd 是有失敗情形的。失敗的原因很多,比如原來的宏不是按標準 LaTeX 方式定義各種參數,其參數定義方式不標準;比如宏是受保護的,或有其他特殊的展開模式。xpatch 在這些方面做了很多努力,但仍然不可能覆蓋所有情形。
即使 patchcmd 不失敗,它也不能覆蓋各種使用場景。例如原來的宏定義中可能有三處 #1,我們想把第 2 處 #1 換成 extbf{#1},這時候 patchcmd 就不管用。又例如原來的宏定義本來也沒多長,但裡面卻有好幾處數字要改動,那用好幾遍 patchcmd 就不如直接重新定義來得方便。ctex 包中很多修改都是這種情形。
推薦閱讀:
※求推薦 LaTeX 編輯器?
※上古時期的 TeX Users 都有哪些當今 TeX Users 無法想像的神級操作?
※學習 MetaPost 和 TikZ 這一類的 LaTeX 繪圖工具有價值嗎?
※LaTeX 如何進行 debug?
※LaTeX 命令的可選參數不能有方括弧么?
TAG:LaTeX |