Como anexar comandos a uma macro sem expandi-los

Como anexar comandos a uma macro sem expandi-los

Estou trabalhando na construção de um expensespacote. A intenção é poder escrever

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

Para fazer isso, estou iniciando uma \allexpensesmacro interna

\def\allexpenses{}

Em seguida, cada \expensecomando acrescenta a ele um \writeexpensecomando definido como

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

Para que eventualmente o \makeexpensetablecomando simplesmente inicie uma tabela, depois tenha uma \allexpenseslinha contendo todas as linhas e termine a tabela.

Meu \expensecomando atual é

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

Porém, o TeX está gerando erros devido à presença do \writeexpensecomando dentro dele. Como faço para impedir que esse comando se expanda? Suponho que a resposta tenha algo a ver com o uso correto de um \noexpandcomando, mas não consigo descobrir.

Responder1

Solução alternativa e @gratuita:

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

Há também um ou doispacote-soluções gratuitas, mas que efetivamente reinventam a \apptoroda. O problema é que \edefexpande seu conteúdo recursivamente, e você quer apenas que o inicial \allexpensesseja expandidouma vez. Na verdade, não é \noexpandmas \unexpandedvocê quer:

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

Isso faz com \allexpensesque seja expandido uma vez em tudo o que contém e, em seguida, esses conteúdos sejam protegidos de futuras expansões. A primeira linha equivale a \expandonce\allexpenses, onde \expandoncetambém está definida em etoolbox. A eTeXsolução -free é usar um registro de token para isso:

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

Os registradores de token eram os originais \expandonce, mas como sua atribuição não é totalmente expansível, eles nem sempre são adequados onde esta macro baseada em eTeX está.

Responder2

usar \g@addto@macro\allexpenses{\writeexpense{#1}{#2}{#3}{#4}{#5}}
em um arquivo de pacote ou entre\makeatletter \makeatother

informação relacionada