Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

After a lot of trial and error, I haven't been able to solve the following problem:
A simplified version: I want to use \g@addto@macro to add code to another macro wich will use a command of the macro, I expected this code to work:

\newcommand{\foo}[1]{#1, }
\newcommand{\bar}[1]{
    \g@addto@macro\foo{
        ##1#1
    }
}

And to produce this output:

\foo{A} -> A,
\bar{B}
\show\foo = #1, #1B
\foo{A} -> A, AB
\bar{C}
\show\foo = #1, #1B#1C
\foo{A} -> A, ABAC

I hope it is clear what I want. In an actual implementation, I want to expand a \switch-like structure dynamically. The problem with the code is, that the ## is not expanded to # when adding code, however #1 is expanded to the first parameter of \bar. This causes

\bar{B}
\show\foo = #1, ##1B

wich in turn doesn't produce the desired output. I would like to avoid additional packages if possible.

share|improve this question
    
Egreg's provided a solution but I'll note that apart from the problem with # you are missing several % which would add spurious space tokens to your result. \g@addto@macro goes to some lengths passing the tokens through a toks register specifically to prevent the need to double # (so you can build up strings including that character) –  David Carlisle Feb 6 at 1:57
    
@DavidCarlisle In my original code I had the comments in; thanks for the advice though :) –  AlexR Feb 6 at 2:04

2 Answers 2

up vote 4 down vote accepted

\g@addto@macro uses a token register to stop the interpretation of # that you want.

You just want \def.

\documentclass{article}

\begin{document}

\newcommand{\foo}[1]{#1, }

\def\zfoo#1\relax{\long\def\foo##1{#1}}
\newcommand{\baR}[1]{%
   \expandafter\zfoo\foo{##1}##1#1\relax
}

\foo{A}
\show\foo


\baR{B}
\show\foo %= #1, #1B

\foo{A} %-> A, AB

\baR{C}
\show\foo% = #1, #1B#1C

\foo{A} %-> A, ABAC


\end{document}

which produces

> \foo=\long macro:
#1->#1, .
l.13 \show\foo

? 
> \foo=\long macro:
#1->#1, #1B.
l.17 \show\foo
               %= #1, #1B
? 
> \foo=\long macro:
#1->#1, #1B#1C.
l.22 \show\foo
              % = #1, #1B#1C
? 

enter image description here

share|improve this answer

No, you can't append tokens to a macro with parameters using \g@addto@macro. Nor you can do it with \apptocmd of etoolbox.

You can do it with regexpatch, though.

\documentclass{article}
\usepackage{regexpatch}

\newcommand{\foo}[1]{#1,\space}
\newcommand{\baz}[1]{%
  \def\temp{#1}%
  \regexpatchcmd{\foo}{ \Z }{ \cP\#1 \u{temp} }{}{}%
}


\begin{document}

\foo{A}

\baz{B}\foo{A}

\baz{C}\foo{A}

\end{document}

The "search" regular expression matches the end of the replacement text; this is replaced by \cP\#1 (which means #1 with the correct category codes) followed by the expansion of the macro \temp. Thus I set \temp to the argument of \baz.

Unfortunately, the current version of regexpatch can't patch macros whose replacement text ends with a space, so in this particular case I used \space at the beginning.

Here's the output:

enter image description here

share|improve this answer
    
Thanks for the answer. So there's no way to, say manually set the catcode at the specific position? Or to adapt the code of \g@addto@macro? Seems like a serious flaw to me... –  AlexR Feb 6 at 0:26
    
@AlexR Serious flaw (of LaTeX2e itself probably, but certainly of many packages) is the need for patching. –  yo' Feb 6 at 0:33
    
@AlexR it was written that way so you could use \newcommand in \AtBeginDocument in a way that you didn't have to have multiple doubling of #. –  David Carlisle Feb 6 at 2:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.