# Next word macro inside braces

I have defined a macro that highlights the next word using

\def!##1 {\hkw{##1} }%


where in this scope, ! is an active character. So it works fine to write.

\emph{This is a !good example}


but not

\emph{This example is !good}


where it would complain about ! Argument of ! has an extra }..

Is there a nice way to let ! consider everything up to the next space, but at most everything in the current group, as its argument?

• Only if you use another macro instead of \emph (or change it, not recommended). – egreg Jul 17 '15 at 9:53
• The emph is just an example; for what it’s worth it could be just a group on its own, e.g. {!good}. – Joachim Breitner Jul 17 '15 at 10:28
• You can't have a macro with two distinct delimiters. I consider this sort of thing as bad markup, anyway. – egreg Jul 17 '15 at 10:47

I took Martin’s answer to a related question and simplified it a bit:

With this code

\documentclass{article}

% next word parser, based on https://tex.stackexchange.com/a/11925/15107
\makeatletter
\def\consumenextword#1{%
\begingroup
\let\@cmd#1%
\def\@selectedword{}%
\consumenextword@
}

\def\consumenextword@{%
\futurelet\ntoken\consumenextword@@
}

\def\consumenextword@@{%
\ifcase 0%
\ifx\ntoken\@sptoken 0\else
\ifcat a\ntoken 1\else
\ifcat 0\ntoken 2\fi% test of token is catcode "other"
\fi\fi
\relax
\expandafter\consumenextword@end
\or
\else
\expandafter\consumenextword@checknum
\fi
}

% Checks if token is a number (ASCII 48-57)
\def\consumenextword@checknum#1{%
\ifcase 0%
\ifnum#1>47
\ifnum#1<58 1\fi\fi
\relax
\def\next{\consumenextword@end#1}%
\else
\fi
\next
}

\edef\@selectedword{\@selectedword#1}%
\consumenextword@
}

\def\consumenextword@end{%
\@cmd\@selectedword%
\endgroup%
}
\makeatother

\catcode!=\active
\def!{\consumenextword{\textbf}}

\begin{document}
This is a !good example, and this !is2. Also works at the end of the !Line

And well well in an \textit{!argument}.
\end{document}
`

I get this output: