Within your attempt one can find
\renewcommand\nmerge[#1] {%
\noindent\tempcommand
}%
This does not work out: You need to distinguish the moment in time when a macro is defined from the moment in time when a macro is carried out=expanded for obtaining its replacement text:
At the moment of defining the macro \nmerge
TeX does not see the sequences hashes (#
) and digits that make the definition/replacement text of the macro \tempcommand
. At the moment of defining the macro \nmerge
TeX just sees the token \tempcommand
.
When \nmerge
is carried out and thus \tempcommand
is carried out as well and delivers hashes and digits, TeX will not see a connection between these hashes and digits and the parameter text of the macro \nmerge
at the time of defining the macro \merge
. TeX will not take the hashes coming from expanding \tempcommand
for denotations of arguments of \nmerge
. These will just be some hashes and digits that go into the token-stream...
You need to get something like
\renewcommand\nmerge[#1] {%
\noindent⟨replacement text/toplevel expansion of \tempcommand⟩
}%
Hereby \tempcommand
needs to hold the right amount of hashes.
This is slightly tricky, but you were almost there with your attempt:
You can use tikz/pgffor's \foreach
-loop for accumulating ##1##2...
within the definition-text of a scratch-macro \tempcommand
.
If you do this you need to know about \unexpanded
:
While the definition-text of an \edef
- or \xdef
-definition is expanded, stuff wrapped in \unexpanded{...}
is not expanded but the token \unexpanded
and the pair of matching curly braces {...}
surrounding that stuff go away.
A peculiarity of \unexpanded
(and anything else that processes so-called ⟨general text⟩) is that TeX keeps expanding things until "seeing" the curly opening brace of the ⟨general text⟩. Thus, with \unexpanded{\foobar}
expansion of \foobar
is prevented while with \unexpanded\expandafter{\foobar}
expansion of things that come from expanding \foobar
is prevented, i.e., you get the so-called top-level-expansion of \foobar
. This is because after \unexpanded
TeX keeps expanding things until "seeing" the curly opening brace of the ⟨general text⟩ and hereby encounters \expandafter
which in turn triggers top-level-expansion of the token \foobar
right behind the curly opening brace. As soon as the toplevel-expansion of \foobar
is delivered, expanding \expandafter
itself (and thus removing that token from the token-stream) is done so that TeX can now "see" the curly opening brace belonging to \unexpanded
's ⟨general text⟩.
If you do this you also need to know how TeX treats hashes (#
) during macro-expansion:
- A single hash trailed by one of the digits 1..9 in the macro definition denotes an argument of the macro.
- If in the definition-text of a macro a hash is not trailed by a digit but is trailed by another hash, these two consecutive hashes are not taken for something that denotes an argument of that macro. During expansion of the macro these two hashes collapse into a single hash.
E.g., with \def\foobar#1{#####1}
doing \foobar{X}
yields ##X
: The first and the third hash each are trailed by another hash, namely the second/fourth hash - this collapses into single hashes that get delivered. The fifth hash is not trailed by another hash but is trailed by the digit 1
- this denotes the 1st argument of the macro \foobar
.
When nesting macro definitions inside macro definitions you can/need to use hash-doubling with those hashes that belong to denotations of macro-arguments of inner macro definitions.
- Carrying out an
\edef
- or \xdef
-assignment goes along with expanding the tokens that form the definition-text of the macro. Hereby hashes nested between \unexpanded{...}
or coming from \the
-expansion of a token-register get doubled (and the token \unexpanded
and the curly braces are removed). This is a nice features because this way you can use \unexpanded
for ensuring that you get as many pairs of hashes into the definition-text of the macro as you had single hashes between \unexpanded{...}
. During expansion of the macro each of these pairs of hashes collapses into a single hash so that after expansion you get the same amount of hashes as you had in the definition-text of the macro between \unexpanded{...}
.
\foreach
defines a temporary macro from the argument that contains the tokens that shall be carried out repeatedly. Expanding that macro yields halving the amounts of consecutive hashes contained in that argument.
Summa summarum:
Expanding \tempcommand
shall yield something like #1#2...
.
Thus the definition-text of \tempcommand
is to consist of s.th. like ##1##2...
so that each pair of consecutive hashes can collapse into a single hash when expanding \tempcommand
.
Directives for defining \tempcommand
are within the argument of a \foreach
-loop so that hashes need to be doubled once more because \foreach
defines a scratch-macro from that argument during whose expansion amounts of consecutive hashes get halved.
Everything comes from expanding the macro \nmergeinit
which implies the need of doubling hashes yet once more.
All in all hashes need to be doubled three times. Doubling hashes three times outgoing from a single hash yields eight consecutive hashes.
In order to compensate the halving of amounts of hashes when in the \foreach
-loop expanding \tempcommand
, the expansion of \tempcommand
needs to be wrapped between \unexpanded{...}
.
So here is the code using \foreach
for accumulating ##1##2...
within the definition-text of \tempcommand
:
\documentclass{article}
\usepackage{tikz}
\newcommand\nmergeinit[1]{%
\gdef\tempcommand{}%
\foreach \i in {1,...,#1}{%
\xdef\tempcommand{%
\unexpanded\expandafter{\tempcommand}########\i
}%
}%
\providecommand\nmerge{}%
\xdef\tempcommand{%
\unexpanded{\renewcommand\nmerge[#1]}{\unexpanded\expandafter{\tempcommand}}%
}%
\tempcommand
}%
\begin{document}
\nmergeinit{6}
\nmerge{12}{34}{56}{78}{90}{12} \\
\nmergeinit{5}
\nmerge{hello }{nice }{to }{meet }{you} \\
\nmergeinit{4}
\nmerge{latex }{is }{so }{hard}
\end{document}
Using expl3, s.th. like the following might do the trick—x-expansion of \exp_args:Nnx
requires hash-doubling. That's why \__ally_hashprepend:n
is defined to deliver two hashes prepended to the number of the argument:
\documentclass{article}
\ExplSyntaxOn
\cs_new:Npn \nmerge #1 { #1 }
\cs_new:Nn \__ally_hashprepend:n { #### #1 }
\NewDocumentCommand{\nmergeinit}{m}
{
\exp_args:Nnx
\use:nn
{ \cs_set:Npn \nmerge }
{ \int_step_function:nN { #1 } \__ally_hashprepend:n
{ \int_step_function:nN { #1 } \__ally_hashprepend:n }
}
}
\ExplSyntaxOff
\begin{document}
\nmergeinit{6}
\nmerge{12}{34}{56}{78}{90}{12}
\nmergeinit{5}
\nmerge{hello }{nice }{to }{meet }{you}
\nmergeinit{4}
\nmerge{latex }{is }{so }{hard}
\end{document}
With these approaches you are restricted to concatenating at most nine arguments.
You can implement a tail-recursive mechanism where \romannumeral\nmergeamount000
is used for obtaining as many m
as denoted by \nmergeamount
and then tail-recursively consuming m
and gathering another argument until all m
are consumed:
\documentclass{article}
\csname @ifdefinable\endcsname\stopromannumeral{\chardef\stopromannumeral=`\^^00}%
\newcommand\firstoftwo[2]{#1}%
\newcommand\secondoftwo[2]{#2}%
\newcommand*\nmergeamount{}%
\newcommand*\nmergeinit[1]{\edef\nmergeamount{\number\numexpr(#1)\relax}}%
\newcommand*\nmerge{%
\romannumeral\expandafter\nmergeloop\expandafter{\romannumeral\nmergeamount000}{}{}%
}%
\newcommand\nmergeloop[3]{%
\ifx\relax#1\relax\expandafter\secondoftwo\else\expandafter\firstoftwo\fi
{\expandafter\nmergeloop\expandafter{\firstoftwo{}#1}}%
{\expandafter\stopromannumeral\secondoftwo{}}%
{#2#3}%
}%
\begin{document}
\nmergeinit{6}
\nmerge{12}{34}{56}{78}{90}{12} \\
\nmergeinit{5}
\nmerge{hello }{nice }{to }{meet }{you} \\
\nmergeinit{4}
\nmerge{latex }{is }{hard }{hard}
\nmergeinit{15}
% This strips braces from the first 15 of the 20 arguments:
\edef\test{%
\nmerge{1 }{2 }{3 }{4 }{5 }{6 }{7 }{8 }{9 }{10 }{11 }{12 }{13 }{14 }{15 }{16 }{17 }{18 }{19 }{20 }%
}
{\ttfamily\string\test=\meaning\test}
\end{document}

\#
and#
are very different things. The former is the literal character#
and the latter is the parameter indicator. You can't use\#
so that it means#
in another context (unless you use it like\h
in wipet's answer, of course).