# Why does a defined command appear differently in the align environment?

In the LaTeX document shown below, my definition \comp does not show correctly in the align environment. Why it is this the case?

========== Begin LaTeX scripts =============

\documentclass[12pt,reqno, oneside]{amsart}
%
{\catcode\,=13 \gdef,{\mskip 5mu}} % 5 mu is the space between parts
\def\comp{\bgroup\catcode\,=13\relax\compx}
\def\compx(#1){#1\egroup}
%
\begin{document}
The desired effect of comp'' is
$$\text{The natural numbers are }\comp(1, 2, 3, 4, \dots).$$

However, in the align environment it becomes the following, with annoying commas in between the numbers:
\begin{align*}
\text{The natural numbers are }&\comp(1, 2, 3, 4, \dots).
\end{align*}
\end{document}

-
If you include \usepackage{amsmath} your code seems to work fine. –  Peter Grill Sep 8 '11 at 5:24

A \scantokens free solution is the following:

\newcommand{\comp}{\begingroup\mathcode,=\string"8000 \compx}
\def\compx(#1){\begingroup\lccode~=,
\lowercase{\endgroup\def~}{\mskip 5mu}#1\endgroup}


which has also the advantage that it's not necessary to have a global definition of an active comma. In this code the definition of the active comma is done only at the last moment; of course it's slightly less efficient, but safer, as it limits risks of conflicts.

Caution. Don't use a comma in the definition of the active comma (in the above code the bit {\mskip 5mu}); if it's needed, then

\mathchardef\normalcomma=\mathcode,


issued before tinkering with catcode and mathcode of the comma allows to use \normalcomma in the definition, with the usual meaning for the comma.

# More general implementation

\documentclass[a4paper]{article}
\usepackage{amsmath}
\makeatletter
\@ifundefined{@xp}{\let\@xp\expandafter}{}
\newcommand\DeclareMathActive[2]{%
\ifnum\catcode#1=12
\DMA@math@active{#1}{#2}%
\else
\ifnum\catcode#1=11
\DMA@math@active{#1}{#2}%
\else
\ERROR
\fi
\fi}
\def\DMA@math@active#1#2{\@namedef{DMA#1ACTIVE}{#2}%
\@xp\mathchardef\csname DMA#1INACTIVE\endcsname=\the\mathcode#1 }
\newcommand{\mathactivate}[1]{%
\ifnum\catcode#1=12
\DMA@math@activate{#1}%
\else
\ifnum\catcode#1=11
\DMA@math@activate{#1}%
\else
\ERROR
\fi
\fi}
\def\DMA@math@activate#1{%
\mathcode#1=\string"8000
\begingroup\lccode\~=#1
\@xp\let\@xp\@tempa\csname DMA#1ACTIVE\endcsname
\lowercase\@xp{\@xp\endgroup\@xp\def\@xp~\@xp}\@xp{\@tempa}}
\newcommand{\mathinactive}[1]{\@nameuse{DMA#1INACTIVE}}

\DeclareMathActive{,}{\mskip 5mu}

\begin{document}
$\mathactivate{,}1,2,3$

\DeclareMathActive{,}{abc}

$\mathactivate{,}1,2,3\mathinactive{,}$

\begin{align}
a&=\mathactivate{,}1,2,3
\end{align}

\DeclareMathActive{,}{\mathinactive{,}aaa}
$\mathactivate{,}1,2,3$

\end{document}


The \ERROR command is undefined and should be given a proper meaning in a real world example.

\DeclareMathActive has two arguments: the character and its requested definition. In the second argument one must not use the same character unadorned, but \mathinactive{<char>} is allowed as the last example shows.

One can give new definitions for the character, which obey the normal scope rules. However, if the math activation is required in more than one cell in an alignment, it should be either done outside the alignment or in each cell where it's needed.

-

In math mode you can use \mathcode, a concept somewhat similar to \catcode. The "active" mathcode is 0x8000.

{\catcode\,=\active \gdef,{\mskip 5mu\relax}}
\def\comp(#1){\begingroup \mathcode\,="8000 #1\endgroup}

-
It seems that with this solution, or using \usepackage{amsmath}, the commas are not displayed. However, the 5mu spacing is ignored within the align (more easily seen once you change the spacing to a larger number, say 20mu). –  Peter Grill Sep 8 '11 at 5:31

The align environment reads it's input in and typesets it more than once, in order to achieve the alignment. As a result, the category code of , is fixed as 'other'. On the other hand, a normal math environment ([ ... \] would be better than ) does not read in it's input, so your category code change gets applied. You could use \mathcode, as suggested by Andrey, or could use \scantokens:

\documentclass[12pt,reqno, oneside]{amsart}
%
{\catcode\,=13 \gdef,{\mskip 5mu}} % 5 mu is the space between parts
\def\comp{\begingroup\catcode\,=13\relax\compx}
\def\compx(#1){\scantokens{#1}\endgroup}
%
\begin{document}
The desired effect of comp'' is
$\text{The natural numbers are }\comp(1, 2, 3, 4, \dots).$

However, in the align environment it becomes the following, with annoying commas in between the numbers:
\begin{align*}
\text{The natural numbers are }&\comp(1, 2, 3, 4, \dots).
\end{align*}
\end{document}

-
This does apply the spacing properly, which the \mathcode solution for some reason does not. –  Peter Grill Sep 8 '11 at 5:42