I'm trying to define a macro which grabs everything until the next # (parameter token).
My twisted imagination wants something like this:
\def\test#1###2{(#1)[#2]}
\test hello#{world}
to grab hello in #1 (delimited by #) and world in #2 (brace delimited) and then print
(hello)[world]
However I'm failing (miserably) because no matter what combination of ## I try, TeX yells back:
! Parameters must be numbered consecutively.
<to be read again>
##
l.1 \def\test#1##
#2{(#1)[#2]}
?
so I guess that simply writing down the # in there is not the way to go.
Is it possible somehow to have a #-delimited macro?

#not simply\test hello{world}? :-) – David Carlisle May 17 '19 at 11:33\meaning\macro: With\meaningyou don't have information about category codes. The meaning of the following macros looks the same but the 1st one does process two args and the 2nd one has just a delimiter and does not process args: 1)\def\macro#1#2{#1 text #2}2)\catcode`\#=12\relax\def\macro#1#2{#1 text #2}. Also, you are not bound to using hashes for denoting args. You can use any character after assigning catcode 6 to it. You can also use control-sequences/active chars let equal to catcode-6-chars. – Ulrich Diez May 17 '19 at 20:26\scandef\def\test#1{something with #1}), not with\meaning, so the hashes do have catcode 6 and, in this case, it doesn't matter which character they are because TeX will not allow this. Thanks for the input, though :-) – Phelype Oleinik May 17 '19 at 20:35\scandefcatch both the definition-command, the macro-name and the parameter-text into an argument via#{-notation and then iteratively examine that argument token-wise, taking into account the fact that parameter-text cannot contain{... You can, e.g., implement a loop which counts the hashes in the sequence formed by the definition-command, the control sequence-name and the parameter-text. – Ulrich Diez May 17 '19 at 20:47#-delimited approach first precisely because the parameter text can't have braced groups, so it wouldn't skip any#1{#2}and I think the code is simpler that way. – Phelype Oleinik May 17 '19 at 20:52\named\def\test#[name]{Hello #[name]!}. It's pretty stupid, but it makes life easier when you have macros with lots of arguments and change their order once every two lines of code :P Here's the source, if you want to take a look. – Phelype Oleinik May 17 '19 at 21:08\setkeysonly process a mandatory keyval-argument for (re)defining some control-word-tokens which have meaningful names and then calls its belonging "underlying macro" which in turn does not process any argument at all but instead uses those (re)defined control-word-tokens with the meaningful names... Of course this approach does not work out with macros that are intended to work in pure-expansion-contexts. – Ulrich Diez May 17 '19 at 21:28\catcode`\A=6\relax\let\A=A\catcode`\A=13\relax\let A=\Aunless using predefined macros where catcode-13-A is used as argument delimiter. You'd need such a macro for each character/code-point which in the input can possibly occur. On utf8-machines you'd need a lot of such macros. In this case distinguishing\AfromAwhen\escapecharis -1... – Ulrich Diez May 19 '19 at 13:37\catcode`[=1\catcode`]=2 \printf{Integer \%02d and \textbf[float \%6.4f]}{3,pi}toInteger 03 and \textbf{float 3.1416}, and a more dedicated interface,\printf_f_type:nnnn{}{6}{4}{pi}which should be safer in a programming level. The former interface is supposed to be more user-level, where you don't expect weird catcode settings, but if a user does that in an actual document they should know what they are signing up for ;-) – Phelype Oleinik May 19 '19 at 15:50