diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/tools/calc.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/tools/calc.dtx | 583 |
1 files changed, 487 insertions, 96 deletions
diff --git a/Master/texmf-dist/source/latex/tools/calc.dtx b/Master/texmf-dist/source/latex/tools/calc.dtx index a96821e3c3f..b49f228f192 100644 --- a/Master/texmf-dist/source/latex/tools/calc.dtx +++ b/Master/texmf-dist/source/latex/tools/calc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 +% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 % The LaTeX3 Project and any individual authors listed elsewhere % in this file. % @@ -8,12 +8,12 @@ % ------------------------------------------------------- % % It may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 +% conditions of the LaTeX Project Public License, either version 1.3c % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2003/12/01 or later. +% and version 1.3c or later is part of all distributions of LaTeX +% version 2005/12/01 or later. % % The list of all files belonging to the LaTeX `Tools Bundle' is % given in the file `manifest.txt'. @@ -23,7 +23,7 @@ %% File `calc.dtx'. %% Copyright (C) 1992--1995 %% Kresten Krab Thorup and Frank Jensen. -%% Copyright (C) 1997--1998 +%% Copyright (C) 1997--2005 %% Kresten Krab Thorup, Frank Jensen and the LaTeX3 Project. %% %% The original authors (fj@hugin.dk and krab@daimi.aau.dk) have @@ -39,11 +39,13 @@ %<driver> \ProvidesFile{calc.drv} % \fi % \ProvidesFile{calc.dtx} - [1998/07/07 v4.1b Infix arithmetic (KKT,FJ)] + [2005/08/06 v4.2 Infix arithmetic (KKT,FJ)] % % \iffalse %<*driver> \documentclass{ltxdoc} +\EnableCrossrefs +\RecordChanges \usepackage{calc} \begin{document} \DocInput{calc.dtx} @@ -52,7 +54,7 @@ % \fi % % \GetFileInfo{calc.dtx} -% \CheckSum{426} +% \CheckSum{667} % % \title{The \texttt{calc} package\\Infix notation % arithmetic in \LaTeX\thanks{We thank Frank Mittelbach for his @@ -110,9 +112,9 @@ % % The infix expressions can be used in arguments to macros (the % \texttt{calc} package doesn't employ category code changes to -% achieve its goals)\footnote{However, it therefore assumes that the +% achieve its goals).\footnote{However, it therefore assumes that the % category codes of the special characters, such as \texttt{(*/)} -% in its syntax do not change.}. +% in its syntax do not change.} % % \section{Informal description} % @@ -151,7 +153,7 @@ % commands take a length argument. After loading this package, most of % these commands will accept a \<glue expression>. This includes % the optional width argument of |\makebox|, the width argument of -% |\parbox|, |minipage|, and a |tabluar| |p|-column, and many similar +% |\parbox|, |minipage|, and a |tabular| |p|-column, and many similar % constructions. (This package does not redefine any of these commands, % but they are defined by default to read their arguments by |\setlength| % and so automatically benefit from the enhanced |\setlength| command @@ -230,6 +232,16 @@ % These calculate the natural sizes of the \<text> in exactly the % same way as is done for the commands |\settowidth| etc.~on % Page~216 of the manual~\cite{latexman}. +% In August 2005 the package was further extended to provide the command +%\begin{quote} +% |\totalheightof{|\<text>|}| +%\end{quote} +% This command does exactly what you'd expect from its name. +% Additionally the package also provides the command +%\begin{quote} +% |\settototalheight{|\<cmd>|}{|\<text>|}| +%\end{quote} +% % % Note that there is a small difference in the usage of these two % methods of accessing text dimensions. After @@ -277,6 +289,33 @@ % \setlength{\newYsize}{\Ysize*\ratio{\textwidth}{\Xsize}} %\end{verbatim} % +% +% +% Another new feature introduced in August 2005 was $\max$ and $\min$ +% operations with associated macros +%\begin{quote} +% |\maxof{|\<\textit{type} expression>|}{|\<\textit{type} expression>|}| +% \\ +% |\minof{|\<\textit{type} expression>|}{|\<\textit{type} expression>|}| +%\end{quote} +% When \textit{type} is either \meta{glue} or \meta{dimen} these macros +% are allowed only as part of addition or subtraction but when +% \textit{type} is \meta{integer} they can also be used when +% multiplying and dividing. In the latter case they follow the +% same syntax rules as |\ratio| and |\real| which means they must come +% after the |*| or the |/|. Thus +%\begin{verbatim} +% \setcounter{x}{3*\maxof{4+5}{3*4}+\minof{2*\real{1.6}}{5-1}} +%\end{verbatim} +% will assign $3\times\max(9,12)+\min(3,4)=39$ to |x|. Similarly +%\begin{verbatim} +% \setlength{\parindent}{% +% \minof{3pt}{\parskip}*\real{1.5}*\maxof{2*\real{1.6}}{2-1}} +%\end{verbatim} +% will assign $\min(13.5\textrm{pt},4.5\cs{parskip})$ to \cs{parindent} +% +% +% % \section{Formal syntax} % % The syntax is described by the following set of rules. @@ -287,46 +326,93 @@ % We use \textit{type} as a meta-variable, standing for % `integer', `dimen', and `glue'.\footnote{This version of the % \texttt{calc} package doesn't support evaluation of muglue expressions.} +% % \begin{calc-syntax} -% \<\textit{type} expression> -% \is \<\textit{type} term> +% \<\textit{type} expression>^^A +% \is \<\textit{type} term>^^A % \alt \<\textit{type} expression> \<plus or minus> \<\textit{type} term> % -% \<\textit{type} term> -% \is \<\textit{type} factor> -% \alt \<\textit{type} term> \<multiply or divide> \<integer factor> -% \alt \<\textit{type} term> \<multiply or divide> \<real number> -% -% \<\textit{type} factor> -% \is \<\textit{type}> -% \alt \<text dimen factor> +% \<\textit{type} term>^^A +% \is \<\textit{type} factor>^^A +% \alt \<\textit{type} term> \<multiply or divide> \<integer>^^A +% \alt \<\textit{type} term> \<multiply or divide> \<real number>^^A +% \alt \<\textit{type} term> \<multiply or divide>^^A +% \<$\max$ or $\min$ integer> +% +% \<\textit{type} factor>^^A +% \is \<\textit{type}>^^A +% \alt \<text dimen factor>^^A +% \alt \<$\max$ or $\min$ \textit{type}>^^A % \alt |(|$_{12}$ \<\textit{type} expression> |)|$_{12}$ % % \<integer> \is \<number> % -% \<text dimen factor> +% \<$\max$ or $\min$ \textit{type}> \is \<$\max$ or $\min$ command>^^A +% |{| \<\textit{type} expression> |}|^^A +% |{| \<\textit{type} expression> |}| +% +% \<$\max$ or $\min$ command> \is |\maxof|^^A +% \alt |\minof| +% +% \<text dimen factor>^^A % \is \<text dimen command>|{| \<text> |}| % -% \<text dimen command> -% \is |\widthof| -% \alt |\heightof| -% \alt |\depthof| +% \<text dimen command>^^A +% \is |\widthof|^^A +% \alt |\heightof|^^A +% \alt |\depthof|^^A +% \alt |\totalheightof|^^A % -% \<multiply or divide> -% \is |*|$_{12}$ +% \<multiply or divide>^^A +% \is |*|$_{12}$^^A % \alt |/|$_{12}$ % -% \<real number> -% \is |\ratio{| \<dimen expression> |}{| \<dimen expression> |}| -% \alt |\real{| \<decimal constant> |}| +% \<real number>^^A +% \is |\ratio{| \<dimen expression> |}{| \<dimen expression> |}|^^A +% \alt |\real{| \<optional signs> \<decimal constant> |}| +% +% \<plus or minus>^^A +% \is |+|$_{12}$^^A +% \alt |-|$_{12}$ +% +% \<decimal constant>^^A +% \is |.|$_{12}$^^A +% \alt |,|$_{12}$^^A +% \alt \<digit> \<decimal constant>^^A +% \alt \<decimal constant> \<digit> +% +% \<digit>^^A +% \is |0|$_{12}$^^A +% \alt |1|$_{12}$^^A +% \alt |2|$_{12}$^^A +% \alt |3|$_{12}$^^A +% \alt |4|$_{12}$^^A +% \alt |5|$_{12}$^^A +% \alt |6|$_{12}$^^A +% \alt |7|$_{12}$^^A +% \alt |8|$_{12}$^^A +% \alt |9|$_{12}$ +% +% \<optional signs>^^A +% \is \<optional spaces>^^A +% \alt \<optional signs> \<plus or minus> \<optional spaces> +% % \end{calc-syntax} % -% Note that during most of the parsing of calc expressions, no -% expansion happens; thus the above syntax must be -% explicit\footnote{Two exceptions to this are: the first token -% is expanded one-level (thus the whole expression can be put into a -% macro); wherever a \<decimal constant> or \<\texttt{type}> is -% expected.}. +% +% Relying heavily on \TeX\ to do the underlying assignments, it is +% only natural for \texttt{calc} to simulate \TeX's parsing machinery +% for these quantities. Therefore it a)~imposes the same restrictions +% on the catcode of syntax characters as \TeX\ and b)~tries to expand +% its argument fully. a)~means that implicit characters for the tokens +% |*|$_{12}$, |/|$_{12}$, |(|$_{12}$, and |)|$_{12}$ will not +% work\footnote{e\TeX\ also assumes these catcodes when parsing a +% \cs{numexpr}, \cs{dimexpr}, \cs{glueexpr}, or \cs{muglueexpr} and +% does not allow implicit characters.} but because of~b), the +% expansion should allow you to use macros that expand to explicit +% syntax characters. +% +% % \StopEventually{ % \begin{thebibliography}{1} % \bibitem{texbook} @@ -339,6 +425,7 @@ % \newblock Addison-Wesley, Reading, Massachusetts, Second % edition 1994/1985. % \end{thebibliography} +% \PrintChanges % } % % \section{The evaluation scheme} @@ -480,7 +567,7 @@ % \subsection{Getting started} % % Now we have enough insight to do the actual implementation in \TeX. -% First, we announce the macro package\footnote{Code moved to top of file}. +% First, we announce the macro package.\footnote{Code moved to top of file} % \begin{macrocode} %<*package> %\NeedsTeXFormat{LaTeX2e} @@ -490,6 +577,7 @@ % \subsection{Assignment macros} % % \begin{macro}{\calc@assign@generic} +% \changes{v4.2}{2005/08/06}{Removed a few redundant \cs{expandafter}s} % The |\calc@assign@generic| macro takes four arguments: (1~and~2) the % registers to be used % for global and local manipulations, respectively; (3)~the lvalue @@ -520,14 +608,12 @@ % tokens of this expansion are inserted explicitly, except that the % last assignment has been replaced by the lvalue part (i.e., % argument~|#3| of |\calc@assign@generic|) followed by |\calc@B|. -% \end{macro} % \begin{macrocode} \def\calc@assign@generic#1#2#3#4{\let\calc@A#1\let\calc@B#2% - \expandafter\calc@open\expandafter(#4!% + \calc@open(#4!% \global\calc@A\calc@B\endgroup#3\calc@B} % \end{macrocode} -% (The |\expandafter| tokens allow the user to use expressions stored -% one-level deep in a macro as arguments in assignment commands.) +% \end{macro} % % \begin{macro}{\calc@assign@count} % \begin{macro}{\calc@assign@dimen} @@ -551,14 +637,50 @@ % % \subsection{The \LaTeX\ interface} % +% \begin{macro}{\setcounter} +% \begin{macro}{\addtocounter} +% \changes{v4.2}{2005/08/06} +% {Fix to make \cs{addtocounter} work with \texttt{amstext}} +% \begin{macro}{\steptocounter} +% \changes{v4.2}{2005/08/06} +% {Avoid redundant processing. PR/3795} +% \begin{macro}{\setlength} +% \begin{macro}{\addtolength} % As promised, we redefine the following standard \LaTeX\ commands: % |\setcounter|, % |\addtocounter|, |\setlength|, and |\addtolength|. % \begin{macrocode} \def\setcounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}% {\calc@assign@count{\global\csname c@#1\endcsname}{#2}}} -\def\addtocounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}% - {\calc@assign@count{\global\advance\csname c@#1\endcsname}{#2}}} +% \end{macrocode} +% \begin{macrocode} + \def\addtocounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}% + {\calc@assign@count{\global\advance\csname c@#1\endcsname}{#2}}}% +% \end{macrocode} +% We also fix \cs{stepcounter} to not go through the whole \texttt{calc} +% process. +% \begin{macrocode} + \def\stepcounter#1{\@ifundefined {c@#1}% + {\@nocounterr {#1}}% + {\global\advance\csname c@#1\endcsname \@ne + \begingroup + \let\@elt\@stpelt \csname cl@#1\endcsname + \endgroup}}% +% \end{macrocode} +% If the \texttt{amstext} package is loaded we must add the +% |\iffirstchoice@| switch as well. We patch the commands this +% way since it's good practice when we know how many arguments they take. +% \begin{macrocode} +\@ifpackageloaded{amstext}{% + \expandafter\def\expandafter\stepcounter + \expandafter#\expandafter1\expandafter{% + \expandafter\iffirstchoice@\stepcounter{#1}\fi + } + \expandafter\def\expandafter\addtocounter + \expandafter#\expandafter1\expandafter#\expandafter2\expandafter{% + \expandafter\iffirstchoice@\addtocounter{#1}{#2}\fi + } +}{} % \end{macrocode} % \begin{macrocode} \DeclareRobustCommand\setlength{\calc@assign@skip} @@ -566,6 +688,11 @@ % \end{macrocode} % (|\setlength| and |\addtolength| are robust according to % \cite{latexman}.) +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \subsection{The scanner} % @@ -576,7 +703,11 @@ % |\calc@post@scan|; |\calc@pre@scan| consumes left parentheses, and % |\calc@post@scan| consumes binary operator, |\real|, |\ratio|, and % right parenthesis tokens. +% % \begin{macro}{\calc@pre@scan} +% \begin{macro}{\@calc@pre@scan} +% \changes{v4.2}{2005/08/06} +% {Added macro and force expansion} % % Note that this is called at least once on every use of calc % processing, even when none of the extended syntax is present; it @@ -592,26 +723,46 @@ % illegal will simply generate a \TeX-level error, often a % reasonably comprehensible one! % +% The |\romannumeral-`\a| part is a little trick which forces expansion +% in case |#1| is a normal macro, something that occurs from time to +% time. A conditional test inside will possibly leave a trailing +% \cs{fi} but this remnant is removed later when \cs{calc@post@scan} +% performs the same trick. +% % The many |\expandafter|s are needed to efficiently end the nested -% conditionals so that |\calc@textsize| can process its argument. +% conditionals so that |\calc@textsize| and |\calc@maxmin@addsub| can +% process their argument. % \changes{v4.1a}{1998/06/07} % {Added code for text sizes: CAR} % \changes{v4.1b}{1998/07/07} % {Correction to ifx true case} +% \changes{v4.2}{2005/08/06} +% {Added \cs{maxof} and \cs{minof} operations} % \begin{macrocode} \def\calc@pre@scan#1{% - \ifx(#1% - \expandafter\calc@open - \else - \ifx\widthof#1% - \expandafter\expandafter\expandafter\calc@textsize - \else - \calc@numeric% no \expandafter needed for this one. - \fi - \fi - #1} + \expandafter\@calc@pre@scan\romannumeral-`\a#1} +\def\@calc@pre@scan#1{% + \ifx(#1% + \expandafter\calc@open + \else + \ifx\widthof#1% + \expandafter\expandafter\expandafter\calc@textsize + \else + \ifx\maxof#1% + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\calc@maxmin@addsub + \else + \calc@numeric% no \expandafter needed for this one. + \fi + \fi + \fi + #1} % \end{macrocode} % \end{macro} +% \end{macro} +% +% \begin{macro}{\calc@open} +% \begin{macro}{\calc@initB} % |\calc@open| is used when there is a left parenthesis right ahead. % This parenthesis is replaced by \TeX\ code corresponding to the code % sequence ``$\{\savecode{B\lassign A}\{\savecode{B\lassign A}$'' @@ -624,49 +775,76 @@ \calc@pre@scan} \def\calc@initB{\calc@B\calc@A} % \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\calc@numeric} % |\calc@numeric| assigns the following value to |\calc@A| and then % transfers control to |\calc@post@scan|. % \begin{macrocode} \def\calc@numeric{\afterassignment\calc@post@scan \global\calc@A} % \end{macrocode} +% \end{macro} % % \begin{macro}{\widthof} % \begin{macro}{\heightof} % \begin{macro}{\depthof} % \changes{v4.1a}{1998/06/07} % {Added macros: CAR} +% \begin{macro}{\totalheightof} +% \changes{v4.2}{2005/08/06} +% {Added macro} +% \changes{v4.2}{2005/08/06} +% {Added informative message for reserved macros} % % These do not need any particular definition when they are scanned % so, for efficiency and robustness, we make them all equivalent to -% the same harmless (I hope) unexpandable command\footnote{If this +% the same harmless (I hope) unexpandable command.\footnote{If this % level of safety is not needed then the code can be speeded up: -% CAR.}. Thus the test in |\calc@pre@scan| finds any of them. -% They are first defined using |\newcommand| so that they appear to -% be normal user commands to a \LaTeX{} user\footnote{Is this -% necessary, CAR?}. +% CAR.} Thus the test in |\@calc@pre@scan| finds any of them. +% +% As we have to check for these commands explicitly we must ensure +% that our definition wins. Using \cs{newcommand} gives an error when +% loading \texttt{calc} and may be mildly surprising. This should be +% a little more informative. % \begin{macrocode} -\newcommand\widthof{} +\@for\reserved@a:=widthof,heightof,depthof,totalheightof,maxof,minof\do +{\@ifundefined{\reserved@a}{}{% + \PackageError{calc}{% + The\space calc\space package\space reserves\space the\space + command\space name\space `\@backslashchar\reserved@a'\MessageBreak + but\space it\space has\space already\space been\space defined\space + with\space the\space meaning\MessageBreak + `\expandafter\meaning\csname\reserved@a\endcsname'.\MessageBreak + This\space original\space definition\space will\space be\space lost}% + {If\space you\space need\space a\space command\space with\space + this\space definition,\space you\space must\space use\space a\space + different\space name.}}% +} \let\widthof\ignorespaces -\newcommand\heightof{} \let\heightof\ignorespaces -\newcommand\depthof{} \let\depthof\ignorespaces +\let\totalheightof\ignorespaces % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\calc@textsize} % \changes{v4.1a}{1998/06/07} % {Added macro: CAR} -% The presence of the above three commands invokes this code, where +% \changes{v4.1a}{1998/06/07} +% {Added macro: CAR} +% \changes{v4.2}{2005/08/06} +% {Extended macro with \cs{totalheightof}} +% The presence of the above four commands invokes this code, where % we must distinguish them from each other. % This implementation is somewhat optimized by using low-level -% code from the commands |\settowidth|, etc\footnote{It is based on -% suggestions by Donald Arsenau and David Carlisle.}. +% code from the commands |\settowidth|, etc.\footnote{It is based on +% suggestions by Donald Arseneau and David Carlisle.} % % Within the text argument we must restore the normal meanings of -% the three user-level commands since arbitrary material can appear +% the four user-level commands since arbitrary material can appear % in here, including further uses of calc. % \begin{macrocode} \def\calc@textsize #1#2{% @@ -674,12 +852,18 @@ \let\widthof\wd \let\heightof\ht \let\depthof\dp - \@settodim #1% + \def\totalheightof{\ht\dp}% +% \end{macrocode} +% We must expand the argument one level if it's \cs{totalheightof} +% and it doesn't hurt the other three. +% \begin{macrocode} + \expandafter\@settodim\expandafter{#1}% {\global\calc@A}% {% \let\widthof\ignorespaces \let\heightof\ignorespaces \let\depthof\ignorespaces + \let\totalheightof\ignorespaces #2}% \endgroup \calc@post@scan} @@ -687,10 +871,12 @@ % \end{macro} % % \begin{macro}{\calc@post@scan} +% \begin{macro}{\@calc@post@scan} +% \changes{v4.2}{2005/08/06}{Added macro and force expansion} % The macro |\calc@post@scan| is called right after a value has been % read. At this point, a binary operator, a sequence of right % parentheses, and the end-of-expression mark (`|!|') is -% allowed\footnote{Is \texttt{!} a good choice, CAR?}. +% allowed.\footnote{Is \texttt{!} a good choice, CAR?} % Depending on our findings, we call a suitable macro to generate the % corresponding \TeX\ code (except when we detect the % end-of-expression marker: then scanning ends, and @@ -702,25 +888,34 @@ % to be performed if the expression consists of a single \<numeric>. % This ensures that documents that do not use the extra expressive % power provided by the \texttt{calc} package only suffer a minimum -% slowdown in processing time. -% \end{macro} +% slowdown in processing time. % \begin{macrocode} \def\calc@post@scan#1{% - \ifx#1!\let\calc@next\endgroup \else + \expandafter\@calc@post@scan\romannumeral-`\a#1} +\def\@calc@post@scan#1{% + \ifx#1!\let\calc@next\endgroup \else \ifx#1+\let\calc@next\calc@add \else - \ifx#1-\let\calc@next\calc@subtract \else - \ifx#1*\let\calc@next\calc@multiplyx \else - \ifx#1/\let\calc@next\calc@dividex \else - \ifx#1)\let\calc@next\calc@close \else \calc@error#1% + \ifx#1-\let\calc@next\calc@subtract \else + \ifx#1*\let\calc@next\calc@multiplyx \else + \ifx#1/\let\calc@next\calc@dividex \else + \ifx#1)\let\calc@next\calc@close \else + \calc@error#1% + \fi + \fi \fi - \fi \fi - \fi \fi - \fi - \calc@next} + \fi + \calc@next} % \end{macrocode} +% \end{macro} +% \end{macro} % +% \begin{macro}{\calc@add} +% \begin{macro}{\calc@subtract} +% \begin{macro}{\calc@generic@add} +% \begin{macro}{\calc@addAtoB} +% \begin{macro}{\calc@subtractAfromB} % The replacement code for the binary operators `\texttt{+}' and % `\texttt{-}' follow a common pattern; the only difference is the % token that is stored away by |\aftergroup|. After this replacement @@ -734,12 +929,22 @@ \def\calc@addAtoB{\advance\calc@B\calc@A} \def\calc@subtractAfromB{\advance\calc@B-\calc@A} % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\real} % \begin{macro}{\ratio} +% \begin{macro}{\calc@ratio@x} +% \begin{macro}{\calc@real@x} % The multiplicative operators, `\texttt{*}' and `\texttt{/}', may be -% followed by a |\real| or a |\ratio| token. Those control sequences -% are not defined (at least not by the \texttt{calc} package); this, +% followed by a |\real|, |\ratio|, |\minof|, or |\maxof| token. The +% last two of these control sequences are defined by \texttt{calc} as +% they are needed by the scanner for addition or subtraction while the +% first two are not defined (at least not by the \texttt{calc} +% package); this, % unfortunately, leaves them highly non-robust. We therefore % equate them to |\relax| but only if they have not already been % defined\footnote{Suggested code from David Carlisle.} @@ -752,31 +957,52 @@ \ifx\real\@undefined\let\real\relax\fi \ifx\ratio\@undefined\let\ratio\relax\fi % \end{macrocode} -% In order to test for them, we define these two\footnote{May not -% need the extra names, CAR?}. +% In order to test for |\real| or |\ratio|, we define these +% two.\footnote{May not need the extra names, CAR?} % \begin{macrocode} \def\calc@ratio@x{\ratio} \def\calc@real@x{\real} % \end{macrocode} % \end{macro} % \end{macro} -% +% \end{macro} +% \end{macro} +% \begin{macro}{\calc@multiplyx} +% \changes{v4.2}{2005/08/06} +% {Added $\protect\max$ and $\protect\min$ operations} +% \begin{macro}{\calc@dividex} +% \changes{v4.2}{2005/08/06} +% {Added $\protect\max$ and $\protect\min$ operations} +% Test which operator followed |*| or |/|. If none followed it's just +% a standard multiplication or division. % \begin{macrocode} \def\calc@multiplyx#1{\def\calc@tmp{#1}% - \ifx\calc@tmp\calc@ratio@x \let\calc@next\calc@ratio@multiply \else - \ifx\calc@tmp\calc@real@x \let\calc@next\calc@real@multiply \else - \let\calc@next\calc@multiply + \ifx\calc@tmp\calc@ratio@x \let\calc@next\calc@ratio@multiply \else + \ifx\calc@tmp\calc@real@x \let\calc@next\calc@real@multiply \else + \ifx\maxof#1\let\calc@next\calc@maxmin@multiply \else + \let\calc@next\calc@multiply \fi - \fi - \calc@next#1} + \fi + \fi + \calc@next#1} \def\calc@dividex#1{\def\calc@tmp{#1}% - \ifx\calc@tmp\calc@ratio@x \let\calc@next\calc@ratio@divide \else - \ifx\calc@tmp\calc@real@x \let\calc@next\calc@real@divide \else - \let\calc@next\calc@divide + \ifx\calc@tmp\calc@ratio@x \let\calc@next\calc@ratio@divide \else + \ifx\calc@tmp\calc@real@x \let\calc@next\calc@real@divide \else + \ifx\maxof#1\let\calc@next\calc@maxmin@divide \else + \let\calc@next\calc@divide \fi - \fi - \calc@next#1} + \fi + \fi + \calc@next#1} % \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc@multiply} +% \begin{macro}{\calc@divide} +% \begin{macro}{\calc@generic@multiply} +% \begin{macro}{\calc@multiplyBbyA} +% \begin{macro}{\calc@divideBbyA} % The binary operators `\texttt{*}' and `\texttt{/}' also insert code % as determined above. Moreover, the meaning of |\calc@A| and % |\calc@B| is changed as factors following a multiplication and @@ -795,7 +1021,13 @@ % Since the value to use in the multiplication/division operation is % stored in the |\calc@Acount| register, the |\calc@multiplyBbyA| and % |\calc@divideBbyA| macros use this register. +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % +% \begin{macro}{\calc@close} % |\calc@close| generates code for a right parenthesis (which was % derived to be ``$\}A\gassign B\}A\gassign B$'' in % Section~\ref{evaluation:scheme}). After this code, the control is @@ -808,9 +1040,12 @@ \endgroup\global\calc@A\calc@B \calc@post@scan} % \end{macrocode} +% \end{macro} % % \subsection{Calculating a ratio} % +% \begin{macro}{\calc@ratio@multiply} +% \begin{macro}{\calc@ratio@divide} % When |\calc@post@scan| encounters a |\ratio| control sequence, it hands % control to one of the macros |\calc@ratio@multiply| or |\calc@ratio@divide|, % depending on the preceding character. Those macros both forward the @@ -826,13 +1061,23 @@ \def\calc@ratio@multiply\ratio{\calc@ratio@evaluate} \def\calc@ratio@divide\ratio#1#2{\calc@ratio@evaluate{#2}{#1}} % \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\calc@Ccount} +% \begin{macro}{\calc@numerator} +% \begin{macro}{\calc@denominator} % We shall need two registers for temporary usage in the % calculations. We can save one register since we can reuse % |\calc@Bcount|. % \begin{macrocode} +\newcount\calc@Ccount \let\calc@numerator=\calc@Bcount -\newcount\calc@denominator +\let\calc@denominator=\calc@Ccount % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\calc@ratio@evaluate} % Here is the macro that handles the actual evaluation of ratios. The % procedure is % this: First, the two expressions are evaluated and coerced to @@ -885,9 +1130,11 @@ \begingroup \calc@post@scan} % \end{macrocode} +% \end{macro} % The |\begingroup| inserted before the |\calc@post@scan| will be % matched by the |\endgroup| generated as part of the replacement of a % subsequent binary operator or right parenthesis. +% \begin{macro}{\calc@next@digit} % \begin{macrocode} \def\calc@next@digit{% \multiply\calc@Acount\calc@denominator @@ -897,6 +1144,8 @@ \divide\calc@Acount\calc@denominator \xdef\calc@the@ratio{\calc@the@ratio\number\calc@Acount}} % \end{macrocode} +% \end{macro} +% \begin{macro}{\calc@multiply@by@real} % In the following code, it is important that we first assign the % result to a dimen register. Otherwise, \TeX\ won't allow us to % multiply with a real number. @@ -912,9 +1161,12 @@ % expressions can appear as part of a muglue expression, it would be % necessary to determine the correct register to use each time a % multiplication is made.) +% \end{macro} % % \subsection{Multiplication by real numbers} % +% \begin{macro}{\calc@real@multiply} +% \begin{macro}{\calc@real@divide} % This is similar to the |\calc@ratio@evaluate| macro above, except that % it is considerably simplified since we don't need to calculate the % factor explicitly. @@ -924,9 +1176,115 @@ \calc@post@scan} \def\calc@real@divide\real#1{\calc@ratio@evaluate{1pt}{#1pt}} % \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{$\max$ and $\min$ operations} +% +% \begin{macro}{\maxof} +% \begin{macro}{\minof} +% \changes{v4.2}{2005/08/06} +% {Added macros} +% With version 4.2, the $\max$ and $\min$ operators were +% added to \texttt{calc}. The user functions for them are \cs{maxof} and +% \cs{minof} respectively. +% These macros are internally similar to \cs{widthof} etc.\ in that they +% are unexpandable and easily recognizable by the scanner. +% \begin{macrocode} +\let\maxof\@@italiccorr +\let\minof\@@italiccorr +% \end{macrocode} +% \end{macro} +% \end{macro} % -% \section{Reporting errors} % +% \begin{macro}{\calc@Cskip} +% \begin{macro}{\ifcalc@count@} +% The $\max$ and $\min$ operations take two arguments so we need an extra +% \<skip> register. We also add a switch for determining when to perform +% a \<skip> or a \<count> assignment. +% \begin{macrocode} +\newskip\calc@Cskip +\newif\ifcalc@count@ +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\calc@maxmin@addsub} +% \begin{macro}{\calc@maxmin@generic} +% \changes{v4.2}{2005/08/06}{Macros added} +% When doing addition or subtraction with a $\max$ or $\min$ operator, we +% first check if |\calc@A| is a \<count> register or not and then set the +% switch. Then call the real function which sets |\calc@A| to the desired +% value and continue as usual with |\calc@post@scan|. +% \begin{macrocode} +\def\calc@maxmin@addsub#1#2#3{\begingroup + \ifx\calc@A\calc@Acount% + \calc@count@true + \else + \calc@count@false + \fi + \calc@maxmin@generic#1{#2}{#3}% + \endgroup + \calc@post@scan +} +% \end{macrocode} +% Check the switch and do either \<count> or \<skip> assignments. Note that +% |\maxof| and |\minof| are not set to |>| and |<| until after the +% assignments, which ensures we can nest them without problems. Then set +% |\calc@A| to the correct one. +% \begin{macrocode} +\def\calc@maxmin@generic#1#2#3{% + \begingroup + \ifcalc@count@ + \calc@assign@count\calc@Ccount{#2}% + \calc@assign@count\calc@Bcount{#3}% + \def\minof{<}\def\maxof{>}% + \global\calc@A\ifnum\calc@Ccount#1\calc@Bcount + \calc@Ccount\else\calc@Bcount\fi + \else + \calc@assign@skip\calc@Cskip{#2}% + \calc@assign@skip\calc@Bskip{#3}% + \def\minof{<}\def\maxof{>}% + \global\calc@A\ifdim\calc@Cskip#1\calc@Bskip + \calc@Cskip\else\calc@Bskip\fi + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc@maxmin@divmul} +% \begin{macro}{\calc@maxmin@multiply} +% \begin{macro}{\calc@maxmin@divide} +% \changes{v4.2}{2005/08/06}{Macros added} +% When doing division or multiplication we must be using \<count> registers +% so we set the switch. Other than that it is almost business as usual when +% multiplying or dividing. |#1| is the instruction to either multiply or +% divide |\calc@B| by |\calc@A|, |#2| is either |\maxof| or |\minof| which +% is waiting in the input stream and |#3| and |#4| are the calc expressions. +% We end it all as usual by calling |\calc@post@scan|. +% \begin{macrocode} +\def\calc@maxmin@divmul#1#2#3#4{% + \endgroup\begingroup + \calc@count@true + \aftergroup#1% + \calc@maxmin@generic#2{#3}{#4}% + \endgroup\begingroup + \calc@post@scan +} +% \end{macrocode} +% The two functions called when seeing a |*| or a |/|. +% \begin{macrocode} +\def\calc@maxmin@multiply{\calc@maxmin@divmul\calc@multiplyBbyA} +\def\calc@maxmin@divide {\calc@maxmin@divmul\calc@divideBbyA} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \section{Reporting errors} +% \begin{macro}{\calc@error} % \changes{v4.0d}{1997/11/08} % {Use \cs{PackageError} for error messages (DPC)} % \changes{v4.0e}{1997/11/11} @@ -942,6 +1300,39 @@ \PackageError{calc}% {`#1' invalid at this point}% {I expected to see one of: + - * / )}} +% \end{macrocode} +% \end{macro} +% +% \section{Other additions} +% \begin{macro}{\@settodim} +% \changes{v4.2}{2005/08/06} +% {Changed kernel macro} +% \begin{macro}{\settototalheight} +% \changes{v4.2}{2005/08/06} +% {Added macro} +% The kernel macro \cs{@settodim} is changed so that it runs through a list +% containing \cs{ht}, \cs{wd}, and \cs{dp} and than advance the length +% one step at a time. We just have to use a scratch register in case the +% user decides to put in a \cs{global} prefix on the length register. +% A search on the internet confirmed that some people do that kind of thing. +% \begin{macrocode} +\def\@settodim#1#2#3{% + \setbox\@tempboxa\hbox{{#3}}% + \dimen@ii=\z@ + \@tf@r\reserved@a #1\do{% + \advance\dimen@ii\reserved@a\@tempboxa}% + #2=\dimen@ii + \setbox\@tempboxa\box\voidb@x} +% \end{macrocode} +% Now the user level macro is straightforward. +% \begin{macrocode} +\def\settototalheight{\@settodim{\ht\dp}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% That's the end of the package. +% \begin{macrocode} %</package> % \end{macrocode} % |