更通用的实现

更通用的实现

在下面显示的 LaTeX 文档中,我的定义\comp在 align 环境中无法正确显示。为什么会这样?

========== 开始 LaTeX 脚本 =============

\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}

答案1

环境align读取其输入并多次排版,以实现对齐。因此,的类别代码,固定为“其他”。另一方面,普通数学环境([...\]比 更好$$)不会读取其输入,因此您的类别代码更改会应用。您可以\mathcode按照 Andrey 的建议使用,也可以使用\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}

答案2

免费的解决方案\scantokens如下:

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

这样做还有一个好处,就是不需要对活动逗号进行全局定义。在此代码中,活动逗号的定义仅在最后一刻完成;当然,这样做效率稍低,但更安全,因为它限制了冲突的风险。

警告。不要在活动逗号的定义中使用逗号(在上面的代码中为位{\mskip 5mu});如果需要,那么

\mathchardef\normalcomma=\mathcode`,

在修改 catcode 和 mathcode 之前发布的逗号允许\normalcomma在定义中使用,其含义与逗号的通常含义相同。

更通用的实现

\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}

\ERROR命令未定义,应在真实世界中的例子中赋予适当的含义。

\DeclareMathActive有两个参数:字符及其请求的定义。在第二个参数中,不能使用未修饰的相同字符,但\mathinactive{<char>}如上一个示例所示,这是允许的。

可以为字符赋予新的定义,这些定义遵循正常的作用域规则。但是,如果在对齐中多个单元格中需要数学激活,则应该这样做外部对齐或每个到需要它的单元格。

答案3

在数学模式中,您可以使用\mathcode,概念有点类似于\catcode。“活动”数学代码为 0x8000。

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

相关内容