# How to check if token is a macro?

I am thinking about possibility to parse LaTeX document. What I really need is to track category codes of symbols. As I understand TeX expands all of macros in his mouth and tracks changes of category codes without executing anything. Is it possible to check if the next token is a macro, collect it unexpanded (together with arguments), execute it and move to next token?

-
What do you mean by "collect it unexpanded" followed by "execute it"? Isn't that just expansion? – Ryan Reich Mar 25 '13 at 14:19
If you do \meaning\cs and \cs is a macro, the expansion is macro:<parameter text>-><replacement text> (in stringified form). But the category codes in both the <parameter text> and the <replacement text> are not recoverable. So the general problem is not solvable; if the <parameter text> is simply a list of undelimited parameters, then you can use the expansion of \meaning\cs for knowing how many arguments you have to collect. But I don't understand what you're trying to do. – egreg Mar 25 '13 at 14:33
I am sorry if I was not clear, my English is poor :). My goal is to collect all the tokens from external LaTeX document together with their category codes with possibility to put them back in their original form (macros should not be expanded). For example if there is a macro \foo which has inside \catcode\@=3, so when I am collecting tokens and I meet \foo, I recognize that it is a macro, collect it in its original form however letting TeX to execute it and change catcode for symbol @. The question is, is it possible to do it with TeX? – user21710 Mar 25 '13 at 15:36
@user21710 Your description of the interaction of macro arguments and catcode values doesn't seem to match TeX's processing so it makes it hard to see what you want to do. catcode values are irrelevant to macro replacement texts they are only consulted when turning characters in the input into tokens, after that they are not used at all. So a macro does not store any kind of table of catcode values current at the time it was defined, it just has a definition consisting of a list of tokens. – David Carlisle Mar 25 '13 at 16:11

It is not clear what you want to do however this detects whether or not the following token is a macro. It distinguishes \centerline from 5

This is a macro: macro:#1->\line {\hss #1\hss }
This is a not macro: the character 5


Plain TeX example (Change \bye to \stop for LaTeX)

\def\tst{\afterassignment\xtst\let\next= }

\def\xtst{%
\edef\tmp{\meaning\next}%
\expandafter\macrotest\tmp.........\relax
\ifx\tmpb\macrotestmacro
\immediate\write20{This is a macro: \meaning\next}%
\else
\immediate\write20{This is a not macro: \meaning\next}%
\fi
}

\def\macrotest#1#2#3#4#5#6#7\relax{\def\tmpb{#1#2#3#4#5#6}}

\expandafter\macrotest\meaning\macrotest.........\relax

\let\macrotestmacro\tmpb

\tst\centerline

\tst 5

\bye

-
Not to nitpick excessively, since you were clearly not aiming for completeness, but this doesn't work with \long (etc.) macros. – Ryan Reich Mar 25 '13 at 15:40
@RyanReich yes true (could be fixed) but basically the idea is doomed anyway it will tell you for example that \makebox has no arguments, and finding out just from \meaning that it has some optional and mandatory arguments would be an interesting exercise. – David Carlisle Mar 25 '13 at 16:07