Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
    
If you include \usepackage{amsmath} your code seems to work fine. –  Peter Grill Sep 8 '11 at 5:24
add comment

3 Answers

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}
share|improve this answer
1  
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
add comment

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}
share|improve this answer
    
This does apply the spacing properly, which the \mathcode solution for some reason does not. –  Peter Grill Sep 8 '11 at 5:42
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.