# How can I set underscore to be a letter for use in normal macro names?

I'd like to change the category code of the underscore _ to 11 from 8 temporarily in two places. Why doesn't my code work? It seems to work for @ when using \makeatletter.

1. Once for the list of definitions (one def in my example).
2. In the document when I need to call the macros (up to n times).

# Code

\documentclass{article}
\usepackage{fontspec}% xelatex

\def\setfields{\catcode\_=11}   % set underscore to letter
\def\endsetfields{\catcode\_=8} % restore underscore to subscript

\begingroup
\catcode\_=11
\def\AAA_BBB_CCC{Highly specialized TeX operations in progress.}
\endgroup

\begin{document}

\begin{setfields}
\AAA_BBB_CCC
\end{setfields}

\end{document}


Try

\begingroup
\catcode\_=11
\def\AAA_BBB_CCC{Highly specialized TeX operations in progress.}
\endgroup
\begin{setfields}
\show\AAA_BBB_CCC
\end{setfields}


and you'll discover that \AAA_BBB_CCC is undefined. Why is it so? Because \def respects grouping.

Do

\catcode\_=11
\gdef\AAA_BBB_CCC{Highly specialized TeX operations in progress.}
\endgroup


instead, so \AAA_BBB_CCC is defined globally.

Maybe better:

\documentclass{article}

\newenvironment{setfields}
{\catcode\_=11 \ignorespaces}
{\ignorespacesafterend}

% define the _ commands
\chardef\underscorecatcode=\catcode\_ \catcode\_=11

\newcommand\AAA_BBB_CCC{Highly specialized TeX operations in progress.}

\catcode\_=\underscorecatcode
% end of definitions for _ commands

\begin{document}

\begin{setfields}
\AAA_BBB_CCC
\end{setfields}

\end{document}

• That is a nice use of \chardef`. Curious, is that in there for an educational purpose or some other reason. You could have just referred to the standards and set the category code of the underscore back to 8, explicitly, like I did. – Jonathan Komar Apr 18 '18 at 6:27
• @JonathanKomar Maybe a document loads a package that changes the category code of the underscore… – egreg Apr 18 '18 at 6:31