Underscore in textmode vs mathmode

I use _ character often in text mode, so I changed category of underscore: \catcode\_=12, but that applies also to mathmode and now I'm unable to make subscripts with underscore in mathmode. Is there a way to make latex interpret underscore in text mode as the underscore character, and in mathmode as subscript?

• Check the underscore package. – Ulrike Fischer Jul 9 '12 at 11:23

You can make _ math active:

\AtBeginDocument{
\catcode_=12
\begingroup\lccode~=_
\lowercase{\endgroup\let~}\sb
\mathcode_="8000
}


MWE:

\documentclass{article}
\usepackage[T1]{fontenc}

\AtBeginDocument{
\catcode_=12
\begingroup\lccode~=_
\lowercase{\endgroup\let~}\sb
\mathcode_="8000
}

\begin{document}
a_b $a_b$
\end{document}


• What are the advantages of this code over my more simplistic solution (below)? – JLDiaz Jul 9 '12 at 11:29
• This code is in general more robust: in \write operations the underscore will be written as is. Active characters may do surprising things, at times; math active characters, on the contrary, assume the "active aspect" only when typesetting math, so well down TeX's digestive process. – egreg Jul 9 '12 at 11:34
• @egreg: I think you have a spurious \def\mathunderscore in your first code snippet. – Bruno Le Floch Jul 9 '12 at 12:10
• @JLDiaz: I don't know where to paste your answer. This solution worked after pasting after usepackage but before begindocument – qwe Jul 16 '12 at 7:29
• If you do this, be aware of tex.stackexchange.com/questions/245880. – bers Apr 8 '16 at 18:29
\catcode\_=\active
\def_{\relax\ifmmode\sb \else \_\fi}

• Where do I put this? Just after \catcode\_=12 ? – qwe Jul 9 '12 at 11:08
• Better to do it instead of making it catcode 12. – David Carlisle Jul 9 '12 at 11:10

FWIW, in ConTeXt the special characters _ and ^ do not need to be escaped in text mode and work correctly in math mode.

ConTeXt table and math alignment macros do not use & as an alignment marker, so & also does not need to be escaped in text mode.

The underscore _ is already math active by default: one does not need to explicitely set its mathcode to "8000. Thus one could do:

\documentclass{article}
\usepackage[T1]{fontenc}

\AtBeginDocument{%
\begingroup\lccode~=_%
\lowercase{\endgroup\let~}_%
\catcode_=12
}

\begin{document}
a_b

$a_b$
\end{document}


It is perhaps better to do as in JLDiaz's answer and rather than make it catcode 12, make it catcode 13, and change its active definition to do as \_ hence \textunderscore only in text mode.

However this will cause problems in labels; except if the activation is done via Babel services, as babel patches various things to allow use of shorthands in labels.

But it was dangerous with Babel 3.8 (I don't know about 3.9) to have a shorthand also mathematically active, as the \normal@char<char> was defined to be the catcode 12 version (if it is already catcode 12 at the time of declaration to babel as a shorthand), but in math mode, with a math active character this creates an infinite loop.

Thus, the \catcode _ 12` thing avoids these potential difficulties.