summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/eqnalign/eqnalign.dtx
blob: 7361e689b15137de229241c0982cbed62c696c65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
% \iffalse meta-comment
%!TeX program = T_do_dtx
% 
% This part is not going to appear anywhere so is good for 'header'
% information.
%
%
%<*driver>
\documentclass{ltxdoc}

\usepackage[vmargin=0.7in,hmargin={1.5in,0.6in},marginparsep=0.1in,marginparwidth=1in,a4paper]{geometry}
\usepackage{lmodern,anttor}
\usepackage[T1]{fontenc}
\usepackage{enumerate}
\usepackage{xcolor}
\usepackage{url, hyperref}
\usepackage{amsmath}

\DisableCrossrefs
\CodelineNumbered
\def\theCodelineNo{{\color{black}\normalfont\fontseries{sb}\selectfont\footnotesize\arabic{CodelineNo}}}
\def\MacroFont{\ttfamily\color{blue}}

% Whatever packages here
%
% Might include
% \usepackage{\jobname}
%
% Very handy is
% \usepackage[numbered]{hypdoc} % hyperref for l3doc
%
% You might want the following
%\EnableCrossrefs
%\CodelineIndex
%\RecordChanges
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% ^^A Comments in the documentation part start ^^A
%
% ^^A If you use the extracted package itself you can do
% \GetFileInfo{\jobname.sty}
% ^^A and define \filedate, etc.
%
% ^^A Meta data for the package
% \title{\pkg{mypkg}\thanks{^^A
%   This file describes version \fileversion, last revised \filedate.^^A
% }}
% \author{^^A
%   Tom Hejda\thanks{E-mail: tohecz@gmail.com}^^A
% }
% \date{Released \filedate}
%
% ^^A \section{User documentation}
%
% ^^A User documentation would appear here.
%
% ^^A This will appear at the end of the PDF, which might or might not include
% ^^A the typeset code
% \StopEventually{^^A
%   \PrintChanges
%   \PrintIndex
% }
%
% \vspace*{2cm}
% \begingroup
%  \centering
%  {\Huge\bfseries \LaTeX\@ package \texttt{eqnalign}\par}
%  \bigskip
%  {\Large\bfseries --- --- making |eqnarray|(|*|) look and work like |align|(|*|) --- ---\par}
%  \bigskip
%  {\Large by Tom Hejda, \texttt{tohecz@gmail.com}\par}
% \endgroup
% \vspace*{2cm}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{The goal}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The goal of this package is to allow easy conversion from the insanely-looking |eqnarray| to
%  the look and behaviour of |align| from |amsmath|.
% It is inspired by a \TeX.StackEchange question \url{http://tex.stackexchange.com/q/96210/11002} by a user called ``Werner'',
%  and by an answer of mine to the question.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{The behaviour}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The package is activated by simply loading it, and it does not have any package options.
% It just redefines |eqnarray| and |eqnarray*|,
%  and then it makes |amsthm| aware of this redefinition so that |\qedhere| works inside these environments.
% At the same time, we keep the original definition od |eqnarray| and |eqnarray*| as |EQNarray| and |EQNarray*|,
%  respectively.
% Note that |hyperref| modifies |eqnarray|, so the package shall be loaded after |hyperref|;
%  this also means that |hyperref| tweaks do not make it into |EQNarray|(|*|).
%
% The main feature is implemented in a simple way:
% We keep track of |&| count, and we disable the 2nd |&| of each line.
% (Note that we also disable the 5th, 8th etc.\@ ones.)
% We do it in a way that correctly interacts with cases such as when |array| or |matrix| is inside the environment.
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{License and remarks}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \begin{enumerate}[(A)]
%
% \item
% The package is licensed under the \LaTeX\@ Project Public License version 1.3c (LPPL v1.3c) or higher.
% The latest version of this license is in \url{http://www.latex-project.org/lppl.txt}\,.
%
% \item
% Note that actually, the usage of this package is discouraged, in favour of converting the code into
%  proper ``|amsmath| code'', using the true |align| and |align*| environments.
% It is intended for cases where a lot of already existing code needs to be converted and there
%  is no capacity for doing it the right but time-consuming way.
%
% \item
% All bugs shall be reported to the GitHub page \url{http://github.com/tohecz/eqnalign}\,.
% Just note that unless the bug is crucial or easy to deal with, it may not be fixed since
%  (per the previous remark) single problematic cases shall be dealt with by other means.
%
% \end{enumerate}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Known issues}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \begin{enumerate}[(1)]
%
% \item
% Due to catcode changes, |eqnarray| will not work inside macro arguments and similar contexts.
%
% \item
% \fboxsep-5pt
% Note that as the package actually ignores the 2nd |&| of an |eqnarray| line,
%  it in turn kills the alignment in cases such as the following:
% \\[-\baselineskip]
% \begin{tabular}[c]{@{}p{0.55\linewidth}@{}}
% \begin{verbatim}
%\begin{eqnarray*}
%  A & = & 104 x^5 + 84 x^4 + 53 x^3 \\
%    &   & + 17 x^2 + 4 x - 1043
%\end{eqnarray*}\end{verbatim}
% \end{tabular}
% \fbox{\parbox[c]{0.35\linewidth}{\begin{eqnarray*}
%   A & = & 104 x^5 + 84 x^4 + 53 x^3 \\
%     & & + 17 x^2 + 4 x - 1043
%  \end{eqnarray*}}}
% \vspace{-\baselineskip}
%
% This becomes, when |eqnalign| is loaded:
% \\[-\baselineskip]
% \begin{tabular}[c]{@{}p{0.55\linewidth}@{}}
% \begin{verbatim}
%\begin{align*}
%  A & = 104 x^5 + 84 x^4 + 53 x^3 \\
%    & + 17 x^2 + 4 x - 1043
%\end{align*}\end{verbatim}
% \end{tabular}
%  \fbox{\parbox[c]{0.35\linewidth}{\begin{align*}
%   A & = 104 x^5 + 84 x^4 + 53 x^3 \\
%     & + 17 x^2 + 4 x - 1043
%  \end{align*}}}
% \vspace{-\baselineskip}
%
% However, the prefered form would be, for instance:
% \\[-\baselineskip]
% \begin{tabular}[c]{@{}p{0.55\linewidth}@{}}
% \begin{verbatim}
%\begin{align*}
%  A & = 104 x^5 + 84 x^4 + 53 x^3 \\
%    & \phantom{={}} + 17 x^2 + 4 x - 1043
%\end{align*}\end{verbatim}
% \end{tabular}
%  \fbox{\parbox[c]{0.35\linewidth}{\begin{align*}
%   A & = 104 x^5 + 84 x^4 + 53 x^3 \\
%     & \phantom{={}} + 17 x^2 + 4 x - 1043
%  \end{align*}}}
% \vspace{-\baselineskip}
%
% This issue is actually somehow inherited from |align|, which in stardard usage shows the very same behaviour.
%
%
% \end{enumerate}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Implementation}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Note that we in general say |eqnarray| where we really mean either |eqnarray| or |eqnarray*|.
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% Package header.
%    \begin{macrocode}
\ProvidesPackage{eqnalign}[2017/02/19 v1.0a Make eqnarray(*) behave like align(*).]
%    \end{macrocode}
% The only necessary package is |amsmath| so that |align| and |align*| are defined.
%    \begin{macrocode}
\RequirePackage{amsmath}
%    \end{macrocode}
%
% The package does some catcode mysteries that shouldn't propagate out, so we make everything
%  in a group and use |\gdef| everywhere.
%    \begin{macrocode}
\begingroup
%    \end{macrocode}
%
% \begin{macro}{\eqna@tab@amp}
%    We store a catcode-4 (tab alignment char) |&| in a macro.
%    We need a catcode-13 (active) |&| througout the rest of the package.
%    \begin{macrocode}
\catcode`\&=4
\gdef\eqna@tab@amp{&}
\catcode`\&=13
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqna@new@amp}
%    This will be the replacement of |&| inside |eqnarray|.
%    We use |\eqna@amp@| if the innermost environment is |eqnarray| and |\eqna@tab@amp| otherwise;
%     this is to allow things like arrays and matrices inside |eqnarray|.
%    \begin{macrocode}
\gdef\eqna@new@amp{%
	\ifx\@currenvir\eqna@currenvir 
		\expandafter\eqna@amp@
	\else
		\expandafter\eqna@tab@amp
	\fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqna@amp@i}
