summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/calculation/calculation.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/calculation/calculation.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/calculation/calculation.dtx')
-rw-r--r--macros/latex/contrib/calculation/calculation.dtx804
1 files changed, 804 insertions, 0 deletions
diff --git a/macros/latex/contrib/calculation/calculation.dtx b/macros/latex/contrib/calculation/calculation.dtx
new file mode 100644
index 0000000000..aa5b57ac97
--- /dev/null
+++ b/macros/latex/contrib/calculation/calculation.dtx
@@ -0,0 +1,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