在下面显示的 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}