27

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?

doncherry
  • 54,637
qwe
  • 475

4 Answers4

20

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}

enter image description here

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
egreg
  • 1,121,712
  • What are the advantages of this code over my more simplistic solution (below)? – JLDiaz Jul 09 '12 at 11:29
  • 2
    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 09 '12 at 11:34
  • @egreg: I think you have a spurious \def\mathunderscore in your first code snippet. – Bruno Le Floch Jul 09 '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 07:29
  • If you do this, be aware of https://tex.stackexchange.com/questions/245880/. – bers Apr 08 '16 at 18:29
11
\catcode`\_=\active
\def_{\relax\ifmmode\sb \else \_\fi}
JLDiaz
  • 55,732
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.

Aditya
  • 62,301
2

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.