If the prefix is always one letter, then you can do it:
\makeatletter
\newcommand{\defcommand}[1]{\@namedef{custom#1}{}}
\newcommand{\foo}[1]{\@foo#1\@nil}
\def\@foo#1#2\@nil{%
\expandafter\ifx\csname custom#1\endcsname\@empty
\expandafter\g@addto@macro\csname custom#1\endcsname{#1#2}%
\else
\expandafter\g@addto@macro\csname custom#1\endcsname{ #1#2}%
\fi}
\makeatother
\defcommand{A}
\foo{A1}\foo{A2}\foo{A355}
\defcommand{B}
\foo{B123} \foo{Ba} \foo{B3}
\show\customA
\show\customB
This will print on the terminal
> \customA=macro:
->A1 A2 A355.
l.19 \show\customA
?
> \customB=macro:
->B123 Ba B3.
l.20 \show\customB
Of course this wouldn't work if one wants
\defcommand{ABC}
and \foo{ABC1}
, because it wouldn't be possible to know what's the prefix.
If the prefix may consist of more than one letter, I suggest a different syntax:
\makeatletter
\newcommand{\defcommand}[1]{\@namedef{custom#1}{}}
\newcommand{\foo}[2]{%
\expandafter\ifx\csname custom#1\endcsname\@empty
\expandafter\g@addto@macro\csname custom#1\endcsname{#1#2}%
\else
\expandafter\g@addto@macro\csname custom#1\endcsname{ #1#2}%
\fi}
\makeatother
\defcommand{A}
\foo{A}{1}\foo{A}{2}\foo{A}{355}
\defcommand{ABC}
\foo{ABC}{123} \foo{ABC}{a} \foo{ABC}{3}
\show\customA
\show\customABC
This will print on the terminal
> \customA=macro:
->A1 A2 A355.
l.17 \show\customA
?
> \customABC=macro:
->ABC123 ABCa ABC3.
l.18 \show\customABC
If the intent is to establish a macro to which subsequent calls should add, then it's a different matter.
\makeatletter
\newcommand{\defcommand}[1]{%
\gdef#1{}%
\gdef\foo@current@command{#1}%
}
\newcommand{\foo}[1]{%
\expandafter\ifx\foo@current@command\@empty
\expandafter\g@addto@macro\foo@current@command{#1}%
\else
\expandafter\g@addto@macro\foo@current@command{ #1}%
\fi
}
\makeatother
\defcommand{\macroA}
\foo{x} \foo{y} \foo{z}
\defcommand{\macroB}
\foo{Here}\foo{is}\foo{a}\foo{new}\foo{one}
\show\macroA
\show\macroB
This will print on the terminal
> \macroA=macro:
->x y z.
l.21 \show\macroA
?
> \macroB=macro:
->Here is a new one.
l.22 \show\macroB
The trick is to define \foo
always in terms of the same wrapper command, and to add to \defcommand
a part that defines the wrapper command as the current macro that's initialized.
How does this last set of macros work? Let's see it in slow motion.
Here's \defcommand
:
\newcommand{\defcommand}[1]{%
\gdef#1{}%
\gdef\foo@current@command{#1}%
}
If we say \defcommand{\mymacro}
the effect will be to initialize \mymacro
to have empty expansion. Then the (global) definition will make \foo@current@command
expand to \mymacro
(not to the contents of \mymacro
, at least at the first expansion).
Here's \foo
\newcommand{\foo}[1]{%
\expandafter\ifx\foo@current@command\@empty
\expandafter\g@addto@macro\foo@current@command{#1}%
\else
\expandafter\g@addto@macro\foo@current@command{ #1}%
\fi
}
This has some complications, so let's look at a simplified version:
\newcommand{\foo}[1]{%
\expandafter\g@addto@macro\foo@current@command{#1}%
}
One has to know that \g@addto@macro
adds its second argument to the (parameterless) macro given as first argument. So, assume we have declared \defcommand{\mymacro}
and then we do \foo{x}
: this becomes
\expandafter\g@addto@macro\foo@current@command{x}
and now \expandafter
comes into action, changing \foo@current@command
to its first level expansion, which gives \mymacro
, so now we have
\g@addto@macro\mymacro{x}
which does the desired thing.
The more complex definition is used to ensure that no space is added in front of the first item we add:
\newcommand{\foo}[1]{%
\expandafter\ifx\foo@current@command\@empty
\expandafter\g@addto@macro\foo@current@command{#1}%
\else
\expandafter\g@addto@macro\foo@current@command{ #1}%
\fi
}
Let's see assuming that now \defcommand{\bar}
has just been given, so that now \foo@current@command
expands to \bar
, whose expansion is empty. As soon as we say \foo{abc}\foo{def}
, TeX will transform it into
\expandafter\ifx\foo@current@command\@empty
\expandafter\g@addto@macro\foo@current@command{#1}%
\else
\expandafter\g@addto@macro\foo@current@command{ #1}%
\fi
\foo{def}
The first \expandafter
changes \foo@current@command
into \bar
:
\ifx\bar\@empty
\expandafter\g@addto@macro\foo@current@command{abc}%
\else
\expandafter\g@addto@macro\foo@current@command{ abc}%
\fi
\foo{def}
Now \bar
has empty expansion, so the "true" branch is followed:
\expandafter\g@addto@macro\foo@current@command{abc}%
\foo{def}
and, again,
\g@addto@macro\bar{abc}\foo{def}
so that, now, the expansion of \bar
will be abc
and TeX will examine \foo{def}
. This will do exactly the same as before, but following the "false" branch, because \bar
is no longer empty. So we'll have
\expandafter\g@addto@macro\foo@current@command{ def}
that becomes
\g@addto@macro\bar{ def}
and the final result will be the same as if we had said
\def\bar{abc def}
to begin with.
\foo{A}{1}
would be preferable, unless the prefix is always one letter only.foo
's wit the same second argument. For example\foo{A1}{\mymacroA}
\foo{A2}{\mymacroA}
\foo{A3}{\mymacroA}
... so in my case it would much easier to write something like\defcommand{\mymacroA}
and then just\foo{A1}
\foo{A2}
\foo{A3}
...