How can I get the category code of a character that is the value of a control sequence?

If I do this

The catcode for A is \the\catcode`A.

I get

The catcode for A is 11.

If I do this

The catcode for \abc\ is \the\catcode\abc.

I get "Missing number, treated as zero."

I think I understand it like this: \abc is replaced with the character code, category code pair <65, 11>, but TeX expects just a number after \the\catcode, so it inserts a 0, then leaves my A hanging around.

  • 2
    Pity one cannot add a tag for the! – Yiannis Lazarides Dec 19 '10 at 20:37
  • 1
    After doing \let\abc=@, you can access the catcode of @ by \expandafter\SomeMagic\meaning\abc, where \SomeMagic reads the meaning of \abc (which is the character @), and converts it to the form you want. I see two things you might want: know the catcode of the @ that is inside \abc, or the catcode that the character @ currently has. Just tell me which one you want and I can write an expandable command for that. – Bruno Le Floch Jan 29 '11 at 9:59
  • @BrunoLeFloch: And how can you access the character code of the token \let to \abc? – Evan Aad Sep 27 '17 at 7:07
  • Something like \long \def \getcharcode #1{\if \space \noexpand #1\expandafter 3\expandafter 2\else \expandafter \expandafter \expandafter \getcharcodeI \expandafter \meaning \expandafter #1\expandafter A\fi } \def \getcharcodeI #1A{\getcharcodeII #1A#1A#1AB} \def \getcharcodeII #1 #2 #3 #4 #5 #6 #7A#8B{\number `#7 } should work (try \getcharcode {\abc}), but it will choke horribly if given anything else than an explicit or implicit character token. – Bruno Le Floch Sep 27 '17 at 18:19

Sadly Knuth in his wisdom gave only few clues in the TeXBook for cases like this.

In order to understand the error we need to firstly understand the definition of \the, which is for the case of catcode \the<codename><8-bit number>, where <codename> stands for either \catcode, \mathcode, \lccode etc...

So clearly in this case catcode TeX expects a number and hence the error generated in the example provided by the OP.

All solutions provided by the other posts revolve around changing the definition one way or another to produce the required character code number and which I am demonstrating here with some different examples:

The example below will produce the right answer in both cases,

% results category 11
\def\ABC{`@ }

% results category 12
\def\ABC{`@ }

While comparing two tokens using \ifcat things become a bit more complicated, if you want to compare two active characters you have to say \noexpand - Knuth says so somewhat obscurely in Exercise 20.11!

Consider the following definitions

\catcode`[=13 \catcode`]=13

The following will result True since we comparing [ with ']' both now being category 13

\ifcat\noexpand[\noexpand]  True \else False \fi

Also \ifcat[* True \else False \fi is True

Since now we have established two facts \the\catcode needs a number and if you use an active character, implicitly or explicitly we can understand why the following will all work!


or Joseph's suggestion for comparisons:

   \ifcat\noexpand\abc A%
  • Stefan is right, it's a bit strange that you include the backtick in the definition of \ABC. (Although for illustration purposes it's interesting to see that then you don't need the \expandafter, I'm pretty sure that the OP wouldn't want the backtick included: He wants to test some existing macro, I guess.) – Hendrik Vogt Dec 20 '10 at 11:55
  • @Henrik you need the backtick so you can use the \the\catcode\ABC straight without an error you either have to do it at the definition stage or when typesetting \the\catcode..., with an expandafter as per Stefan's example. – Yiannis Lazarides Dec 20 '10 at 22:30

This works for me, using \expandafter:

The catcode for \abc\ is \the\catcode\expandafter`\abc.

and prints

The catcode for A is 11.

  • 1
    This is not quite what the question asks: you're using an explicit token whereas the example in the question is an implicit token. – Joseph Wright Dec 19 '10 at 16:30
  • @Joseph: Though Colin used \let, the question seemed a bit more general to me, so I made this suggestion in the hope that it might help. The catcode of a character as value of a control sequence is asked for, not the catcode of an implicit token itself. – Stefan Kottwitz Dec 19 '10 at 16:52
  • It helps a little, but I'm (sadly) still confused. If I have a \cs (perhaps assigned by \futurelet), how can I get the category code of that token? – Colin Fraizer Dec 19 '10 at 16:56
  • @Colin. I've updated my answer to reflect the fact that \ifcat is not quite the same as simply trying to get a number out. – Joseph Wright Dec 19 '10 at 17:09
  • @Stephan you can also use \def\abc{`A}, then you do not need the expandafter! – Yiannis Lazarides Dec 19 '10 at 19:05

As the excellent TeX by Topic gives us a clue in the discussion of \ifcat:

Control sequence tokens are considered to have category code 16, which makes them all equal to each other, and unequal to all character tokens.

This 'magic' category code is not accessible by normal methods. However, things do work with \ifcat if you have implicit tokens:

\ifcat\noexpand\ABC A%

While you do not need the \noexpand here, if this were for example part of a \futurelet then you would do, in case the test token was expandable.

  • this of course will fail the test \the\catcode\ABC looking for a number! – Yiannis Lazarides Dec 19 '10 at 20:27
The catcode for \abc\ is \the\catcode\abc
  • 1
    For defining, directly writing \chardef\abc=`A is easier, it doesn't require to know the ASCII code. – Stefan Kottwitz Dec 19 '10 at 16:56
  • Interesting approach, but means that \abc can't be expanded and then used in something like \pdfstrcmp. I guess it depends on the application! – Joseph Wright Dec 19 '10 at 17:09
  • it is the same as the already defined \@ne, \tw@, \thr@@. I never used \pdfstrcmp, because I do not need it for PSTricks :-)) But I use \chardef quite often ... – user2478 Dec 19 '10 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.