修改 eqnarray 以匹配 amsmath 的 align

修改 eqnarray 以匹配 amsmath 的 align

这是\eqnarray对比\align

遗憾的是,一些期刊(及其附带的文档类)仍然需要使用来eqnarray将多个方程式排列在一个块中。修改环境eqnarray以匹配输出的最简单(也是最好的)方法是什么align 没有必须修改输入机制。产生输出align给定第一组方程(在 中),得出第二组方程(在 中eqnarray):

在此处输入图片描述

\documentclass{article}
\usepackage{amsmath}% http://ctan.org/pkg/amsmath
\begin{document}
\begin{eqnarray}
  f(x) & = & ax^2 + bx + c \\
  g(x) & = & dx^2 + ex + f
\end{eqnarray}

\setcounter{equation}{0}
\begin{align}
  f(x) & = ax^2 + bx + c \\
  g(x) & = dx^2 + ex + f
\end{align}
\end{document} 

这个想法是提供一个非常小的包,可以在仍然使用时添加到文档中eqnarray,而无需修改所使用的代码eqnarray

我的第一次尝试是修改设置\eqnarray(从latex.ltx)。目前定义为

\def\eqnarray{%
   \stepcounter{equation}%
   \def\@currentlabel{\p@equation\theequation}%
   \global\@eqnswtrue
   \m@th
   \global\@eqcnt\z@
   \tabskip\@centering
   \let\\\@eqncr
   $$\everycr{}\halign to\displaywidth\bgroup
       \hskip\@centering$\displaystyle\tabskip\z@skip{##}$\@eqnsel
      &\global\@eqcnt\@ne\hskip \tw@\arraycolsep \hfil${##}$\hfil
      &\global\@eqcnt\tw@ \hskip \tw@\arraycolsep
         $\displaystyle{##}$\hfil\tabskip\@centering
      &\global\@eqcnt\thr@@ \hb@xt@\z@\bgroup\hss##\egroup
         \tabskip\z@skip
      \cr
}

显然,方程的三个分量都是这样处理的分别地。此外,在中间组件周围插入一个水平跳过2\arraycolsep,同时使该组件相当于\mathord(将其包裹在内{..})。因此,对此的可能纠正是:

在此处输入图片描述

\documentclass{article}
\usepackage{amsmath}% http://ctan.org/pkg/amsmath
\makeatletter
\def\eqnarray{%
   \stepcounter{equation}%
   \def\@currentlabel{\p@equation\theequation}%
   \global\@eqnswtrue
   \m@th
   \global\@eqcnt\z@
   \tabskip\@centering
   \let\\\@eqncr
   $$\everycr{}\halign to\displaywidth\bgroup
       \hskip\@centering$\displaystyle\tabskip\z@skip{##}$\@eqnsel
      &\global\@eqcnt\@ne${}##{}$% Removed horizontal skip + forced mathord
      &\global\@eqcnt\tw@% Removed horizontal skip
         $\displaystyle{##}$\hfil\tabskip\@centering
      &\global\@eqcnt\thr@@ \hb@xt@\z@\bgroup\hss##\egroup
         \tabskip\z@skip
      \cr
}
\makeatother
\begin{document}
\begin{eqnarray}
  f(x) & = & ax^2 + bx + c \\
  g(x) & = & dx^2 + ex + f
\end{eqnarray}

\setcounter{equation}{0}
\begin{align}
  f(x) & = ax^2 + bx + c \\
  g(x) & = dx^2 + ex + f
\end{align}
\end{document}

还有什么?

答案1

这是一个仅基于激活的强大解决方案&。我希望代码注释得很好:

\documentclass{article}
\usepackage{amsmath}% http://ctan.org/pkg/amsmath

\begingroup % we group everything so that our \catcode changes are local, and we use \gdef everywhere
\makeatletter
\gdef\eqna@origamp{&} % `&` stored
\catcode`\&\active % set `&` active in the scope of these hooks
\gdef\eqna@newamp{%
  \ifx\@currenvir\eqna@currenvir % if the inner-most environment is `eqnarray`
    \eqna@onlyfirstamp\let\eqna@onlyfirstamp\@empty % use `&`, but only once for each line
  \else % if there's another environment inside `eqnarray`
    \eqna@origamp % use `&` as is
  \fi
}
\gdef\eqna@hook{% modification of `eqnarray`
  \let\eqna@currenvir\@currenvir % store the current environment, which is `eqnarray` or `eqnarray*`
  \catcode`\&\active % `&` has to be active
  \let&\eqna@newamp % define `&` expansion
  \let\eqna@onlyfirstamp\eqna@origamp % `&` that is used only once on a line
  }
\catcode`\*11 % set `*` letter so that we can redefine `eqnarray*`
\gdef\eqnarray{\eqna@hook\align} % `eqnarray` is our hooks and `align`
\gdef\eqnarray*{\eqna@hook\align*} % `eqnarray*` is our hooks and `align*`
\global\let\endeqnarray\endalign
\global\let\endeqnarray*\endalign*
\endgroup

\begin{document}\thispagestyle{empty}

\begin{eqnarray}
  f(x) & = & \begin{cases} 1 & x\geq0 \\ 0 & x<0 \end{cases}\\
  \begin{pmatrix}1&0\\0&1\end{pmatrix} & = & dx^2 + ex + f \nonumber\\
  kkk(x) & = & gx^2 + kx + m
\end{eqnarray}

\begin{align}
  f(x) & = \begin{cases} 1 & x\geq0 \\ 0 & x<0 \end{cases}\\
  \begin{pmatrix}1&0\\0&1\end{pmatrix} & = dx^2 + ex + f \notag\\
  kkk(x) & = gx^2 + kx + m
\end{align}

\end{document}

答案2

将 eqnarray 转换为 align

原始热情:当我看到它起作用时,我简直不敢相信。好吧,在这个非常小的情况下,它确实有效,但我想在现实生活中肯定会失败

当我提出这个方法时,我犹豫了是使用一种active &方法(tochecz代码似乎非常稳健地实现了这个方法)还是使用分隔参数的更实际的方法。我很惊讶分隔参数方法能够快速工作,所以我在这里发布了它,然后扩展到多行情况。我还浪费了一些时间扩展到多选项卡,因为我不知道那eqnarray 是一种严格的三列格式,有两个选项卡。

但是,如果想要扩展代码以允许\begin{env}...\end{env}这样做,则需要付出相当大的努力。实际上,可能要重新创建 amsmath\collect@body或类似代码(也许可以强制它在这里为我们服务)。这是我在这个阶段的一点想法,因为我当时正忙于其他事情,回来后发现已经tochecz用该技术实现了转化的想法active &,这显然是更好的选择。所以纯粹出于感性,我将在这里留下一些我的初始代码。

\documentclass{article}
\usepackage{amsmath}% http://ctan.org/pkg/amsmath

\newtoks\arraytoaligntoks

%% Initial version for two lines
%%\long\def\eqnarray #1&#2&#3\\#4&#5&#6\end{%
%%    \arraytoaligntoks={#1&#2#3\\#4&#5#6}%
%%    \edef\endeqnarray{\noexpand\begin{align}\the\arraytoaligntoks
%%                     \noexpand\end{align}}\end}

%% version for arbitrarily many lines*
%% But this will fail completely if some \begin..\end is not within braces


\def\transmute #1&#2&#3\\{\arraytoaligntoks\expandafter
                     {\the\arraytoaligntoks #1&#2#3}}

\def\jfbu{\jfbu}

\long\def\eqnarray #1\end{\arraytoaligntoks{}%
    \def\\##1\\{\transmute ##1\\%
                \def\\####1\\{\ifx\jfbu####1\jfbu\else
                \arraytoaligntoks\expandafter{\the\arraytoaligntoks \\}%
                \transmute ####1\\\expandafter\\\fi}\\}%
    \\#1\\\\%
    \edef\endeqnarray{\noexpand\begin{align}\the\arraytoaligntoks
                      \noexpand\end{align}}\end}



\begin{document}\thispagestyle{empty}

\begin{eqnarray}
  f(x) & = & ax^2 + bx + c \\
  g(x) & = & dx^2 + ex + f \nonumber\\
  k(x) & = & gx^2 + kx + m
\end{eqnarray}

\begin{align}
  f(x) & = ax^2 + bx + c \\
  g(x) & = dx^2 + ex + f \notag\\
  k(x) & = gx^2 + kx + m 
\end{align}

\end{document}

逐字逐句地使用代码

相关内容