% \begin{macro}{\eqna@amp@ii}
% \begin{macro}{\eqna@amp@iii}
%    Three macros that are ``rotated'', after the first, the second shall be used, then the third.
%    The third one ends a group since it ends a table cell,
%     therefore after that the first one is again in action.
%    The first |&| on a line is kept, the second is ignored, the third is kept.
%    \begin{macrocode}
\gdef\eqna@amp@i{\eqna@tab@amp\let\eqna@amp@\eqna@amp@ii}
\gdef\eqna@amp@ii{\let\eqna@amp@\eqna@amp@iii}
\gdef\eqna@amp@iii{\eqna@tab@amp}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\eqna@doamp}
%    The default is |\eqna@amp@i|.
%    \begin{macrocode}
\global\let\eqna@amp@\eqna@amp@i
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\eqna@hook}
%    Hook exectuted at the beginning of |eqnarray|.
%    We store the current environment, which is either |eqnarray| or |eqnarray*|;
%     it is used in |\eqna@new@amp| for the test for nested environments.
%    Then we activate |&| and make its meaning |\eqna@new@amp|.
%    \begin{macrocode}
\gdef\eqna@hook{%
	\let\eqna@currenvir\@currenvir
	\catcode`\&=\active
	\let&\eqna@new@amp
}
%    \end{macrocode}
% \end{macro}
%
% Now we will be defining environments containing |*| in name, so we make it a letter.
%    \begin{macrocode}
\catcode`\*=11
%    \end{macrocode}
%
% \begin{macro}{\eqna@def@env}
% \begin{macro}{eqnarray}
% \begin{macro}{eqnarray*}
%    We define a macro |\eqna@def@env| that contains the redefinitions of |eqnarray| (and |eqnarray*|).
%    The environments themselves are like |align|, just hooked using |\eqna@hook|.
%    We then call this macro immediately to define the environments.
%    (All this fuss with |\eqna@def@env| is to correct things in case |hyperref| is loaded after |eqnalign|.
%    \begin{macrocode}
\gdef\eqna@def@env{%
	\gdef\eqnarray{\eqna@hook\align}%
	\gdef\eqnarray*{\eqna@hook\align*}%
	\global\let\endeqnarray\endalign
	\global\let\endeqnarray*\endalign*
}
\eqna@def@env
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\eqnarray@qed}
% \begin{macro}{\eqnarray*@qed}
%    To make |amsthm|'s |\qedhere| work in |eqnarray|, we need to ``hint'' |amsthm| that it exists
%    \begin{macrocode}
\global\let\eqnarray@qed\align@qed
\global\let\eqnarray*@qed\align*@qed
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% End the group we began at the very beginning.
%    \begin{macrocode}
\endgroup
%    \end{macrocode}
%
% \begin{macro}{EQNarray}
%    Just of sentiment, we keep the original |eqnarray| as |EQNarray|;
%     the code is a verbatim copy from |ltmath.dtx| (part of \LaTeXe\@ kernel).
%    \begin{macrocode}
\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
}
\def\endEQNarray{%
		\@@eqncr
		\egroup
		\global\advance\c@equation\m@ne
	$$\@ignoretrue
}
\@namedef{EQNarray*}{\def\@eqncr{\nonumber\@seqncr}\EQNarray}
\@namedef{endEQNarray*}{\nonumber\endEQNarray}
%    \end{macrocode}
% \end{macro}
%
% Last but not least, if |hyperref| is loaded after |eqnalign| (and only in that case),
%  we issue a warning since |hyperref| is doing bad things to |eqnarray|, and we redefine |eqnalign| once more.
%    \begin{macrocode}
\@ifpackageloaded{hyperref}{}{
	\AtBeginDocument{
		\@ifpackageloaded{hyperref}{
			\@latex@warning{Package `eqnalign' should be loaded after
			`hyperref'.\MessageBreak Redefining `eqnarray' and `eqnarray*' at this
			point \MessageBreak and crossing fingers...}
			\eqna@def@env
		}{}
	}
}
%    \end{macrocode}
%
% That's all.
%    \begin{macrocode}
\endinput
%    \end{macrocode}
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale