13

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

\let\abc=A
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.

4
  • 2
    Pity one cannot add a tag for the!
    – yannisl
    Commented Dec 19, 2010 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. Commented Jan 29, 2011 at 9:59
  • @BrunoLeFloch: And how can you access the character code of the token \let to \abc?
    – Evan Aad
    Commented Sep 27, 2017 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. Commented Sep 27, 2017 at 18:19

4 Answers 4

5

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
\makeatletter
\def\ABC{`@ }
\the\catcode\ABC

% results category 12
\makeatother
\def\ABC{`@ }
\the\catcode\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
\def[{*}

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!

\def\abc{`A}
\chardef\abc=65

or Joseph's suggestion for comparisons:

\let\abc=A
   \ifcat\noexpand\abc A%
     \TRUE
   \else
     \FALSE
   \fi
2
  • 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.) Commented Dec 20, 2010 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.
    – yannisl
    Commented Dec 20, 2010 at 22:30
5

This works for me, using \expandafter:

\def\abc{A}
The catcode for \abc\ is \the\catcode\expandafter`\abc.

and prints

The catcode for A is 11.

6
  • 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
    Commented Dec 19, 2010 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
    Commented Dec 19, 2010 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? Commented Dec 19, 2010 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
    Commented Dec 19, 2010 at 17:09
  • @Stephan you can also use \def\abc{`A}, then you do not need the expandafter!
    – yannisl
    Commented Dec 19, 2010 at 19:05
4

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:

\let\ABC=A
\ifcat\noexpand\ABC A%
  \TRUE
\else
  \FALSE
\fi

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.

1
  • this of course will fail the test \the\catcode\ABC looking for a number!
    – yannisl
    Commented Dec 19, 2010 at 20:27
3
\chardef\abc=65
The catcode for \abc\ is \the\catcode\abc
3
  • 1
    For defining, directly writing \chardef\abc=`A is easier, it doesn't require to know the ASCII code.
    – Stefan Kottwitz
    Commented Dec 19, 2010 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
    Commented Dec 19, 2010 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
    Commented Dec 19, 2010 at 17:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .