遗憾的是,一些期刊(及其附带的文档类)仍然需要使用来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\\#4\end{%
%% \arraytoaligntoks={#1#3\\#4#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\\{\arraytoaligntoks\expandafter
{\the\arraytoaligntoks #1#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}