ifacconf.cls 和包含超过十二个方程的子方程存在错误

ifacconf.cls 和包含超过十二个方程的子方程存在错误

我正在写一篇论文国际会计师联合会你应该使用他们的会议配置文件subequations,从而得到一个相当标准的布局。但是,当您使用( ) 包含十二个或更多方程式(L 是第十二个字母)时,会出现错误amsmath。原来,类文件重新定义了输出\alph,因此\alph{12}返回的\ell是 而不是l

\def\@alph#1{\ifcase#1\or a\or b\or c\or d\or e\or f\or g\or h\or i\or j\or % line  1402
k\or \ell\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or

[...]

et\or eu\or ew\or ex\or ey\or ez\else\@ctrerr\fi} % line 1414

我猜这样做的动机是为了避免因小写 l、大写 i 和数字 1 的相似性而产生混淆。但是,他们不可能对此进行非常彻底的测试,因为这\ell是一个数学模式命令;当在公式标签中使用时,它会引发错误,这并不奇怪。在花时间找出此错误的原因之前,我想到了一些解决方法。一个明显的解决方法当然是用\ell\ensuremath{ell}简单地l在类文件中替换,但如果您与不知道如何(或没有必要的管理员权限)修改类文件的人合作,这种方法不会对您有很大帮助。如何最好地解决这个问题?我在这里回答我自己的“问题”(我认为每个答案一个可能的修复是最好的方法 --- 如果我错了,请纠正我),但如果有人有更好的建议,我会非常感兴趣。

这是一个引发错误的 MWE:

\documentclass{ifacconf}
\usepackage{amsmath}
\usepackage{natbib} % required by ifacconf.cls?

\begin{document}

\begin{subequations}
\begin{gather}
  a = 1  \\
  b = 2  \\
  c = 3  \\
  d = 4  \\
  e = 5  \\
  f = 6  \\
  g = 7  \\
  h = 8  \\
  i = 9  \\
  j = 10 \\
  k = 11  
\\l = 12  % comment out this line to compile successfully 
\end{gather}
\end{subequations}

\end{document}

答案1

只需添加到你的序言中

\protected\edef\ell{\noexpand\ensuremath{{\mathchar\the\ell}}}

您将获得\alph他们喜欢的风格(并且当您选择最多 12 件商品时不会出现错误)。

完整示例:

\documentclass{ifacconf}
\usepackage{amsmath}
\usepackage{natbib}

\protected\edef\ell{\noexpand\ensuremath{{\mathchar\the\ell}}}

\begin{document}

\begin{subequations}
\begin{gather}
  a = 1  \\
  b = 2  \\
  c = 3  \\
  d = 4  \\
  e = 5  \\
  f = 6  \\
  g = 7  \\
  h = 8  \\
  i = 9  \\
  j = 10 \\
  k = 11 \\
  l = 12
\end{gather}
\end{subequations}

\end{document}

在此处输入图片描述

我们在做什么?我们必须修复\@alph类对 的错误重新定义,它\ell在文本模式下使用,而这仅在数学模式下是合法的。我们可以简单地获取类中的代码并在整个过程中更改为\ell$\ell$但我们可以用更巧妙的方式来做到这一点,而是更改 的定义\ell

\ell因此我们需要小心:首先,我们必须保留其他地方的含义;其次,我们希望\ell在数学模式下输入能够正确执行;第三,我们必须确保重新定义能够经受住全面扩展。可能的重新定义可能是

\let\latexell\ell
\renewcommand{\ell}{\ensuremath{\latexell}}

如果我们这样做,并添加\label{test}到最后一行(最终编号为 1ℓ 的行),我们将在.aux文件中

\newlabel{test}{{1\ensuremath  {\latexell }}{1}}

虽然正确,但它提到了\latexell应该避免的事情。可以使用\DeclareRobustCommand以下方式代替\renewcommand

\let\latexell\ell
\let\ell\relax % to avoid a spurious warning
\DeclareRobustCommand{\ell}{\ensuremath{\latexell}}

在这种情况下,文件中的行将.aux

\newlabel{test}{{1\ell  }{1}}

更巧妙的方法是使用一些低级技巧。

  1. \the\ell扩展为分配给的数学代码\ell

  2. \protected创建一个在“危险上下文”中根本不扩展的控制序列

  3. \edef扩展一切可扩展的东西

因此我们可以

\protected\edef\ell{\noexpand\ensuremath{{\mathchar\the\ell}}}

不会\edef扩展\ensuremath,因为\noexpand它前面有;它不会扩展\mathchar,这是不可扩展的;但它会扩展\the\ell。因此重新定义的宏\ell可以做到

\ensuremath{{\mathchar<math code>}}

我们从哪里<math code>得到了正确的值\the\ell。如果我们用检查宏\show\ell,我们会发现

> \ell=\protected macro:
->\ensuremath {{\mathchar 352}}.

现在文件.aux将具有

\newlabel{test}{{1\ell }{1}}

优点是没有\latexell宏;我们也不需要查找分配给的数学代码\ell:我们让 TeX 使用它已经知道的内容。

答案2

最简单的解决方案可能是更新序言中的\ell.\renewcommand{\ell}{l}以修复子方程中的编号,但如果在其他地方使用,当然会破坏“\ell”。您可以在本地执行此操作:

\begin{subequations}
\renewcommand{\ell}{l}
\begin{gather}
  [math]

但是,你不能\ell在该方程组中使用。如果你添加

\let\oldell\ell
\renewcommand{\ell}{\ensuremath{\oldell}}

相反,如果将公式标签改为序言,则不会中断\ell,但第十二个公式标签看起来有点不对劲(在直立的 k 后面有一个倾斜的 ell)。当然,这也可以在本地完成。我个人不喜欢这些修复,因为我更喜欢l子公式标签中的正常形式。

答案3

在任何具有十二个或更多标签的方程式中,我都采取了以下方法:

\begin{subequations}
\renewcommand{\theequation}{\theparentequation\MakeLowercase{\Alph{equation}}}
\begin{gather}
  [math]

虽然不是很优雅,但它确实完成了工作(你l在第十二个标签中得到了一个正常值,并且没有改变ell)。请注意

\renewcommand{\theequation}{\theparentequation\alph{equation}}

不会起作用,因为重新定义alph首先被破坏了。

相关内容