I want to use underscore as a usual char in most cases, so I do this in global:


Usually, I work in Chinese context, the code ~ is not so useful, so I use it to replace code 8 _:


It works perfectly in Chinese workaround, including tikz, reference and so on.

But when I write a English document, sometimes I want to keep code 13:


To use underscore as a simple printable char and use subscript at the same time, I defined a new command for subscript:

\def\mf#1{\catcode`_=8 _{#1}\catcode`_=11}

What I desire is that $a\mf{b}$ can print a subscript "b" after "a". But it printed a visual underscore "_" between "a" and "b", just like a_b.

What happened in the command \mf{b}? It is about order or scope? And how to implement \mf?

Besides, when I use the package \usepackage{underscore}, it will make an error at underscore in reference \ref{_}. So I tried implementing it by primitive command.


  • As tempting as it is to change catcodes, it’s usually not worth the trouble. Sure, if you don’t like using backslash for commands, you can use @, |, ?, or anything else. And as you say, you can make _ a letter and use it in commands. But no TeX syntax highlighting system will be able to recognize these changes. Plus, it makes collaboration more difficult, and it may raise eyebrows if you try submitting it to a journal. And LaTeX code generated by external programs will become useless.
    – Gaussler
    Commented Sep 13, 2021 at 11:20

1 Answer 1


Answering the question in the title, for the record, the scope of \catcode is the current TeX group, as usual with most assignments (unless preceded by \global).

But the problem here is not scope, rather the time of tokenisation. As TeX processes a line of input, it translates every character (or sequence) it sees into a token. A token may be categorised as character tokens (for example _8 or A11) and control symbol/sequence tokens (for example \, or \relax). TeX turns a character into a token as soon as it “sees” the character for the first time, and that token is then frozen and cannot be changed to something else.

The practical implication of this in your case is that here:

\def\mf#1{\catcode`_=8 _{#1}\catcode`_=11}

the first line makes a _ be a catcode 11 token, then the second line does the definition, and the definition of \mf ends up with all _ with catcode 11, and then _11{#1} just typesets a _. To make a subscript you need a _8 instead.

There are a few ways you could do that, but the easiest is to use \sb, defined in the LaTeX kernel as:


so that \sb behaves exactly as a _8. You can also do \let\mf=\sb so that you can use \mf as an alias.

  • When I see that there is written \catcode I immediately think of the cathode ray tube :-) +1
    – Sebastiano
    Commented Sep 13, 2021 at 12:14

You must log in to answer this question.

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