如何將命令附加到巨集而不擴展它們

如何將命令附加到巨集而不擴展它們

我正在努力建立一個expenses包。目的是能夠寫

\expense{someone}{something}{something a bit longer}{10}{GBP}
\expense{someone else }{something else}{something a bit longer}{11}{EUR}
\makeexpensetable

為此,我啟動一個內部\allexpenses

\def\allexpenses{}

然後每個\expense命令都會附加一個\writeexpense定義為的命令

\newcommand{\writeexpense}[5]{%
    #1 & #2 & #4 \\ %
}

因此,最終該\makeexpensetable命令將簡單地開始一個表,然後有一行\allexpenses包含所有行並結束該表。

我當前的\expense命令是

\newcommand{\expense}[5]{%
    \edef\allexpenses{\allexpenses%
        \writeexpense{#1}{#2}{#3}{#4}{#5}%
    }%
}

然而,TeX 因內部存在該\writeexpense命令而引發錯誤。如何阻止該指令擴充?我猜答案與命令的正確使用有關\noexpand,但我無法弄清楚。

答案1

替代的@免費解決方案:

\usepackage{etoolbox}
\appto\allexpenses{\writeexpense{#1}{#2}{#3}{#4}{#5}}

還有一兩個包裹-免費的解決方案,但它們有效地重新發明了\appto輪子。問題是\edef遞歸地擴展其內容,而您只想\allexpenses擴展首字母一次。事實上,這不是\noexpand\unexpanded想要的:

\edef\allexpenses{%
  \expandafter\unexpanded\expandafter{\allexpenses}%
  \unexpanded{\writeexpense{#1}{#2}{#3}{#4}{#5}}%
}

這會導致\allexpenses一次擴展到它所包含的任何內容,然後這些內容將受到保護,免於進一步擴展。第一行相當於\expandonce\allexpenses,其中\expandonce也在 中定義etoolbox。 -free 解決方案eTeX是為此使用令牌暫存器:

\toks0=\expandafter{\allexpenses \writeexpense{#1}{#2}{#3}{#4}{#5}}
\edef\allexpenses{\the\toks0}

令牌暫存器是原始的\expandonce,但由於它們的分配不能完全擴展,因此它們並不總是適合這個基於 eTeX 的巨集所在的位置。

答案2

\g@addto@macro\allexpenses{\writeexpense{#1}{#2}{#3}{#4}{#5}}
在套件檔案中或之間使用\makeatletter \makeatother

相關內容