You are defining a macro with delimited argument, something that the primitive commands \def
, \gdef
, \edef
and \xdef
can do, but \newcommand
can't.
Let's see:
\def\demo#1-#2\stop{#2}
The parameter text consists of the following tokens
#1 • - • #2 • \stop
Here I use • just to separate the tokens and the spaces are for readability; in the context of the parameter text it's common to consider #1
as just one token.
This means that the first argument to \demo
will be all that comes after \demo
up to (and not including) the first -
token at the same brace level; the second argument will be all after that -
up to (and not including) \stop
, again at the same brace level. So, if the call is
\demo 1{2-3}4-5\stop
TeX will set #1 <- 1{2-3}4
and #2 <- 5
The meaning of the delimiter tokens is never looked at when \demo
is expanded: TeX just matches the pattern, taking the shortest match. For instance, with
\demo--\stop
we'll have an empty #1
and #2
will be changed into -
.
You can even use an undefined token as delimiter:
\def\demo#1-#2\nobodydarestodefinethistoken{#2}
and TeX won't complain: the pattern is matched, parameters are substituted with the found arguments and the tokens used for the match will be discarded.
There is one exception: the left brace that starts the replacement text can be used also as a delimiter with a peculiar syntax: if you say
\def\demo#1-#2#{#2}
and then
\demo ABC-DEF{}
the second argument will be DEF
and the left brace that must follow will not be discarded.
\makeatletter
required? In that post, the@
is also used as a delimiter token.