summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/calculation/calculation.dtx
blob: aa5b57ac97a9af913436f0198bc1045c601e9eeb (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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
%
% \title{The calculation environment\\
%   \normalsize formatting reasoned calculations and calculational proofs}
%
% \author{Maarten Fokkinga ({m.m.fokkinga@gmail.com})}
% \maketitle
% \MakeShortVerb{\"}
% \begin{abstract}
%   \noindent
%   The "calculation" environment formats \emph{reasoned calculations},
%   also called \emph{calculational proofs}.  The notion of reasoned
%   calculations was originally advocated by Wim Feijen and Edsger
%   Dijkstra.  The "calculation" package accepts options "fleqn" and
%   "leqno" (with the same effect as \LaTeX\ options "fleqn" and "leqno",
%   and inherits these from the document class), it allows steps and
%   expressions to be numbered (by \LaTeX\ equation numbers, obeying the
%   \LaTeX\ "\label" command to refer to these numbers), and a step
%   doesn't take vertical space if its hint is empty.  An expression in a
%   calculation can be given a comment; it is placed at the side opposite
%   to the equation numbers.  
%   \par 
%   Calculations are allowed inside hints although numbering and
%   commenting is then disabled.  
% \end{abstract}
% 
% \section{User manual}
% This package provides the "calculation" environment, to format
% \emph{reasoned calculations}, also called \emph{calculational proofs}.
% The \emph{steps} in the calculation are vertically listed, and each step
% is accompanied by a (possibly empty) \emph{hint}, explaining why the
% step is valid. This style was originally advocated by Wim Feijen and
% Edsger Dijkstra.  The "calculation" package accepts options "fleqn" and
% "leqno" (with the same effect as \LaTeX\ options "fleqn" and "leqno",
% and inherits these from the document class), it allows steps and
% expressions to be numbered (obeying \LaTeX's "\label" command to refer
% to these numbers).  A step doesn't take vertical space if its hint is
% empty.  An expression in a calculation can be given a comment; it is
% placed at the side opposite to the equation numbers.  
% \par 
% Calculations are allowed inside hints by the "subcalculation"
% environment (for small calculations which do not deserve a separate
% discussion before or after the main calculation), although numbering
% and commenting is then disabled.
% 
% \iffalse ================= BEGIN example ===============================
%    Here is some stuff to generate file "calculation.expl", containing an
%    example of the "calculation" environment.  This file will be read
%    twice: once to show it verbatim, and once to show \LaTeX's output.
%
%    In order to process this example, this file that you are reading now
%    should be used as package. Thus, assuming that this file is called
%    calculation.dtx, the driver file should have in its prelude:
%    \makeatletter
%    \input{calculation.dtx}
%    \calc@fleqn\calc@leqno\calc@blocktrue % options: fleqn, leqno, block.
%    \makeatother
%    Once "calculation.sty" has been generated, you may use
%       \usepackage[fleqn,leqno,block]{calculation}
%    instead.
% ==================================================================== \fi
% \iffalse From the \TeX book, page 422: \fi
% \chardef\other=12
% \newwrite\expl
% \immediate\openout\expl=calculation.example
% \def\copytoblankline{\begingroup\setupcopy\copyexpl}
% \def\setupcopy{\def\do##1{\catcode`##1=\other}\dospecials
%    \catcode`\|=\other \obeylines}
% {\obeylines \gdef\copyexpl#1
%    {\def\next{#1}%
%    \ifx\next\empty\let\next=\endgroup %
%    \else\immediate\write\expl{\next} \let\next=\copyexpl\fi\next}}
% \copytoblankline%
% \begin{verbatim}
% Demo:
% \begin{calculation}[\approx]
%    expr \comment{cmnt!}
% \step*{\label{N}%
% This step has nbr~\ref{N}}
%    expr
% \step*{}
%    \label{N2}
%    expr~left~part~~~ + ~~~
%    \\
%    expr~right~part
% \step[=]{
%    left part:\\
%    \begin{subcalculation}[\leq]
%       expr
%    \step{hint}
%       expr
%    \step{hint}
%       expr
%    \end{subcalculation}
%    \\
%    right part, similarly:\\
%    \begin{subcalculation}
%       expr \step{} expr
%    \step{} expr
%    \end{subcalculation}
%    \\
%    end of hint
%    }
%    \doNumber\label{E}
%    this~expr~has~number~\ref{E}
% \step{hint 1st line\\
% hint 2nd line}
%    expr
% \end{calculation}
% Note: step (\ref{N2}) is empty.
% \end{verbatim}

% \iffalse Previous blank line is significant! \fi
% \immediate\closeout\expl
% \IfFileExists{calculation.example}{
%       \subsection{Example}
%       \newsavebox{\fminibox}
%       \newlength{\fminilength}
%       \newenvironment{fminipage}[1][\linewidth]
%        {\setlength{\fminilength}{##1}%
%         \begin{lrbox}{\fminibox}\begin{minipage}{\fminilength}}
%        {\end{minipage}\end{lrbox}\noindent
%         \makebox[0pt][r]{\fbox{\usebox{\fminibox}}}\ignorespaces}
%       Here is an example (with options "fleqn", "leqno", and "block",
%       and default step symbol `$=$'); \LaTeX\ source on the left,
%       output on the right:
%       \par\noindent
%       \begin{center}\hspace*{-0.08\linewidth}
%       \begin{fminipage}[0.43\linewidth]
%       \input{calculation.example}
%       \end{fminipage}%
%       \renewenvironment{verbatim}{\relax}{\relax}%
%       \makebox[0pt][l]{\fbox{\begin{minipage}{0.5\linewidth}
%       \input{calculation.example}
%       \end{minipage}}}
%       \end{center}}{}
% \iffalse ================= END of example ========================= \fi
% \iffalse ========================================================== \fi
%
% \subsection{Usage}
% The "calculation" environment is used in it most simple form as
% follows:
% \pagebreak[3]
% \begin{verbatim}
%    \begin{calculation}
%        EXPRESSION
%    \step{HINT}
%       EXPRESSION
%    \step{HINT}
%       EXPRESSION
%     ...
%    \end{calculation}\end{verbatim}
% Each "HINT" is normal text, each "EXPRESSION" is mathematical text.\par
% Depending on various parameters, the output is, more or less, like
% this:
% \begin{verbatim}
%      EXPRESSION
%    =   { HINT }
%      EXPRESSION
%    =   { HINT }
%      EXPRESSION
%    ...\end{verbatim}
% Command "\stepsymbol" defines the default step symbol, "=" in the
% above example; it can be redefined with "\renewcommand". Moreover, the
% "calculation" environment itself has an optional parameter, overruling
% the default step symbol in this specific calculation, and even each
% step has an optional parameter giving the step symbol for that
% particular step. Command "\step*" produces a step that is numbered
% with an equation number, as in \LaTeX; \LaTeX\ command "\label" may be
% used to label the number so that references can be made to it. Command
% "\doNumber" inside an EXPRESSION produces an equation number. Command
% "\comment{TEXT}" inside an EXPRESSION produces TEXT at the side of the
% paper opposite to the equation number side.  So, in full glory, the
% environment has the following appearance:
%    \begin{macrocode}
%% ==================== Usage ====================================
%%
%%    \begin{calculation}[SYMBOL]
%%       EXPRESSION   <-- may contain \doNumber and \comment{TEXT}
%%    \step*[SYMBOL]{HINT}
%%       EXPRESSION   <-- may contain \doNumber and \comment{TEXT}
%%    \step*[SYMBOL]{HINT}
%%       EXPRESSION   <-- may contain \doNumber and \comment{TEXT}
%%       ...
%%    \end{calculation}
%%    Each asterisk "*" and each part "[...]" is optional. 
%%
%    \end{macrocode}
% An empty "HINT"
% takes no vertical space while the "SYMBOL" is still vertically
% centered in between the two "EXPRESSIONs". Both in "EXPRESSION" and in
% "HINT" new lines may be generated by~"\\". As in \LaTeX, "EXPRESSION"
% may not contain empty lines. Hints may have empty lines, even at the
% beginning.
%
% Option "block" makes the entire hint (possibly several lines) into one
% block which, as a whole, is surrounded by delimiters.
%
% Page breaks will occur only immediately after a step-plus-hint; a
% page break within or after an expression would be confusing for the
% reader.
% 
% \subsection{Options and document style parameters}
% By default, calculations are placed horizontally centered on the page,
% but when the entire document has option "fleqn" (``flush left
% equations''), or when the package is given this option explicitly,
% then calculations are placed flush left.
% 
% By default, calculations have their step and expression numbers at the
% right side of the page (just as in \LaTeX), but when the entire
% document has option "leqno" (``left equation numbers''), or when the
% package is given this option explicitly, then calculations are placed
% at the left side of the page.
% 
% By default, the first line of a "HINT" is opened by "\Hlineopen" and
% the last one is closed by "\Hlineclose" (braces in the above example),
% but when option "block" is given to the package, then the entire hint
% is made into one block surrounded by "\Hblockopen" and "\Hblockclose".
% Both "\Hblockopen" and "\Hblockclose" must be ``delimiters'' so that
% they can be stretched vertically. At least the following symbols are
% delimiters: braces~$\{~\}$, brackets~$[~]$, vertical bar~$|$, vertical
% double bar~$\|$, angles~$\langle~\rangle$, and ``nothing'' (in \LaTeX\
% indicated by a dot~".").  These commands can be redefined with
% "\renewcommand".
%
% The amount of space between "\Hlineopen" and the first token of the
% hint is given by "\Hsep".  The amount of indentation of the text of a
% hint, relative to the expressions, is given by "\Hindent" plus "\Hsep"
% (plus the width of "\Hblockopen" if option "block" is valid).
% 
%
% In summary, the following are the style parameters and options:
%    \begin{macrocode}
%% -------------- DOCUMENT STYLE PARAMETERS ------------------------
%% options:
%%    fleqn, leqno, block
%% commands:
%%    \newcommand{\stepsymbol}{=}
%%    \newcommand{\Hblockopen}{|} 
%%    \newcommand{\Hblockclose}{.} 
%%    \newcommand{\Hlineopen}{\lbrace}
%%    \newcommand{\Hlineclose}{\rbrace}
%%    \newcommand{\Hindent}{1em}
%%    \newcommand{\Hsep}{1ex}
%%    \newcommand{\calculcolsep}{\arraycolsep}
%%    \newcommand{\Hposv}{t}
%%     % vertical position of the step symbol in front of a block hint
%% These default values may be redefined by "\renewcommand".
%    \end{macrocode}
%%
\iffalse ============================== code =======================\fi
% \section{The LaTeX code for the macros}
%
%    \begin{macrocode}

\def\fileversion{1.00}
\def\filedate{5 Jan 2015}
\def\docdate{5 Jan 2015}

\ProvidesPackage{calculation}[2014/12/05 Format reasoned calculations]

%    \end{macrocode}
% \changes{v0.x}{1991-2014}{Ugly constructed, ugly to use, nice output}
% \changes{v1.00}{5 Jan 2015}{Original idea implemented anew}

%
% \noindent
% All auxiliary variables specific to this package are named as follows:
% \begin{verbatim}
%   \calc@.... or
%   \subcalc@... or
%   \ifcalc@... or 
%   \endcalc@...
% \end{verbatim}
% Here are the options "fleqn", "leqno", and "block", and their effect:
%    \begin{macrocode}

\DeclareOption{fleqn}{\calc@fleqn}
\DeclareOption{leqno}{\calc@leqno}
\DeclareOption{block}{\calc@blocktrue}

%    \end{macrocode}
%
% \subsection{Preliminary auxiliaries}
% To place comments and step/expr numbers at opposite sides, we place
% them in a very wide box at the right side of the page, and
% surround them by suitable fill's:
% \begin{verbatim}
%    ... \calc@eqnoLfil <exprno>  \calc@eqnoRfil ...
%    ... \calc@eqnoLfil <stepno>  \calc@eqnoRfil ...
%    ... \calc@eqnoRfil <comment> \calc@eqnoLfil ...
% \end{verbatim}
% Depending on the options, these ``fill''s are set to "\hfil" or "{}".
% We first check that these fill commands are not yet in use:
%    \begin{macrocode}

\newcommand{\calc@fill}{\relax}
\newcommand{\calc@eqnoLfil}{\relax}
\newcommand{\calc@eqnoRfil}{\relax}

%    \end{macrocode}
% Eqno's at the left side means no fill at the L~side and a real fill at the R~side:
%    \begin{macrocode}

\newcommand{\calc@leqno}
    {\def\calc@eqnoLfil{}\def\calc@eqnoRfil{\hfil}}

%    \end{macrocode}
% Eqno's at the right side:
%    \begin{macrocode}

\newcommand{\calc@reqno}
    {\def\calc@eqnoRfil{}\def\calc@eqnoLfil{\hfil}}

%    \end{macrocode}
% Calculations horizontally centered on the page:
%    \begin{macrocode}

\newcommand{\calc@ceqn}{\def\calc@fill{fil}}

%    \end{macrocode}
% Calculations flush left: set "\calc@indent" to "\mathindent".
% However, global document option fleqn defines "\mathindent";
% if global option fleqn is not used, "\mathindent" is defined now:
%    \begin{macrocode}

\newcommand{\calc@fleqn}
   {\@ifundefined{mathindent}
         {\calc@indent\leftmargini}{\calc@indent\mathindent}
    \def\calc@fill{fill}}

%    \end{macrocode}
% \subsection{Default settings related to the options}
%
% By default, calculations are centered and eqno's at the right (LaTeX'
% default); and by default no block hints (so "\Hlineopen" at the very
% first line and "\Hlineclose" at the very last line):
%    \begin{macrocode}

\calc@ceqn
\calc@reqno
\newif\ifcalc@block \calc@blockfalse
\newdimen\calc@indent\calc@indent\z@skip 

%    \end{macrocode}
% Recall that "\calc@indent" is set to "\mathindent" if "fleqn" is
% valid.  
%    \begin{macrocode}

\ProcessOptions

%    \end{macrocode}
% \subsection{Auxiliary commands of general use}
%    \begin{macrocode}

\RequirePackage{delarray}

%    \end{macrocode}
% Package "delarray" (and hence package "array") is required for "\left"
% and "\right" delimiters for array's and tabulars --- which we will
% exploit for hints.  With this package, the delimiters come out well if
% the array (tabular, in our case) has option "[t]" (top alignment).
% Command "\@ifmtarg" is my poor man's way to test for an empty
% argument; it should be "\protect"ed in moving arguments. Note: the
% command "\@ifmtarg" provided by "\RequirePackage{ifmtarg}" doesn't
% work if the argument (a HINT in our case) contains `"&"' symbols.  
%    \begin{macrocode}

\newcommand\@ifmtarg[3]
   {{\def\myempty{}\def\myarg{#1}\ifx\myempty\myarg{#2}\else{#3}\fi}}
   %% usage:  \@ifmtarg {arg} {then} {else}

%    \end{macrocode}
% 
% \subsection{Default values for the document style parameters}
% \noindent
% \iffalse===========================================================\fi
% \fbox{NAMING CONVENTION:  EXPR = Expression,  H = Hint}
% \iffalse===========================================================\fi
%    \begin{macrocode}

\newcommand{\stepsymbol}{=}
\newcommand{\Hblockopen}{|} 
\newcommand{\Hblockclose}{.} 
\newcommand{\Hlineopen}{\lbrace}
\newcommand{\Hlineclose}{\rbrace}
\newcommand{\Hindent}{1em}
\newcommand{\Hsep}{1ex}
\newcommand{\Hposv}{t}
\newcommand{\calculcolsep}{\arraycolsep}

%    \end{macrocode}
% The delimiters need some preprocessing in view of the way they will be used (in command "\calc@@@step"). In particular, the spaces at the beginning of a hint will be ignored (see "\HlineOPEN" below).
%    \begin{macrocode}

\newcommand{\Hsepskip}{\hbox to \Hsep {}}
\newcommand{\HlineOPEN}
  {\ifcalc@block\else\makebox[0pt][r]{\m@th$\Hlineopen$\Hsepskip}\fi
   \ignorespaces}
\newcommand{\HlineCLOSE}
  {\ifcalc@block\else\makebox[0pt][l]{\m@th\Hsepskip$\Hlineclose$}\fi}

%    \end{macrocode}
% NOTE: 
% The else clause in "\HlineCLOSE", above, assumes that the last hint
% line is not empty. In order to get "\Hlineopen" and "\Hlineclose"
% vertically aligned in case the last hint line is empty, the else
% clause should read in that case:
%
%        ``"\makebox[0pt][r]{\m@th$\Hlineclose$\Hsepskip}"''. 
%
% \noindent
% Alas, I don't know how to check ``the preceding line is empty'' in
% the definition of "\calc@@@step" below, just in front of
% "\HlineCLOSE".
%    \begin{macrocode}

\newcommand{\HblockOPEN}{\ifcalc@block\Hblockopen\else.\fi}
\newcommand{\HblockCLOSE}{\ifcalc@block\Hblockclose\else.\fi}

%    \end{macrocode}
% 
% \subsection{Specific auxiliaries}
% Some sanity checks, and several auxiliaries:
%    \begin{macrocode}
\newcommand{\calc@origmath}{\relax}
\newcommand{\calc@stepsymbol}{\relax}
\newlength\calc@math       % to store the value of \mathsurround
\newif\ifcalc@emptyH       % for temporary local use only
\newif\ifcalc@numberedstep % true if currently in \step* 
\newif\ifcalc@eqnoswitch   % true if an eqno will be produced
\newcommand{\calc@emptyHskip}{-0.5\baselineskip}% for empty hints
\calc@eqnoswitchfalse
%    \end{macrocode}
% By default the expressions in a calculation are not numbered.
% Whenever an expression is to be numbered, the switch is set true.
% This is done by "\doNumber", which will be made available inside expressions of a calculation. Doing "\doNumber" twice should have the same effect as doing it once!
%    \begin{macrocode}
\newcommand{\calc@doNumber}
    {\ifcalc@eqnoswitch \else
       \global\calc@eqnoswitchtrue
       \stepcounter{equation}
       \gdef\@currentlabel{\p@equation\theequation}
     \fi}
%    \end{macrocode}

\iffalse ================= calculation environment ===================\fi
% \subsection{Main code: calculation and step}
% The main idea of the calculation environment is to adapt \LaTeX's way
% of formatting math expressions, and eqnarray in particular. Thus
% "calculation" sets up a "\halign" with three columns:
% \begin{itemize}\item[]
%    The 1st one for the step symbol (math mode) \\
%    The 2nd for the hint and expression (math mode) \\
%    The 3rd one for the comment and step/expr number (LR mode)
% \end{itemize}
% 
% \noindent
% An eqno is placed in a large "\hbox" of length "\linewidth" which
% itself is considered of zero length and placed at the right in the
% last column. By suitable fill's the eqno then appears either at the
% left or right side of that large "\hbox", and thus at the left or
% right side of the page.
% 
% Command "\step" will be invoked inside an expression; thus, briefly
% said, it should have this effect: ``end the expression, begin a new
% line, print the step symbol and hint, and begin a new expression''. 
% 
% \subsubsection{The calculation environment}
% \begin{environment}{calculation}
% The "calculation" environment has one optional argument, for the step
% symbol, the default being "\stepsymbol"; within the code for the
% environment, the step symbol is known as "\calc@stepsymbol".
% Because the step symbol and expr/hint must be set with zero
% mathsurround, we set mathsurround to zero (by \TeX's "\m@th"), but
% take measures to reset "\mathsurround" to its original value inside
% hints.
% 
% A newline command "\\" inside expressions is delegated to "\calc@cr"
% (defined below).
% 
% Inside the environment, command "\step" and environment
% "subcalculation" are made available; outside the environment "\step"
% and "subcalculation" may have another meaning.
% 
%    \begin{macrocode}

\newenvironment{calculation}[1][\stepsymbol]
 {\setlength\calc@math\mathsurround
  \def\calc@origmath{\mathsurround\calc@math}%
  \abovedisplayskip\topsep
  \ifvmode\advance\abovedisplayskip\partopsep\fi
  \belowdisplayskip\abovedisplayskip
  \belowdisplayshortskip\abovedisplayskip
  \abovedisplayshortskip\abovedisplayskip
  \def\calc@stepsymbol{#1}%
  \tabskip\calc@indent plus 1fil
  \let\\=\calc@cr
  \def\step{\calc@step}% Make \step available inside calculations
  \def\subcalculation{\calc@subcalculation}% similarly subcalculation
  \def\endsubcalculation{\endcalc@subcalculation}% 
  $$
    \halign to \displaywidth
    \bgroup 
        \tabskip\z@ \hfil\m@th$ ## $\hskip\calculcolsep 
     &  \m@th$ ## $\hfil\tabskip 0pt plus 1\calc@fill
     &  \hfil\llap{##}\tabskip\z@
    \cr
    \calc@beginEXPR
 }
%    \end{macrocode}
% In the preceding line, the "\halign" declaration ends with the
% beginning of a math expression ("\calc@beginEXPR", which will skip to
% the the 2nd column, that is, the column for expressions).  The
% following line closes the environment; it ends the last math
% expression ("\calc@endEXPR", which will step over to the last column,
% and print the eqno and comment):
%    \begin{macrocode}
 {\calc@endEXPR
  \egroup $$ \global\@ignoretrue\ignorespaces}

%    \end{macrocode}
% \end{environment}
% 
% \begin{macro}{\calc@cr}
% The command "\\" within expressions is delegated to "\calc@cr"; it
% ends the current expression, gives a little extra vspace, 
% and begins a new line of the expression: 
%    \begin{macrocode}

\newcommand\calc@cr{
     \calc@endEXPR 
     \noalign{\nopagebreak\vskip\jot} 
     \calc@beginEXPR} 

%    \end{macrocode}
% From \LaTeX\ we've taken over the idea of extra "\jot" vertical space
% between lines of one mathematical expression.  The "\nopagebreak"
% prevents a calculation to be split within or just after an expression;
% that would be too confusing for the reader.
% \end{macro}
% 
\iffalse ================= step command ===================\fi
% \subsubsection{The step command}
% \begin{macro}{\...step}
% Most of the work for the calculation environment, is done in command
% "\step" or its companions "\calc@step", "\cal@@step" and
% "\calc@@@step".
% Recall that "\step" has been made available inside "calculation" by a
% local definition that simply calls "\calc@step". This latter one first
% checks whether the next token is a star~"*" (and stores this
% information in the global "\calc@numberedstep") and then calls
% "\calc@@step".  This "\calc@@step" has one optional argument, the
% default being "\calc@stepsymbol" (set by the calculation environment);
% it calls "\calc@@@step" with the step symbol:
%    \begin{macrocode}

\newcommand{\calc@step}
  {\@ifstar{\global\calc@numberedsteptrue\calc@@step}
           {\global\calc@numberedstepfalse\calc@@step}}

\newcommand{\calc@@step}[1][\calc@stepsymbol]{\calc@@@step{#1}}

%    \end{macrocode}
% 
% \noindent
% \DescribeMacro{\calc@@@step}
% Now, the final "\calc@@@step" has two obligatory arguments:
% \begin{itemize}\item[]
%     "#1" = step symbol\\
%     "#2" = hint lines possibly including several "\\"'s
% \end{itemize}
% As a preparation it checks whether the hint is empty and stores this
% in "\calc@Hempty". Then it ends the current expression, does a
% negative vskip if the hint is empty, and increases the equation
% counter if the step is numbered:
%    \begin{macrocode}

\newcommand{\calc@@@step}[2]
 { \@ifmtarg{#2}{\global\calc@emptyHtrue}{\global\calc@emptyHfalse}
   \calc@endEXPR
   \ifcalc@emptyH \noalign{\vskip \calc@emptyHskip}
     \else \noalign{\nopagebreak\vskip\jot}
   \fi
   \ifcalc@numberedstep
     \refstepcounter{equation}
     \gdef\@currentlabel{\p@equation\theequation}
     \gdef\calc@stepno{\theequation}
   \fi
%    \end{macrocode}
%    After these preparations, print the step symbol in the 1st column:
%    \begin{macrocode}
   #1 & 
%    \end{macrocode}
%    Now print the hint, if not empty. First take care of the
%    indentation, then take the hint lines as body of a tabular which
%    has "\HblockOPEN" and "\HblockCLOSE" as delimiters and put
%    "\HlineOPEN" in front of the 1st line and "\HlineCLOSE" after the
%    last line.  These delimiters have been defined to be null depending
%    on the validity of option "block". The "tabular" comes from package
%    "delarray", and thus has the feature of allowing the delimiters
%    around the column specification. We also take care to restore
%    "\mathsurround" to its original value within each hint line. 
%    \begin{macrocode}
   \ifcalc@emptyH
   \else
      \hskip\Hindent
      \begin{tabular}[\Hposv]
      \HblockOPEN{>{\calc@origmath\Hsepskip}l<{\Hsepskip}}\HblockCLOSE 
      \HlineOPEN #2\HlineCLOSE
      \end{tabular}
   \fi
   & 
   \ifcalc@numberedstep \calc@print@theequation \fi
   \cr 
%    \end{macrocode}
%    Now, having completed the step-and-hint line by "\cr" and before
%    beginning the next math expression, do a negative vskip if the hint
%    was empty, and put some extra space between the hint and expression
%    (just as within expressions):
%    \begin{macrocode}
   \ifcalc@emptyH \noalign{\vskip \calc@emptyHskip} \fi
   \noalign{\vskip\jot}
   \calc@beginEXPR
 }

%    \end{macrocode}
% \end{macro}
% 
\iffalse ====================== Auxiliary commands ===================\fi
% \subsubsection{Remaining auxiliary commands}
% \begin{macro}{\calc@beginEXPR}
% When "\calc@beginEXPR" is called, a new line of the "\halign" of
% "calculation" is to be filled. Since no step symbol has to be printed,
% we skip over to the next column (the 2nd one). This column is
% processed in math mode, so nothing has to be done, except for making
% "\doNumber" and "\comment" available and resetting the current comment
% to ``nothing, yet'':
%    \begin{macrocode}

\newcommand{\calc@beginEXPR}
   {& 
    \def\doNumber{\calc@doNumber}
    \def\comment{\gdef\calc@comment}
    \gdef\calc@comment{}
    }

%    \end{macrocode}
% \end{macro}
% \begin{macro}{\calc@endEXPR}
% When "\calc@endEXPR" is called, we simply step over to the last (3rd)
% column by~"&" and print the eqno and comment (possibly null), and
% close the line with "\cr":
%    \begin{macrocode}

\newcommand{\calc@endEXPR} 
   { & \calc@@eqno\calc@@comment \cr }

%    \end{macrocode}
% \end{macro}
% \begin{macro}{\calc@@comment}
% The type setting of comments and numbers is rather straightforward: at
% the very right end of a wide "\hbox", which is pretended to be of zero
% width, and surrounded by suitable fill's to shift them to the other
% side, if needed.
% \begin{macrocode}

\newcommand{\calc@@comment}
   {\llap{\hbox to\linewidth
       {\calc@eqnoRfil \normalfont\normalcolor\calc@comment
        \calc@eqnoLfil}}}
\newcommand{\calc@@eqno}
   {\ifcalc@eqnoswitch
     \calc@print@theequation
     \global\calc@eqnoswitchfalse
    \fi}
\newcommand{\calc@print@theequation}
   {\llap{\hbox to\displaywidth
      {\calc@eqnoLfil \m@th\normalfont\normalcolor (\theequation)%
       \calc@eqnoRfil}}}

%    \end{macrocode}
% \end{macro}
%
\iffalse ===================== subcalculation ===================== \fi
% \section{Subcalculation}
% 
% There are several problems in using the "calculation" environment
% within hints. First, the width need be determined. (When option "fleqn"
% is valid, then the width is more or less the line length minus these
% three: "\calc@indent", width of widest step symbol, "\Hindent".)
% Second, even if the width for the sub calculation is known, it is hard
% to get the eqno and comment at the right place on the page. Third, in
% all my attempts, a sub calculation in the hint of a numbered step
% takes the number for it self. (This could be solved by implementing a
% stack or push down store in \TeX\ or a kind of recursive commands that
% build their own stack.) In view of all this, we forbid sub
% calculations to have numbered steps, numbered expressions, and
% comments in expressions. (This seems reasonable; after all, a
% subcalculation within a hint should be very simple and not
% ``view-able'' from the outside.) Also, we pretend the calculation to
% have zero width; it is the users responsibility to observe overfull
% lines!  Finally, as a kind of fine tuning the lay-out, we halve the
% indentation for the calculation, and make sub calculations flush left.
% Actions within "subcalculation" must not overwrite gobal
% variables of environment  "calculation", of course. So, we have to
% introduce some new global variables:
%    \begin{macrocode}

\newif\ifsubcalc@emptyH
\newcommand{\subcalc@stepsymbol}{\relax}

%    \end{macrocode}
%
% \begin{environment}{subcalculation}
% Since numbering and comments are not allowed, we use only two columns.
%
%    \begin{macrocode}

\newenvironment{calc@subcalculation}[1][\stepsymbol]{%
  \begin{minipage}[c]{0pt}
  \abovedisplayskip 0pt 
  \belowdisplayskip \abovedisplayskip
  \belowdisplayshortskip\belowdisplayskip
  \abovedisplayshortskip\abovedisplayskip
  \def\subcalc@stepsymbol{#1}%
  \@ifundefined{mathindent}{\calc@indent\leftmargini}{}%
  \divide\calc@indent by 2 
  \tabskip\calc@indent plus 1fil
  \let\\=\subcalc@cr
  \def\step{\subcalc@step}% Make \step available
  \def\comment
     {\@latex@error{No \string\comment\space in subcalculations}}%
  $$
  \m@th
    \halign 
    \bgroup 
      \tabskip\z@ \hfil$ ## $\hskip\calculcolsep 
     &
      $ ## $\hfil\tabskip 0pt plus 1\calc@fill
    \cr
    & 
    \global\@ignoretrue
  }
  { \raisebox{0pt}[0pt][1.5ex]{}
    \cr \egroup $$\par\end{minipage}
    \ignorespaces}
%    \end{macrocode}
% \end{environment}
%
% \noindent
% How to deal with "\\" (which will invoke "\subcalc@cr") in hints and
% exprs: Close the current line (of the "\halign") and in the next line
% skip the column for the step symbol:
%    \begin{macrocode}

\newcommand\subcalc@cr
    {\cr
     \noalign{\nopagebreak\vskip\jot} 
     &
     \global\@ignoretrue\ignorespaces
    }

%    \end{macrocode}
%
% \begin{macro}{\subcalc@step}
% A step in a subcalculation is more or less the same as a step in the
% normal calculation, except that numbering is not allowed:
% \begin{macrocode}

\newcommand{\subcalc@step}
    {\@ifstar{\subcalc@@stepSTAR}{\subcalc@@step}}

\newcommand{\subcalc@@stepSTAR}[1]
    {\@latex@error
     {No \string\step* in subcalculations; use \string\step.}}

\newcommand{\subcalc@@step}[1][\subcalc@stepsymbol]
     {\subcalc@@@step{#1}}

\newcommand{\subcalc@@@step}[2]
 {\@ifmtarg{#2}
      {\global\subcalc@emptyHtrue}{\global\subcalc@emptyHfalse}
  \cr 
  \ifsubcalc@emptyH
    \noalign{\vskip \calc@emptyHskip}
  \else
    \noalign{\nopagebreak\vskip\jot}
  \fi
  #1 & 
  \ifsubcalc@emptyH \else
    \hskip\Hindent
    \hbox to 0pt {%
    \begin{tabular}[\Hposv]
    \HblockOPEN{>{\calc@origmath\Hsepskip}l<{\Hsepskip}}\HblockCLOSE 
        \HlineOPEN #2\HlineCLOSE
    \end{tabular}}
  \fi
  \cr 
    \ifsubcalc@emptyH \noalign{\vskip \calc@emptyHskip} \fi
  & \global\@ignoretrue
  }
%    \end{macrocode}
% \end{macro}
% \iffalse =============== end of calculation.dtx =====================\fi