I am interesting in parsing a string of input character by character, and doing something to each character. In this MWE, I merely apply a \textbf
to each successive character as an example, to verify that the parser is working.
The problem arises if the argument contains embedded macros. What I would like to do, if I come a across a macro in the argument, is to halt the parsing and let the macro execute, eating up as many arguments as it would desire from the original argument stream, and then resume parsing the remainder of the argument.
While \charparse
is the parsing macro, I am trying to design a helper macro \execmacro
to do what needs to occur when a macro is detected in the argument stream. In the MWE below, I can accomplish that, but only if I presuppose the nature of the embedded macros. In particular, I show 3 versions of \execmacro
, depending on whether I presuppose the embedded macros to require 0, 1, or 2 arguments, respectively.
What I would like instead is to have a version of \execmacro
that will work regardless of how many arguments the embedded macros demand.
\documentclass{article}
\newcommand\charparse[1]{\charparsehelp#1\relax\relax\relax}
\def\charparsehelp#1#2\relax{%
\ifcat\noexpand\relax\noexpand#1%
% MACRO DETECTED IN INPUT STREAM
\execmacro#1#2\relax% EXECUTE THE MACRO THEN RETURN TO PARSING
\else\textbf{#1}% BOLDING IS JUST AN EXAMPLE TO SHOW THAT PARSING MACRO IS WORKING
\ifx\relax#2\else
\charparsehelp#2\relax
\fi\fi
}
\begin{document}
% THIS ONLY WORKS IF THE EMBEDDED MACRO TAKES EXACTLY ZERO ARGUMENTS
\def\execmacro#1#2\relax{#1\ifx\relax#2\else\charparsehelp#2\relax\fi}Case 1\par
\charparse{0123\itshape456\upshape789}\par
I would like the output from the above character-parsing macro to be\par
\charparse{0123}\itshape\charparse{456}\upshape\charparse{789}\medskip
% THIS ONLY WORKS IF THE EMBEDDED MACRO TAKES EXACTLY ONE ARGUMENT
\def\execmacro#1#2#3\relax{#1{#2}\ifx\relax#3\else\charparsehelp#3\relax\fi}Case 2\par
\charparse{0123\textit{456}789}\par
I would like the output from the above character-parsing macro to be\par
\charparse{0123}\textit{456}\charparse{789}\medskip
% THIS ONLY WORKS IF THE EMBEDDED MACRO TAKES EXACTLY TWO ARGUMENTS
\def\execmacro#1#2#3#4\relax{#1{#2}{#3}\ifx\relax#4\else\charparsehelp#4\relax\fi}Case 3\par
\charparse{0123\rule{3ex}{1ex}456789}\par
I would like the output from the above character-parsing macro to be\par
\charparse{0123}\rule{3ex}{1ex}\charparse{456789}
\end{document}
\makebox
has no argument: you'd need to build a TeX parser.