6

I've been using Hendrik Vogt's answer to my earlier question Redefine underscore to produce roman subscript, in which he explained how to make the underscore character active and assign a macro to it so that it can be redefined to produce roman type in subscripts:

\catcode`_=\active
\newcommand_[1]{\ensuremath{\sb{\mathrm{#1}}}}

The solution works like a charm in maths and text environments, however I've run into trouble when I use it in 'literal' environments, such as file names or references, where making _ active breaks things.

Question: How can I make the underscore produce roman subscript, yet still function as a normal character in file names, labels, references and the like? I only need the subscript function in maths environments.

MWE:

\documentclass{article}

\catcode`_=\active
\newcommand_[1]{\ensuremath{\sb{\mathrm{#1}}}}

\begin{document}
$D_H$
\label{sec_a} % This causes a "! Missing \endcsname inserted." error
\end{document}

3 Answers 3

7

If you only need the _ in math, then \mathcode does the trick. However, TeX seems to see the \catcode before the \mathcode, so I changed that, too:

\documentclass{article}

\begingroup
  \catcode`\_=\active
  \gdef_#1{\ensuremath{\sb{\mathrm{#1}}}}
\endgroup
\mathcode`\_=\string"8000
\catcode`\_=12

\begin{document}
$D_H$
\label{sec_a} % This no longer causes a "! Missing \endcsname inserted." error
\end{document}

For simplicity I used \gdef here; this can be avoided if you want to.

1
  • Excellent, thank you very much. Your original solution has already saved me so much typing, and I'm glad I don't have to stop using it because of the file name issue.
    – Jake
    Mar 8, 2011 at 22:34
3

You can test for mathmode using \ifmmode like \ensuremath is doing it. This should then be done with two macros so that the "normal underscore" doesn't take an argument:

\documentclass{article}

\catcode`_=\active
\newcommand{_}{\ifmmode\expandafter\sbrm\else\string_\fi}
\newcommand{\sbrm}[1]{\sb{\mathrm{#1}}}

\begin{filecontents}{\jobname_test.tex}
   Read input file test Test!
\end{filecontents}

\begin{document}
\label{sec_a} % Works now
$D_H$

\input{\jobname_test}

\end{document}
3
  • Thanks for the additional approach (and the filecontents environment, that'll definitely come in handy)!
    – Jake
    Mar 8, 2011 at 22:37
  • @Jake: Note that without loading the filecontents package the environment does not overwrite existing files. Mar 8, 2011 at 22:51
  • @Martin Scharrer Your solution is causing troubles using greek in the subscript (like $H_{\alpha}$). Adding an extra \ensuremath solves that: \catcode`_=\active \newcommand{}[1]{\ifmmode\expandafter\ensuremath{\sb{\mathsf{#1}}}\else\string\fi} Anyway, Hendriks approach works out of the box for greek subscript.
    – HannesDamm
    Aug 7, 2017 at 10:09
1

You need not necessarily name labels like that (try \label{sec:a}), and for filenames or other use cases force _ to be an ordinary character:

\input{file\string_name}
1
  • Actually, \_ does this - or not ?
    – Max
    May 27, 2022 at 23:08

You must log in to answer this question.

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