Как добавлять команды в макрос, не расширяя их

Как добавлять команды в макрос, не расширяя их

Я работаю над созданием 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. 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

Связанный контент