diff options
author | Karl Berry <karl@freefriends.org> | 2014-08-07 21:52:35 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2014-08-07 21:52:35 +0000 |
commit | 2ee761738d4c85b1ba6c9f83f026c72cecff5d96 (patch) | |
tree | f1cc91a18988a2a97068721d30dda75526895a10 /Master/texmf-dist/source/latex | |
parent | 7d5a5498dbbf998f4d0297668e733a9203582241 (diff) |
breqn (6aug14)
git-svn-id: svn://tug.org/texlive/trunk@34867 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r-- | Master/texmf-dist/source/latex/breqn/breqn.dtx | 7331 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/breqn/flexisym.dtx | 1603 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/breqn/mathstyle.dtx | 487 |
3 files changed, 9421 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/breqn/breqn.dtx b/Master/texmf-dist/source/latex/breqn/breqn.dtx new file mode 100644 index 00000000000..86551eee0cb --- /dev/null +++ b/Master/texmf-dist/source/latex/breqn/breqn.dtx @@ -0,0 +1,7331 @@ +% \iffalse meta-comment +% +% Copyright (C) 1997-2003 by Michael J. Downes +% Copyright (C) 2007-2008 by Morten Hoegholm +% Copyright (C) 2007-2014 by Lars Madsen +% Copyright (C) 2007-2014 by Will Robertson +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 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 2005/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% The Current Maintainer of this work is Will Robertson. +% +% This work consists of the main source file breqn.dtx +% and the derived files +% breqn.sty, breqn.pdf, breqn.ins. +% +% Distribution: +% CTAN:macros/latex/contrib/mh/breqn.dtx +% CTAN:macros/latex/contrib/mh/breqn.pdf +% +% Unpacking: +% (a) If breqn.ins is present: +% tex breqn.ins +% (b) Without breqn.ins: +% tex breqn.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{breqn.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% Programm calls to get the documentation (example): +% pdflatex breqn.dtx +% makeindex -s gind.ist breqn.idx +% pdflatex breqn.dtx +% makeindex -s gind.ist breqn.idx +% pdflatex breqn.dtx +% +% Installation: +% TDS:tex/latex/breqn/breqn.sty +% TDS:doc/latex/breqn/breqn.pdf +% TDS:source/latex/breqn/breqn.dtx +% +%<*ignore> +\begingroup + \def\x{LaTeX2e} +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: breqn 2014/06/10 v0.98c Breqn} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 1997-2003 by Michael J. Downes +Copyright (C) 2007-2008 by Morten Hoegholm +Copyright (C) 2007-2014 by Lars Madsen +Copyright (C) 2007-2014 by Will Robertson + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 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 2005/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +The Current Maintainer of this work is Will Robertson. + +This work consists of the main source file breqn.dtx +and the derived files + breqn.sty, breqn.pdf, breqn.ins. + +\endpreamble + +\generate{% + \file{breqn.ins}{\from{breqn.dtx}{install}}% + \usedir{tex/latex/breqn}% + \file{breqn.sty}{\from{breqn.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* breqn.sty} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{breqn.drv}% + [2014/06/10 v0.98c breqn] +\documentclass{ltxdoc} +\CodelineIndex +\EnableCrossrefs +\setcounter{IndexColumns}{2} +\usepackage{color,verbatim,xspace,varioref,listings,amsmath,trace} + +\usepackage{geometry} + +\AtBeginDocument{\addtocontents{toc}{\protect\begin{multicols}{2}}} +\AtEndDocument{\addtocontents{toc}{\protect\end{multicols}}} + +\def\partname{Part} + +\definecolor{hilite}{rgb}{0.2,0.4,0.7} +\def\theCodelineNo{\textcolor{hilite}{\sffamily\tiny\arabic{CodelineNo}}} + +\lstloadlanguages{[AlLaTeX]TeX} + +\lstnewenvironment{literalcode} + {\lstset{gobble=2,columns=fullflexible,basicstyle=\color{hilite}\ttfamily}} + {} +\makeatletter + +{\catcode`\%=12 + \long\gdef\@gobble@percent@space#1{\ifx + #1%\expandafter\@gobble\else\expandafter#1\fi}} + + +\AtBeginDocument{\def\verbatim@processline{\expandafter\check@percent + \the\verbatim@line\par}} +\newwrite\tmp@out +\newcounter{xio} +\newenvironment{xio}{% example input and output + \par\addvspace\bigskipamount + \hbox{\itshape + \refstepcounter{xio}\kern-\p@ Example \thexio}\@nobreaktrue + \immediate\openout\tmp@out\jobname.tmp \relax + \begingroup + \let\do\@makeother\dospecials\catcode`\^^M\active + \def\verbatim@processline{ + \immediate\write\tmp@out{\expandafter\@gobble@percent@space + \the\verbatim@line}}% + \verbatim@start +}{% + \immediate\closeout\tmp@out + \@verbatim\frenchspacing\@vobeyspaces + \@@input \jobname.tmp \relax + \endgroup + \par\medskip + \noindent\ignorespaces + \@@input \jobname.tmp \relax + \par\medskip +} + + + + +\providecommand*\pkg[1]{\textsf{#1}} +\providecommand*\cls[1]{\textsf{#1}} +\providecommand*\opt[1]{\texttt{#1}} +\providecommand*\env[1]{\texttt{#1}} +\providecommand*\fn[1]{\texttt{#1}} + + +\providecommand*\cn[1]{\cs{#1}} +\providecommand*\csarg[1]{\texttt{\char`\{#1\char`\}}} + +\providecommand*\tex{\TeX\xspace} +\providecommand*\latex{\LaTeX\xspace} +\providecommand*\dbldollars{\texttt{\detokenize{$$}}}%$$ +\providecommand*\arg{} +\edef\arg{\expandafter\@gobble\string\#} + +\newenvironment{aside}{\begin{quote}\bfseries}{\end{quote}} +\newenvironment{dn}{\begin{quote}\bfseries}{\end{quote}} + +\newcommand\dash{\textemdash} +\newcommand\dbslash[1]{\texttt{\string\\}} +\newcommand\thepkg{the \pkg{breqn} package\xspace} + +\providecommand*\texbook{\textsl{The \protect\TeX{}book}\xspace} + +\providecommand*\dotsc{\ldots} +\providecommand*\eqref[1]{(\ref{#1})} + +\providecommand*\qq[1]{\textquotedblleft#1\textquotedblright} +\providecommand*\quoted[1]{\textquoteleft#1\textquoteright} +\providecommand*\dquoted[1]{\textquotedblleft#1\textquotedblright} + +\providecommand*\ie{i.e.,\xspace} +\providecommand*\eg{e.g.,\xspace} +\providecommand*\etc{etc.\xspace} +\providecommand*\cf{cf.\xspace} + +\providecommand*\ndash{\unskip\textendash\ignorespaces} +\providecommand*\mdash{\unskip\textemdash\ignorespaces} + +\makeatother + +\usepackage{breqn} + +\begin{document} + \DocInput{breqn.dtx} +\end{document} +%</driver> +% \fi +% +% +% \title{The \pkg{breqn} package} +% \date{2014/06/10 v0.98c} +% \author{Authors: Michael J. Downes, Morten H\o gholm\\ Inactively maintained by Will Robertson\\ Feedback: \texttt{https://github.com/wspr/breqn/issues}} +% +% \maketitle +% \begin{abstract} +% The \pkg{breqn} package facilitates automatic line-breaking of +% displayed math expressions. +% \end{abstract} +% +% +% \tableofcontents +% +% +% \part{User's guide} +% +% \section{A bit of history} +% +% Originally \pkg{breqn}, \pkg{flexisym}, and \pkg{mathstyle} were +% created by Michael J.~Downes from the American Mathematical Society +% during the 1990's up to late 2002. Sadly---and much to the shock of +% the \TeX\ world---Michael passed away in early 2003 at the age of +% only~44. +% +% The American Mathematical Society kindly allowed Morten H\o gholm to +% assume maintainership of this part of his work and we wish to +% express our gratitude to them and to Barbara Beeton in particular for +% providing the files needed. +% +% MH brought Michael's work to a wider audience, thereby allowing users to create +% more \emph{masterpieces of the publishing art} as we think he would +% have wanted. +% +% Following the July 2008 breqn release, \pkg{breqn} was left in the hands +% of a maintenance team, while MH moved on with other projects. +% +% \section{Package loading} +% +% +% The recommended way of loading the \pkg{breqn} package is to load it +% \emph{after} other packages dealing with math, \ie, after +% \pkg{amsmath}, \pkg{amssymb}, or packages such as \pkg{mathpazo} or +% \pkg{mathptmx}. +% +% The \pkg{flexisym} package (described in section \vref{flexisym}) is +% required by \pkg{breqn} and ensures the math symbols are set up +% correctly. By default \pkg{breqn} loads it with support for Computer +% Modern but if you use a different math package requiring slightly +% different definitions, it must be loaded before \pkg{breqn}. Below +% is an example of how you enable \pkg{breqn} to work with the widely +% used \pkg{mathpazo} package. +% \begin{verbatim} +%\usepackage{mathpazo} +%\usepackage[mathpazo]{flexisym} +%\usepackage{breqn} +% \end{verbatim} +% Currently, the packages \pkg{mathpazo} and \pkg{mathptmx} are +% supported. Despair not: Chances are that the package will work using +% the default settings. If you find that a particular math font +% package doesn't work then please see implementation in +% \fn{flexisym.dtx} for how to create a support file---it is easier +% than one might think. Contributions welcome. +% +% The documentation for the package was formerly found in +% \fn{breqndoc}. It has now been added to this implementation +% file. Below follows the contents of the original \pkg{breqn} +% documentation. Not all details hold anymore but I have prioritized +% fixing the package. +% +% \section{Introduction} +% +% The \pkg{breqn} package for \LaTeX\ provides solutions to a number of +% common difficulties in writing displayed equations and getting +% high-quality output. For example, it is a well-known inconvenience that +% if an equation must be broken into more than one line, \cs{left} \dots\ +% \cs{right} constructs cannot span lines. The \pkg{breqn} package makes +% them work as one would expect whether or not there is an intervening +% line break. +% +% The single most ambitious goal of the \pkg{breqn} package, however, is +% to support automatic linebreaking of displayed equations. Such +% linebreaking cannot be done without substantial changes under the hood +% in the way math formulas are processed. For this reason, especially in +% the alpha release, users should proceed with care and keep an eye out +% for unexpected glitches or side effects. +% +% \section{Principal features} +% The principal features of the \pkg{breqn} package are: +% \begin{description} +% +% \item[semantically oriented structure] The way in which compound +% displayed formulas are subdivided matches the logical structure more +% closely than, say, the standard \env{eqnarray} environment. Separate +% equations in a group of equations are written as separate environments +% instead of being bounded merely by \dbslash/ commands. Among other +% things, this clears up a common problem of wrong math symbol spacing at +% the beginning of continuation lines. It also makes it possible to +% specify different vertical space values for the space between lines of a +% long, broken equation and the space between separate equations in a +% group of equations. +% +% \item[automatic line breaking] Overlong equations will be broken +% automatically to the prevailing column width, and continuation lines +% will be indented following standard conventions. +% +% \item[line breaks within delimiters] Line breaks within \cs{left} \dots\ +% \cs{right} delimiters work in a natural way. Line breaks can be +% forbidden below a given depth of delimiter nesting through a package +% option. +% +% \item[mixed math and text] Display equations that contain mixed +% math and text, or even text only, are handled naturally by means of a +% \env{dseries} environment that starts out in text mode instead of math +% mode. +% +% \item[ending punctuation] The punctuation at the end of a displayed +% equation can be handled in a natural way that makes it easier to promote +% or demote formulas from\slash to inline math, and to apply special +% effects such as adding space before the punctuation. +% +% \item[flexible numbering] Equation numbering is handled in a natural +% way, with all the flexibility of the \pkg{amsmath} package and with no +% need for a special \cs{nonumber} command. +% +% \item[special effects] It is easy to apply special effects to individual +% displays, e.g., changing the type size or adding a frame. +% +% \item[using available space] Horizontal shrink is made use of +% whenever feasible. With most other equation macros it is frozen when it +% occurs between \cs{left} \dots\ \cs{right} delimiters, or in any sort of +% multiline structure, so that some expressions require two lines that would +% otherwise fit on one. +% +% \item[high-quality spacing] The \cs{abovedisplayshortskip} is used when +% applicable (other equation macros fail to apply it in equations of more +% than one line). +% +% \item[abbreviations] Unlike the \pkg{amsmath} equation environments, the +% \pkg{breqn} environments can be called through user-defined abbreviations +% such as \cs{beq} \dots\ \cs{eeq}. +% +% \end{description} +% +% \section{Shortcomings of the package} +% The principal known deficiencies of the \pkg{breqn} package are: +% +% \subsection{Incompatibilities} As it pushes the envelope +% of what is possible within the context of \LaTeXe, \thepkg will tend +% to break other packages when used in combination with them, or to fail +% itself, when there are any areas of internal overlap; successful use may +% in some cases depend on package loading order. +% +% +% +% \subsection{Indention of delimited fragments} When line breaks within +% delimiters are involved, the automatic indention of continuation lines +% is likely to be unsatisfactory and need manual adjustment. I don't see +% any easy way to provide a general solution for this, though I have some +% ideas on how to attain partial improvements. +% +% \subsection{Math symbol subversion} +% In order for automatic line breaking to work, the operation of all the +% math symbols of class 2, 3, 4, and 5 must be altered (relations, binary +% operators, opening delimiters, closing delimiters). This is done by an +% auxiliary package \pkg{flexisym}. As long as you stick to the advertised +% \LaTeX\ interface for defining math symbols (\cs{DeclareMathSymbol}), +% things should work OK most of the time. Any more complex math symbol +% setup is quite likely to quarrel with the \pkg{flexisym} package. +% See Section~\vref{flexisym} for further information. +% +% \subsection{Subscripts and superscripts} +% +% Because of the changes to math symbols of class 2--5, writing certain +% combinations such as \verb'^+' or \verb'_\pm' or \verb'^\geq' without +% braces would lead to error messages; (The problem described here +% already exists in standard \LaTeX\ to a lesser extent, as you may know +% if you ever tried \verb'^\neq' or \verb'^\cong'; and indeed there are +% no examples in the \LaTeX\ book to indicate any sanction for omitting +% braces around a subscript or superscript.) +% +% The \pkg{flexisym} package therefore calls, as of version 0.92, another +% package called \pkg{mathstyle} which turns \verb'^' and \verb'_' into +% active characters. This is something that I believe is desirable in any +% case, in the long run, because having a proper mathstyle variable +% eliminates some enormous burdens that affect almost any +% nontrivial math macros, as well as many other things where the +% connection is not immediately obvious, e.g., the \LaTeX\ facilities for +% loading fonts on demand. +% +% Not that this doesn't introduce new and interesting problems of its +% own---for example, you don't want to put usepackage statements +% after flexisym for any package that refers to, e.g., \verb'^^J' or +% \verb'^^M' +% internally (too bad that the \LaTeX\ package loading code does not +% include automatic defenses to ensure normal catcodes in the interior of +% a package; but it only handles the \verb'@' character). +% +% But I took a random AMS journal article, with normal end-user kind of +% \LaTeX\ writing, did some straightforward substitutions to change all +% the equations into dmath environments, and ran it with active math +% sub/sup: everything worked OK. This suggests to me that it can work in +% the real world, without an impossible amount of compatibility work. +% +% \section{Incomplete} +% In addition, in the \textbf{alpha release [1997/10/30]} the following +% gaps remain to be filled in: +% \begin{description} +% \item[documentation] +% The documentation could use amplification, especially more +% illustrations, and I have undoubtedly overlooked more than a few errors. +% +% \item[group alignment] The algorithm for doing alignment +% of mathrel symbols across equations in a \env{dgroup} environment +% needs work. Currently the standard and \opt{noalign} alternatives +% produce the same output. +% +% \item[single group number] When a \env{dgroup} has a group number and +% the individual equations are unnumbered, the handling and placement of +% the group number aren't right. +% +% \item[group frame] Framing a group doesn't work, you might be able to +% get frames on the individual equations at best. +% +% \item[group brace] The \opt{brace} option for \env{dgroup} is intended +% to produce a large brace encompassing the whole group. This hasn't been +% implemented yet. +% +% \item[darray environment] The \env{darray} environment is unfinished. +% +% \item[dseries environment] The syntax and usage for the \env{dseries} +% environment are in doubt and may change. +% +% \item[failure arrangements] When none of the line-breaking passes for a +% \env{dmath} environment succeeds\dash i.e., at least one line is +% overfull\dash the final arrangement is usually rather poor. A better +% fall-back arrangement in the failure case is needed. +% +% \end{description} +% +% \section{Package options} +% +% Many of the package options for \thepkg are the same as options of the +% \env{dmath} or \env{dgroup} environments, and some of them require an +% argument, which is something that cannot be done through the normal +% package option mechanism. Therefore most of the \pkg{breqn} package +% options are designed to be set with a \cs{setkeys} command after the +% package is loaded. For example, to load the package and set the +% maximum delimiter nesting depth for line breaks to~1: +% \begin{verbatim} +% \usepackage{breqn} +% \setkeys{breqn}{breakdepth={1}} +% \end{verbatim} +% +% See the discussion of environment options, Section~\vref{envopts}, for +% more information. +% +% Debugging information is no longer available as a package +% option. Instead, the tracing information has been added in a fashion +% so that it can be enabled as a docstrip option: +% \begin{verbatim} +% \generate{\file{breqn.sty}{\from{breqn.dtx}{package,trace}}} +% \end{verbatim} +% +% +% \section{Environments and commands} +% \subsection{Environments} +% All of the following environments take an optional argument for +% applying local effects such as changing the typesize or adding a +% frame to an individual equation. +% +% \begin{description} +% \item[\env{dmath}] Like \env{equation} but supports line breaking and variant +% numbers. +% +% \item[\env{dmath*}] Unnumbered; like \env{displaymath} but supports line +% breaking +% +% \item[\env{dseries}] Like \env{equation} but starts out in text mode; +% intended for series of mathematical expressions of the form `A, B, and +% C'. As a special feature, if you use +% \begin{verbatim} +% \begin{math} ... \end{math} +% \end{verbatim} +% for each expression in the series, a suitable amount of inter-expression +% space will be automatically added. This is a small step in the direction of +% facilitating conversion of display math to inline math, and vice versa: If +% you write a display as +% \begin{verbatim} +% \begin{dseries} +% \begin{math}A\end{math}, +% \begin{math}B\end{math}, +% and +% \begin{math}C\end{math}. +% \end{dseries} +% \end{verbatim} +% then conversion to inline form is simply a matter of removing the +% \verb'\begin{dseries}' and \verb'\end{dseries}' lines; the contents of the +% display need no alterations. +% +% It would be nice to provide the same feature for \verb'$' notation but +% there is no easy way to do that because the \verb'$' function has no +% entry point to allow changing what happens before math mode is entered. +% Making it work would therefore require turning \verb'$' into an active +% character, something that I hesitate to do in a \LaTeXe\ context. +% +% \item[\env{dseries*}] Unnumbered variant of \env{dseries} +% +% \item[\env{dgroup}] Like the \env{align} environment of \pkg{amsmath}, +% but with each constituent equation wrapped in a \env{dmath}, +% \env{dmath*}, \env{dseries}, or \env{dseries*} environment instead of being +% separated by \dbslash/. The equations are numbered with a group number. +% When the constituent environments are the numbered forms (\env{dmath} or +% \env{dseries}) they automatically switch to `subequations'-style +% numbering, i.e., something like (3a), (3b), (3c), \dots, depending on +% the current form of non-grouped equation numbers. See also +% \env{dgroup*}. +% +% \item[\env{dgroup*}] Unnumbered variant of \env{dgroup}. If the +% constituent environments are the numbered forms, they get normal +% individual equation numbers, i.e., something like (3), (4), (5), \dots~. +% +% \item[\env{darray}] Similar to \env{eqnarray} but with an argument like +% \env{array} for giving column specs. Automatic line breaking is not +% done here. +% +% \item[\env{darray*}] Unnumbered variant of \env{darray}, rather like +% \env{array} except in using \cs{displaystyle} for all column +% entries. +% +% \item[\env{dsuspend}] Suspend the current display in order to print +% some text, without loss of the alignment. There is also a command +% form of the same thing, \cs{intertext}. +% \end{description} +% +% \subsection{Commands} +% +% The commands provided by \thepkg are: +% \begin{description} +% \item[\cs{condition}] This command is used for +% a part of a display which functions as a condition on the main +% assertion. For example: +% \begin{verbatim} +% \begin{dmath} +% f(x)=\frac{1}{x} \condition{for $x\neq 0$} +% \end{dmath}. +% \end{verbatim} +% \begin{dmath} +% f(x)=\frac{1}{x} \condition{for $x\neq 0$} +% \end{dmath}. +% The \cs{condition} command automatically switches to text mode (so that +% interword spaces function the way they should), puts in a comma, and +% adds an appropriate amount of space. To facilitate promotion\slash +% demotion of formulas, \cs{condition} \qq{does the right thing} if used +% outside of display math. +% +% To substitute a different punctuation mark instead of the default comma, +% supply it as an optional argument for the \cs{condition} command: +% \begin{verbatim} +% \condition[;]{...} +% \end{verbatim} +% (Thus, to get no punctuation: \verb'\condition[]{...}'.) +% +% For conditions that contain no text, you can use the starred form of the +% command, which means to stay in math mode: +% \begin{verbatim} +% \begin{dmath} +% f(x)=\frac{1}{x} \condition*{x\neq 0} +% \end{dmath}. +% +% If your material contains a lot of conditions like these, you might like +% to define shorter abbreviations, e.g., +% \begin{verbatim} +% \newcommand{\mc}{\condition*}% math condition +% \newcommand{\tc}{\condition}% text condition +% \end{verbatim} +% But \thepkg refrains from predefining such abbreviations in order that +% they may be left to the individual author's taste. +% +% \item[\cs{hiderel}] In a compound equation it is sometimes desired to +% use a later relation symbol as the alignment point, rather than the +% first one. To do this, mark all the relation symbols up to the desired +% one with \cs{hiderel}: +% \begin{verbatim} +% T(n) \hiderel{\leq} T(2^n) \leq c(3^n - 2^n) ... +% \end{verbatim} +% \end{description} +% +% \section{Various environment options}\label{envopts} +% +% The following options are recognized for the \env{dmath}, \env{dgroup}, +% \env{darray}, and \env{dseries} environments; some of the options do not +% make sense for all of the environments, but if an option is used where +% not applicable it is silently ignored rather than treated as an error. +% \changes{v0.98b}{2010/08/27}{replaced relindent with indentstep} +% +% \begin{verbatim} +% \begin{dmath}[style={\small}] +% \begin{dmath}[number={BV}] +% \begin{dmath}[labelprefix={eq:}] +% \begin{dmath}[label={xyz}] +% \begin{dmath}[indentstep={2em}] +% \begin{dmath}[compact] +% \begin{dmath}[spread={1pt}] +% \begin{dmath}[frame] +% \begin{dmath}[frame={1pt},framesep={2pt}] +% \begin{dmath}[background={red}] +% \begin{dmath}[color={purple}] +% \begin{dmath}[breakdepth={0}] +% \end{verbatim} +% +% Use the \opt{style} option to change the type size of an individual +% equation. This option can also serve as a catch-all option for +% altering the equation style in other ways; the contents are simply +% executed directly within the context of the equation. +% +% Use the \opt{number} option if you want the number for a particular +% equation to fall outside of the usual sequence. If this option is used +% the equation counter is not incremented. If for some reason you need to +% increment the counter and change the number at the same time, use the +% \opt{style} option in addition to the \opt{number} option: +% \begin{verbatim} +% style={\refstepcounter{equation}} +% \end{verbatim} +% +% Use of the normal \cs{label} command instead of the \opt{label} option +% works, I think, most of the time (untested). \opt{labelprefix} prepends +% its argument to the label (only useful as a global option, really), +% and must be called before \opt{label}. +% +% \changes{v0.98b}{2010/08/27}{replaced relindent with indentstep} +% Use the \opt{indentstep} option to specify something other than the +% default amount for the indention of relation symbols. The default is +% 8pt. +% +% Use the \opt{compact} option in compound equations to inhibit line +% breaks at relation symbols. By default a line break will be taken before +% each relation symbol except the first one. With the \opt{compact} option +% \LaTeX\ will try to fit as much material as possible on each line, but +% breaks at relation symbols will still be preferred over breaks at binary +% operator symbols. +% +% Use the \opt{spread} option to increase (or decrease) the amount of +% interline space in an equation. See the example given above. +% +% Use the \opt{frame} option to produce a frame around the body of the +% equation. The thickness of the frame can optionally be specified by +% giving it as an argument of the option. The default thickness is +% \cs{fboxrule}. +% +% Use the \opt{framesep} option to change the amount of space separating +% the frame from what it encloses. The default space is \cs{fboxsep}. +% +% Use the \opt{background} option to produce a colored background for the +% equation body. The \pkg{breqn} package doesn't automatically load the +% \pkg{color} package, so this option won't work unless you remember +% to load the \pkg{color} package yourself. +% +% Use the \opt{color} option to specify a different color for the contents +% of the equation. Like the \opt{background} option, this doesn't work if +% you forgot to load the \pkg{color} package. +% +% Use the \opt{breakdepth} option to change the level of delimiter nesting +% to which line breaks are allowed. To prohibit line breaks within +% delimiters, set this to 0: +% \begin{verbatim} +% \begin{dmath}[breakdepth={0}] +% \end{verbatim} +% The default value for breakdepth is 2. Even when breaks are allowed +% inside delimiters, they are marked as less desirable than breaks outside +% delimiters. Most of the time a break will not be taken within delimiters +% until the alternatives have been exhausted. +% +% Options for the \env{dgroup} environment: all of the above, and also +% \begin{verbatim} +% \begin{dgroup}[noalign] +% \begin{dgroup}[brace] +% \end{verbatim} +% +% By default the equations in a \env{dgroup} are mutually aligned on their +% relation symbols ($=$, $<$, $\geq$, and the like). With the +% \opt{noalign} option each equation is placed individually without +% reference to the others. +% +% The \opt{brace} option means to place a large brace encompassing the +% whole group on the same side as the equation number. +% +% Options for the \env{darray} environment: all of the above (where +% sensible), and also +% \begin{verbatim} +% \begin{darray}[cols={lcr@{\hspace{2em}}lcr}] +% \end{verbatim} +% The value of the \opt{cols} option for the darray environment should be +% a series of column specs as for the \env{array} environment, with the +% following differences: +% \begin{itemize} +% \item For l, c, and r what you get is not text, but math, and +% displaystyle math at that. To get text you must use a 'p' column +% specifier, or put an \cs{mbox} in each of the individual cells. +% +% \item Vertical rules don't connect across lines. +% \end{itemize} +% +% \section{The \pkg{flexisym} package}\label{flexisym} +% +% The \pkg{flexisym} package does some radical changes in the setup for +% math symbols to allow their definitions to change dynamically throughout +% a document. The \pkg{breqn} package uses this to make symbols of classes +% 2, 3, 4, 5 run special functions inside an environment such as +% \env{dmath} that provide the necessary support for automatic line +% breaking. +% +% The method used to effect these changes is to change the definitions of +% \cs{DeclareMathSymbol} and \cs{DeclareMathDelimiter}, and then +% re-execute the standard set of \LaTeX\ math symbol definitions. +% Consequently, additional mathrel and mathbin symbols defined by other +% packages will get proper line-breaking behavior if the other package is +% loaded after the \pkg{flexisym} package and the symbols are defined +% through the standard interface. +% +% +% +% \section{Caution! Warning!} +% Things to keep in mind when writing documents with \thepkg: +% \begin{itemize} +% +% \item The notation $:=$ must be written with the command \cs{coloneq}. +% Otherwise the $:$ and the $=$ will be treated as two separate relation +% symbols with an \qq{empty RHS} between them, and they will be printed +% on separate lines. +% +% \item Watch out for constructions like \verb'^+' where a single binary +% operator or binary relation symbol is subscripted or superscripted. When +% the \pkg{breqn} or \pkg{flexisym} package is used, braces are mandatory +% in such constructions: \verb'^{+}'. This applies for both display and +% in-line math. +% +% \item If you want \LaTeX\ to make intelligent decisions about line +% breaks when vert bars are involved, use proper pairing versions of the +% vert-bar symbols according to context: \verb'\lvert n\rvert' instead of +% \verb'|n|'. With the nondirectional \verb'|' there is no way for \LaTeX\ +% to reliably deduce which potential breakpoints are inside delimiters +% (more highly discouraged) and which are not. +% +% \item If you use the \pkg{german} package or some other package that +% turns double quote \verb'"' into a special character, you may encounter +% some problems with named math symbols of type mathbin, mathrel, +% mathopen, or mathclose in moving arguments. For example, \cs{leq} in a +% section title will be written to the \fn{.aux} file as something like +% \verb'\mathchar "3214'. This situation probably ought to be improved, +% but for now use \cs{protect}. +% +% \item Watch out for the \texttt{[} character at the beginning of a +% \env{dmath} or similar environment, if it is supposed to be interpreted +% as mathematical content rather than the start of the environment's +% optional argument. +% +% This is OK: +% \begin{verbatim} +% \begin{dmath} +% [\lambda,1]... +% \end{dmath} +% \end{verbatim} +% This will not work as expected: +% \begin{verbatim} +% \begin{dmath}[\lambda,1]...\end{dmath} +% \end{verbatim} +% +% \item Watch out for unpaired delimiter symbols (in display math only): +% \begin{verbatim} +% ( ) [ ] \langle \rangle \{ \} \lvert \rvert ... +% \end{verbatim} +% If an open delimiter is used without a close delimiter, or vice versa, +% it is normally harmless but may adversely affect line breaking. This is only +% for symbols that have a natural left or right directionality. Unpaired +% \cs{vert} and so on are fine. +% +% When a null delimiter is used as the other member of the pair +% (\verb'\left.' or \verb'\right.') this warning doesn't apply. +% +% \item If you inadvertently apply \cs{left} or \cs{right} to something +% that is not a delimiter, the error messages are likely to be a bit +% more confusing than usual. The normal \LaTeX\ response to an error such +% as +% \begin{verbatim} +% \left + +% \end{verbatim} +% is an immediate message +% \begin{verbatim} +% ! Missing delimiter (. inserted). +% \end{verbatim} +% When \thepkg is in use, \LaTeX\ will fail to realize anything is wrong +% until it hits the end of the math formula, or a closing delimiter +% without a matching opening delimiter, and then the first message is an +% apparently pointless +% \begin{verbatim} +% ! Missing \endgroup inserted. +% \end{verbatim} +% +% \end{itemize} +% +% \section{Examples} +% +% \renewcommand\theequation{\thesection.\arabic{equation}} +% % Knuth, SNA p74 +% \begin{xio} +% Replace $j$ by $h-j$ and by $k-j$ in these sums to get [cf.~(26)] +% \begin{dmath}[label={sna74}] +% \frac{1}{6} \left(\sigma(k,h,0) +\frac{3(h-1)}{h}\right) +% +\frac{1}{6} \left(\sigma(h,k,0) +\frac{3(k-1)}{k}\right) +% =\frac{1}{6} \left(\frac{h}{k} +\frac{k}{h} +\frac{1}{hk}\right) +% +\frac{1}{2} -\frac{1}{2h} -\frac{1}{2k}, +% \end{dmath} +% which is equivalent to the desired result. +% \end{xio} +% +% % Knuth, SNA 4.6.2, p387 +% \begin{xio} +% \newcommand\mx[1]{\begin{math}#1\end{math}}% math expression +% % +% Now every column which has no circled entry is completely zero; +% so when $k=6$ and $k=7$ the algorithm outputs two more vectors, +% namely +% \begin{dseries}[frame] +% \mx{v^{[2]} =(0,5,5,0,9,5,1,0)}, +% \mx{v^{[3]} =(0,9,11,9,10,12,0,1)}. +% \end{dseries} +% From the form of the matrix $A$ after $k=5$, it is evident that +% these vectors satisfy the equation $vA =(0,\dotsc,0)$. +% \end{xio} +% +% \begin{xio} +% \begin{dmath*} +% T(n) \hiderel{\leq} T(2^{\lceil\lg n\rceil}) +% \leq c(3^{\lceil\lg n\rceil} +% -2^{\lceil\lg n\rceil}) +% <3c\cdot3^{\lg n} +% =3c\,n^{\lg3} +% \end{dmath*}. +% \end{xio} +% +% \begin{xio} +% The reduced minimal Gr\"obner basis for $I^q_3$ consists of +% \begin{dgroup*} +% \begin{dmath*} +% H_1^3 = x_1 + x_2 + x_3 +% \end{dmath*}, +% \begin{dmath*} +% H_2^2 = x_1^2 + x_1 x_2 + x_2^2 - q_1 - q_2 +% \end{dmath*}, +% \begin{dsuspend} +% and +% \end{dsuspend} +% \begin{dmath*} +% H_3^1 = x_1^3 - 2x_1 q_1 - x_2 q_1 +% \end{dmath*}. +% \end{dgroup*} +% \end{xio} +% +% +% +%\section{Technical notes on tag placement} +% +%The method used by the breqn package to place the equation number is +%rather more complicated than you might think, and the whole reason is +%to allow the number to stay properly centered on the total height even +%when the height fluctuates due to stretching or shrinking of the page. +% +% +%Consider the following equation: +%\begin{dmath}[number={3.15}] +% N_{0} \simeq \left( \frac{\nu}{\lVert u\rVert_{H^{i}}} \right) +% \lvert I\rvert^{-1/2} +%\end{dmath} +%It will have only one line, if the column width is not too narrow. +% +%Scrutinizing the vertical list will shed light on some of the basic properties +%shared by all breqn equations. After that we will look at what would happen if +%two or more lines were needed. The numbers added on the left in the following +%\cs{showlists} output mark the points of interest. +%\begin{verbatim} +%[1] \penalty 10000 +% \glue(\abovedisplayskip) 0.0 +% \penalty 10000 +% \glue(\belowdisplayskip) 0.0 +%[2] \glue 4.0 plus 4.0 +% \glue(\lineskip) 1.0 +%[3] \vbox(16.53902+0.0)x0.0, glue set 16.53902fil +% .\glue 0.0 plus 1.0fil minus 1.0fil +% \penalty 10000 +%[4] \glue -8.51945 +%[5] \hbox(7.5+2.5)x25.55563 +% .\OT1/cmr/m/n/10 ( +% .\OT1/cmr/m/n/10 3 +% .\OT1/cmr/m/n/10 . +% .\OT1/cmr/m/n/10 1 +% .\OT1/cmr/m/n/10 5 +% .\kern 0.0 +% .\OT1/cmr/m/n/10 ) +% \penalty 10000 +%[6] \glue(\parskip) -18.01956 +%[7] \hbox(16.53902+9.50012)x360.0, glue set 1.78647 +%\end{verbatim} +%\begin{enumerate} +%\item These four lines are a hidden display structure from \TeX's +% primitive \texttt{\$\$} mechanism. It is used only to get the value +% of \cs{predisplaysize} so that we can later calculate by hand +% whether to use the short display skips or the regular ones. (The +% reason that we have to do it by hand traces back to the fact that +% \TeX\ 3.x does not allow unhboxing in math mode.) The penalties come +% from \cs{predisplaypenalty} and \cs{postdisplaypenalty}, which were +% locally set to 10000 to ensure there would be no unintended page +% breaks at these glue nodes. +% +%\item These two glue nodes are the ones that would normally have been +% produced at the top of a display; the first one is the above-display +% skip node (though we had to put it in by hand with \cs{vskip}) and +% the second one is the usual baselineskip/lineskip node. +% +%\item This is a dummy copy of the equation's first line, which is +% thrown in here to get the proper value of baselineskip (or lineskip +% in this case). Why do we need this? Because this ensures that we get +% the top spacing right before we fiddle with the glue nodes +% surrounding the equation number. And if the equation has a frame, +% this box is a good place to add it from. +% +%\item This is a special glue node that brings us to the right vertical +% position for adding the equation number. Its value is calculated +% from the variables that you would expect, given the presence of the +% dummy first line above the num- ber: starting position of the +% equation, height of first line, total height of equation body. If +% the equation body had more than one line, with stretchable glue +% between the lines, half of the stretch would be added in this glue +% node. +% +%\item The hbox containing the equation number. +% +%\item Backspace to bring the equation body to the right starting point. We use +% \cs{parskip} to put this glue in place because we're going to get a +% parskip node here in any case when we add the equation body with (in +% essence). If we didn't do this we'd get two glue nodes instead of +% one, to no purpose. +% +%\cs{\noindent} \cs{unhbox}\cs{EQ@box}. +% +% +%\item And lastly we see here the first line of the equation body, +% which appears to have height 16.5pt and depth 9.5pt. +%\end{enumerate} +% +%For comparison, the vertical list produced from the above equation in +%standard \LaTeX\ would look like this, if the same values of +%columnwidth and abovedisplayskip are used: +%\begin{verbatim} +%[1] \penalty 10000 +%[2] \glue(\abovedisplayskip) 4.0 plus 4.0 +% \glue(\lineskip) 1.0 +% \hbox(16.53902+9.50012)x232.94844 +%[3] .\hbox(7.5+2.5)x25.55563 +% ..\hbox(7.5+2.5)x25.55563 +% ...\OT1/cmr/m/n/10 ( +% ...\OT1/cmr/m/n/10 3 +% ...\OT1/cmr/m/n/10 . +% ...\OT1/cmr/m/n/10 1 +% ...\OT1/cmr/m/n/10 5 +% ...\kern 0.0 +% ...\OT1/cmr/m/n/10 ) +% .\kern101.49591 +%[4] .\hbox(16.53902+9.50012)x105.8969 +% ... +%[5] \penalty 0 +%[6] \glue(\belowdisplayskip) 4.0 plus 4.0 +% \glue(\lineskip) 1.0 +% \hbox(6.94444+1.94444)x345.0, glue set 62.1106fil +%\end{verbatim} +% +%\begin{enumerate} +% \item \cs{predisplaypenalty} +% \item \cs{abovedisplayskip} +% \item equation number box +% \item equation body +% \item \cs{postdisplaypenaltly} +% \item \cs{belowdisplayskip} +%\end{enumerate} +% +% +% \section{Technical notes on Equation Layouts} +% \textbf{MJD [1998/12/28]} +% +% \providecommand{\qq}[1]{\textquotedblleft#1\textquotedblright} +% \providecommand{\mdash}{\textemdash} +% \providecommand{\ndash}{\textendash} +% +% \newcommand{\ititle}[1]{\textit{#1}} +% +% \newcommand{\LR}[2][.4]{% +% \framebox[#1\displaywidth]{$\displaystyle{}#2$}% +% } +% +% \newcommand{\LHS}[1]{\LR[\relifactor]{#1}} +% +% \newdimen\relindent \newdimen\rhswd +% +% \newcommand{\dwline}{% +% \hbox to\curdw{\vrule height1ex +% \leaders\hrule height.55ex depth-.45ex\hfil +% \tiny \space display width +% \leaders\hrule height.55ex depth-.45ex\hfil +% \vrule height1ex}% +% } +% +% \newenvironment{layout}[1][.15]{% +% \noindent +% $$\edef\curdw{\the\displaywidth}% +% \def\relifactor{#1}% +% \gdef\layoutcr{\cr}\def\\{\layoutcr}% +% \binoppenalty 10000 \relpenalty 10000 +% \setbox8\vbox\bgroup +% \advance\baselineskip .35\baselineskip +% \advance\lineskip .35\baselineskip \lineskiplimit\lineskip +% \relindent=#1\displaywidth +% \rhswd=\displaywidth \advance\rhswd-\relindent +% \global\row 0 \gdef\rhsskew{}% +% \halign\bgroup \global\advance\row 1 $\hfil\displaystyle{}##$&% +% \ifnum\row>1 \rhsskew \fi $\displaystyle{}##\hfil$\cr +% }{% +% \crcr\egroup\egroup +% \vcenter{\halign{\hfil##\hfil\cr +% \hbox{\hss\dwline\hss}\cr\noalign{\vskip.6\baselineskip}\box8 \cr}}% +% $$\relax +% \ignorespacesafterend +% } +% +% \newcommand{\stagger}{\omit\span\gdef\layoutcr{\cr\omit\span}} +% +% \newcount\row +% +% \newcommand{\rhsskew}{} +% \newcommand{\skewleft}[1]{\gdef\rhsskew{\kern-#1\relax}} +% +% +% \subsection{Misc examples} +% +% Let us consider which of these have 50\% or more of wasted whitespace +% \emph{within the bounding box of the visible material}. +% \begin{layout}[.4] +% \LHS{L}&=\LR[.35]{R_{1}}\\ +% &=\LR[.25]{R_{1}} +% \end{layout} +% +% \subsection{Ladder and step layouts} +% +% \subsubsection{Straight ladder layout} +% This is distinguished by a relatively short LHS and one or more RHS's of +% any length. +% \begin{layout} +% \LHS{L} &= \LR[.5]{R_{1}}\\ +% &=\LR[.3]{R_{2}}\\ +% &=\LR[.25]{R_{3}}\\ +% &\qquad\ldots +% \end{layout} +% The simplest kind of equation that fits on one line and has only one RHS +% may be viewed as a trivial subcase of the straight ladder layout: +% \begin{layout} +% \LHS{L} &= \LR[.5]{R} +% \end{layout} +% If some of the RHS's are too wide to fit on a single line they may be +% broken at binary operator symbols such as plus or minus. This is still +% classified as a straight ladder layout if none of the fragments intrude +% into the LHS column, because the underlying parshape is the same. +% \begin{layout} +% \LHS{L} &= \LR[.4]{R_{1a}}\\ +% &\quad +\LR[.6]{R_{1b}}\\ +% &=\LR[.3]{R_{2}}\\ +% &=\LR[.25]{R_{3a}}\\ +% &\quad +\LR[.45]{R_{3b}}\\ +% &\quad +\LR[.54]{R_{3c}}\\ +% &\qquad\ldots +% \end{layout} +% +% \subsubsection{Skew ladder layout} +% \begin{layout}[.5] +% \skewleft{.35\displaywidth} +% \LHS{L}&= \LR[.3]{R_{1}}\\ +% &=\LR[.6]{R_{2}}\\ +% &=\LR[.25]{R_{3}}\\ +% &\qquad\ldots +% \end{layout} +% In a skew ladder layout, the combined LHS width plus width of $R_{1}$ +% does not exceed the available width, but one of the other RHS's is so +% wide that aligning its relation symbol with the others cannot be done +% without making it run over the right margin: $\mbox{width}(L) + +% \mbox{width}_{\mathrm{max}}(R_{i})>\mbox{width}_{\mathrm{avail}}$. In +% that case we next try aligning all but the first relation symbol, +% allowing all the $R_{i}$ after $R_1$ to shift leftward. +% +% \subsubsection{Drop ladder layout} +% \begin{layout}[.6] +% \makebox[.15\displaywidth][l]{\LHS{L}}\\ +% &= \LR[.6]{R_{1}}\\ +% &=\LR[.3]{R_{2}}\\ +% &=\LR[.25]{R_{3}}\\ +% &\qquad\ldots +% \end{layout} +% The drop ladder layout is similar to the skew ladder layout but with the +% width of $R_1$ too large for it to fit on the same line as the LHS. Then +% we move $R_1$ down to a separate line and try again to align all the +% relation symbols. Note that this layout consumes more vertical space +% than the skew ladder layout. +% +% \subsubsection{Step layout} +% \begin{layout}[.6] +% \stagger +% \LHS{R_{a}}\\ +% \qquad + \LR[.7]{R_{b}}\\ +% \qquad\qquad + \LR[.6]{R_{c}}\\ +% \qquad\qquad\qquad + \LR[.45]{R_{d}}\\ +% \qquad\qquad\qquad\qquad\ldots +% \end{layout} +% The chief characteristic of the step layout is that there is no relation +% symbol, so that the available line breaks are (usually) all at binary +% operator symbols. Let $w_1$ and $w_l$ be the widths of the first and +% last fragments. We postulate that the ideal presentation is as follows: +% Choose a small stairstep indent $I$ (let's say 1 or 2 em). We want the +% last fragment to be offset at least $I$ from the start of the first +% fragment, and to end at least $I$ past the end of the first fragment. If +% there are only two lines these requirements determine a target width +% $w_T=\max(w_1+I,w_l+I)$. If there are more than two lines ($l>2$) then +% use $w_T = \max(w_1 + (l-1)I, w_l+I, w_{\mathrm{avail}}$ and reset $I$ +% to $w_T/(l-1)$ if $w_T = w_{\mathrm{avail}}$. +% +% Furthermore, we would like the material to be distributed as evenly as +% possible over all the lines rather than leave the last line exceedingly +% short. If the total width is $1.1(\mbox{width}_{\mathrm{avail}})$, we +% don't want to have .9 of that on line 1 and .2 of it on line 2: +% \begin{layout}[.9] +% \stagger +% \LHS{R_{a}\hfil+\hfil R_{b}\hfil+\hfil R_{c}}\\ +% \qquad + \LR[.1]{R_{d}} +% \end{layout} +% Better to split it as evenly as possible, if the available breakpoints +% permit. +% \begin{layout}[.5] +% \stagger +% \LHS{R_{a}\hfil+\hfil R_{b}}\\ +% \qquad + \LR[.5]{R_{c}\hfil+\hfil R_d} +% \end{layout} +% A degenerate step layout may arise if an unbreakable fragment of +% the equation is so wide that indenting it to its appointed starting +% point would cause it to run over the right margin. In that case, we want +% to shift the fragment leftward just enough to bring it within the right +% margin: +% \begin{layout}[.6] +% \stagger +% \LHS{L_{a}}\\ +% \quad + \LR[.8]{L_{b}}\\ +% \qquad + \LR[.7]{L_{c}}\\ +% \; + \LR[.87]{L_{d}}\\ +% \qquad\ldots +% \end{layout} +% And then we may want to regularize the indents as in the drop ladder +% layout. Let's call this a dropped step layout: +% \begin{layout}[.6] +% \stagger +% \LHS{L_{a}}\\ +% \quad + \LR[.8]{L_{b}}\\ +% \quad + \LR[.7]{L_{c}}\\ +% \quad + \LR[.87]{L_{d}}\\ +% \qquad\ldots +% \end{layout} +% +% \subsection{Strategy} +% +% Here is the basic procedure for deciding which equation layout to use, +% before complications like equation numbers and delimiter clearance come +% into the picture. Let $A$ be the available width, $w_{\mathrm{total}}$ +% the total width of the equation contents, $w(L)$ the width of the +% left-hand side, $w_{\max}(R)$ the max width of the right-hand sides, $I$ +% the standard indent for step layout, and $O$ the standard offset for +% binary operators if a break occurs in the middle of an RHS. Also let +% $t_L$ and $t_R$ represent certain thresholds for the width of the LHS or +% the RHS at which a layout decision may change, as explained below. +% +% \begin{small} +% \begin{enumerate} +% \renewcommand{\labelenumi}{(\theenumi)} +% \item \ititle{Does everything fit on one line?}\label{i:LR} +% $w_{\mathrm{total}}\leq A$? +% +% Yes: print the equation on a single line (done). +% +% No: Check whether the equation has both LHS and RHS (\ref{i:lhs-check}). +% +% \item \ititle{Is there a left-hand side?}\label{i:lhs-check} +% Are there any relation symbols in the equation? +% +% Yes: Try a ladder layout (\ref{i:ladder}). +% +% No: Try a step layout (\ref{i:step}). +% +% \item\ititle{Does the LHS leave room to fit the widest RHS?}\label{i:ladder} +% $w(L)+w_{\max}(R)<A$? +% +% Yes: Use a straight ladder layout (\ref{i:straight-ladder}). +% +% No: Check the width of the LHS (\ref{i:check-lhs}). +% +% \item\ititle{Is the LHS relatively short?}\label{i:check-lhs} +% $w(L)\leq t_L$? (where $t_L$ is typically $0.4A$). +% +% Yes: Subdividing one or more of the RHS's may permit us to use a +% straight ladder layout (\ref{i:straight-ladder}). +% +% No: The straight ladder layout is unlikely to work. +% Try a skew or drop ladder layout (\ref{i:skew-drop}). +% +% \item\ititle{Straight ladder layout}\label{i:straight-ladder} +% Set up a straight ladder parshape [0pt $A$ $w(L)$ $A-w(L)$] and run +% a trial break. If the combined width of the LHS plus the longest RHS is +% no greater than $A$ then we should get a satisfactory layout with all +% line breaks occurring at major division points (relation symbols). +% Otherwise, we hope, some additional line breaks at minor division points +% will allow everything to fit within the text column. +% +% \ititle{Line breaks OK?} +% +% \begingroup \hbadness=9999 +% Yes: The straight ladder layout succeeded +% (done).\par\endgroup +% +% No: Try a skew or drop ladder layout (\ref{i:skew-drop}). +% +% \item\ititle{Do the LHS and the first RHS fit on one +% line?}\label{i:skew-drop} $w(L)+w(R_1) \leq A$? +% +% Yes: Try a skew ladder layout (\ref{i:skew}). +% +% No: Try a drop ladder layout (\ref{i:drop}). +% +% \item\ititle{Skew ladder layout}\label{i:skew} +% Set up a parshape [0pt $A$ $I$ $A-I$] and run a trial break. +% +% \ititle{Line breaks OK?} +% +% Yes: Skew ladder layout succeeded (done). +% +% No: One of the unbreakable fragments of the $R_i$ ($i>1$) is wider than +% $A-I$; try an almost-columnar layout (\ref{i:almost-columnar}). +% +% \item\ititle{Drop ladder layout}\label{i:drop} +% Set up a parshape [0pt $w(L)$ $I$ $A-I$] and run a trial break. +% This is the same parshape as for a skew ladder layout except that the +% width of the first line is limited to the LHS width, so that the RHS is +% forced to drop down to the next line. +% +% \ititle{Line breaks OK?} +% +% Yes: Drop ladder layout succeeded (done). +% +% No: One of the unbreakable fragments of the $R_i$ ($i>1$) is wider than +% $A-I$; try an almost-columnar layout (\ref{i:almost-columnar}). +% +% \item\ititle{Almost-columnar layout}\label{i:almost-columnar} +% This presupposes a trial break that yielded a series of expressions or +% fragments, one per line. Let $w(F)$ denote the width of the first +% fragment and $w(R_i)$ the widths of the remaining fragments. +% Set up a parshape [0pt $w(F)$ $A-w_{\max}(R_i)$ $w_{\max}(R_i)$]: in other +% words, set the first line flush left and the longest line flush right +% and all other lines indented to the same position as the longest line. +% But as a matter of fact there is one other refinement for extreme cases: +% if $w_{\max}(R_i)>A$ then the parshape can be simplified without loss to +% [0pt $w(F)$ 0pt $A$]\mdash for that is the net effect of substituting +% $\min(A,w_{\max})$ in stead of $w_{\max}$. +% (Done.) +% +% \item\ititle{Step layout}\label{i:step} Set target width $w_T$ to $A - +% 2I$. Set parshape to [0pt $w_T$ $I$ $w_T -I$ $2I$ $w_T -2I$ \ldots\ +% $(l-1)I$ $w_T - (l-1)I$], where $l=\lceil w_{\mathrm{total}}/A\rceil$ +% is the expected number of lines that will be required. Trial break +% with that parshape in order to find out the width of the last line. +% +% \ititle{Indents OK?} +% +% Yes: Step layout succeeded (done). +% +% No: One of the fragments is too wide to fit in +% the allotted line width, after subtracting the indent specified by the +% parshape. Try a dropped step layout (\ref{i:drop-step}) +% +% \item\ititle{Dropped step layout}\label{i:drop-step} Set up a parshape +% [0pt $A$ $I$ $A-I$] and run a trial break. Note that this is actually +% the same parshape as for a skew ladder layout. +% +% \ititle{Line breaks OK?} +% +% Yes: Dropped step layout succeeded (done). +% +% No: One of the unbreakable fragments of the $R_i$ ($i>1$) is wider than +% $A-I$; as a last resort try an almost-columnar layout (\ref{i:almost-columnar}). +% +% \end{enumerate} +% \par\end{small} +% +% \section{To do} +% +% \begin{itemize} +% \item Handling of QED +% \item Space between \verb'\end{dmath}' and following punctuation will +% prevent the punctuation from being drawn into the equation. +% \item Overriding the equation layout +% \item Overriding the placement of the equation number +% \item \qq{alignid} option for more widely separated equations where +% shared alignment is desired (requires two passes) +% \item Or maybe provide an \qq{alignwidths} option where you give +% lhs/rhs width in terms of ems? And get feedback later on discrepancies +% with the actual measured contents? +% \item \cs{intertext} not needed within dgroup! But currently there are +% limitations on floating objects within dgroup. +% \item \verb'align={1}' or 2, 3, 4 expressing various levels of demand +% for group-wide alignment. Level 4 means force alignment even if some +% lines then have to run over the right margin! Level 1, the default, +% means first break LHS-RHS equations as if it occurred by itself, then +% move them left or right within the current line width to align them if +% possible. Levels 2 and 3 mean try harder to align but give up if +% overfull lines result. +% \item Need an \cs{hshift} command to help with alignment of +% lines broken at a discretionary times sign. Also useful for adjusting +% inside-delimiter breaks. +% \end{itemize} +% +% \StopEventually{} +% \clearpage +% \newgeometry{left=4cm} +% \part{Implementation} +% +% +% The package version here is Michael's v0.90 updated by Bruce +% Miller. Michael's changes between v0.90 and his last v0.94 will be +% incorporated where applicable. +% +% +% The original sources of \pkg{breqn} and related files exist in a +% non-dtx format devised by Michael Downes himself. +% Lars Madsen has kindly written a Perl script for transforming the +% original source files into near-perfect dtx state, requiring only +% very little hand tuning. Without his help it would have been nigh +% impossible to incorporate the original sources with Michael's +% comments. A big, big thank you to him. +% +% +% +% \section{Introduction} +% The \pkg{breqn} package provides environments +% \env{dmath}, \env{dseries}, and \env{dgroup} for +% displayed equations with \emph{automatic line breaking}, +% including automatic indention of relation symbols and binary operator +% symbols at the beginning of broken lines. These environments +% automatically pull in following punctuation so that it can be written in +% a natural way. The \pkg{breqn} package also provides a +% \env{darray} environment similar to the \env{array} +% environment but using \cs{displaystyle} for all the array cells and +% providing better interline spacing (because the vertical ruling +% feature of \env{array} is dropped). +% These are all autonumbered environments like \env{equation} +% and have starred forms that don't add a number. For a more +% comprehensive and detailed description of the features and intended +% usage of the \pkg{breqn} package see \fn{breqndoc.tex}. +% +% +% +% +% \section{Strategy} +% Features of particular note are the ability to have +% linebreaks even within a \cs{left} \ndash \cs{right} pair of +% delimiters, and the automatic alignment on relations and binary +% operators of a split equation. To make \env{dmath} handle +% all this, we begin by setting the body of the equation in a special +% paragraph form with strategic line breaks whose purpose is not to +% produce line breaks in the final printed output but rather to mark +% significant points in the equation and give us entry points for +% unpacking \cn{left} \ndash \cn{right} boxes. +% After the initial typesetting, we take the resulting stack of line +% fragments and, working backward, splice them into a new, single-line +% paragraph; this will eventually be poured into a custom parshape, after +% we do some measuring to calculate what that parshape should be. +% This streamlined horizontal list may contain embedded material +% from user commands intended to alter line breaks, horizontal alignment, +% and interline spacing; such material requires special handling. +% +% To make the `shortskip' possibility work even for +% multiline equations, we must plug in a dummy \tex display to give us +% the value of \cs{predisplaysize}, and calculate for ourselves when +% to apply the short skips. +% +% In order to measure the equation body and do various +% enervating calculations on whether the equation number will fit and so +% on, we have to set it in a box. Among other things, this means +% that we can't unhbox it inside \dbldollars \dots \dbldollars , or +% even \verb"$" \dots \verb"$": \tex doesn't allow you to +% \cs{unhbox} in math mode. But we do want to unhbox it rather +% than just call \cs{box}, otherwise we can't take advantage of +% available shrink from \cs{medmuskip} to make equations shrink to +% fit in the available width. So even for simple one-line equations +% we are forced to fake a whole display without going through \tex 's +% primitive display mechanism (except for using it to get +% \cs{predisplaysize} as mentioned above). +% +% +% In the case of a framed equation body, the current implementation is +% to set the frame in a separate box, of width zero and height zero, +% pinned to the upper left corner of the equation body, and then print the +% equation body on top of it. +% For attaching an equation number it would be much simpler to wrap +% the equation body in the frame and from then on treat the body as a +% single box instead of multiple line boxes. +% But I had a notion that it might be possible some day to support +% vertical stretching of the frame. +% +% +% +% +% \section{Prelim} +% +% This package doesn't work with \latex 2.09, nor with other +% versions of \latex earlier than 1994/12/01. +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +% \end{macrocode} +% +% Declare package name and date. +% \begin{macrocode} +\RequirePackage{expl3}[2009/08/05] +\ProvidesExplPackage{breqn}{2012/05/10}{0.98b}{Breaking equations} +% \end{macrocode} +% Regrettably, \pkg{breqn} is internally a mess, so we have to take +% some odd steps. +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% +% \section{Package options} +% +% Most options are set with the \cs{options} command (which +% calls \cs{setkeys}) because the standard package option +% mechanism doesn't provide support for key-value syntax. +% +% First we need to get the catcodes sorted out. +% \begin{macrocode} +\edef\breqnpopcats{% + \catcode\number`\"=\number\catcode`\" + \relax} +\AtEndOfPackage{\breqnpopcats}% +\catcode`\^=7 \catcode`\_=8 \catcode`\"=12 \relax +\DeclareOption{mathstyleoff}{% + \PassOptionsToPackage{mathstyleoff}{flexisym}% +} +% \end{macrocode} +% Process options. +% \begin{macrocode} +\ProcessOptions\relax +% \end{macrocode} +% +% +% +% +% \section{Required packages} +% The \pkg{flexisym} package makes it possible to attach +% extra actions to math symbols, in particular mathbin, mathrel, mathopen, +% and mathclose symbols. +% Normally it would suffice to call \cs{RequirePackage} without +% any extra testing, but the nature of the package is such that it is +% likely to be called earlier with different (no) options. +% Then is it really helpful to be always warning the user about +% \quoted{Incompatible Package Options!}? +% I don't think so. +% \begin{macrocode} +\@ifpackageloaded{flexisym}{}{% + \RequirePackage{flexisym}[2009/08/07] + \edef\breqnpopcats{\breqnpopcats + \catcode\number`\^=\number\catcode`\^ + \catcode\number`\_=\number\catcode`\_ + }% + \catcode`\^=7 \catcode`\_=8 \catcode`\"=12 \relax +} +% \end{macrocode} +% The \pkg{keyval} package for handling equation options and +% \pkg{calc} to ease writing computations. +% \begin{macrocode} +\RequirePackage{keyval,calc}\relax +% \end{macrocode} +% +% +% And add an \cs{options} cmd for processing package +% options that require an argument. Maybe this will get added to +% the \pkg{keyval} package eventually. +% \begin{macrocode} +\@ifundefined{options}{% +% \end{macrocode} +% +% +% \begin{macro}{\options} +% Get the package options and run setkeys on them. +% \begin{macrocode} +\newcommand{\options}[2]{% + \expandafter\options@a\csname opt@#1.sty\endcsname{#2}% + \setkeys{#1}{#2}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\options@a} +% \begin{macro}{\options@b} +% \begin{macro}{\options@c} +% \begin{macro}{\options@d} +% Redefine \cs{opt@pkgname.sty} as we go along to take out +% the options that are handled and leave the ones that are not. +% \begin{macrocode} +\def\options@a#1#2{% + \edef\@tempa{\options@b#2,\@empty\@nil}% + \ifx#1\relax \let#1\@empty\fi + \xdef#1{#1\ifx#1\@empty\@xp\@gobble\@tempa\@empty\else\@tempa \fi}% +} +% \end{macrocode} +% Add the next option, and recurse if there remain more +% options. +% \begin{macrocode} +\def\options@b#1,#2#3\@nil{% + \options@c#1 \@nil + \ifx#2\@empty \else\options@b#2#3\@nil\fi +} +% \end{macrocode} +% Discard everything after the first space. +% \begin{macrocode} +\def\options@c#1 #2\@nil{\options@d#1=\@nil} +% \end{macrocode} +% Discard everything after the first = sign; add a comma only if the +% remainder is not empty. +% \begin{macrocode} +\def\options@d#1=#2\@nil{\ifx\@empty #1\@empty\else,\fi#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% The tail of the \cs{@ifundefined} test. +% \begin{macrocode} +}{}% end @ifundefined test +% \end{macrocode} +% +% +% +% +% \section{Some useful tools} +% +% \begin{macro}{\@nx} +% \begin{macro}{\@xp} +% The comparative brevity of \cs{@nx} and \cs{@xp} is +% valuable not so much for typing convenience as for reducing visual +% clutter in code sections that require a lot of expansion control. +% \begin{macrocode} +\let\@nx\noexpand +\let\@xp\expandafter +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@emptytoks} +% Constant empty token register, analogous to \cs{@empty}. +% \begin{macrocode} +\@ifundefined{@emptytoks}{\newtoks\@emptytoks}{} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\f@ur} +% Constants 0\ndash 3 are provided in plain \tex , but not 4. +% \begin{macrocode} +\chardef\f@ur=4 +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\inf@bad} +% \cs{inf@bad} is for testing box badness. +% \begin{macrocode} +\newcount\inf@bad \inf@bad=1000000 +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\maxint} +% +% We want to use \cs{maxint} rather than coerced +% \cs{maxdimen} for \cs{linepenalty} in one place. +% \begin{macrocode} +\newcount\maxint \maxint=2147483647 +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\int@a} +% \begin{macro}{\int@b} +% \begin{macro}{\int@b} +% +% Provide some shorter aliases for various scratch registers. +% \begin{macrocode} +\let\int@a=\@tempcnta +\let\int@b=\@tempcntb +\let\int@c=\count@ +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\dim@a} +% \begin{macro}{\dim@b} +% \begin{macro}{\dim@c} +% \begin{macro}{\dim@d} +% \begin{macro}{\dim@e} +% \begin{macro}{\dim@A} +% +% Same for dimen registers. +% \begin{macrocode} +\let\dim@a\@tempdima +\let\dim@b\@tempdimb +\let\dim@c\@tempdimc +\let\dim@d\dimen@ +\let\dim@e\dimen@ii +\let\dim@A\dimen@i +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\skip@a} +% \begin{macro}{\skip@b} +% \begin{macro}{\skip@c} +% +% Same for skip registers. +% \begin{macrocode} +\let\skip@a\@tempskipa +\let\skip@b\@tempskipb +\let\skip@c\skip@ +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\toks@a} +% \begin{macro}{\toks@b} +% \begin{macro}{\toks@c} +% \begin{macro}{\toks@d} +% \begin{macro}{\toks@e} +% \begin{macro}{\toks@f} +% +% Same for token registers. +% \begin{macrocode} +\let\toks@a\@temptokena +\let\toks@b\toks@ +\toksdef\toks@c=2 +\toksdef\toks@d=4 +\toksdef\toks@e=6 +\toksdef\toks@f=8 +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\abs@num} +% We need an absolute value function for comparing +% penalties. +% \begin{macrocode} +\def\abs@num#1{\ifnum#1<\z@-\fi#1} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@ifnext} +% \begin{macro}{\@ifnexta} +% The \cs{@ifnext} function is a variation of +% \cs{@ifnextchar} that doesn't skip over intervening whitespace. +% We use it for the optional arg of \dbslash inside +% \env{dmath} \etc because we don't want +% unwary users to be tripped up by an unexpected attempt on \latex 's part +% to interpret a bit of math as an optional arg: +% \begin{literalcode} +% \begin{equation} +% ...\\ +% [z,w]... +% \end{equation} +% \end{literalcode} +% . +% \begin{macrocode} +\def\@ifnext#1#2#3{% + \let\@tempd= #1\def\@tempa{#2}\def\@tempb{#3}% + \futurelet\@tempc\@ifnexta +} +% \end{macrocode} +% Switch to \cs{@tempa} iff the next token matches. +% \begin{macrocode} +\def\@ifnexta{\ifx\@tempc\@tempd \let\@tempb\@tempa \fi \@tempb} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@ifstar} +% Similarly let's remove space-skipping from \cs{@ifstar} +% because in some rare case of \dbslash inside an equation, followed by +% a space and a \verb"*" where the \verb"*" is intended as the math +% binary operator, it would be a disservice to gobble the star as an +% option of the \dbslash command. In all other contexts the chance +% of having a space \emph{before} the star is extremely small: either +% the command is a control word which will get no space token after it in +% any case because of \tex 's tokenization rules; or it is a control +% symbol such as \dbslash \verb"*" which is exceedingly unlikely to be +% written as \dbslash \verb"*" by any one who really wants the +% \verb"*" to act as a modifier for the \dbslash command. +% \begin{macrocode} +\def\@ifstar#1#2{% + \let\@tempd*\def\@tempa*{#1}\def\@tempb{#2}% + \futurelet\@tempc\@ifnexta +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@optarg} +% Utility function for reading an optional arg +% \emph{without} skipping over any intervening spaces. +% \begin{macrocode} +\def\@optarg#1#2{\@ifnext[{#1}{#1[#2]}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@True} +% \begin{macro}{\@False} +% \begin{macro}{\@Not} +% \begin{macro}{\@And} +% After \verb"\let\foo\@True" the test +% \begin{literalcode} +% \if\foo +% \end{literalcode} +% evaluates to true. Would rather avoid \cs{newif} because it +% uses three csnames per Boolean variable; this uses only one. +% \begin{macrocode} +\def\@True{00} +\def\@False{01} +\def\@Not#1{0\ifcase#11 \or\@xp 1\else \@xp 0\fi} +\def\@And#1#2{0\ifcase#1#2 \@xp 0\else \@xp 1\fi} +\def\@Or#1#2{0\ifnum#1#2<101 \@xp 0\else \@xp 1\fi} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macrocode} +\def\theb@@le#1{\if#1 True\else False\fi} +% \end{macrocode} +% \begin{macro}{\freeze@glue} +% +% Remove the stretch and shrink from a glue register. +% \begin{macrocode} +\def\freeze@glue#1{#11#1\relax} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\z@rule} +% \begin{macro}{\keep@glue} +% Note well +% the intentional absence of \cs{relax} at the end of the replacement +% text of \cs{z@rule}; use it with care. +% \begin{macrocode} +\def\z@rule{\vrule\@width\z@}% no \relax ! use with care +% \end{macrocode} +% Different ways to keep a bit of glue from disappearing at the +% beginning of a line after line breaking: +% \begin{itemize} +% \item Zero-thickness rule +% \item Null character +% \item \cs{vadjust}\verb"{}" (\texbook , Exercise ??) +% \end{itemize} +% The null character idea would be nice except it +% creates a mathord which then screws up math spacing for \eg a following +% unary minus sign. (the vrule \emph{is} transparent to +% the math spacing). The vadjust is the cheapest in terms of box +% memory\mdash it vanishes after the pass through \tex 's +% paragrapher. +% It is what I would have used, except that the equation contents get +% run through two paragraphing passes, once for breaking up LR boxes and +% once for the real typesetting. +% If \cs{keep@glue} were done with an empty vadjust, it would +% disappear after the first pass and\mdash in particular\mdash the +% pre-bin-op adjustment for relation symbols would disappear at a line break. +% \begin{macrocode} +\def\keep@glue{\z@rule\relax} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\replicate} +% +% This is a fully expandable way of making N copies of a token +% list. +% Based on a post of David Kastrup to comp.text.tex circa January +% 1999. +% The extra application of \cs{number} is needed for maximal +% robustness in case the repeat count N is given in some weird \tex form +% such as \verb|"E9| or \verb|\count9|. +% \begin{macrocode} +% usage: \message{H\replicate{5}{i h}ow de doo dee!} +\begingroup \catcode`\&=11 +\gdef\replicate#1{% + \csname &\expandafter\replicate@a\romannumeral\number\number#1 000q\endcsname +} +\endgroup +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\replicate@a} +% \begin{macrocode} +\long\def\replicate@a#1#2\endcsname#3{#1\endcsname{#3}#2} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\8m}% fix +% \begin{macrocode} +\begingroup \catcode`\&=11 +\long\gdef\&m#1#2{#1\csname \endcsname{#1}} +\endgroup +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\8q}% fix +% \begin{macrocode} +\@xp\let\csname\string &q\endcsname\@gobble +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mathchars@reset} +% +% Need to patch up this function from flexisym a little, to better +% handle certain constructed symbols like \cs{neq}. +% \begin{macrocode} +\ExplSyntaxOn +\g@addto@macro\mathchars@reset{% + %\let\@symRel\@secondoftwo \let\@symBin\@secondoftwo + %\let\@symDeL\@secondoftwo \let\@symDeR\@secondoftwo + %\let\@symDeB\@secondoftwo + \cs_set_eq:NN \math_csym_Rel:Nn \use_ii:nn + \cs_set_eq:NN \math_csym_Bin:Nn \use_ii:nn + \cs_set_eq:NN \math_csym_DeL:Nn \use_ii:nn + \cs_set_eq:NN \math_csym_DeR:Nn \use_ii:nn + \cs_set_eq:NN \math_csym_DeB:Nn \use_ii:nn +} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@cons} +% +% \latex 's \cs{@cons} appends to the end of a list, but we need +% a function that adds material at the beginning. +% \begin{macrocode} +\def\eq@cons#1#2{% + \begingroup \let\@elt\relax \xdef#1{\@elt{#2}#1}\endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@saveprimitive} +% If some preceding package redefined one of the +% primitives that we must change, we had better do some checking to make +% sure that we are able to save the primitive meaning for internal use. +% This is handled by the \cs{@saveprimitive} function. We +% follow the example of \cs{@@input} where the primitive meaning is +% stored in an internal control sequence with a \verb"@@" prefix. +% Primitive control sequences can be distinguished by the fact that +% \cs{string} and \cs{meaning} return the same information. +% Well, not quite all: \cs{nullfont} and \cs{topmark} +% and the other \cs{...mark} primitives being the exceptions. +% \begin{macrocode} +\providecommand{\@saveprimitive}[2]{% + \begingroup + \edef\@tempa{\string#1}\edef\@tempb{\meaning#1}% + \ifx\@tempa\@tempb \global\let#2#1% + \else +% \end{macrocode}% +% If [arg1] is no longer primitive, then we are in trouble unless +% [arg2] was already given the desired primitive meaning somewhere +% else. +% \begin{macrocode} + \edef\@tempb{\meaning#2}% + \ifx\@tempa\@tempb + \else \@saveprimitive@a#1#2% + \fi + \fi + \endgroup +} +% \end{macrocode} +% Aux function, check for the special cases. +% Most of the time this branch will be skipped so we can +% stuff a lot of work into it without worrying about speed costs. +% \begin{macrocode} +\providecommand\@saveprimitive@a[2]{% + \begingroup + \def\@tempb##1#1##2{\edef\@tempb{##2}\@car{}}% + \@tempb\nullfont{select font nullfont}% + \topmark{\string\topmark:}% + \firstmark{\string\firstmark:}% + \botmark{\string\botmark:}% + \splitfirstmark{\string\splitfirstmark:}% + \splitbotmark{\string\splitbotmark:}% + #1{\string#1}% + \@nil % for the \@car + \edef\@tempa{\expandafter\strip@prefix\meaning\@tempb}% + \edef\@tempb{\meaning#1}% + \ifx\@tempa\@tempb \global\let#2#1% + \else + \PackageError{breqn}% + {Unable to properly define \string#2; primitive + \noexpand#1no longer primitive}\@eha + \fi + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@math} +% \begin{macro}{\@@endmath} +% \begin{macro}{\@@display} +% \begin{macro}{\@@enddisplay} +% Move the math-start and math-end functions into control +% sequences. If I were redesigning \tex I guess I'd put these +% functions into primitive control words instead of linking them to a +% catcode. That way \tex would not have to do the special +% lookahead at a \verb"$" to see if there's another one coming up. +% Of course that's related to the question of how to provide user +% shorthand for common constructions: \tex , or an editing interface of +% some sort. +% \begin{macrocode} +\begingroup \catcode`\$=\thr@@ % just to make sure + \global\let\@@math=$ \gdef\@@display{$$}% $$$ +\endgroup +\let\@@endmath=\@@math +\let\@@enddisplay=\@@display +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@@insert} +% \begin{macro}{\@@mark} +% \begin{macro}{\@@vadjust} +% Save the primitives \cs{vadjust}, \cs{insert}, +% \cs{mark} because we will want to change them locally during +% equation measuring to keep them from getting in the way of our vertical +% decomposition procedures. We follow the example of +% \cs{@@input}, \cs{@@end}, \cs{@@par} where the primitive +% meaning is stored in an internal control sequence with a \verb"@@" +% prefix. +% \begin{macrocode} +\@saveprimitive\vadjust\@@vadjust +\@saveprimitive\insert\@@insert +\@saveprimitive\mark\@@mark +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% \section{Debugging} +% Debugging help. +% \begin{macrocode} +%<*trace> +\errorcontextlines=2000\relax +% \end{macrocode} +% +% \begin{macro}{\breqn@debugmsg} +% Print a debugging message. +% \begin{macrocode} +\long\def\breqn@debugmsg#1{\GenericInfo{||}{||=\space#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\debugwr} +% Sometimes the newline behavior of \cs{message} is +% unsatisfactory; this provides an alternative. +% \begin{macrocode} +\def\debugwr#1{\immediate\write\sixt@@n{||= #1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\debug@box} +% Record the contents of a box in the log file, without stopping. +% \begin{macrocode} +\def\debug@box#1{% + \batchmode{\showboxbreadth\maxdimen\showboxdepth99\showbox#1}% + \errorstopmode +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eqinfo} +% Show lots of info about the material before launching into the +% trials. +% \begin{macrocode} +\def\eqinfo{% + \debug@box\EQ@copy + \wlog{!! EQ@copy: \the\wd\EQ@copy\space x + \the\ht\EQ@copy+\the\dp\EQ@copy + }% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\debug@para} +% Check params that affect line breaking. +% \begin{macrocode} +\def\debug@para{% + \debugwr{\hsize\the\hsize, \parfillskip\the\parfillskip}% + \breqn@debugmsg{\leftskip\the\leftskip, \rightskip\the\rightskip}% + \breqn@debugmsg{\linepenalty\the\linepenalty, \adjdemerits\the\adjdemerits}% + \breqn@debugmsg{\pretolerance\the\pretolerance, \tolerance\the\tolerance, + \parindent\the\parindent}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +%</trace> +% \end{macrocode} +% +% +% +% +% \section{The \cs{listwidth} variable} +% The dimen variable \cs{listwidth} is \cs{linewidth} +% plus \cs{leftmargin} plus \cs{rightmargin}, which is typically +% less than \cs{hsize} if the list depth is greater than one. +% In case a future package will provide this variable, define it only +% if not yet defined. +% \begin{macrocode} +\@ifundefined{listwidth}{\newdimen\listwidth}{} +\listwidth=\z@ +% \end{macrocode} +% +% +% +% +% \section{Parameters} +% +% Here follows a list of parameters needed. +% +% \begin{macro}{\eqfontsize} +% \begin{macro}{\eqcolor} +% \begin{macro}{\eqmargin} +% \begin{macro}{\eqindent} +% \begin{macro}{\eqbinoffset} +% \begin{macro}{\eqnumside} +% \begin{macro}{\eqnumplace} +% \begin{macro}{\eqnumsep} +% \begin{macro}{\eqnumfont} +% \begin{macro}{\eqnumform} +% \begin{macro}{\eqnumsize} +% \begin{macro}{\eqnumcolor} +% \begin{macro}{\eqlinespacing} +% \begin{macro}{\eqlineskip} +% \begin{macro}{\eqlineskiplimit} +% \begin{macro}{\eqstyle} +% \begin{macro}{\eqinterlinepenalty} +% \begin{macro}{\intereqpenalty} +% \begin{macro}{\intereqskip} +% +% Note: avoid M, m, P, p because they look like they might be the +% start of a keyword \quoted{minus} or \quoted{plus}. Then +% \tex looks further to see if the next letter is i or l. And if +% the next thing is an undefined macro, the attempt to expand the macro +% results in an error message. +% \begin{macrocode} +\def\eqfontsize{} % Inherit from context [NOT USED?] +\def\eqcolor{black} % Default to black [NOT USED?] +\newdimen\eqnumsep \eqnumsep=10pt % Min space between equ number and body +\newdimen\eqmargin \eqmargin=8pt % For `multline' gap emulation +% \end{macrocode} +% The \cs{eqindent} and \cs{eqnumside} variables need to +% have their values initialized from context, actually. But +% that takes a bit of work, which is postponed till later. +% \begin{macrocode} +\def\eqindent{C}% % C or I, centered or indented +\def\eqnumside{R}% % R or L, right or left +\def\eqnumplace{M}% % M or T or B, middle top or bottom +% \end{macrocode} +% Typesetting the equation number is done thus: +% \begin{literalcode} +% {\eqnumcolor \eqnumsize \eqnumfont{\eqnumform{\eq@number}}} +% \end{literalcode} +% . +% \begin{macrocode} +%d\eqnumfont{\upshape}% % Upright even when surrounding text is slanted +\def\eqnumfont{}% % Null for easier debugging [mjd,1997/09/26] +\def\eqnumform#1{(#1\@@italiccorr)} % Add parens +\def\eqnumsize{} % Allow numbers to have different typesize ... +% \end{macrocode} +% Tricky questions on \cs{eqnumsize}. Should the default +% be \cs{normalsize}? Then the user can scale down the +% equation body with \cs{small} and not affect the equation +% number. Or should the default be empty? Then in large +% sections of smaller text, like the dangerous bend stuff in +% \emph{\TeX book}, the equation number size will keep in synch +% with the context. +% Maybe need an \cs{eqbodysize} param as well to allow separating +% the two cases. +% \begin{macrocode} +\def\eqnumcolor{} % ... or color than eq body e.g. \color{blue} +\newlength\eqlinespacing \eqlinespacing=14pt plus2pt % Base-to-base space between lines +\newlength\eqlineskip \eqlineskip=3pt plus2pt % Min space if eqlinespacing too small +\newdimen\eqlineskiplimit \eqlineskiplimit=2pt % Threshold for switching to eqlineskip +% \end{macrocode} +% The value of \cs{eqbinoffset} should include a negative shrink +% component that cancels the shrink component of medmuskip, otherwise +% there can be a noticeable variation in the indent of adjacent lines if +% one is shrunken a lot and the other isn't. +% \begin{macrocode} +\newmuskip \eqbinoffset \eqbinoffset=15mu minus-3mu % Offset from mathrel alignment pt for mathbins +\newmuskip\eqdelimoffset \eqdelimoffset=2mu % Additional offset for break inside delims +\newdimen\eqindentstep \eqindentstep=8pt % Indent used when LHS wd is n/a or too large +\newtoks\eqstyle % Customization hook +\newcount\eqbreakdepth \eqbreakdepth=2 % Allow breaks within delimiters to this depth +\newcount \eqinterlinepenalty \eqinterlinepenalty=10000 % No page breaks between equation lines +\newcount \intereqpenalty \intereqpenalty=1000 % Pagebreak penalty between equations [BRM: Was \@M] +\newlength \intereqskip \intereqskip=3pt plus2pt % Additional vert space between equations +\newcount\prerelpenalty \prerelpenalty=-\@M % Linebreak penalty before mathrel symbols +\newcount\prebinoppenalty \prebinoppenalty=888 % Linebreak penalty before mathbins +% \end{macrocode} +% When breaking equations we never right-justify, so a stretch +% component of the muskip is never helpful and sometimes it is definitely +% undesirable. Note that thick\slash medmuskips frozen inside a +% fraction or radical may turn out noticeably larger than neighboring +% unfrozen ones. Nonetheless I think this way is the best +% compromise short of a new \tex that can make those built-up objects +% shrink horizontally in proportion; the alternative is to pretty much +% eliminate the shrink possibility completely in displays. +% \begin{macrocode} +\newmuskip \Dmedmuskip \Dmedmuskip=4mu minus 3mu % medmuskip in displays +\newmuskip \Dthickmuskip \Dthickmuskip=5mu minus 2mu % thickmuskip in displays +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% And now some internal variables. 1997/10/22: some of +% these are dead branches that need to be pruned. +% +% MH: Started cleaning up a bit. No more funny loops. +% \begin{macrocode} +\def\eq@number{} % Internal variable +\newlength\eqleftskip \eqleftskip=\@centering % Space on the left [NOT USED?] +\newlength\eqrightskip \eqrightskip=\@centering % Space on the right [NOT USED?] +\newlength\eq@vspan \eq@vspan=\z@skip % Glue used to vcenter the eq number +\newmuskip\eq@binoffset \eq@binoffset=\eqbinoffset % Roughly, \eqbinoffset + \eqdelimoffset +\newsavebox\EQ@box % Storage for equation body +\newsavebox\EQ@copy % For eq body sans vadjust/insert/mark material +\newsavebox\EQ@numbox % For equation number +\newdimen\eq@wdNum % width of number + separation [NEW] +\newsavebox\GRP@numbox % For group number [NEW] +\newdimen\grp@wdNum % width of number + separation [NEW] +%%B\EQ@vimbox % Vadjust, insert, or mark material +%%B\EQ@vimcopy % Spare copy of same +%%B\eq@impinging % Temporary box for measuring number placement +\newcount \eq@lines % Internal counter, actual number of lines +\newcount \eq@curline % Loop counter +\newcount \eq@badness % Used in testing for overfull lines +\newcount \EQ@vims % For bookkeeping +\def\@eq@numbertrue{\let\eq@hasNumber\@True}% +\def\@eq@numberfalse{\let\eq@hasNumber\@False}% +\let\eq@hasNumber\@False +% \end{macrocode} +% Here for the dimens, it would be advisable to do some more careful +% management to conserve dimen registers. First of all, most of the +% dimen registers are needed in the measuring phase, which is a tightly +% contained step that happens after the contents of the equation have been +% typeset into a box and before any external functions have a chance to +% regain control\mdash \eg , the output routine. +% Therefore it is possible to make use of the the dimen registers 0--9, +% reserved by convention for scratch use, without fear of conflict with +% other macros. But I don't want to use them directly with the +% available names: +% \begin{literalcode} +% \dimen@ \dimen@i \dimen@ii \dimen3 \dimen4 ... \dimen9 +% \end{literalcode} +% . It would be much more useful to have names for these registers +% indicative of way they are used. +% +% Another source whence dimen registers could be borrowed is the +% \pkg{amsmath} package, which allocates six registers for +% equation-measuring purposes. We can reuse them under different +% names since the \pkg{amsmath} functions and our functions will +% never be used simultaneously. +% \begin{literalcode} +% \eqnshift@ \alignsep@ \tagshift@ \tagwidth@ \totwidth@ \lineht@ +% \end{literalcode} +% \begin{macrocode} +\newdimen\eq@dp % Depth of last line +\newdimen\eq@wdL % Width of the left-hand-side +\newdimen\eq@wdT % Total width for framing +\newdimen\eq@wdMin % Width of narrowest line in equation +\newdimen\grp@wdL % Max width of LHS's in a group +\newdimen\grp@wdR % Max RHS of all equations in a group +\newdimen\grp@wdT +\newdimen\eq@wdRmax +\newdimen\eq@firstht % Height of first line +% \end{macrocode} +% BRM: measure the condition too. +% \begin{macrocode} +\newdimen\eq@wdCond +\newdimen\eq@indentstep % Indent amount when LHS is not present +\newdimen\eq@linewidth % Width actually used for display +\newdimen\grp@linewidth % Max eq@linewidth over a group +% \end{macrocode} +% Maybe \cs{eq@hshift} could share the same register as +% \cs{mathindent} [mjd,1997/10/22]. +% \begin{macrocode} +\newdimen\eq@hshift +\let\eq@isIntertext\@False +% \end{macrocode} +% Init \cs{eq@indentstep} to a nonzero value so that we can +% detect and refrain from clobbering a user setting of zero. +% And \cs{eq@sidespace} to \cs{maxdimen} because +% that is the right init before computing a min. +% \begin{macrocode} +\eq@indentstep=\maxdimen +\newdimen\eq@given@sidespace +% \end{macrocode} +% +% \begin{macro}{\eq@overrun} +% MH: Appears to be unused. +% +% Not a dimen register; don't need to advance it. +% \begin{macrocode} +\def\eq@overrun{0pt} +% \end{macrocode} +% \end{macro} +% +% +% To initialize \cs{eqnumside} and \cs{eqindent} properly, +% we may need to grub around a bit in \cs{@filelist}. However, +% if the \pkg{amsmath} package was used, we can use its option +% data. More trouble: if a documentclass sends an option of +% \opt{leqno} to \pkg{amsmath} by default, and it gets +% overridden by the user with a \opt{reqno} documentclass option, +% then \pkg{amsmath} believes itself to have received +% \emph{both} options. +% \begin{macrocode} +\@ifpackagewith{amsmath}{leqno}{% + \@ifpackagewith{amsmath}{reqno}{}{\def\eqnumside{L}}% +}{% +% \end{macrocode} +% If the \pkg{amsmath} package was not used, the next +% method for testing the \opt{leqno} option is to see if +% \fn{leqno.clo} is present in \cs{@filelist}. +% \begin{macrocode} + \def\@tempa#1,leqno.clo,#2#3\@nil{% + \ifx @#2\relax\else \def\eqnumside{L}\fi + }% + \@xp\@tempa\@filelist,leqno.clo,@\@nil +% \end{macrocode} +% Even that test may fail in the case of \cls{amsart} if it does +% not load \pkg{amsmath}. Then we have to look whether +% \cs{iftagsleft@} is defined, and if so whether it is true. +% This is tricky if you want to be careful about conditional nesting +% and don't want to put anything in the hash table unnecessarily. +% \begin{macrocode} + \if L\eqnumside + \else + \@ifundefined{iftagsleft@}{}{% + \edef\eqnumside{% + \if TT\csname fi\endcsname\csname iftagsleft@\endcsname + L\else R\fi + }% + } + \fi +} +% \end{macrocode} +% A similar sequence of tests handles the \quoted{fleqn or not fleqn} +% question for the \cls{article} and \cls{amsart} +% documentclasses. +% \begin{macrocode} +\@ifpackagewith{amsmath}{fleqn}{% + \def\eqindent{I}% +}{% + \def\@tempa#1,fleqn.clo,#2#3\@nil{% + \ifx @#2\relax\else \def\eqindent{I}\fi + }% + \@xp\@tempa\@filelist,fleqn.clo,@\@nil + \if I\eqindent + \else + \@ifundefined{if@fleqn}{}{% + \edef\eqindent{% + \if TT\csname fi\endcsname\csname if@fleqn\endcsname + I\else C\fi + }% + }% + \fi +} +% \end{macrocode} +% BRM: This conditional implies we must use ALL indented or ALL centered? +% \begin{macrocode} +%\if I\eqindent + \@ifundefined{mathindent}{% + \newdimen\mathindent + }{% + \@ifundefined{@mathmargin}{}{% + \mathindent\@mathmargin + }% + } +%\fi +% \end{macrocode} +% +% +% +% +% \section{Measuring equation components} +% Measure the left-hand side of an equation. This +% function is called by mathrel symbols. For the first mathrel we +% want to discourage a line break more than for following mathrels; so +% \cs{mark@lhs} gobbles the following \cs{rel@break} and +% substitutes a higher penalty. +% \begin{aside} +% Maybe the LHS should be kept in a separate box. +% \end{aside} +% +% +% +% \begin{macro}{\EQ@hasLHS} +% +% Boolean: does this equation have a \dquoted{left-hand side}? +% \begin{macrocode} +\let\EQ@hasLHS=\@False +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\EQ@QED} +% +% If nonempty: the qed material that should be incorporated into this +% equation after the final punctuation. +% \begin{macrocode} +\let\EQ@QED=\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\mark@lhs} +% +% \begin{macrocode} +\def\mark@lhs#1{% + \ifnum\lr@level<\@ne + \let\mark@lhs\relax + \global\let\EQ@hasLHS=\@True + \global\let\EQ@prebin@space\EQ@prebin@space@a + \mark@lhs@a +% \end{macrocode} +% But the penalty for the first mathrel should still be lower than a +% binoppenalty. If not, when the LHS contains a binop, the split +% will occur inside the LHS rather than at the mathrel. +% On the other hand if we end up with a multline sort of equation +% layout where the RHS is very short, the break before the relation symbol +% should be made \emph{less} desirable than the breakpoints inside +% the LHS. +% Since a lower penalty takes precedence over a higher one, we start +% by putting in the highest relpenalty; during subsequent measuring if we +% find that that RHS is not excessively short then we put in an extra +% \dquoted{normal} relpenalty when rejoining the LHS and RHS. +% \begin{macrocode} + \penalty9999 % instead of normal \rel@break + % else no penalty = forbid break + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\mark@lhs@a} +% +% Temporarily add an extra thickmuskip to the LHS; it will be removed +% later. This is necessary to compensate for the disappearance of +% the thickmuskip glue preceding a mathrel if a line break is taken at +% that point. Otherwise we would have to make our definition of +% mathrel symbols more complicated, like the one for mathbins. The +% penalty of $2$ put in with vadjust is a flag for +% \cs{eq@repack} to suggest that the box containing this line should +% be measured to find the value of \cs{eq@wdL}. The +% second vadjust ensures that the normal prerelpenalty and thickmuskip +% will not get lost at the line break during this preliminary pass. +% +% BRM: I originally thought the \verb"\mskip\thickmuskip" was messing +% up summation limits in LHS. But I may have fixed that problem by +% fixing other things\ldots +% \begin{macrocode} +\def\mark@lhs@a{% + \mskip\thickmuskip \@@vadjust{\penalty\tw@}\penalty-\@Mi\@@vadjust{}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\hiderel} +% If you want the LHS to extend past the first mathrel symbol to a +% following one, mark the first one with \cs{hiderel}: +% \begin{literalcode} +% a \hiderel{=} b = c... +% \end{literalcode} +% . +% \begin{aside} +% I'm not sure now why I didn't use \cs{begingroup} +% \cs{endgroup} here \begin{dn} +% mjd,1999/01/21 +% \end{dn} +% . +% \end{aside} +% +% \begin{macrocode} +\newcommand\hiderel[1]{\mathrel{\advance\lr@level\@ne#1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\m@@Bin} +% \begin{macro}{\m@@Rel} +% \begin{macro}{\bin@break} +% \begin{macro}{\rel@break} +% \begin{macro}{\bin@mark} +% \begin{macro}{\rel@mark} +% \begin{macro}{\d@@Bin} +% \begin{macro}{\d@@Rel} +% +% \cf \pkg{flexisym} handling of mathbins and mathrels. These +% are alternate definitions of \cs{m@Bin} and \cs{m@Rel}, +% activated by \cs{display@setup}. +% \begin{macrocode} +%%%%\let\m@@Bin\m@Bin +%%%%%\let\m@@Rel\m@Rel +\let\EQ@prebin@space\relax +\def\EQ@prebin@space@a{\mskip-\eq@binoffset \keep@glue \mskip\eq@binoffset} +\def\bin@break{\ifnum\lastpenalty=\z@\penalty\prebinoppenalty\fi + \EQ@prebin@space} +\def\rel@break{% + \ifnum\abs@num\lastpenalty <\abs@num\prerelpenalty + \penalty\prerelpenalty + \fi +} +\ExplSyntaxOn +%%%\def\d@@Bin{\bin@break \m@@Bin} +%%%%\def\d@@Rel{\mark@lhs \rel@break \m@@Rel} +\cs_set:Npn \math_dsym_Bin:Nn {\bin@break\math_bsym_Bin:Nn} +\cs_set:Npn \math_dsym_Rel:Nn {\mark@lhs \rel@break \math_bsym_Rel:Nn } +\ExplSyntaxOff +% \end{macrocode} +% The difficulty of dealing properly with the subscripts and +% superscripts sometimes appended to mathbins and mathrels is one of the +% reasons that we do not attempt to handle the mathrels as a separate +% \quoted{column} a la \env{eqnarray}. +% +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\m@@symRel} +% \begin{macro}{\d@@symRel} +% \begin{macro}{\m@@symBin} +% \begin{macro}{\d@@symBin} +% \begin{macro}{\m@@symDel} +% \begin{macro}{\d@@symDel} +% \begin{macro}{\m@@symDeR} +% \begin{macro}{\d@@symDeR} +% \begin{macro}{\m@@symDeB} +% \begin{macro}{\d@@symDeB} +% \begin{macro}{\m@@symDeA} +% \begin{macro}{\d@@symDeA} +% +% More of the same. +% \begin{macrocode} +\ExplSyntaxOn +%%\let\m@@symRel\@symRel +%%%\def\d@@symRel{\mark@lhs \rel@break \m@@symRel} + +\cs_set_protected:Npn \math_dcsym_Bin:Nn {\bin@break \math_bcsym_Bin:Nn} +\cs_set_protected:Npn \math_dcsym_Rel:Nn { \mark@lhs \rel@break \math_bcsym_Rel:Nn} + + +%%\let\m@@symBin\@symBin \def\d@@symBin{\bin@break \m@@symBin} +%%\let\m@@symDel\@symDel +%%\let\m@@symDeR\@symDeR +%%\let\m@@symDeB\@symDeB +%%\let\m@@symDeA\@symDeA + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\display@setup} +% \begin{macro}{\everydisplay} +% Setup. Note that \latex reserves the primitive +% \cs{everydisplay} under the name \cs{frozen@everydisplay}. +% BRM: Disable this! It also affects non-breqn math!!!! +% \begin{macrocode} +%\global\everydisplay\expandafter{\the\everydisplay \display@setup} +% \end{macrocode} +% Change some math symbol function calls. +% \begin{macrocode} +\def\display@setup{% + \medmuskip\Dmedmuskip \thickmuskip\Dthickmuskip + \math_setup_display_symbols: + %%\let\m@Bin\d@@Bin \let\m@Rel\d@@Rel + %%\let\@symRel\d@@symRel \let\@symBin\d@@symBin + %%\let\m@DeL\d@@DeL \let\m@DeR\d@@DeR \let\m@DeB\d@@DeB + %%\let\m@DeA\d@@DeA + %%\let\@symDeL\d@@symDeL \let\@symDeR\d@@symDeR + %%\let\@symDeB\d@@symDeB \let\@symDeA\d@@symDeA + \let\left\eq@left \let\right\eq@right \global\lr@level\z@ + \global\eq@wdCond\z@ %BRM: new +% \end{macrocode} +% If we have an embedded array environment (for example), we +% don't want to have each math cell within the array resetting +% \cs{lr@level} globally to 0\mdash not good! +% And in general I think it is safe to say that whenever we have a +% subordinate level of boxing we want to revert to a normal math setup. +% \begin{macrocode} + \everyhbox{\everyhbox\@emptytoks + \let\display@setup\relax \textmath@setup \let\textmath@setup\relax + }% + \everyvbox{\everyvbox\@emptytoks + \let\display@setup\relax \textmath@setup \let\textmath@setup\relax + }% +} +% \end{macrocode} +% The \cs{textmath@setup} function is needed for embedded inline +% math inside text inside a display. +% +% BRM: DS Experiment: Variant of \cs{display@setup} for use within +% dseries environmnents +% \begin{macrocode} +\def\dseries@display@setup{% + \medmuskip\Dmedmuskip \thickmuskip\Dthickmuskip + \math_setup_display_symbols: +%%%% \let\m@Bin\d@@Bin +%%%\let\m@Rel\d@@Rel +%%% \let\@symRel\d@@symRel +%%% \let\@symBin\d@@symBin +%%% \let\m@DeL\d@@DeL \let\m@DeR\d@@DeR \let\m@DeB\d@@DeB +%%% \let\m@DeA\d@@DeA +%%% \let\@symDeL\d@@symDeL \let\@symDeR\d@@symDeR +%%% \let\@symDeB\d@@symDeB \let\@symDeA\d@@symDeA + \let\left\eq@left \let\right\eq@right \global\lr@level\z@ + \everyhbox{\everyhbox\@emptytoks + \let\display@setup\relax \textmath@setup \let\textmath@setup\relax + }% + \everyvbox{\everyvbox\@emptytoks + \let\display@setup\relax \textmath@setup \let\textmath@setup\relax + }% + \displaystyle +} +% \end{macrocode} +% +% \begin{macrocode} +\def\textmath@setup{% + \math_setup_inline_symbols: +%%%% \let\m@Bin\m@@Bin \let\m@Rel\m@@Rel +%%%% \let\@symRel\m@@symRel \let\@symBin\m@@symBin +%%%% \let\m@DeL\m@@DeL \let\m@DeR\m@@DeR \let\m@DeB\m@@DeB +%%%% \let\m@DeA\m@@DeA +%%%% \let\@symDeL\m@@symDeL \let\@symDeR\m@@symDeR +%%%% \let\@symDeB\m@@symDeB \let\@symDeA\m@@symDeA + \let\left\@@left \let\right\@@right +} + +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\if@display} +% \begin{macro}{\everydisplay} +% The test \cs{ifinner} is unreliable for distinguishing +% whether we are in a displayed formula or an inline formula: any display +% more complex than a simple one-line equation typically involves the use +% of \verb"$" \cs{displaystyle} \dots \verb"$" instead of +% \dbldollars \dots \dbldollars . So we provide a more reliable +% test. But it might have been provided already by the +% \pkg{amsmath} package. +% \begin{macrocode} +\@ifundefined{@displaytrue}{% + \@xp\newif\csname if@display\endcsname + \everydisplay\@xp{\the\everydisplay \@displaytrue}% +}{} +% \end{macrocode} +% +% \begin{aside} +% Is there any reason to maintain separate +% \cs{everydisplay} and \cn{eqstyle}? +% +% \end{aside} +% +% +% \end{macro} +% \end{macro} +% +% +% +% +% \section{The \env{dmath} and \env{dmath*} environments} +% +% Options for the \env{dmath} and \env{dmath*} +% environments. +% \begin{literalcode} +% \begin{dmath}[label={eq:xyz}] +% \begin{dmath}[labelprefix={eq:},label={xyz}] +% \end{literalcode} +% WSPR: added the option for a label prefix, designed to be used in the preamble like so: +% \begin{literalcode} +% \setkeys{breqn}{labelprefix={eq:}} +% \end{literalcode} +% \begin{macrocode} +\define@key{breqn}{label}{% + \edef\next@label{\noexpand\label{\next@label@pre#1}}% + \let\next@label@pre\@empty} +\define@key{breqn}{labelprefix}{\def\next@label@pre{#1}} +\global\let\next@label\@empty +\global\let\next@label@pre\@empty +% \end{macrocode} +% Allow a variant number. +% \begin{literalcode} +% \begin{dmath}[number={\nref{foo}\textprime}] +% \end{literalcode} +% \begin{macrocode} +\define@key{breqn}{number}{\def\eq@number{#1}% + \let\@currentlabel\eq@number +} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[shiftnumber] +% \begin{dmath}[holdnumber] +% \end{literalcode} +% Holding or shifting the number. +% \begin{macrocode} +\define@key{breqn}{shiftnumber}{\let\eq@shiftnumber\@True} +\define@key{breqn}{holdnumber}{\let\eq@holdnumber\@True} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[density={.5}] +% \end{literalcode} +% \begin{macrocode} +\define@key{breqn}{density}{\def\eq@density@factor{#1}} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[indentstep={1em}] +% \end{literalcode} +% To change the amount of indent for post-initial lines. Note: +% for lines that begin with a mathbin symbol there is a fixed amount of +% indent already built in (\cs{eqbinoffset}) and it cannot be +% reduced through this option. The indentstep amount is the indent +% used for lines that begin with a mathrel symbol. +% \begin{macrocode} +\define@key{breqn}{indentstep}{\eqindentstep#1\relax} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[compact] +% \begin{dmath}[compact=-2000] +% \end{literalcode} +% To make mathrels stay inline to the extent possible, use the compact +% option. +% Can give a numeric value in the range $-10000 \dots 10000$ +% to adjust the behavior. +% $-10000$: always break at a rel symbol; $10000$: never +% break at a rel symbol. +% \begin{macrocode} +\define@key{breqn}{compact}[-99]{\prerelpenalty=#1\relax} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[layout={S}]% +% \end{literalcode} +% Specify a particular layout. +% We take care to ensure that \cs{eq@layout} ends up containing +% one and only one letter. +% \begin{macrocode} +\define@key{breqn}{layout}[?]{% + \edef\eq@layout{\@car#1?\@nil}% +} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[spread={1pt}] +% \end{literalcode} +% To change the interline spacing in a particular equation. +% \begin{macrocode} +\define@key{breqn}{spread}{% + \addtolength\eqlinespacing{#1}% + \addtolength\eqlineskip{#1}% + \eqlineskiplimit\eqlineskip +} +% \end{macrocode} +% To change the amount of space on the side for \dquoted{multline} layout. +% \begin{macrocode} +\define@key{breqn}{sidespace}{% + \setlength\eq@given@sidespace{#1}% +} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[style={\small}] +% \end{literalcode} +% The \opt{style} option is mainly intended for changing the +% type size of an equation but as a matter of fact you could put arbitrary +% \latex code here \mdash thus the option name is \quoted{style} rather +% than just \quoted{typesize}. In order for this option to work when +% setting options globally, we need to put the code in +% \cs{eqstyle} rather than execute it directly. +% \begin{macrocode} +\define@key{breqn}{style}{\eqstyle\@xp{\the\eqstyle #1}} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[shortskiplimit={1em}] +% \end{literalcode} +% If the line immediately preceeding a display has length $l$, the +% first line of the display is indented $i$, and a shortskip limit $s$ +% is set, then the spacing above the display is equal to +% \cs{abovedisplayshortskip} if $l+s < i $ and \cs{abovedisplayskip} +% otherwise. The default shortskip limit is 2\,em which is what \TeX\ +% hardcodes but this parameter overrides that. +% \begin{macrocode} +\define@key{breqn}{shortskiplimit}{\def\eq@shortskiplimit{#1}} +\def\eq@shortskiplimit{2em} +% \end{macrocode} +% +% \begin{literalcode} +% \begin{dmath}[frame] +% \end{literalcode} +% The \opt{frame} option merely puts a framebox around the body +% of the equation. To change the thickness of the frame, give the +% thickness as the argument of the option. For greater control, you +% can change the appearance of the frame by redefining +% \cs{eqframe}. It must be a command taking two arguments, the +% width and height of the equation body. The top left corner of the +% box produced by \cs{eqframe} will be pinned to the top-left corner +% of the equation body. +% \begin{macrocode} +\define@key{breqn}{frame}[\fboxrule]{\def\eq@frame{T}% + \dim@a#1\relax\edef\eq@framewd{\the\dim@a}% +% \end{macrocode} +% Until such time as we provide a frame implementation that allows the +% frame to stretch and shrink, we'd better remove any stretch/shrink from +% the interline glue in this case. +% \begin{macrocode} + \freeze@glue\eqlinespacing \freeze@glue\eqlineskip +} +\define@key{breqn}{fullframe}[]{\def\eq@frame{U}% + \freeze@glue\eqlinespacing \freeze@glue\eqlineskip +} +\def\eq@frame{F} % no frame +\def\eq@framewd{\fboxrule} +% \end{macrocode} +% Wishful thinking? +% \begin{literalcode} +% \begin{dmath}[frame={width={2pt},color={blue},sep={2pt}}] +% \end{literalcode} +% To change the space between the frame and the equation there is a +% framesep option. +% \begin{macrocode} +\define@key{breqn}{framesep}[\fboxsep]{% + \if\eq@frame F\def\eq@frame{T}\fi + \dim@a#1\relax \edef\eq@framesep{\the\dim@a}% + \freeze@glue\eqlinespacing \freeze@glue\eqlineskip +} +\def\eq@framesep{\fboxsep} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[background={red}] +% \end{literalcode} +% Foreground and background colors for the equation. By default +% the background area that is colored is the size of the equation, plus +% fboxsep. If you need anything fancier for the background, you'd +% better do it by defining \cs{eqframe} in terms of +% \cs{colorbox} or \cs{fcolorbox}. +% \begin{macrocode} +\define@key{breqn}{background}{\def\eq@background{#1}% + \freeze@glue\eqlinespacing \freeze@glue\eqlineskip +} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[color={purple}] +% \end{literalcode} +% \begin{macrocode} +\define@key{breqn}{color}{\def\eq@foreground{#1}} +% \end{macrocode} +% \begin{literalcode} +% \begin{dmath}[center] +% \begin{dmath}[nocenter] +% \end{literalcode} +% The \opt{center} option means add leftskip stretch to make the +% individual lines be centered; this is the default for +% \env{dseries}. +% \begin{macrocode} +\define@key{breqn}{center}[]{\let\eq@centerlines\@True} +\define@key{breqn}{nocenter}[]{\let\eq@centerlines\@False} +\let\eq@centerlines\@False +% \end{macrocode} +% \begin{literalcode} +% \begin{dgroup}[noalign] +% \end{literalcode} +% Equation groups normally have alignment of the primary relation +% symbols across the whole group. The \opt{noalign} option +% switches that behavior. +% \begin{macrocode} +\define@key{breqn}{noalign}[]{\let\grp@aligned\@False} +\let\grp@aligned\@True % default +% \end{macrocode} +% \begin{literalcode} +% \begin{dgroup}[breakdepth={2}] +% \end{literalcode} +% Break depth of 2 means that breaks are allowed at mathbin symbols +% inside two pairs of delimiters, but not three. +% \begin{macrocode} +\define@key{breqn}{breakdepth}{\eqbreakdepth#1\relax} +% \end{macrocode} +% \begin{literalcode} +% \begin{darray}[cols={lcrlcr}] +% \end{literalcode} +% The \opt{cols} option only makes sense for the +% \env{darray} environment but we liberally allow all the options to +% be used with all the environments and just ignore any unsensible ones +% that happen to come along. +% \begin{macrocode} +\define@key{breqn}{cols}{\global\let\@preamble\@empty + \darray@mkpream#1\@percentchar +} +% \end{macrocode} +% +% FORMAT STATUS% +% \begin{verbatim} +% \def\eq@frame{T}% +% CLM works tolerably +% \def\eqindent{C}\def\eqnumside{L}\def\eqnumplace{M} +% CLT works tolerably +% \def\eqindent{C}\def\eqnumside{L}\def\eqnumplace{T} +% ILM +% \def\eqindent{I}\def\eqnumside{L}\def\eqnumplace{M}\mathindent40\p@ +% ILT +% \def\eqindent{I}\def\eqnumside{L}\def\eqnumplace{T}\mathindent40\p@ +% Indended w/left number +% work ok if mathindent is larger than number width, +% but then equations must fit into smaller space. +% Is shiftnumber allowed to put eqn at left, instead of indent? +% CRM +% \def\eqindent{C}\def\eqnumside{R}\def\eqnumplace{M} +% CRB +% \def\eqindent{C}\def\eqnumside{R}\def\eqnumplace{B} +% IRM +% \def\eqindent{I}\def\eqnumside{R}\def\eqnumplace{M}\mathindent10\p@ +% IRB +% \def\eqindent{I}\def\eqnumside{R}\def\eqnumplace{B}\mathindent10\p@ +% \end{verbatim} +% +% The main environments. +% +%BRM: The following incorporates several changes: +% 1) modifications supplied by MJD to fix the eaten \cs{paragraph} problem. +% 2) Added \cs{display@setup} here, rather than globally. +% +% \begin{macro}{\dmath} +% \begin{macro}{\enddmath} +% For the \env{dmath} environment we don't want the standard +% optional arg processing because of the way it skips over whitespace, +% including newline, while looking for the \verb"[" char; which is not good +% for math material. So we call \cs{@optarg} instead. +% \begin{macrocode} +\newenvironment{dmath}{% + \let\eq@hasNumber\@True \@optarg\@dmath{}}{} +\def\@dmath[#1]{% +%<trace> \breqn@debugmsg{=== DMATH ==================================================}% + \everydisplay\expandafter{\the\everydisplay \display@setup}% + \if@noskipsec \leavevmode \fi + \if@inlabel \leavevmode \global\@inlabelfalse \fi + \if\eq@group\else\eq@prelim\fi + \setkeys{breqn}{#1}% + \the\eqstyle +% \end{macrocode} +% The equation number might have been overridden in \verb|#1|. +% \begin{macrocode} + \eq@setnumber +% \end{macrocode} +% Start up the displayed equation by reading the contents into a +% box register. Enclose this phase in an extra group so that +% modified \cs{hsize} and other params will be auto-restored +% afterwards. +% \begin{macrocode} + \begingroup + \eq@setup@a + \eq@startup +} +% \end{macrocode} +% Before it finishes off the box holding the equation body, +% \cs{enddmath} needs to look ahead for punctuation (and +% \cs{qed}?). +% \begin{macrocode} +\def\enddmath#1{\check@punct@or@qed} +\def\end@dmath{% + \gdef\EQ@setwdL{}% Occasionally undefined ??? + \eq@capture + \endgroup + \EQ@setwdL +% \end{macrocode} +% Measure (a copy of) the equation body to find the minimum width +% required to get acceptable line breaks, how many lines will be required +% at that width, and whether the equation number needs to be shifted to +% avoid overlapping. This information will then be used by +% \cs{eq@finish} to do the typesetting of the real equation body. +% \begin{macrocode} + \eq@measure +% \end{macrocode} +% Piece together the equation from its constituents, recognizing +% current constraints. If we are in an equation group, this might +% just save the material on a stack for later processing. +% \begin{macrocode} + \if\eq@group \grp@push \else \eq@finish\fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\dmath*} +% \begin{macro}{\enddmath*} +% Ah yes, now the lovely \env{dmath*} environment. +% \begin{macrocode} +\newenvironment{dmath*}{% + \let\eq@hasNumber\@False \@optarg\@dmath{}% +}{} +\@namedef{end@dmath*}{\end@dmath} +\@namedef{enddmath*}#1{\check@punct@or@qed} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\eq@prelim} +% If \cs{everypar} has a non-null value, it's probably +% some code from \cs{@afterheading} that sets \cs{clubpenalty} +% and\slash or removes the parindent box. Both of those actions +% are irrelevant and interfering for our purposes and need to be deflected +% for the time being. +% If an equation appears at the very beginning of a list item +% (possibly from a trivlist such as \env{proof}), we need to +% trigger the item label. +% \begin{macrocode} +\def\eq@prelim{% + \if@inlabel \indent \par \fi + \if@nobreak \global\@nobreakfalse \predisplaypenalty\@M \fi + \everypar\@emptytoks +% \end{macrocode} +% If for some reason \env{dmath} is called between paragraphs, +% \cn{noindent} is better than \cn{leavevmode}, which would produce +% an indent box and an empty line to hold it. If we are in a list +% environment, \cn{par} is defined as \verb"{\@@par}" to preserve +% \cs{parshape}. +% \begin{macrocode} + \noindent + \eq@nulldisplay + \par %% \eq@saveparinfo %% needs work + \let\intertext\breqn@intertext +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\breqn@parshape@warning} +% Warning message extracted to a separate function to streamline the +% calling function. +% \begin{macrocode} +\def\breqn@parshape@warning{% + \PackageWarning{breqn}{% + Complex paragraph shape cannot be followed by this equation}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@prevshape} +% Storage; see \cs{eq@saveparinfo}. +% \begin{macrocode} +\let\eq@prevshape\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@saveparinfo} +% Save the number of lines and parshape info for the text preceding +% the equation. +% \begin{macrocode} +\def\eq@saveparinfo{% + \count@\prevgraf \advance\count@-\thr@@ % for the null display + \edef\eq@prevshape{\prevgraf\the\count@\space}% + \ifcase\parshape + % case 0: no action required + \or \edef\eq@prevshape{\eq@prevshape + \parshape\@ne\displayindent\displaywidth\relax + }% +% \end{macrocode} +% Maybe best to set \cs{eq@prevshape} the same in the else case +% also. Better than nothing. +% \begin{macrocode} + \else + \breqn@parshape@warning + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@setnumber} +% If the current equation number is not explicitly given, then +% use an auto-generated number, unless the no-number switch has been +% thrown (\env{dmath*}). +% \cs{theequation} is the number form to be used for all equations, +% \cs{eq@number} is the actual value for the current equation +% (might be an exception to the usual sequence). +% \begin{macrocode} +\def\eq@setnumber{% + \eq@wdNum\z@ + \if\eq@hasNumber + \ifx\eq@number\@empty + \stepcounter{equation}\let\eq@number\theequation + \fi +% \fi +% \end{macrocode} + % This sets up numbox, etc, even if unnumbered????? +% \begin{macrocode} + \ifx\eq@number\@empty + \else +% \end{macrocode} +% Put the number in a box so we can use its measurements in our +% number-placement calculations. The extra braces around +% \cs{eqnumform} make it possible for \cs{eqnumfont} to have +% either an \cs{itshape} (recommended) or a \cs{textit} +% value. +% \begin{macrocode} +%<trace> \breqn@debugmsg{Number \eq@number}% + \set@label{equation}\eq@number + \global\sbox\EQ@numbox{% + \next@label \global\let\next@label\@empty + \eqnumcolor\eqnumsize\eqnumfont{\eqnumform{\eq@number}}% + }% + \global\eq@wdNum\wd\EQ@numbox\global\advance\eq@wdNum\eqnumsep +% \let\eq@hasNumber\@True % locally true + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@finish} +% The information available at this point from preliminary +% measuring includes the number of lines required, the width of the +% equation number, the total height of the equation body, and (most +% important) the parshape spec that was used in determining height and +% number of lines. +% +% Invoke the equation formatter for the requested centering/indentation +% having worked out the best parshape. +% BRM: This portion is extensively refactored to get common operations +% together (so corrections get consistently applied). +% +% MH: I've destroyed Bruce's nice refactoring a bit to get the +% abovedisplayskips correct for both groups of equations and single +% \env{dmath} environments. I will have to redo that later. +% \begin{macrocode} +\newcount\eq@final@linecount +\let\eq@GRP@first@dmath\@True +\def\eq@finish{% + \begingroup +%<trace> \breqn@debugmsg{Formatting equation}% +%<trace> \debug@showmeasurements + \if F\eq@frame\else + \freeze@glue\eqlinespacing \freeze@glue\eqlineskip + \fi +% \eq@topspace{\vskip\parskip}% Set top spacing + \csname eq@\eqindent @setsides\endcsname % Compute \leftskip,\rightskip + \adjust@parshape\eq@parshape% Final adjustment of parshape for left|right skips +% \end{macrocode} +% If we are in an a group of equations we don't want to calculate the +% top space for the first one as that will be delayed until later when +% the space for the group is calculated. However, we do need to store +% the leftskip used here as that will be used later on for calculating +% the top space. +% \begin{macrocode} + \if\eq@group + \if\eq@GRP@first@dmath + \global\let\eq@GRP@first@dmath\@False + \xdef\dmath@first@leftskip{\leftskip=\the\leftskip\relax}% +%<trace> \breqn@debugmsg{Stored\space\dmath@first@leftskip} + \else + \eq@topspace{\vskip\parskip}% Set top spacing + \fi + \else + \eq@topspace{\vskip\parskip}% Set top spacing + \fi +%<trace> \debug@showformat +% \end{macrocode} +% We now know the final line count of the display. If it is a +% single-line display, we want to know as that greatly simplifies the +% equation tag placement (until such a time where this algorithm has +% been straightened out). +% \begin{macrocode} + \afterassignment\remove@to@nnil + \eq@final@linecount=\expandafter\@gobble\eq@parshape\@nnil +% \end{macrocode} +% Now, invoke the appropriate typesetter according to number placement +% \begin{macrocode} + \if\eq@hasNumber + \if\eq@shiftnumber + \csname eq@typeset@\eqnumside Shifted\endcsname + \else +% \end{macrocode} +% If there is only one line and the tag doesn't have to be shifted, we +% call a special procedure to put the tag correctly. +% \begin{macrocode} + \ifnum\eq@final@linecount=\@ne + \csname eq@typeset@\eqnumside @single\endcsname + \else + \csname eq@typeset@\eqnumside\eqnumplace\endcsname + \fi + \fi + \else + \eq@typeset@Unnumbered + \fi + \endgroup + \eq@botspace +} +% \end{macrocode} +% \end{macro} +% +% +% These are temporary until the tag position algorithm gets +% rewritten. At least the tag is positioned correctly for single-line +% displays. The horizontal frame position is not correct but the +% problem lies elsewhere. +% \begin{macrocode} +\def\eq@typeset@L@single{% + \nobreak + \eq@params\eq@parshape + \nointerlineskip\noindent + \add@grp@label + \rlap{\kern-\leftskip\box\EQ@numbox}% + \if F\eq@frame + \else + \rlap{\raise\eq@firstht\hbox to\z@{\eq@addframe\hss}}% + \fi + \eq@dump@box\unhbox\EQ@box \@@par +} +\def\eq@typeset@R@single{% + \nobreak + \eq@params\eq@parshape + \nointerlineskip\noindent + \add@grp@label + \if F\eq@frame + \else + \rlap{\raise\eq@firstht\hbox to\z@{\eq@addframe\hss}}% + \fi + \rlap{\kern-\leftskip\kern\linewidth\kern-\wd\EQ@numbox\copy\EQ@numbox}% + \eq@dump@box\unhbox\EQ@box + \@@par +} +% \end{macrocode} +% +% +% +% \section{Special processing for end-of-equation} +% +% At the end of a displayed equation environment we need to peek ahead +% for two things: following punction such as period or command that +% should be pulled in for inclusion at the end of the equation; and +% possibly also an \verb"\end{proof}" with an implied \dquoted{qed} +% symbol that is traditionally included at the end of the display rather +% than typeset on a separate line. +% We could require that the users type \cs{qed} explicitly at the +% end of the display when they want to have the display take notice of it. +% But the reason for doing that would only be to save work for the +% programmer; the most natural document markup would allow an inline +% equation and a displayed equation at the end of a proof to differ only +% in the environment name: +% \begin{literalcode} +% ... \begin{math} ... \end{math}. +% \end{proof} +% \end{literalcode} +% versus +% \begin{literalcode} +% ... +% \begin{dmath} +% ... +% \end{dmath}. +% \end{proof} +% \end{literalcode} +% . +% The technical difficulties involved in supporting this markup within +% \latex2e are, admittedly, nontrivial. +% Nonetheless, let's see how far we can go. +% +% +% The variations that we will support are only the most +% straightforward ones: +% \begin{literalcode} +% \end{dmath}. +% \end{proof} +% \end{literalcode} +% or +% \begin{literalcode} +% \end{dmath}. +% Perhaps a comment +% \end{proof} +% \end{literalcode} +% . +% If there is anything more complicated than a space after the +% period we will not attempt to scan any further for a possible +% \verb"\end{proof}". +% This includes material such as: +% \begin{literalcode} +% \begin{figure}...\end{figure}% +% \footnote{...} +% \renewcommand{\foo}{...} +% \par +% \end{literalcode} +% or even a blank line\mdash because in \latex a blank line is +% equivalent to \cs{par} and the meaning of \cs{par} is +% \dquoted{end-paragraph}; in my opinion if explicit end-of-paragraph +% markup is given before the end of an element, it has to be respected, +% and the preceding paragraph has to be fully finished off before +% proceeding further, even inside an element like \dquoted{proof} whose +% end-element formatting requires integration with the end of the +% paragraph text. +% And \tex nically speaking, a \cs{par} token that comes from a +% blank line and one that comes from the sequence of characters +% \verb"\" \verb"p" \verb"a" \verb"r" are equally explicit. +% I hope to add support for \cs{footnote} in the future, as it +% seems to be a legitimate markup possibility in that context from a +% purely logical point of view, but there are additional technical +% complications if one wants to handle it in full generality +% \begin{dn} +% mjd,1999/02/08 +% \end{dn} +% . +% +% +% \begin{macro}{\peek@branch} +% This is a generalized \dquoted{look at next token and choose some action +% based on it} function. +% \begin{macrocode} +\def\peek@branch#1#2{% + \let\peek@b#1\let\peek@space#2\futurelet\@let@token\peek@a +} +\def\peek@skipping@spaces#1{\peek@branch#1\peek@skip@space} +\def\peek@a{% + \ifx\@let@token\@sptoken \expandafter\peek@space + \else \expandafter\peek@b\fi +} +\lowercase{\def\peek@skip@space} {\futurelet\@let@token\peek@a}% +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\check@punct} +% \changes{v0.96a}{2007/12/17}{Insert \cs{finish@end} if no special +% case is found.} +% For this one we need to recognize and grab for inclusion any of the +% following tokens: \verb",;.!?", both catcode 12 (standard \latex +% value) and catcode 13 (as might hold when the Babel package is +% being used). +% We do not support a space preceding the punctuation since that would +% be considered simply invalid markup if a display-math environment were +% demoted to in-line math; and we want to keep their markup as parallel as +% possible. +% If punctuation does not follow, then the \cs{check@qed} branch +% is not applicable. +% \begin{macrocode} +\def\check@punct{\futurelet\@let@token\check@punct@a} +\def\check@punct@a{% + \edef\@tempa{% + \ifx\@let@token\@sptoken\@nx\finish@end + \else\ifx\@let@token ,\@nx\check@qed + \else\ifx\@let@token .\@nx\check@qed + \else\check@punct@b % check the less common possibilities + \fi\fi\fi + }% + \@tempa +} +\begingroup +\toks@a{% + \ifx\@let@token ;\@nx\check@qed + \else\ifx\@let@token ?\@nx\check@qed + \else\ifx\@let@token !\@nx\check@qed +} +\toks@c{\fi\fi\fi}% matching with \toks@a +\catcode`\.=\active \catcode`\,=\active \catcode`\;=\active +\catcode`\?=\active \catcode`\!=\active +\toks@b{% + \else\ifx\@let@token ,\@nx\check@qed + \else\ifx\@let@token .\@nx\check@qed + \else\ifx\@let@token ;\@nx\check@qed + \else\ifx\@let@token ?\@nx\check@qed + \else\ifx\@let@token !\@nx\check@qed + \else\@nx\finish@end + \fi\fi\fi\fi\fi +} +\xdef\check@punct@b{% + \the\toks@a\the\toks@b\the\toks@c +} +\endgroup +% \end{macrocode} +% +% \begin{macrocode} +\let\found@punct\@empty +\def\check@qed#1{% + \gdef\found@punct{#1}% + \peek@skipping@spaces\check@qed@a +} +\def\check@qed@a{% + \ifx\end\@let@token \@xp\check@qed@b + \else \@xp\finish@end + \fi +} +% \end{macrocode} +% For each environment ENV that takes an implied qed at the end, the +% control sequence ENVqed must be defined; and it must include suitable +% code to yield the desired results in a displayed equation. +% \begin{macrocode} +\def\check@qed@b#1#2{% + \@ifundefined{#2qed}{}{% + \toks@\@xp{\found@punct\csname#2qed\endcsname}% + \xdef\found@punct{\the\toks@}% + }% + \finish@end + \end{#2}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\latex@end} +% \begin{macro}{\finish@end} +% The lookahead for punctuation following a display requires +% mucking about with the normal operation of \cn{end}. Although +% this is not exactly something to be done lightly, on the other hand this +% whole package is so over-the-top anyway, what's a little more +% going to hurt? And rationalizing this aspect of +% equation markup is a worthy cause. Here is the usual +% definition of \cs{end}. +% \begin{literalcode} +% \def\end#1{ +% \csname end#1\endcsname \@checkend{#1}% +% \expandafter\endgroup\if@endpe\@doendpe\fi +% \if@ignore \global\@ignorefalse \ignorespaces \fi +% } +% \end{literalcode} +% We can improve the chances of this code surviving through future +% minor changes in the fundamental definition of \cs{end} by taking a +% little care in saving the original meaning. +% \begin{macrocode} +\def\@tempa#1\endcsname#2\@nil{\def\latex@end##1{#2}} +\expandafter\@tempa\end{#1}\@nil +\def\end#1{\csname end#1\endcsname \latex@end{#1}}% +% \end{macrocode} +% Why don't we call \cs{CheckCommand} here? Because that +% doesn't help end users much; it works better to use it during package +% testing by the maintainer. +% +% +% If a particular environment needs to call a different end action, the +% end command of the environment should be defined to gobble two args and +% then call a function like \cs{check@punct@or@qed}. +% \begin{macrocode} +\def\check@punct@or@qed#1{% + \xdef\found@punct{\@empty}% BRM: punctuation was being remembered past this eqn. + % WSPR: err, why isn't that just \global\let\found@punct\@empty ? + \def\finish@end{\csname end@#1\endcsname\latex@end{#1}}% + \check@punct +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eqpunct} +% User-settable function for handling +% the punctuation at the end of an equation. You could, for example, +% define it to just discard the punctuation. +% \begin{macrocode} +\newcommand\eqpunct[1]{\thinspace#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\set@label} +% \cs{set@label} just sets \cs{@currentlabel} but it +% takes the counter as an argument, in the hope that \latex will some +% day provide an improved labeling system that includes type info on the +% labels. +% \begin{macrocode} +\providecommand\set@label[2]{\protected@edef\@currentlabel{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@topspace} +% \begin{macro}{\eq@botspace} +% The action of \cs{eq@topspace} is complicated by the +% need to test whether the \quoted{short} versions of the display skips +% should be used. This can be done only after the final parshape +% and indent have been determined, so the calls of this function are +% buried relatively deeply in the code by comparison to the calls of +% \cs{eq@botspace}. This also allows us to optimize +% slightly by setting the above-skip with \cs{parskip} instead of +% \cs{vskip}. \verb|#1| is either \cs{noindent} or +% \verb"\vskip\parskip". +% +% BRM: Hmm; we need to do *@setspace BEFORE this for small skips to work! +% \begin{macrocode} +\def\eq@topspace#1{% + \begingroup + \global\let\EQ@shortskips\@False +% \end{macrocode} +% If we are in \env{dgroup} or \env{dgroup*} and not before the top +% one, we just insert \cs{intereqskip}. Otherwise we must check for +% shortskip. +% \begin{macrocode} + \if\@And{\eq@group}{\@Not\eq@GRP@first@dmath}% +%<trace>\breqn@debugmsg{Between lines}% + \parskip\intereqskip \penalty\intereqpenalty +%<trace>\breqn@debugmsg{parskip=\the\parskip}% + \else + \eq@check@shortskip + \if\EQ@shortskips + \parskip\abovedisplayshortskip + \aftergroup\belowdisplayskip\aftergroup\belowdisplayshortskip +% \end{macrocode} +% BRM: Not exactly \TeX's approach, but seems right\ldots +% \begin{macrocode} + \ifdim\predisplaysize>\z@\nointerlineskip\fi + \else + \parskip\abovedisplayskip + \fi + \fi + \if F\eq@frame + \else + \addtolength\parskip{\eq@framesep+\eq@framewd}% + \fi +%<*trace> + \breqn@debugmsg{Topspace: \theb@@le\EQ@shortskips, \parskip=\the\parskip, + \predisplaysize=\the\predisplaysize}% +%</trace> + #1% + \endgroup +} +% \end{macrocode} +% \begin{macro}{\eq@check@shortskip} +% \changes{v0.96a}{2007/12/17}{Insert \cs{finish@end} if no special +% case is found.} +% \changes{v0.97a}{2007/12/22}{Use design parameter and fix +% shortskips properly.} +% \begin{macrocode} +\def\eq@check@shortskip {% + \global\let\EQ@shortskips\@False + \setlength\dim@a{\abovedisplayskip+\ht\EQ@numbox}% +% \end{macrocode} +% Here we work around the hardwired standard TeX value and use the +% designer parameter instead. +% \begin{macrocode} + \ifdim\leftskip<\predisplaysize + \else +% \end{macrocode} +% If the display was preceeded by a blank line, \cs{predisplaysize} is +% $-\cs{maxdimen}$ and so we should insert a fairly large skip to +% separate paragraphs, i.e., no short skip. Perhaps this should be a +% third parameter \cs{abovedisplayparskip}. +% \begin{macrocode} + \ifdim -\maxdimen=\predisplaysize + \else + \if R\eqnumside + \global\let\EQ@shortskips\@True + \else + \if\eq@shiftnumber + \else + \if T\eqnumplace + \ifdim\dim@a<\eq@firstht + \global\let\EQ@shortskips\@True + \fi + \else + \setlength\dim@b{\eq@vspan/2}% + \ifdim\dim@a<\dim@b + \global\let\EQ@shortskips\@True + \fi + \fi + \fi + \fi + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% At the end of an equation, need to put in a pagebreak penalty +% and some vertical space. Also set some flags to remove parindent +% and extra word space if the current paragraph text continues without an +% intervening \cs{par}. +% \begin{macrocode} +\def\eq@botspace{% + \penalty\postdisplaypenalty +% \end{macrocode} +% Earlier calculations will have set \cs{belowdisplayskip} locally +% to \cs{belowdisplayshortskip} if applicable. So we can just use +% it here. +% \begin{macrocode} + \if F\eq@frame + \else + \addtolength\belowdisplayskip{\eq@framesep+\eq@framewd}% + \fi + \vskip\belowdisplayskip + \@endpetrue % kill parindent if current paragraph continues + \global\@ignoretrue % ignore following spaces + \eq@resume@parshape +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eq@resume@parshape} +% This should calculate the total height of the equation, +% including space above and below, and set prevgraf to the number it would +% be if that height were taken up by normally-spaced normal-height +% lines. We also need to restore parshape if it had a non-null +% value before the equation. Not implemented yet. +% \begin{macrocode} +\def\eq@resume@parshape{} +% \end{macrocode} +% \end{macro} +% +% \section{Preprocessing the equation body} +% \begin{macro}{\eq@startup} +% Here is the function that initially collects the equation +% material in a box. +% +% \begin{macrocode} +\def\eq@startup{% + \global\let\EQ@hasLHS\@False + \setbox\z@\vbox\bgroup + \noindent \@@math \displaystyle + \penalty-\@Mi +} +% \end{macrocode} +% +% This setup defines the environment for the first typesetting +% pass, note the \cs{hsize} value for example. +% \begin{macrocode} +\def\eq@setup@a{% + \everymath\everydisplay + %\let\@newline\eq@newline % future possibility? + \let\\\eq@newline + \let\insert\eq@insert \let\mark\eq@mark \let\vadjust\eq@vadjust + \hsize\maxdimen \pretolerance\@M +% \end{macrocode} +% Here it is better not to use \cs{@flushglue} (0pt +% plus1fil) for \cs{rightskip}, or else a negative penalty +% (such as $-99$ for \cs{prerelpenalty}) will tempt +% \tex to use more line breaks than necessary in the first typesetting +% pass. Ideal values for \cs{rightskip} and +% \cs{linepenalty} are unclear to me, but they are rather sensitively +% interdependent. Choice of 10000 pt for rightskip is derived by +% saying, let's use a value smaller than 1 fil and smaller than +% \cs{hsize}, but more than half of \cs{hsize} so that if a line +% is nearly empty, the glue stretch factor will always be less than 2.0 +% and so the badness will be less than 100 and so \tex will not issue +% badness warnings. +% \begin{macrocode} + \linepenalty\@m + \rightskip\z@\@plus\@M\p@ \leftskip\z@skip \parfillskip\z@skip + \clubpenalty\@ne \widowpenalty\z@ \interlinepenalty\z@ +% \end{macrocode} +% After a relation symbol is discovered, binop symbols should start +% including a special offset space. +% But until then \cs{EQ@prebin@space} is a no-op. +% \begin{macrocode} + \global\let\EQ@prebin@space\relax +% \end{macrocode} +% Set binoppenalty and relpenalty high to prohibit line breaks +% after mathbins and mathrels. As a matter of fact, the penalties are +% then omitted by \tex , since bare glue without a penalty is +% \emph{not} a valid breakpoint if it occurs within +% mathon\ndash mathoff items. +% \begin{macrocode} + \binoppenalty\@M \relpenalty\@M +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{figure} +% \centering +% The contents of an equation after the initial typesetting pass, +% as shown by \cs{showlists}. This is the material on which the +% \cs{eq@repack} function operates. The equation was +% \begin{literalcode} +% a=b +\left(\frac{c\sp 2}{2} -d\right) +(e -f) +g +% \end{literalcode} +% . The contents are shown in four parts in this figure and the next +% three. The first part contains two line boxes, one for the mathon +% node and one for the LHS. +% \begin{literalcode} +% \hbox(0.0+0.0)x16383.99998, glue set 1.6384 +% .\mathon +% .\penalty -10000 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \penalty 1 +% \glue(\baselineskip) 7.69446 +% \hbox(4.30554+0.0)x16383.99998, glue set 1.63759 +% .\OML/cmm/m/it/10 a +% .\glue 2.77771 minus 1.11108 +% .\penalty -10001 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \penalty 2 +% \glue(\lineskip) 1.0 +% ... +% \end{literalcode} +% \caption{Preliminary equation contents, part 1} +% \end{figure} +% \begin{figure}\centering +% This is the first part of the RHS, up to the +% \cs{right}, where a line break has been forced so that we can break +% open the left-right box. +% \begin{literalcode} +% ... +% \penalty 2 +% \glue(\lineskip) 1.0 +% \hbox(14.9051+9.50012)x16383.99998, glue set 1.63107 +% .\penalty -99 +% .\glue(\thickmuskip) 2.77771 minus 1.11108 +% .\OT1/cmr/m/n/10 = +% .\glue(\thickmuskip) 2.77771 minus 1.11108 +% .\OML/cmm/m/it/10 b +% .\penalty 888 +% .\glue -10.5553 +% .\rule(*+*)x0.0 +% .\penalty 10000 +% .\glue 10.5553 +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OT1/cmr/m/n/10 + +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\hbox(14.9051+9.50012)x43.36298 +% ..\hbox(0.39998+23.60025)x7.36115, shifted -14.10013 +% ...\OMX/cmex/m/n/5 \hat \hat R +% ..\hbox(14.9051+6.85951)x11.21368 +% ...\hbox(14.9051+6.85951)x11.21368 +% ... [fraction contents, elided] +% ..\penalty 5332 +% ..\glue -10.5553 +% ..\rule(*+*)x0.0 +% ..\penalty 10000 +% ..\glue 10.5553 +% ..\glue(\medmuskip) 2.22217 minus 1.66663 +% ..\OMS/cmsy/m/n/10 \hat \hat @ +% ..\glue(\medmuskip) 2.22217 minus 1.66663 +% ..\OML/cmm/m/it/10 d +% ..\hbox(0.39998+23.60025)x7.36115, shifted -14.10013 +% ...\OMX/cmex/m/n/5 \hat \hat S +% .\penalty -10000 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \penalty 3 +% \glue(\lineskip) 1.0 +% ... +% \end{literalcode} +% \caption{Preliminary equation contents, part 2} +% \end{figure} +% +% \begin{figure} +% \centering +% This is the remainder of the RHS after the post-\cs{right} +% split. +% \begin{literalcode} +% ... +% \penalty 3 +% \glue(\lineskip) 1.0 +% \hbox(7.5+2.5)x16383.99998, glue set 1.63239 +% .\penalty 888 +% .\glue -10.5553 +% .\rule(*+*)x0.0 +% .\penalty 10000 +% .\glue 10.5553 +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OT1/cmr/m/n/10 + +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OT1/cmr/m/n/10 ( +% .\OML/cmm/m/it/10 e +% .\penalty 5332 +% .\glue -10.5553 +% .\rule(*+*)x0.0 +% .\penalty 10000 +% .\glue 10.5553 +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OMS/cmsy/m/n/10 \hat \hat @ +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OML/cmm/m/it/10 f +% .\kern1.0764 +% .\OT1/cmr/m/n/10 ) +% .\penalty 888 +% .\glue -10.5553 +% .\rule(*+*)x0.0 +% .\penalty 10000 +% .\glue 10.5553 +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OT1/cmr/m/n/10 + +% .\glue(\medmuskip) 2.22217 minus 1.66663 +% .\OML/cmm/m/it/10 g +% .\kern0.35878 +% .\penalty -10000 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \glue(\baselineskip) 9.5 +% ... +% \end{literalcode} +% \caption{Preliminary equation contents, part 3} +% \end{figure} +% +% \begin{figure} +% \centering +% This is the mathoff fragment. +% \begin{literalcode} +% ... +% \glue(\baselineskip) 9.5 +% \hbox(0.0+0.0)x16383.99998, glue set 1.6384 +% .\mathoff +% .\penalty 10000 +% .\glue(\parfillskip) 0.0 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \end{literalcode} +% \caption{Preliminary equation contents, part 4} +% \end{figure} +% +% \begin{macro}{\eq@capture} +% \begin{macro}{\eq@punct} +% If an equation ends with a \cs{right} delim, the last thing +% on the math list will be a force-break penalty. Then don't +% redundantly add another forcing penalty. (question: when does a +% penalty after a linebreak not disappear? Answer: when you have +% two forced break penalties in a row). Ending punctuation, if +% any, goes into the last box with the mathoff kern. If the math list +% ends with a slanted letter, then there will be an italic correction +% added after it by \tex . Should we remove it? I guess +% so. +% +% +% \subsection{Capturing the equation} +% +% BRM: There's a problem here (or with \cs{ss@scan}). If the LHS has +% \cs{left} \cs{right} pairs, \ss@scan gets involved. It seems to produce +% a separate box marked w/\cs{penalty} 3. But it appears that \cs{eq@repack} +% is only expecting a single box for the LHS; when it measures that +% box it's missing the (typically larger) bracketted section, +% so the LHS is measured => 0pt (or very small). +% I'm not entirely clear what Michael had in mind for this case; +% whether it's an oversight, or whether I've introduced some other bug. +% At any rate, my solution is to measure the RHS (accumulated in \cs{EQ@box}), +% at the time of the relation, and subtract that from the total size. +% \begin{macrocode} +\newdimen\eq@wdR\eq@wdR\z@%BRM +\def\eq@capture{% + \ifnum\lastpenalty>-\@M \penalty-\@Mi \fi +% \end{macrocode} +% We want to keep the mathoff kern from vanishing at the line break, +% so that we can reuse it later. +% \begin{macrocode} + \keep@glue\@@endmath + \eq@addpunct + \@@par + \eq@wdL\z@ +% \end{macrocode} +% First snip the last box, which contains the mathoff node, and put it +% into \cs{EQ@box}. Then when we call \cs{eq@repack} it +% will recurse properly. +% \begin{macrocode} + \setbox\tw@\lastbox + \global\setbox\EQ@box\hbox{\unhbox\tw@\unskip\unskip\unpenalty}% + \unskip\unpenalty + \global\setbox\EQ@copy\copy\EQ@box +%% \global\setbox\EQ@vimcopy\copy\EQ@vimbox + \clubpenalty\z@ +%\batchmode\showboxbreadth\maxdimen\showboxdepth99\showlists\errorstopmode + \eq@wdR\z@%BRM: eq@wdL patch + \eq@repack % recursive +% \end{macrocode} +% Finally, add the mathon item to \cs{EQ@box} and \cs{EQ@copy}. +% \begin{macrocode} + \setbox\tw@\lastbox + \global\setbox\EQ@box\hbox{\unhcopy\tw@\unskip\unpenalty \unhbox\EQ@box}% + \global\setbox\EQ@copy\hbox{\unhbox\tw@\unskip\unpenalty \unhbox\EQ@copy}% +%\batchmode\showbox\EQ@copy \showthe\eq@wdL\errorstopmode + \ifdim\eq@wdR>\z@% BRM: eq@wdL patch + \setlength\dim@a{\wd\EQ@box-\eq@wdR + % Apparently missing a \thickmuskip = 5mu = 5/18em=0.27777777777.. ? + + 0.2777777777777em}% FUDGE??!?!?! + \ifdim\dim@a>\eq@wdL +%<*trace> + \breqn@debugmsg{Correcting LHS from \the\eq@wdL\space to + \the\dim@a = \the\wd\EQ@box - \the\eq@wdR}% +%</trace> + \eq@wdL\dim@a + \xdef\EQ@setwdL{\eq@wdL\the\eq@wdL\relax}% + \fi + \fi +%<*trace> + \breqn@debugmsg{Capture: total length=\the\wd\EQ@box \MessageBreak + ==== has LHS=\theb@@le\EQ@hasLHS, \eq@wdL=\the\eq@wdL, \eq@wdR=\the\eq@wdR, + \MessageBreak + ==== \eq@wdCond=\the\eq@wdCond}% +%</trace> + \egroup % end vbox started earlier +%<*trace> +%\debugwr{EQ@box}\debug@box\EQ@box +%\debugwr{EQ@copy}\debug@box\EQ@copy +%</trace> +} +% \end{macrocode} +% Now we have two copies of the equation, one in \cs{EQ@box}, +% and one in \cs{EQ@copy} with inconvenient stuff like inserts and +% marks omitted. +% +% \cs{eq@addpunct} is for tacking on text punctuation at the end +% of a display, if any was captured by the \quoted{gp} lookahead. +% \begin{macrocode} +\def\eq@addpunct{% + \ifx\found@punct\@empty + \else \eqpunct{\found@punct}% + \fi + % BRM: Added; the punctuation kept getting carried to following environs + \xdef\found@punct{\@empty}% + \EQ@afterspace +} +% \end{macrocode} +% Needed for the \env{dseries} environment, among other things. +% \begin{macrocode} +\global\let\EQ@afterspace\@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eq@repack} +% The \cs{eq@repack} function looks at the information at hand +% and proceeds accordingly. +% +% TeX Note: this scans BACKWARDS from the end of the math. +% \begin{macrocode} +\def\eq@repack{% +% A previous penalty of 3 on the vertical list means that we need +% to break open a left-right box. +% \begin{macrocode} + \ifcase\lastpenalty + % case 0: normal case + \setbox\tw@\lastbox + \eq@repacka\EQ@copy \eq@repacka\EQ@box + \unskip + \or % case 1: finished recursing +% \end{macrocode} +% Grab the mathon object since we need it to inhibit line breaking at +% bare glue nodes later. +% \begin{macrocode} + \unpenalty + \setbox\tw@\lastbox + \eq@repacka\EQ@copy \eq@repacka\EQ@box + \@xp\@gobble + \or % case 2: save box width = LHS width +% \end{macrocode} +% Don't need to set \cs{EQ@hasLHS} here because it was set earlier +% if applicable. +% \begin{macrocode} + \unpenalty + \setbox\tw@\lastbox + \setbox\z@\copy\tw@ \setbox\z@\hbox{\unhbox\z@\unskip\unpenalty}% + \addtolength\eq@wdL{\wd\z@} + \setlength\eq@wdR{\wd\EQ@box}% BRM: eq@wdL patch + \xdef\EQ@setwdL{\eq@wdL\the\eq@wdL\relax}% +% \end{macrocode} +% At this point, box 2 typically ends with +% \begin{literalcode} +% .\mi10 a +% .\glue 2.77771 plus 2.77771 +% .\penalty -10001 +% .\glue(\rightskip) 0.0 plus 10000.0 +% \end{literalcode} +% and we want to ensure that the thickmuskip glue gets removed. +% And we now arrange for \cs{EQ@copy} and \cs{EQ@box} to +% keep the LHS in a separate subbox; this is so that we can introduce a +% different penalty before the first relation symbol if necessary, +% depending on the layout decisions that are made later. +% \begin{macrocode} + \global\setbox\EQ@copy\hbox{% + \hbox{\unhcopy\tw@\unskip\unpenalty\unskip}% + \box\EQ@copy + }% + \global\setbox\EQ@box\hbox{% + \hbox{\unhbox\tw@\unskip\unpenalty\unskip}% + \box\EQ@box + }% + \unskip + \or % case 3: unpack left-right box + \unpenalty + \eq@lrunpack + \else + \breqn@repack@err + \fi + \eq@repack % RECURSE +} +% \end{macrocode} +% Error message extracted to streamline calling function. +% \begin{macrocode} +\def\breqn@repack@err{% + \PackageError{breqn}{eq@repack penalty neq 0,1,2,3}\relax +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@repacka} +% We need to transfer each line into two separate boxes, one +% containing everything and one that omits stuff like \cs{insert}s +% that would interfere with measuring. +% \begin{macrocode} +\def\eq@repacka#1{% + \global\setbox#1\hbox{\unhcopy\tw@ \unskip + \count@-\lastpenalty + \ifnum\count@<\@M \else \advance\count@-\@M \fi + \unpenalty +% \end{macrocode} +% If creating the measure copy, ignore all cases above case 3 by +% folding them into case 1. +% \begin{macrocode} + \ifx\EQ@copy#1\ifnum\count@>\thr@@ \count@\@ne\fi\fi + \ifcase\count@ + % case 0, normal line break + \penalty-\@M % put back the linebreak penalty + \or % case 1, do nothing (end of equation) + \relax + \or % case 2, no-op (obsolete case) + \or % case 3, transfer vspace and/or penalty + \ifx#1\EQ@box \eq@revspace \else \eq@revspaceb \fi + \or % case 4, put back an insert + \eq@reinsert + \or % case 5, put back a mark + \eq@remark + \or % case 6, put back a vadjust + \eq@readjust + \else % some other break penalty + \penalty-\count@ + \fi + \unhbox#1}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@nulldisplay} +% Throw in a null display in order to get predisplaysize \etc . +% My original approach here was to start the null display, then measure +% the equation, and set a phantom of the equation's first line before +% ending the null display. That would allow finding out if \tex used +% the short displayskips instead of the normal ones. But because of +% some complications with grouping and the desirability of omitting +% unnecessary invisible material on the vertical list, it seems better to +% just collect information about the display (getting \cs{prevdepth} +% requires \cs{halign}) and manually perform our own version of +% \TeX's shortskip calculations. This approach also gives greater +% control, \eg , the threshold amount of horizontal space between +% predisplaysize and the equation's left edge that determines when the +% short skips kick in becomes a designer-settable parameter rather than +% hardwired into \TeX . +% \begin{macrocode} +\def\eq@nulldisplay{% + \begingroup \frozen@everydisplay\@emptytoks + \@@display + \predisplaypenalty\@M \postdisplaypenalty\@M + \abovedisplayskip\z@skip \abovedisplayshortskip\z@skip + \belowdisplayskip\z@skip \belowdisplayshortskip\z@skip + \xdef\EQ@displayinfo{% + \prevgraf\the\prevgraf \predisplaysize\the\predisplaysize + \displaywidth\the\displaywidth \displayindent\the\displayindent + \listwidth\the\linewidth +% \end{macrocode} +% Not sure how best to test whether leftmargin should be +% added. Let's do this for now [mjd,1997/10/08]. +% \begin{macrocode} + \ifdim\displayindent>\z@ + \advance\listwidth\the\leftmargin + \advance\listwidth\the\rightmargin + \fi + \relax}% +% \end{macrocode} +% An \cs{halign} containing only one \cs{cr} (for the +% preamble) puts no box on the vertical list, which means that no +% \cs{baselineskip} will be added (so we didn't need to set it to +% zero) and the previous value of prevdepth carries through. Those +% properties do not hold for an empty simple equation without +% \cs{halign}. +% \begin{macrocode} + \halign{##\cr}% + \@@enddisplay + \par + \endgroup + \EQ@displayinfo +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@newline} +% \begin{macro}{\eq@newlinea} +% \begin{macro}{\eq@newlineb} +% Here we use \cs{@ifnext} so that in a sequence like +% \begin{literalcode} +% ...\\ +% [a,b] +% \end{literalcode} +% \latex does not attempt to interpret the \verb"[a,b]" as a +% vertical space amount. We would have used \cs{eq@break} in the +% definition of \cs{eq@newlineb} except that it puts in a +% \cs{keep@glue} object which is not such a good idea if a mathbin +% symbol follows \mdash the indent of the mathbin will be wrong because +% the leading negative glue will not disappear as it should at the line +% break. +% \begin{macrocode} +\def\eq@newline{% + \@ifstar{\eq@newlinea\@M}{\eq@newlinea\eqinterlinepenalty}} +\def\eq@newlinea#1{% + \@ifnext[{\eq@newlineb{#1}}{\eq@newlineb{#1}[\maxdimen]}} +\def\eq@newlineb#1[#2]{\penalty-\@M} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\eq@revspace} +% \begin{macro}{\eq@revspaceb} +% When \cs{eq@revspace} (re-vspace) is called, we are the +% end of an equation line; we need to remove the existing penalty of +% $-10002$ in order to put a vadjust object in front of it, then put +% back the penalty so that the line break will still take place in the +% final result. +% \begin{macrocode} +\def\eq@revspace{% + \global\setbox\EQ@vimbox\vbox{\unvbox\EQ@vimbox + \unpenalty + \global\setbox\@ne\lastbox}% + \@@vadjust{\unvbox\@ne}% + \penalty-\@M +} +% \end{macrocode} +% The b version is used for the \cs{EQ@copy} box. +% \begin{macrocode} +\def\eq@revspaceb{% + \global\setbox\EQ@vimcopy\vbox{\unvbox\EQ@vimcopy + \unpenalty + \global\setbox\@ne\lastbox}% + \@@vadjust{\unvbox\@ne}% + \penalty-\@M +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\eq@break} +% The function \cs{eq@break} does a preliminary linebreak with +% a flag penalty. +% \begin{macrocode} +\def\eq@break#1{\penalty-1000#1 \keep@glue} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \section{Choosing optimal line breaks} +% The question of what line width to use when breaking an +% equation into several lines is best examined in the light of an extreme +% example. Suppose we have a two-column layout and a displayed +% equation falls inside a second-level list with nonzero leftmargin and +% rightmargin. Then we want to try in succession a number of +% different possibilities. In each case if the next possibility is +% no wider than the previous one, skip ahead to the one after. +% \begin{enumerate} +% \item First try linewidth(2), the linewidth for the current +% level-2 list. +% +% +% \item If we cannot find adequate linebreaks at that width, next try +% listwidth(2), the sum of leftmargin, linewidth, and rightmargin for +% the current list. +% +% +% \item If we cannot find linebreaks at that width, next try linewidth +% (1) (skipping this step if it is no larger then +% listwidth(2)). +% +% +% \item If we cannot find linebreaks at that width, next try +% listwidth(1). +% +% +% \item If we cannot find linebreaks at that width, next try column +% width. +% +% +% \item If we cannot find linebreaks at that width, next try text +% width. +% +% +% \item If we cannot find linebreaks at that width, next try equation +% width, if it exceeds text width (\ie , if the style allows equations +% to extend into the margins). +% +% +% \end{enumerate} +% +% +% \begin{figure} +% \centering +% needs work +% \caption{first-approximation parshape for equations}\label{f:parshape-1} +% \end{figure} +% +% At any given line width, we run through a series of parshape +% trials and, essentially, use the first one that gives decent line +% breaks. +% But the process is a bit more complicated in fact. +% In order to do a really good job of setting up the parshapes, we +% need to know how many lines the equation will require. +% And of course the number of lines needed depends on the parshape! +% So as our very first trial we run a simple first-approximation +% parshape (Figure~\vref{f:parshape-1}) whose +% main purpose is to get an estimate on the number of lines that will be +% needed; it chooses a uniform indent for all lines after the first one +% and does not take any account of the equation number. +% A substantial majority of equations only require one line anyway, +% and for them this first trial will succeed. +% In the one-line case if there is an equation number and it doesn't +% fit on the same line as the equation body, we don't go on to other +% trials because breaking up the equation body will not gain us +% anything\mdash we know that we'll have to use two lines in any case +% \mdash so we might as well keep the equation body together on one line +% and shift the number to a separate line. +% +% If we learn from the first trial that the equation body +% requires more than one line, the next parshape trial involves adjusting +% the previous parshape to leave room for the equation number, if +% present. If no number is present, again no further trials are +% needed. +% +% Some remarks about parshape handling. The \tex +% primitive doesn't store the line specs anywhere, \verb"\the\parshape" +% only returns the number of line specs. This makes it well nigh +% impossible for different packages that use \cs{parshape} to work +% together. Not that it would be terribly easy for the package +% authors to make inter-package collaboration work, if it were +% possible. If we optimistically conjecture that +% someone some day may take on such a task, then the thing to do, +% obviously, is provide a parshape interface that includes a record of all +% the line specs. For that we designate a macro \cs{@parshape} +% which includes not only the line specs, but also the line count and even +% the leading \cs{parshape} token. +% This allows it to be directly executed without an auxiliary if-empty +% test. It should include a trailing \cs{relax} when it has a +% nonempty value. +% \begin{macrocode} +\let\@parshape\@empty +% \end{macrocode} +% +% +% The function \cs{eq@measure} runs line-breaking trials +% on the copy of the equation body that is stored in the box register +% \cs{EQ@copy}, trying various possible layouts in order of +% preference until we get successful line breaks, where \quoted{successful} +% means there were no overfull lines. The result of the trials is, +% first, a parshape spec that can be used for typesetting the real +% equation body in \cs{EQ@box}, and second, some information that +% depends on the line breaks such as the depth of the last line, the +% height of the first line, and positioning information for the equation +% number. The two main variables in the equation layout are the line +% width and the placement of the equation number, if one is present. +% +% +% \begin{macro}{\eq@measure} +% Run linebreak trials on the equation contents and measure the +% results. +% \begin{macrocode} +\def\eq@measure{% +% \end{macrocode} +% If an override value is given for indentstep in the env options, use +% it. +% \begin{macrocode} + \ifdim\eq@indentstep=\maxdimen \eq@indentstep\eqindentstep \fi +% \end{macrocode} +% If \cs{eq@linewidth} is nonzero at this point, it means that +% the user specified a particular target width for this equation. +% In that case we override the normal list of trial widths. +% \begin{macrocode} + \ifdim\eq@linewidth=\z@ \else \edef\eq@linewidths{{\the\eq@linewidth}}\fi + \begingroup \eq@params + \leftskip\z@skip +% \end{macrocode} +% Even if \cs{hfuzz} is greater than zero a box whose contents +% exceed the target width by less then hfuzz still has a reported badness +% value of 1000000 (infinitely bad). Because we use inf-bad +% to test whether a particular trial succeeds or fails, we want to make +% such boxes return a smaller badness. To this end we include an +% \cs{hfuzz} allowance in \cs{rightskip}. In fact, +% \cs{eq@params} ensures that \cs{hfuzz} for equations is at +% least 1pt. +% \begin{macrocode} + \rightskip\z@\@plus\columnwidth\@minus\hfuzz +% \eqinfo + \global\EQ@continue{\eq@trial}% + \eq@trial % uses \eq@linewidths + \eq@failout % will be a no-op if the trial succeeded + \endgroup +% \end{macrocode} +% \quoted{local} parameter settings are passed outside the endgroup through +% \cs{EQ@trial}. +% \begin{macrocode} + \EQ@trial +} +% \end{macrocode} +% \end{macro} +% \begin{macrocode} +%<*trace> +\def\debug@showmeasurements{% + \breqn@debugmsg{=> \number\eq@lines\space lines}% + \begingroup + \def\@elt##1X##2{\MessageBreak==== \space\space##1/##2}% + \let\@endelt\@empty + \breqn@debugmsg{=> trial info:\eq@measurements}% + \breqn@debugmsg{=> bounding box: \the\eq@wdT x\the\eq@vspan, badness=\the\eq@badness}% + \let\@elt\relax \let\@endelt\relax + \endgroup +} +\def\debug@showmeasurements{% + \begingroup + \def\@elt##1X##2{\MessageBreak==== ##1/##2}% + \let\@endelt\@empty + \breqn@debugmsg{===> Measurements: \number\eq@lines\space lines + \eq@measurements + \MessageBreak + ==== bounding box: \the\eq@wdT x\the\eq@vspan, badness=\the\eq@badness + \MessageBreak + ==== \leftskip=\the\leftskip, \rightskip=\the\rightskip}% + \endgroup +} +%</trace> +% \end{macrocode} +% +% Layout Trials Driver +% Basically, trying different sequences of parshapes. +% +% +% \begin{macro}{\EQ@trial} +% Init. +% \begin{macrocode} +\let\EQ@trial\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\EQ@continue} +% This is a token register used to carry trial info past a +% group boundary with only one global assignment. +% \begin{macrocode} +\newtoks\EQ@continue +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\EQ@widths} +% This is used for storing the actual line-width info of the equation +% contents after breaking. +% \begin{macrocode} +\let\EQ@widths\@empty +% \end{macrocode} +% \end{macro} +% \begin{macro}{\EQ@fallback} +% \begin{macrocode} +\let\EQ@fallback\@empty +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@linewidths} +% This is the list of target widths for line breaking. +% +%======================================== +% BRM: Odd; I don't think I've seen this use anything but \cs{displaywidth}... +% \begin{macrocode} +\def\eq@linewidths{\displaywidth\linewidth\columnwidth} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@trial} +% The \cs{eq@trial} function tries each candidate +% line width in \cs{eq@linewidths} until an equation layout is found +% that yields satisfactory line breaks. +% \begin{macrocode} +\def\eq@trial{% + \ifx\@empty\eq@linewidths + \global\EQ@continue{}% + \else + \iffalse{\fi \@xp\eq@trial@a \eq@linewidths}% + \fi + \the\EQ@continue +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@trial@a} +% The \cs{eq@trial@a} function reads the leading line +% width from \cs{eq@linewidths}; if the new line width is greater +% than the previous one, start running trials with it; otherwise do +% nothing with it. +% Finally, run a peculiar \cs{edef} that leaves +% \cs{eq@linewidths} redefined to be the tail of the list. +% If we succeed in finding satisfactory line breaks +% for the equation, we will reset \cs{EQ@continue} in such a +% way that it will terminate the current trials. +% An obvious branch here would be to check whether the width of +% \cs{EQ@copy} is less than \cs{eq@linewidth} and go immediately +% to the one-line case if so. +% However, if the equation contains more than one RHS, by +% default each additional RHS starts on a new line\mdash \ie , we want +% the ladder layout anyway. +% So we choose the initial trial on an assumption of multiple lines +% and leave the one-line case to fall out naturally at a later point. +% \begin{macrocode} +\def\eq@trial@a#1{% + \dim@c#1\relax + \if T\eq@frame \eq@frame@adjust\dim@c \fi + \ifdim\dim@c>\eq@linewidth + \eq@linewidth\dim@c +%<trace> \breqn@debugmsg{Choose Shape for width(#1)=\the\eq@linewidth}% + \let\eq@trial@b\eq@trial@d + \csname eq@try@layout@\eq@layout\endcsname +%<trace> \else +%<trace> \breqn@debugmsg{Next width (#1) is shorter; skip it}% + \fi + \edef\eq@linewidths{\iffalse}\fi +} +\def\eq@frame@adjust#1{% + %\addtolength#1{-2\eq@framewd-2\eq@framesep}% + \dim@a\eq@framewd \advance\dim@a\eq@framesep + \advance#1-2\dim@a +} +% \end{macrocode} +% \end{macro} +%======================================== +% Note curious control structure. +% Try to understand interaction of \cs{EQ@fallback}, \cs{EQ@continue}, +% \cs{eq@failout} +% \begin{macrocode} +\def\eq@trial@succeed{% + \aftergroup\@gobbletwo % cancel the \EQ@fallback code; see \eq@trial@c (?) + \global\EQ@continue{\eq@trial@done}% +} +% \end{macrocode} +% \begin{macro}{\eq@trial@done} +% Success. +% \begin{macrocode} +\def\eq@trial@done{% +%<trace> \breqn@debugmsg{End trial: Success!}% + \let\eq@failout\relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@trial@init} +% This is called from \cs{eq@trial@b} to initialize or +% re-initialize certain variables as needed when running one or more +% trials at a given line width. +% By default assume success, skip the fallback code. +% \begin{macrocode} +\def\eq@trial@init{\global\let\EQ@fallback\eq@nextlayout} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@nextlayout} +% +% In the fallback case cancel the current group to avoid unnecessary +% group nesting (with associated save-stack cost, \etc ). +% \begin{macrocode} +\def\eq@nextlayout#1{% + \endgroup +%<trace> \breqn@debugmsg{Nope ... that ain't gonna work.}% + \begingroup #1% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@failout} +% +% . +% \begin{macrocode} +\def\eq@failout{% +%<trace>\breqn@debugmsg{End trial: failout}% + \global\let\EQ@trial\EQ@last@trial +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@trial@save} +% +% Save the parameters of the current trial. +% \begin{macrocode} +\def\eq@trial@save#1{% +%<*trace> +% \begingroup \def\@elt##1X##2{\MessageBreak==== \space\space##1/##2}\let\@endelt\@empty\breqn@debugmsg{=> trial info:\eq@measurements}% +% \breqn@debugmsg{=> bounding box: \the\eq@wdT x\the\eq@vspan, badness=\the\eq@badness\MessageBreak}% +% \let\@elt\relax \let\@endelt\relax +% \endgroup +%</trace> + \xdef#1{% + \eq@linewidth\the\eq@linewidth + % save info about the fit + \eq@lines\the\eq@lines \eq@badness\the\eq@badness \def\@nx\eq@badline{\eq@badline}% + % save size info + \eq@wdT\the\eq@wdT \eq@wdMin\the\eq@wdMin + \eq@vspan\the\eq@vspan \eq@dp\the\eq@dp \eq@firstht\the\eq@firstht + % save info about the LHS + \eq@wdL\the\eq@wdL \def\@nx\EQ@hasLHS{\EQ@hasLHS}% + % save info about the numbering + \def\@nx\eq@hasNumber{\eq@hasNumber}% + % save info about the chosen layout + \def\@nx\eq@layout{\eq@layout}% + \def\@nx\eq@parshape{\@parshape}% + \def\@nx\eq@measurements{\eq@measurements}% + \def\@nx\adjust@rel@penalty{\adjust@rel@penalty}% + \def\@nx\eq@shiftnumber{\eq@shiftnumber}% + \def\@nx\eq@isIntertext{\@False}% + }% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@trial@b} +% +% By default this just runs \cs{eq@trial@c}; \cf +% \cs{eq@trial@d}. +% \begin{macrocode} +\def\eq@trial@b{\eq@trial@c} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@trial@c} +% +% Run the equation contents through the current parshape. +% \begin{macrocode} +\def\eq@trial@c#1#2{% +%<trace> \breqn@debugmsg{Trying layout "#1" with\MessageBreak==== parshape\space\@xp\@gobble\@parshape}% + \begingroup + \eq@trial@init + \def\eq@layout{#1}% + \setbox\z@\vbox{% + \hfuzz\maxdimen + \eq@trial@p % run the given parshape + \if\@Not{\eq@badline}% + \eq@trial@save\EQ@trial +% \end{macrocode} +% If there is a number, try the same parshape again with adjustments +% to make room for the number. +% +% This is an awkward place for this: +% It only allows trying to fit the number w/the SAME layout shape! +% \begin{macrocode} + \if\eq@hasNumber\eq@retry@with@number\fi + \if L\eq@layout \eq@check@density + \else + \if\@Not{\eq@badline}% + \eq@trial@succeed + \fi + \fi + \else + \eq@trial@save\EQ@last@trial + \fi + }% + \EQ@fallback{#2}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@trial@d} +% \begin{macrocode} +\def\eq@trial@d#1#2{\eq@trial@c{#1}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@check@density} +% \begin{macrocode} +\def\eq@check@density{% +%<trace> \breqn@debugmsg{Checking density for layout L}% + \if\@Or{\@Not\EQ@hasLHS}{\eq@shortLHS}% +%<trace> \breqn@debugmsg{Density check: No LHS, or is short; OK}% + \eq@trial@succeed + \else\if\eq@dense@enough + \eq@trial@succeed + \fi\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@shortLHS} +% Test to see if we need to apply the \cs{eq@dense@enough} test. +% \begin{macrocode} +\def\eq@shortLHS{\ifdim\eq@wdL>.44\eq@wdT 1\else 0\fi 0} +% \end{macrocode} +% \end{macro} +% +%\verb|\def\eq@shortLHS{\@False}| +%======================================== +% \begin{macro}{\eq@trial@p} +% Run a trial with the current \cs{@parshape} and measure it. +% \begin{macrocode} +\def\eq@trial@p{% + \@parshape % + \eq@dump@box\unhcopy\EQ@copy + {\@@par}% leave \parshape readable + \eq@lines\prevgraf + \eq@fix@lastline + \let\eq@badline\@False + \if i\eq@layout \ifnum\eq@lines>\@ne \let\eq@badline\@True \fi\fi + \eq@curline\eq@lines % loop counter for eq@measure@lines + \let\eq@measurements\@empty + \eq@ml@record@indents + \eq@measure@lines + \eq@recalc +%<trace> \debug@showmeasurements +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\adjust@rel@penalty} +% Normally this is a no-op. +% \begin{macrocode} +\let\adjust@rel@penalty\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@fix@lastline} +% Remove parfillskip from the last line box. +% \begin{macrocode} +\def\eq@fix@lastline{% + \setbox\tw@\lastbox \dim@b\wd\tw@ + \eq@dp\dp\tw@ +% \end{macrocode} +% Remove \cs{parfillskip} but retain \cs{rightskip}. +% Need to keep the original line width for later shrink testing. +% \begin{macrocode} + \nointerlineskip\hbox to\dim@b{\unhbox\tw@ + \skip@c\lastskip \unskip\unskip\hskip\skip@c + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@recalc} +% Calculate \cs{eq@wdT} et cetera. +% \begin{macrocode} +\def\eq@recalc{% + \eq@wdT\z@ \eq@wdMin\maxdimen \eq@vspan\z@skip \eq@badness\z@ + \let\@elt\eq@recalc@a \eq@measurements \let\@elt\relax +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@recalc@a} +% \begin{macrocode} +\def\eq@recalc@a#1x#2+#3\@endelt{% + \eq@firstht#2\relax + \let\@elt\eq@recalc@b + \@elt#1x#2+#3\@endelt +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@recalc@b} +% \begin{macrocode} +\def\eq@recalc@b#1X#2,#3x#4+#5@#6\@endelt{% + \setlength\dim@a{#2+#3}% + \ifdim\dim@a>\eq@wdT \eq@wdT\dim@a \fi + \ifdim\dim@a<\eq@wdMin \eq@wdMin\dim@a \fi + \eq@dp#5\relax + \addtolength\eq@vspan{#1+#4+\eq@dp}% +% \end{macrocode} +% Record the max badness of all the lines in \cs{eq@badness}. +% \begin{macrocode} + \ifnum#6>\eq@badness \eq@badness#6\relax\fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@layout} +% A value of \verb"?" for \cs{eq@layout} means that we should +% deduce which layout to use by looking at the size of the components. +% Any other value means we have a user-specified override on the +% layout. +% +% Layout Definitions. +% Based on initial equation measurements, we can choose a sequence of +% candidate parshapes that the equation might fit into. +% We accept the first shape that `works', else fall to next one. +% [The sequence is hardcoded in the \cs{eq@try@layout@}<shape> +% Would it be useful be more flexible? (eg. try layouts LDA, in order...)] +% \begin{macrocode} +\def\eq@layout{?} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@try@layout@?} +% This is a branching function used to choose a suitable layout if +% the user didn't specify one in particular. +% +% Default layout: +% Try Single line layout first, else try Multiline layouts +% \begin{macrocode} +\@namedef{eq@try@layout@?}{% + \let\eq@trial@b\eq@trial@c + \edef\@parshape{\parshape 1 0pt \the\eq@linewidth\relax}% +% \eq@trial@b{i}{\eq@try@layout@multi}% + \setlength\dim@a{\wd\EQ@copy-2em}% Fudge; can't shrink more than this? + % if we're in a numbered group, try hard to fit within the numbers + \dim@b\eq@linewidth + \if\eq@shiftnumber\else\if\eq@group + \if\eq@hasNumber\addtolength\dim@b{-\wd\EQ@numbox-\eqnumsep}% + \else\if\grp@hasNumber\addtolength\dim@b{-\wd\GRP@numbox-\eqnumsep}% + \fi\fi\fi\fi + \ifdim\dim@a<\dim@b% Do we even have a chance of fitting to one line? +%<trace> \breqn@debugmsg{Choose Shape: (\the\wd\EQ@copy) may fit in \the\dim@b}% +% \end{macrocode} +% BRM: assuming it might fit, don't push too hard +% \begin{macrocode} + \setlength\dim@b{\columnwidth-\dim@a+\eq@wdCond}% + \rightskip\z@\@plus\dim@b\@minus\hfuzz + \eq@trial@b{i}{\eq@try@layout@multi}% + \else +%<*trace> + \breqn@debugmsg{Choose Shape: Too long (\the\wd\EQ@copy) for one line + (free width=\the\dim@b)}% +%</trace> + \eq@try@layout@multi + \fi +} +% \end{macrocode} +% Layout Multiline layout: +% If no LHS, try Stepped(S) layout +% Else try Stepped(S), Ladder(L), Drop-ladder(D) or Stepladder(l), depending on LHS length. +% \begin{macrocode} +\def\eq@try@layout@multi{% + \if\EQ@hasLHS + \ifdim\eq@wdL>\eq@linewidth +%<trace> \breqn@debugmsg{Choose Shape: LHS \the\eq@wdL > linewidth}% +% \end{macrocode} +% Find the total width of the RHS. +% If it is relatively short, a step layout is the thing to try. +% \begin{macrocode} + \setlength\dim@a{\wd\EQ@copy-\eq@wdL}% + \ifdim\dim@a<.25\eq@linewidth \eq@try@layout@S + \else \eq@try@layout@l + \fi + % BRM: Originally .7: Extreme for L since rhs has to wrap within the remaining 30+%! + \else\ifdim\eq@wdL>.50\eq@linewidth +%<*trace> + \breqn@debugmsg{Choose Shape: LHS (\the\eq@wdL) > .50 linewidth (linewidth=\the\eq@linewidth)}% +%</trace> + \eq@try@layout@D + \else +%<trace> \breqn@debugmsg{Choose Shape: LHS (\the\eq@wdL) not extraordinarily wide}% + \eq@try@layout@L + \fi\fi + \else +%<trace> \breqn@debugmsg{Choose Shape: No LHS here}% +% \end{macrocode} +% Try one-line layout first, then step layout. +% \begin{macrocode} + \eq@try@layout@S % (already checked case i) + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@try@layout@D} +% Change the penalty before the first mathrel symbol to encourage a +% break there. +% +% Layout D=Drop-Ladder Layout, for wide LHS. +% \begin{literalcode} +% LOOOOOOOONG LHS +% = RHS +% = ... +% \end{literalcode} +% If fails, try Almost-Columnar layout +% \begin{macrocode} +\def\eq@try@layout@D{% + \setlength\dim@a{\eq@linewidth -\eq@indentstep}% + \edef\@parshape{\parshape 2 + 0pt \the\eq@wdL\space \the\eq@indentstep\space \the\dim@a\relax + }% + \def\adjust@rel@penalty{\penalty-99 }% + \eq@trial@b{D}{\eq@try@layout@A}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\eq@try@layout@L} +% Try a straight ladder layout. +% Preliminary filtering ensures that \cs{eq@wdL} is less than 70% +% of the current line width. +% \begin{literalcode} +% Layout L=Ladder layout +% LHS = RHS +% = RHS +% ... +% \end{literalcode} +% If fails, try Drop-ladder layout. +% NOTE: This is great for some cases (multi relations?), but +% tends to break really badly when it fails.... +% \begin{macrocode} +\def\eq@try@layout@L{% + \setlength\dim@b{\eq@linewidth-\eq@wdL}% + \edef\@parshape{\parshape 2 0pt \the\eq@linewidth\space + \the\eq@wdL\space \the\dim@b\relax + }% + \eq@trial@b{L}{\eq@try@layout@D}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@try@layout@S} +% In the \dquoted{stepped} layout there is no LHS, or LHS +% is greater than the line width and RHS is small. +% Then we want to split up the equation into lines of roughly equal +% width and stagger them downwards to the right, leaving a small amount of +% whitespace on both sides. +% But also, if there is an equation number, we want to try first a +% layout that leaves room for the number. +% Otherwise it would nearly always be the case that the number would +% get thrown on a separate line. +% +% Layout S=Stepped layout, typically no LHS or very long, variations on +% \begin{literalcode} +% STUFF .... +% + MORE STUFF ... +% + MORE STUFF ... +% \end{literalcode} +% If fails, try Almost-Columnar layout +% \begin{macrocode} +\def\eq@try@layout@S{% + \setlength\dim@b{\eq@linewidth-2\eqmargin}% \advance\dim@b-1em% +% \end{macrocode} +% About how many lines will we need if dim@b is the line width? +% \begin{macrocode} + \int@a\wd\EQ@copy \divide\int@a\dim@b +% \end{macrocode} +% Adjust the target width by number of lines times indentstep. +% We don't need to decrement \cs{int@a} because \tex +% division is integer division with truncation. +% \begin{macrocode} + \addtolength\dim@b{-\int@a\eq@indentstep}% +% \end{macrocode} +% Adjust for equation number. +% But try not to leave too little room for the equation body. +% \begin{macrocode} + \if\eq@hasNumber + \ifdim\dim@b>15em% +% \advance\dim@b-\eqnumsep \advance\dim@b-\wd\EQ@numbox + \addtolength\dim@b{-\eq@wdNum}% + \fi + \fi +% \end{macrocode} +% Now some hand-waving to set up the parshape. +% \begin{macrocode} + \int@b\z@ + \def\@tempa{\dim}% + \edef\@parshape{\parshape 2 0pt \the\dim@b\space + \the\eqmargin\space\the\dim@b\relax}% + \eq@trial@b{S}{\eq@try@layout@A}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@try@layout@l} +% This is the \dquoted{step-ladder} layout: similar to the drop-ladder +% layout but the LHS is too wide and needs to be broken up. +% +% Layout l = Stepladder +% Similar to Drop-Ladder, but LHS is long and needs to be broken up. +% If fails, try Almost-Columnar layout +% \begin{macrocode} +\def\eq@try@layout@l{% + \setlength\dim@a{\eq@linewidth -\eq@indentstep}% + \int@a\eq@wdL \divide\int@a\dim@a + \advance\int@a\tw@ + \edef\@parshape{\parshape \number\int@a\space + 0pt \the\eq@linewidth + }% + \advance\int@a-\tw@ + \setlength\dim@b{2\eq@indentstep}% + \setlength\dim@c{\eq@linewidth -\dim@b}% + \edef\@parshape{\@parshape + \replicate{\int@a}{\space\the\eq@indentstep\space\the\dim@a}% + \space\the\dim@b\space\the\dim@c\relax + }% + \eq@trial@b{l}{\eq@try@layout@A}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@try@layout@A} +% In the \dquoted{almost-columnar} layout, which is the layout of last +% resort, we let all lines run to the full width and leave the adjusting +% of the indents to later. +% +% Layout A = Almost-Columnar layout. +% Pretty much straight full width, more of a last-resort. +% If fails, give up. +% \begin{macrocode} +\def\eq@try@layout@A{% + \edef\@parshape{\parshape 1 0pt \the\eq@linewidth\relax}% + \if\EQ@hasLHS \def\adjust@rel@penalty{\penalty-99 }\fi + \eq@trial@b{A}{}% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@shiftnumber} +% MH: Should be moved to a section where all keys are set to defaults. +% \begin{macrocode} +\let\eq@shiftnumber\@False +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@retry@with@number@a} +% Number placement adjustments +% \begin{macrocode} +\def\eq@retry@with@number{% + \if\eq@shiftnumber +%<trace> \breqn@debugmsg{Place number: Shifted number requested}% + \else +% \end{macrocode} +% Condition and right numbers? We're just going to have to shift. +% \begin{macrocode} + \ifdim\eq@wdCond>\z@\if R\eqnumside +%<trace> \breqn@debugmsg{Place number: Condition w/Right number => Shift number}% + \let\eq@shiftnumber\@True + \fi\fi +% \end{macrocode} +% Compute free space. +% \begin{macrocode} +% \dim@b\eqnumsep\advance\dim@b\wd\EQ@numbox + \dim@b\eq@wdNum + \if L\eqnumside + \ifdim\@totalleftmargin>\dim@b\dim@b\@totalleftmargin\fi + \else + \addtolength\dim@b{\@totalleftmargin}% + \fi + \setlength\dim@a{\eq@linewidth-\dim@b}%\advance\dim@a1em\relax% Allowance for shrink? +% \end{macrocode} +% Set up test against 1-line case only if not in a group +% \begin{macrocode} + \int@a\@ne\if\eq@group\int@a\maxint\fi +% \end{macrocode} +% Now check for cases. +% \begin{macrocode} + \if\eq@shiftnumber % Already know we need to shift + \else\ifdim\eq@wdT<\dim@a % Fits! +% \end{macrocode} +% left \& right skips will be done later, and parshape adjusted if +% needed. +% \begin{macrocode} +%<trace> \breqn@debugmsg{Place number: eqn and number fit together}% +% \else\ifnum\eq@lines=\int@a % Shift, if single line, unless inside a dgroup. +% \end{macrocode} +% NOTE: this is too strong for dgroup! +% \begin{macrocode} +%<*trace> +% \breqn@debugmsg{Place number: single line too long with number => Shift number \the\int@a}% +%</trace> +% \let\eq@shiftnumber\@True + \else +% \end{macrocode} +% % Retry: use leftskip for space for number(for now; whether +% % right/left) \& adjust parshape +% \begin{macrocode} +% \leftskip\wd\EQ@numbox\advance\leftskip\eqnumsep + \setlength\leftskip{\eq@wdNum}% + \setlength\rightskip{\z@\@plus\dim@a}% + \adjust@parshape\@parshape +%<*trace> + \breqn@debugmsg{Place number: Try with \leftskip=\the\leftskip, \rightskip=\the\rightskip, + \MessageBreak==== parshape\space\@xp\@gobble\@parshape}% +%</trace> + \nointerlineskip + \edef\eq@prev@lines{\the\eq@lines}% + \edef\eq@prev@badness{\the\eq@badness}% BRM + \eq@trial@p + \int@a\eq@prev@badness\relax\advance\int@a 50\relax%? + \int@b\eq@prev@lines \if\eq@group\advance\int@b\@ne\fi% Allow 1 extra line in group + \ifnum\eq@lines>\int@b % \eq@prev@lines +%<trace> \breqn@debugmsg{Adjustment causes more breaks => Shift number}% + \let\eq@shiftnumber\@True + \else\if\eq@badline +%<trace> \breqn@debugmsg{Adjustment causes bad lines (\the\eq@badness) => Shift}% + \let\eq@shiftnumber\@True + \else\ifnum\eq@badness>\int@a % BRM: New case +%<*trace> + \breqn@debugmsg{Adjustment is badder than previous + (\the\eq@badness >> \eq@prev@badness) => Shift}% +%</trace> + \let\eq@shiftnumber\@True + \else +%<trace> \breqn@debugmsg{Adjustment succeeded}% + \fi\fi%\fi + \fi\fi\fi +% \end{macrocode} +% If we got shifted, restore parshape, etc, +% \begin{macrocode} + \if\eq@shiftnumber + \EQ@trial% Restore parshape & other params, + \leftskip\z@\let\eq@shiftnumber\@True % But set shift & leftskip + \edef\@parshape{\eq@parshape}% And copy saved parshape back to `working copy' !?!? + \fi + \eq@trial@save\EQ@trial % Either way, save the trial state. + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\adjust@parshape} +% Varies depending on the layout. +% +% Adjust a parshape variable for a given set of left\textbar right skips. +% Note that the fixed part of the left\textbar right skips effectively +% comes out of the parshape widths (NOT in addition to it). +% We also must trim the widths so that the sum of skips, indents +% and widths add up to no more than the \cs{eq@linewidth}. +% \begin{macrocode} +\def\adjust@parshape#1{% + \@xp\adjust@parshape@a#1\relax + \edef#1{\temp@a}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\adjust@parshape@a} +% \begin{macro}{\adjust@parshape@b} +% \begin{macrocode} +\def\adjust@parshape@a#1 #2\relax{% + \setlength\dim@a{\leftskip+\rightskip}% + \edef\temp@a{#1}% + \adjust@parshape@b#2 @ @ \relax +} +\def\adjust@parshape@b#1 #2 {% + \ifx @#1\edef\temp@a{\temp@a\relax}% + \@xp\@gobble + \else + \dim@b#1\relax + \dim@c#2\relax + \addtolength\dim@c{\dim@a+\dim@b}% + \ifdim\dim@c>\eq@linewidth\setlength\dim@c{\eq@linewidth}\fi + \addtolength\dim@c{-\dim@b}% + \edef\temp@a{\temp@a\space\the\dim@b\space\the\dim@c}% + \fi + \adjust@parshape@b +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\eq@ml@record@indents} +% Plunk the parshape's indent values into an array for easy access +% when constructing \cs{eq@measurements}. +% \begin{macrocode} +\def\eq@ml@record@indents{% + \int@a\z@ + \def\@tempa{% + \advance\int@a\@ne + \@xp\edef\csname eq@i\number\int@a\endcsname{\the\dim@a}% + \ifnum\int@a<\int@b \afterassignment\@tempb \fi + \dim@a + }% + \def\@tempb{\afterassignment\@tempa \dim@a}% + \def\@tempc##1##2 {\int@b##2\afterassignment\@tempa\dim@a}% + \@xp\@tempc\@parshape +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@endelt} +% This is a scan marker. +% It should get a non-expandable definition. +% It could be \cs{relax}, but let's try a chardef instead. +% \begin{macrocode} +\chardef\@endelt=`\? +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@measurements} +% This is similar to a parshape spec but for each line we record more +% info: space above, indent, width x height + dp, and badness. +% \begin{macrocode} +\def\eq@measurements{% + \@elt 4.5pt/5.0pt,66.0ptx6.8pt+2.4pt@27\@endelt + ... +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@measure@lines} +% Loop through the list of boxes to measure things like total +% height (including interline stretch), \etc . We check the +% actual width of the current line against the natural width \mdash +% after removing rightskip \mdash in case the former is +% \emph{less} than the latter because of shrinkage. In that +% case we do not want to use the natural width for RHS-max-width because +% it might unnecessarily exceed the right margin. +% \begin{macrocode} +\def\eq@measure@lines{% + \let\eq@ml@continue\eq@measure@lines + \setbox\tw@\lastbox \dim@b\wd\tw@ % find target width of line + \setbox\z@\hbox to\dim@b{\unhbox\tw@}% check for overfull + \eq@badness\badness + \ifnum\eq@badness<\inf@bad \else \let\eq@badline\@True \fi + \eq@ml@a \eq@ml@continue +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@ml@a} +% +% \begin{macrocode} +\def\eq@ml@a{% + \setbox\tw@\hbox{\unhbox\z@ \unskip}% find natural width +%<*trace> + \ifnum\eq@badness<\inf@bad\else\breqn@debugmsg{!?! Overfull: \the\wd\tw@ >\the\dim@b}\fi +%</trace> +% \end{macrocode} +% Is actual width less than natural width? +% \begin{macrocode} + \ifdim\dim@b<\wd\tw@ \setlength\dim@a{\dim@b}% shrunken line + \else \setlength\dim@a{\wd\tw@}% OK to use natural width + \fi + \addtolength\dim@a{-\leftskip}% BRM: Deduct the skip if we're retrying w/number +% \end{macrocode} +% If there's no aboveskip, assume we've reached the top of the +% equation. +% \begin{macrocode} + \skip@a\lastskip \unskip \unpenalty + \ifdim\skip@a=\z@ + \let\eq@ml@continue\relax % end the recursion + \else + % Sum repeated vskips if present + \def\@tempa{% + \ifdim \lastskip=\z@ + \else \addtolength\skip@a{\lastskip}\unskip\unpenalty \@xp\@tempa + \fi + }% + \fi + \edef\eq@measurements{\@elt + \the\skip@a\space X% extra space to facilitate extracting only the + % dimen part later + \csname eq@i% + \ifnum\eq@curline<\parshape \number\eq@curline + \else\number\parshape + \fi + \endcsname,\the\dim@a x\the\ht\tw@+\the\dp\tw@ @\the\eq@badness\@endelt + \eq@measurements + }% + \advance\eq@curline\m@ne + \ifnum\eq@curline=\z@ \let\eq@ml@continue\relax\fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@ml@vspace} +% +% Handle an embedded vspace. +% \begin{macrocode} +\def\eq@ml@vspace{% + \global\advance\eq@vspan\lastskip \unskip\unpenalty + \ifdim\lastskip=\z@ \else \@xp\eq@ml@vspace \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@dense@enough} +% +% \begin{macrocode} +\def\eq@dense@enough{% + \ifnum\eq@lines<\thr@@ +%<trace> \breqn@debugmsg{Density check: less than 3 lines; OK}% + \@True + \else + \ifdim\eq@wdL >.7\eq@wdT +%<trace> \breqn@debugmsg{Density check: LHS too long; NOT OK}% + \@False + \else \@xp\@xp\@xp\eq@dense@enough@a + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\true@true@true} +% \begin{macro}{\true@false@true} +% \begin{macro}{\false@true@false} +% \begin{macro}{\false@false@false} +% \begin{macrocode} +\def\true@true@true {\fi\fi\iftrue \iftrue \iftrue } +\def\true@false@true {\fi\fi\iftrue \iffalse\iftrue } +\def\false@true@false {\fi\fi\iffalse\iftrue \iffalse} +\def\false@false@false{\fi\fi\iffalse\iffalse\iffalse} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\eq@density@factor} +% +% This number specifies, for the ladder layout, how much of the +% equation's bounding box should contain visible material rather than +% whitespace. +% If the amount of visible material drops below this value, then we +% switch to the drop-ladder layout. +% The optimality of this factor is highly dependent on the equation +% contents; .475 was chosen as the default just because it worked well +% with the sample equation, designed to be as average as possible, that I +% used for testing. +% \begin{macrocode} +\def\eq@density@factor{.475} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@dense@enough@a} +% +% Calculate whether there is more +% visible material than whitespace within the equation's bounding box. +% Sum up the actual line widths and compare to the total +% \dquoted{area} of the bounding box. +% But if we have an extremely large number of lines, fall back to an +% approximate calculation that is more conservative about the danger of +% exceeding \cs{maxdimen}. +% \begin{macrocode} +\def\eq@dense@enough@a{% + \@True \fi + \ifnum\eq@lines>\sixt@@n + \eq@dense@enough@b + \else + \dim@b\z@ \let\@elt\eq@delt \eq@measurements + \dim@c\eq@density@factor\eq@wdT \multiply\dim@c\eq@lines +%<trace> \breqn@debugmsg{Density check: black \the\dim@b/\eq@density@factor total \the\dim@c}% + \ifdim\dim@b>\dim@c \true@false@true \else \false@false@false \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@delt} +% Args are space-above, indent, width, height, depth, badness. +% \begin{macrocode} +\def\eq@delt#1X#2,#3x#4+#5@#6\@endelt{\addtolength\dim@b{#3}}% +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@dense@enough@b} +% This is an approximate calculation used to keep from going over +% \cs{maxdimen} if the number of lines in our trial break is large +% enough to make that a threat. +% If l, t, n represent left-side-width, total-width, and number of +% lines, the formula is +% \begin{literalcode} +% l/t < .4n/(.9n-1) +% \end{literalcode} +% or equivalently, since rational arithmetic is awkward in \tex : +% b +% \begin{literalcode} +% l/t < 4n/(9n-10) +% \end{literalcode} +% . +% \begin{macrocode} +\def\eq@dense@enough@b{% + \int@b\eq@wdT \divide\int@b\p@ + \dim@b\eq@wdL \divide\dim@b\int@b + \dim@c\eq@lines\p@ \multiply\dim@c\f@ur + \int@b\eq@lines \multiply\int@b 9 \advance\int@b -10% + \divide\dim@c\int@b +%<trace> \breqn@debugmsg{Density check: l/t \the\dim@b\space< \the\dim@c\space 4n/(9n-10)?}% + \ifdim\dim@b<\dim@c \true@true@true \else \false@true@false \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eq@parshape} +% \begin{macrocode} +\let\eq@parshape\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\eq@params} +% The interline spacing and penalties in \cs{eq@params} +% are used during both preliminary line breaking and final typesetting. +% \begin{macrocode} +\def\eq@params{% + \baselineskip\eqlinespacing + \lineskip\eqlineskip \lineskiplimit\eqlineskiplimit +% \end{macrocode} +% Forbid absolutely a pagebreak that separates the first line or last +% line of a multiline equation from the rest of it. Or in other +% words: no equation of three lines or less will be broken at the bottom +% of a page; instead it will be moved whole to the top of the next +% page. If you really really need a page break that splits the +% first or last line from the rest of the equation, you can always fall +% back to\cs{pagebreak}, I suppose. +% +% \begin{macrocode} + \clubpenalty\@M \widowpenalty\@M \interlinepenalty\eqinterlinepenalty + \linepenalty199 \exhyphenpenalty5000 % was 9999: make breaks at, eg. \* a bit easier. +% \end{macrocode} +% For equations, hfuzz should be at least 1pt. +% But we have to fake it a little because we are running the equation +% through \tex 's paragrapher. +% In our trials we use minus 1pt in the rightskip rather than hfuzz; +% and we must do the same during final breaking of the equation, otherwise +% in borderline cases \tex will use two lines instead of one when our +% trial indicated that one line would be enough. +% \begin{macrocode} + \ifdim\hfuzz<\p@ \hfuzz\p@ \fi +%\hfuzz=2pt +% \ifdim\hfuzz<2pt\relax \hfuzz2pt \fi + \parfillskip\z@skip +% \hfuzz\z@ +% \end{macrocode} +% Make sure we skip \tex 's preliminary line-breaking pass to save +% processing time. +% \begin{macrocode} + \tolerance9999 \pretolerance\m@ne +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \section{Equation layout options} +% Using the notation C centered, I indented (applied to +% the equation body), T top, B bottom, M +% middle, L left, R right (applied to the equation number), +% the commonly used equation types are C, CRM, CRB, CLM, CLT, +% I, IRM, IRB, ILM, ILT. In other words, CLM stands for Centered equation +% body with Left-hand Middle-placed equation number, and IRB stands for +% Indented equation with Right-hand Bottom-placed equation number. +% +% Here are some general thoughts on how to place an equation +% tag. Currently it does not work as desired: the L option positions +% the tag app. 10 lines below the math expression, the RM doesn't +% position the tag on the baseline for single-line math +% expressions. Therefore I am going to first write what I think is +% supposed to happen and then implement it. +% +% Below is a small list where especially the two three specifications +% should be quite obvious, I just don't want to forget anything and it +% is important to the implementation. +% \begin{description} +% \item[Definition 1] If a display consists of exactly one line, the +% tag should always be placed on the same baseline as the math +% expression. +% \end{description} +% The remaining comments refer to multi-line displays. +% \begin{description} +% \item[Definition 2] If a tag is to be positioned at the top (T), it +% should be placed such that the baseline of the tag aligns with the +% baseline of the top line of the display. +% +% \item[Definition 3] If a tag is to be positioned at the bottom (B), +% it should be placed such that the baseline of the tag aligns with +% the baseline of the bottom line of the display. +% +% \item[Definition 4] If a tag is to be positioned vertically centered +% (M), it should be placed such that the baseline of the tag is +% positioned exactly halfway between the baseline of the top line of +% the display and the baseline of the bottom line of the display. +% \end{description} +% +% Definitions 1--3 are almost axiomatic in their +% simplicity. Definition~4 is different because I saw at least two +% possibilities for which area to span: +% \begin{itemize} +% \item Calculate distance from top of top line to the bottom of the +% bottom line, position the vertical center of the tag exactly +% halfway between those two extremes. +% +% \item Calculate the distance from the baseline of the top line to +% the baseline of the bottom line, position the baseline of the tag +% exactly halfway between these two extremes. +% \end{itemize} +% Additional combinations of these methods are possible but make +% little sense in my opinion. I have two reasons for choosing the +% latter of these possibilities: Firstly, two expressions looking +% completely identical with the exception of a superscript in the +% first line or a subscript in the last line will have the tag +% positioned identically. Secondly, then M means halfway between T and +% B positions which makes good sense and then also automatically +% fulfills Definition~1. +% +% From an implementation perspective, these definitions should also +% make it possible to fix a deficiency in the current implementation, +% namely that the tag does not influence the height of a display, even +% if the display is a single line. This means that two single-line +% expressions in a \env{dgroup} can be closer together than +% \cs{intereqskip} if the math expressions are (vertically) smaller +% than the tag. +% +% \section{Centered Right-Number Equations} +% +% \begin{macro}{\eq@dump@box} +% \arg1 might be \cs{unhbox} or \cs{unhcopy}; \arg2 is +% the box name. +% \begin{macrocode} +\def\eq@dump@box#1#2{% +%\debug@box#1% + \noindent #1#2\setbox\f@ur\lastbox \setbox\tw@\lastbox +% \end{macrocode} +% If the LHS contains shrinkable glue, in an L layout the alignment +% could be thrown off if the first line is shrunk noticeably. +% For the time being, disable shrinking on the left-hand side. +% The proper solution requires more work \begin{dn} +% mjd,1999/03/17 +% \end{dn} +% . +% \begin{macrocode} + \if L\eq@layout \box\tw@ \else\unhbox\tw@\fi + \adjust@rel@penalty \unhbox\f@ur +} +% \end{macrocode} +% \end{macro} +% +% Various typesetting bits, invoked from \cs{eq@finish} +% BRM: This has been extensively refactored from the original breqn, +% initially to get left\textbar right skips and parshape used consistently, +% ultimately to get most things handled the same way, in the same order. +% +% Given that left and right skips have been set, +% typeset the frame, number and equation with the +% given number side and placement +% +% \begin{macrocode} +\def\eq@typeset@Unnumbered{% + \eq@typeset@frame + \eq@typeset@equation +} +\def\eq@typeset@LM{% + \setlength\dim@a{(\eq@vspan+\ht\EQ@numbox-\dp\EQ@numbox)/2}% + \eq@typeset@leftnumber + \eq@typeset@frame + \eq@typeset@equation +} +% \end{macrocode} +% Typeset equation and left-top number (and shifted) +% \begin{macrocode} +\def\eq@typeset@LT{% + \dim@a\eq@firstht + \eq@typeset@leftnumber + \eq@typeset@frame + \eq@typeset@equation +} +% \end{macrocode} +% Typeset equation and left shifted number +% \begin{macrocode} +\def\eq@typeset@LShifted{% + % place number + \copy\EQ@numbox \penalty\@M + \dim@a\eqlineskip + \if F\eq@frame\else + \setlength\dim@a{\eq@framesep+\eq@framewd}% + \fi + \kern\dim@a + \eq@typeset@frame + \eq@typeset@equation +} +% \end{macrocode} +% Typeset equation and right middle number +% \begin{macrocode} +\def\eq@typeset@RM{% + \setlength\dim@a{(\eq@vspan+\ht\EQ@numbox-\dp\EQ@numbox)/2}% + \eq@typeset@rightnumber + \eq@typeset@frame + \eq@typeset@equation +} +% \end{macrocode} +% Typeset equation and right bottom number +% \begin{macrocode} +\def\eq@typeset@RB{% + % NOTE: is \eq@dp useful here + \setlength\dim@a{\eq@vspan-\ht\EQ@numbox-\dp\EQ@numbox}% + \eq@typeset@rightnumber + \eq@typeset@frame + \eq@typeset@equation +} +% \end{macrocode} +% Typeset equation and right shifted number +% \begin{macrocode} +\def\eq@typeset@RShifted{% + % place number + \eq@typeset@frame + \eq@typeset@equation + \penalty\@M + \dim@a\eqlineskip + \if F\eq@frame\else + \addtolength\dim@a{\eq@framesep+\eq@framewd}% + \fi + \parskip\dim@a + \hbox to\hsize{\hfil\copy\EQ@numbox}\@@par% +} +% \end{macrocode} +% +% Debugging aid to show all relevant formatting info for a given eqn. +% \begin{macrocode} +%<*trace> +\def\debug@showformat{% + \breqn@debugmsg{Formatting Layout:\eq@layout\space Center/indent: \eqindent\space + Number placement \eqnumside\eqnumplace: + \MessageBreak==== \eq@linewidth=\the\eq@linewidth, \@totalleftmargin=\the\@totalleftmargin, + \MessageBreak==== Centered Lines=\theb@@le\eq@centerlines, Shift Number=\theb@@le\eq@shiftnumber, + \MessageBreak==== \eq@wdT=\the\eq@wdT, \eq@wdMin=\the\eq@wdMin, + \MessageBreak==== LHS=\theb@@le\EQ@hasLHS: \eq@wdL=\the\eq@wdL, + \MessageBreak==== \eq@firstht=\the\eq@firstht, \eq@vspan=\the\eq@vspan + \MessageBreak==== \eq@wdNum=\the\eq@wdNum + \MessageBreak==== \eq@wdCond=\the\eq@wdCond, \conditionsep=\the\conditionsep, + \MessageBreak==== \leftskip=\the\leftskip, \rightskip=\the\rightskip, + \MessageBreak==== \abovedisplayskip=\the\abovedisplayskip, + \MessageBreak==== \belowdisplayskip=\the\belowdisplayskip + \MessageBreak==== parshape=\eq@parshape}% +} +%</trace> +% \end{macrocode} +% +% Set left \& right skips for centered equations, +% making allowances for numbers (if any, right, left) and constraint. +% +% Amazingly, I've managed to collect all the positioning logic for +% centered equations in one place, so it's more manageable. +% Unfortunately, by the time it does all it needs to do, +% it has evolved I'm (re)using so many temp variables, it's becoming +% unmanageble! +% +% \begin{macrocode} +\def\eq@C@setsides{% + % \dim@c = space for number, if any, and not shifted. + \dim@c\z@ + \if\eq@hasNumber\if\eq@shiftnumber\else + \dim@c\eq@wdNum + \fi\fi + % \dim@e = space for condition(on right), if any and formula is only a single line.(to center nicely) + % but only count it as being right-aligned if we're not framing, since the frame must enclose it. + \dim@e\z@ + \if F\eq@frame + \ifnum\eq@lines=\@ne\ifdim\eq@wdCond>\z@ + \setlength\dim@e{\eq@wdCond+\conditionsep}% + \fi\fi\fi + % \dim@b = minimum needed on left max(totalleftmargin, left number space) + \dim@b\z@ + \if L\eqnumside\ifdim\dim@b<\dim@c + \dim@b\dim@c + \fi\fi + \ifdim\dim@b<\@totalleftmargin + \dim@b\z@ + \else + \addtolength\dim@b{-\@totalleftmargin}% + \fi + % \dim@d = minimum needed on right max(condition, right number space) + \dim@d\dim@e + \if R\eqnumside\ifdim\dim@d<\dim@c + \dim@d\dim@c + \fi\fi + % \dim@a = left margin; initially half available space + % \dim@c = right margin; ditto + \setlength\dim@a{(\eq@linewidth-\eq@wdT+\dim@e+\@totalleftmargin)/2}% + \dim@c=\dim@a + % If too far to the left + \ifdim\dim@a<\dim@b + \addtolength\dim@c{\dim@a-\dim@b}% + \ifdim\dim@c<\z@\dim@c=\z@\fi + \dim@a=\dim@b + % Or if too far to the right + \else\ifdim\dim@c<\dim@d + \addtolength\dim@a{\dim@c-\dim@d}% + \ifdim\dim@a<\z@\dim@a=\z@\fi + \dim@c=\dim@d + \fi\fi + % Now, \dim@d,\dim@e is the left & right glue to center each line for centerlines + \setlength\dim@e{\eq@wdT-\eq@wdMin}\dim@d=\z@ +% \end{macrocode} +% NOTE: Need some work here centering when there's a condition +% \begin{macrocode} +% \advance\dim@e-\eq@wdT\multiply\dim@e-1\relax +% \if\eq@wdMin<\dim@e\dim@e\eq@wdMin\fi +% \multiply\dim@e-1\relax\advance\dim@e\eq@wdT + \dim@d\z@ + \if\eq@centerlines + \divide\dim@e2\relax + \dim@d=\dim@e + \fi + \setlength\leftskip{\dim@a\@plus\dim@d}% + \addtolength\dim@e{\dim@c}% + \setlength\rightskip{\z@\@plus\dim@e}%\@minus5\p@ + % Special case: if framing, reduce the stretchiness of the formula (eg. condition) + % Or if we have a right number, FORCE space for it + \dim@b\z@ + \if F\eq@frame\else + \dim@b\dim@c + \fi + \if\@And{\eq@hasNumber}{\@Not{\eq@shiftnumber}}% + \if R\eqnumside + \dim@c\eq@wdNum + \ifdim\dim@c>\dim@b + \dim@b\dim@c + \fi + \fi + \fi + % If either of those cases requires hard rightskip, move that part from glue. + \ifdim\dim@b>\z@ + \addtolength\dim@e{-\dim@c}% + \rightskip\dim@b\@plus\dim@e%\@minus5\p@ + \fi + % And peculiar further special case: in indented environs, width isn't where it would seem + \ifdim\eq@wdCond>\z@ + \addtolength\rightskip{-\@totalleftmargin}% + \fi + \parfillskip\z@skip +} +% \end{macrocode} +% +% Set the left and right side spacing for indented equations +% Some things handled by eq@C@setsides that probably apply here???? +% \begin{itemize} +% \item centerlines +% \item \cs{@totalleftmargin}: SHOULD we move farther right? +% \end{itemize} +% Leftskip is normally just the requested indentation +% \begin{macrocode} +\def\eq@I@setsides{% + \leftskip\mathindent +% \end{macrocode} +% But move left, if shifted number presumably because of clashed w/ number? +% \begin{macrocode} + \if\eq@shiftnumber + \setlength\dim@a{\eq@linewidth-\eq@wdT-\mathindent}% + \ifdim\dim@a<\z@ + \leftskip=\z@ % Or something minimal? + \fi + \fi +% \end{macrocode} +% Push gently from right. +% \begin{macrocode} + \dim@a=\z@ + \setlength\dim@b{\eq@linewidth-\leftskip-\eq@wdMin}% +% \end{macrocode} +% Special case: if framing be much more rigid(?) +% \begin{macrocode} + \if F\eq@frame + \else + \setlength\dim@a{\eq@linewidth-\leftskip-\eq@wdT} + \addtolength\dim@b{-\dim@a}% + \fi + % Or force the space for right number, if needed +% \begin{macrocode} + \if\@And{\eq@hasNumber}{\@Not{\eq@shiftnumber}}% + \if R\eqnumside + \dim@c=\eq@wdNum + \if\dim@c>\dim@a + \addtolength\dim@b{-\dim@c}% + \dim@a=\dim@c + \fi + \fi + \fi + \setlength\rightskip{\dim@a\@plus\dim@b \@minus\hfuzz }%\hfuzz\z@ + \parfillskip\z@skip +} +% \end{macrocode} +% \paragraph{Typesetting pieces: frame, equation and number (if any)} +% \cs{dim@a} should contain the downward displacement of number's baseline +% \begin{macrocode} +\def\eq@typeset@leftnumber{% + \setlength\skip@c{\dim@a-\ht\EQ@numbox}% + \vglue\skip@c% NON discardable + \copy\EQ@numbox \penalty\@M + \kern-\dim@a +} +\def\eq@typeset@rightnumber{% + \setlength\skip@c{\dim@a-\ht\EQ@numbox}% + \vglue\skip@c% NON discardable + \hbox to \hsize{\hfil\copy\EQ@numbox}\penalty\@M + \kern-\dim@a +} +\def\eq@typeset@equation{% + \nobreak + \eq@params\eq@parshape + \nointerlineskip\noindent + \add@grp@label + \eq@dump@box\unhbox\EQ@box\@@par +} +% \end{macrocode} +% +% \section{Framing an equation} +% \begin{macro}{\eqframe} +% The \cs{eqframe} function is called in vertical mode +% with the reference point at the top left corner of the equation, including +% any allowance for \cs{fboxsep}. Its arguments are the width +% and height of the equation body, plus fboxsep. +% \changes{v0.95}{2007/12/03}{Made \cs{eqframe} obey the key settings +% for frame and framesep.} +% \begin{macrocode} +\newcommand\eqframe[2]{% + \begingroup + \fboxrule=\eq@framewd\relax\fboxsep=\eq@framesep\relax + \framebox{\z@rule\@height#2\kern#1}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% The frame is not typeset at the correct horizontal position. Will +% fix later. +% \begin{macrocode} +\def\eq@addframe{% + \hbox to\z@{% + \setlength\dim@a{\eq@framesep+\eq@framewd}% + \kern-\dim@a + \vbox to\z@{\kern-\dim@a + \hbox{\eqframe{\eq@wdT}{\eq@vspan}}% + \vss + }% + \hss + }% +} +\def\eq@typeset@frame{% + \if F\eq@frame\else + % Tricky: put before \noindent, so it's not affected by glue in \leftskip + \nobreak\nointerlineskip + \vbox to\eq@firstht{\moveright\leftskip\hbox to\z@{\eq@addframe\hss}\vss}% + \kern-\eq@firstht + \fi +} +% \end{macrocode} +% +% \section{Delimiter handling} +% The special handling of delimiters is rather complex, but +% everything is driven by two motives: to mark line breaks inside +% delimiters as less desirable than line breaks elsewhere, and to make it +% possible to break open left-right boxes so that line breaks between +% \cs{left} and \cs{right} delimiters are not absolutely +% prohibited. To control the extent to which line breaks will be +% allowed inside delimiters, set \cs{eqbreakdepth} to the maximum +% nesting depth. Depth 0 means never break inside delimiters. +% +% Note: \cs{eqbreakdepth} is not implemented as a \latex +% counter because changes done by \cs{setcounter} \etc are always +% global. +% +% It would be natural to use grouping in the implementation +% \mdash at an open delimiter, start a group and increase mathbin +% penalties; at a close delimiter, close the group. But this gives us +% trouble in situations like the \env{array} environment, where a +% close delimiter might fall in a different cell of the \cs{halign} +% than the open delimiter. +% Ok then, here's what we want the various possibilities to +% expand to. Note that \cs{right} and \cs{biggr} are +% being unnaturally applied to a naturally open-type delimiter. +% \begin{literalcode} +% ( -> \delimiter"4... \after@open +% \left( -> +% \@@left \delimiter"4... \after@open +% \right( -> +% \@@right \delimiter"4... \after@close +% \biggl( -> +% \mathopen{\@@left \delimiter... \vrule...\@@right.} +% \after@open +% \biggr( -> +% \mathclose{\@@left \delimiter... \vrule...\@@right.} +% \after@close +% \bigg\vert -> +% \mathord{\@@left \delimiter... \vrule...\@@right.} +% \biggm\vert -> +% \mathrel{\@@left \delimiter... \vrule...\@@right.} +% \end{literalcode} +% +% First save the primitive meanings of \cs{left} and +% \cs{right}. +% \begin{macrocode} +\@saveprimitive\left\@@left +\@saveprimitive\right\@@right +% \end{macrocode} +% +% The variable \cs{lr@level} is used by the first mathrel in +% an equation to tell whether it is at top level: yes? break and measure +% the LHS, no? keep going. +% \begin{macrocode} +\newcount\lr@level +% \end{macrocode} +% +% It would be nice to have better error checking here if the +% argument is not a delimiter symbol at all. +% +% Ah, a small problem when renaming commands. In the original version, +% |\delimiter| is hijacked in order to remove the |\after@bidir| (or +% open or close) instruction following the delimiter declaration. +% \begin{macrocode} +\ExplSyntaxOn +\def\eq@left{% + \@ifnext .{\eq@nullleft}{\begingroup \let\math_delimiter:NNnNn \eq@left@a}% +} +\def\eq@right{% + \@ifnext .{\eq@nullright}{\begingroup \let \math_delimiter:NNnNn \eq@right@a}% +} +% \end{macrocode} +% The arguments are: \arg1 delim symbol, \arg2 . +% \begin{macrocode} +%\def\eq@left@a#1 #2{\endgroup\@@left\delimiter#1\space \after@open} +\def\eq@left@a#1#2#3#4#5#6{\endgroup + \@@left \math_delimiter:NNnNn #1#2{#3}#4{#5}\after@open} +\def\eq@right@a#1#2#3#4#5#6{\endgroup + \@@right \math_delimiter:NNnNn #1#2{#3}#4{#5}\after@close \ss@scan{#1#2{#3}#4{#5}}% +} +\ExplSyntaxOff +% \end{macrocode} +% The null versions. +% \begin{macrocode} +\def\eq@nullleft#1{\@@left#1\after@open} +\def\eq@nullright#1{\@@right#1\after@close} +% \end{macrocode} +% +% Here is the normal operation of \cs{biggl}, for example. +% \begin{literalcode} +% \biggl ->\mathopen \bigg +% {\mathopen} +% +% \bigg #1->{\hbox {$\left #1\vbox to14.5\p@ {}\right .\n@space $}} +% #1<-( +% \end{literalcode} +% ^^AFor paren matching: ) +% Like \cs{left}, \cs{biggl} coerces its delimiter to be of +% mathopen type even if its natural inclination is towards closing. +% +% The function \cs{delim@reset} makes delimiter characters +% work just about the same as they would in normal \latex . +% \begin{macrocode} +\def\delim@reset{% + \let\after@open\relax \let\after@close\relax + \let\left\@@left \let\right\@@right +} +% \end{macrocode} +% If the \pkg{amsmath} or \pkg{exscale} package is loaded, it +% will have defined \cs{bBigg@}; if not, the macros \cs{big} and +% variants will have hard-coded point sizes as inherited through the ages +% from \fn{plain.tex}. In this case we can kluge a little by +% setting \cs{big@size} to \cs{p@}, so that our definition of +% \cs{bBigg@} will work equally well with the different multipliers. +% \begin{macrocode} +\@ifundefined{bBigg@}{% not defined + \let\big@size\p@ + \def\big{\bBigg@{8.5}}\def\Big{\bBigg@{11.5}}% + \def\bigg{\bBigg@{14.5}}\def\Bigg{\bBigg@{17.5}}% + \def\biggg{\bBigg@{20.5}}\def\Biggg{\bBigg@{23.5}}% +}{} +\def\bBigg@#1#2{% + {\delim@reset + \left#2% + \vrule\@height#1\big@size\@width-\nulldelimiterspace + \right. + }% +} +% \end{macrocode} +% . +% \begin{macrocode} +\def\bigl#1{\mathopen\big{#1}\after@open} +\def\Bigl#1{\mathopen\Big{#1}\after@open} +\def\biggl#1{\mathopen\bigg{#1}\after@open} +\def\Biggl#1{\mathopen\Bigg{#1}\after@open} +\def\bigggl#1{\mathopen\biggg{#1}\after@open} +\def\Bigggl#1{\mathopen\Biggg{#1}\after@open} + +\def\bigr#1{\mathclose\big{#1}\after@close} +\def\Bigr#1{\mathclose\Big{#1}\after@close} +\def\biggr#1{\mathclose\bigg{#1}\after@close} +\def\Biggr#1{\mathclose\Bigg{#1}\after@close} +\def\bigggr#1{\mathclose\biggg{#1}\after@close} +\def\Bigggr#1{\mathclose\Biggg{#1}\after@close} + +%% No change needed, I think. [mjd,1998/12/04] +%%\def\bigm{\mathrel\big} +%%\def\Bigm{\mathrel\Big} +%%\def\biggm{\mathrel\bigg} +%%\def\Biggm{\mathrel\Bigg} +%%\def\bigggm{\mathrel\biggg} +%%\def\Bigggm{\mathrel\Biggg} +% \end{macrocode} +% +% +% \begin{macro}{\m@@DeL} \begin{macro}{\d@@DeL} +% \begin{macro}{\m@@DeR} \begin{macro}{\d@@DeR} +% \begin{macro}{\m@@DeB} \begin{macro}{\d@@DeB} +% Original definition of \cs{m@DeL} from +% \pkg{flexisym} is as follows. \cs{m@DeR} and +% \cs{m@DeB} are the same except for the math class number. +% \begin{literalcode} +% \def\m@DeL#1#2#3{% +% \delimiter"4\@xp\delim@a\csname sd@#1#2#3\endcsname #1#2#3 } +% \end{literalcode} +% +% Save the existing meanings of \cs{m@De[LRB]}. +% +% Define display variants of DeL, DeR, DeB +% \begin{macrocode} +\ExplSyntaxOn +\cs_set:Npn \math_dsym_DeL:Nn #1#2{\math_bsym_DeL:Nn #1{#2}\after@open} +\cs_set:Npn \math_dsym_DeR:Nn #1#2{\math_bsym_DeR:Nn #1{#2}\after@close} +\cs_set:Npn \math_dsym_DeB:Nn #1#2{\math_bsym_DeB:Nn #1{#2}\after@bidir} + +%%%%% +%%%%%\let\m@@DeL\m@DeL \let\m@@DeR\m@DeR \let\m@@DeB\m@DeB +%%%%%\def\d@@DeL#1#2#3{% +%%%%% \delimiter"4\@xp\delim@a\csname sd@#1#2#3\endcsname #1#2#3 \after@open +%%%%%} +%%%%%\def\d@@DeR#1#2#3{% +%%%%% \delimiter"5\@xp\delim@a\csname sd@#1#2#3\endcsname #1#2#3 \after@close +%%%%%} +%%%%%\def\d@@DeB#1#2#3{% +%%%%% \delimiter"0\@xp\delim@a\csname sd@#1#2#3\endcsname #1#2#3 \after@bidir +%%%%%} +% \end{macrocode} +%%BRM: These weren't defined, but apparently should be. +% Are these the right values??? +% \begin{macrocode} +%%%%%%\let\m@@DeA\m@DeA\let\d@@DeA\m@DeA% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\after@open} +% \begin{macro}{\after@close} +% \begin{macro}{\after@bidir} +% \begin{macro}{\zero@bop} +% \begin{macro}{\bop@incr} +% \cs{after@open} and \cs{after@close} are carefully +% written to avoid the use of grouping and to run as fast as possible. +% \cs{zero@bop} is the value used for \cs{prebinoppenalty} at +% delimiter level 0, while \cs{bop@incr} is added for each level of +% nesting. The standard values provide that breaks will be prohibited +% within delimiters below nesting level 2. +% \begin{macrocode} +\let\after@bidir\@empty +\mathchardef\zero@bop=888 \relax +\mathchardef\bop@incr=4444 \relax +\def\after@open{% + \global\advance\lr@level\@ne + \prebinoppenalty\bop@incr \multiply\prebinoppenalty\lr@level + \advance\prebinoppenalty\zero@bop + \ifnum\eqbreakdepth<\lr@level + \cs_set_eq:NN \math_sym_Bin:Nn \math_isym_Bin:Nn %%%%%%\let\m@Bin\m@@Bin +% \end{macrocode} +% Inside delimiters, add some fillglue before binops so that a broken off +% portion will get thrown flush right. Also shift it slightly +% further to the right to ensure that it clears the opening delimiter. +% \begin{macrocode} + \else + \eq@binoffset=\eqbinoffset + \advance\eq@binoffset\lr@level\eqdelimoffset plus1fill\relax + \def\dt@fill@cancel{\hskip\z@ minus1fill\relax}% + \fi + \penalty\@M % BRM: discourage break after an open fence? +} +\def\after@close{% + \global\advance\lr@level\m@ne + \prebinoppenalty\bop@incr \multiply\prebinoppenalty\lr@level + \advance\prebinoppenalty\zero@bop + \ifnum\eqbreakdepth<\lr@level + \else \cs_set_eq:NN \math_sym_Bin:Nn \math_dsym_Bin:Nn %%%%%%\let\m@Bin\d@@Bin + \fi +% \end{macrocode} +% When we get back to level 0, no delimiters, remove the stretch +% component of \cs{eqbinoffset}. +% \begin{macrocode} + \ifnum\lr@level<\@ne \eq@binoffset=\eqbinoffset\relax \fi +} + +\ExplSyntaxOff + +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\subsup@flag} +% \begin{macro}{\ss@scan} +% \cs{ss@scan} is called after a \cs{right} delimiter and +% looks ahead for sub and superscript tokens. +% If sub and/or superscripts are present, we adjust the line-ending +% penalty to distinguish the various cases (sub, sup, or both). +% This facilitates the later work of excising the sub/sup box and +% reattaching it with proper shifting. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Sub/Superscript measurement +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% BRM: There's possibly a problem here. +% When \cs{ss@scan} gets invoked after a \cs{left}...\cs{right} pair in the LHS +% during \cs{eq@measure}, it produces an extra box (marked with \cs{penalty} 3); +% Apparently \cs{eq@repack} expects only one for the LHS. +% The end result is \cs{eq@wdL} => 0.0pt !!! (or at least very small) +% \begin{macrocode} +\let\subsup@flag=\count@ +\def\ss@delim@a@new#1#2#3#4#5{\xdef\right@delim@code{\number"#4#5}} +% \end{macrocode} +% The argument of \cs{ss@scan} is an expanded form of a +% right-delimiter macro. +% We want to use the last three digits in the expansion +% to define \cs{right@delim@code}. +% The assignment to a temp register is just a way to scan away the +% leading digits that we don't care about. +% \begin{macrocode} +\def\ss@scan#1{% +% \end{macrocode} +% This part of the code. +% \begin{macrocode} + \begingroup + \ss@delim@a@new #1% + \endgroup + \subsup@flag\@M \afterassignment\ss@scan@a \let\@let@token=} +\def\ss@scan@a{% + \let\breqn@next\ss@scan@b + \ifx\@let@token\sb \advance\subsup@flag\@ne\else + \ifx\@let@token\@@subscript \advance\subsup@flag\@ne\else + \ifx\@let@token\@@subscript@other \advance\subsup@flag\@ne\else + \ifx\@let@token\sp \advance\subsup@flag\tw@\else + \ifx\@let@token\@@superscript \advance\subsup@flag\tw@\else + \ifx\@let@token\@@superscript@other \advance\subsup@flag\tw@\else + \ss@finish + \let\breqn@next\relax + \fi\fi\fi\fi\fi\fi + \breqn@next\@let@token +} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +\def\ss@scan@b#1#2{#1{% +% \end{macrocode} +% hack! coff! +% \begin{macrocode} + %%%%%\let\m@Bin\m@@Bin \let\m@Rel\m@@Rel + \cs_set_eq:NN \math_sym_Bin:Nn \math_isym_Bin:Nn + \cs_set_eq:NN \math_sym_Rel:Nn \math_isym_Rel:Nn + #2}\afterassignment\ss@scan@a \let\@let@token=}% +\ExplSyntaxOff +% \end{macrocode} +% We need to keep following glue from disappearing +% \mdash \eg , a thickmuskip or medmuskip from a following mathrel or +% mathbin symbol. +% \begin{macrocode} +\def\ss@finish{% + \@@vadjust{\penalty\thr@@}% + \penalty\right@delim@code \penalty-\subsup@flag \keep@glue +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\eq@lrunpack} +% For \cs{eq@lrunpack} we need to break open a left-right box and +% reset it just in case it contains any more special breaks. After +% it is unpacked the recursion of \cs{eq@repack} will continue, +% acting on the newly created lines. +% \begin{macrocode} +\def\eq@lrunpack{\setbox\z@\lastbox +% \end{macrocode} +% We remove the preceding glue item and deactivate +% baselineskip for the next line, otherwise we would end up with +% three items of glue (counting parskip) at this point instead of +% the single one expected by our recursive repacking +% procedure. +% \begin{macrocode} + \unskip \nointerlineskip +% \end{macrocode} +% Then we open box 0, take the left-right box at the right end of +% it, and break that open. If the line-ending penalty is greater than +% 10000, it means a sub and/or superscript is present on the right +% delimiter and the box containing them must be taken off first. +% \begin{macrocode} + \noindent\unhbox\z@ \unskip + \subsup@flag-\lastpenalty \unpenalty + \xdef\right@delim@code{\number\lastpenalty}% + \unpenalty + \ifnum\subsup@flag>\@M + \advance\subsup@flag-\@M + \setbox\tw@\lastbox + \else \setbox\tw@\box\voidb@x + \fi + \setbox\z@\lastbox + \ifvoid\tw@ \unhbox\z@ + \else \lrss@reattach % uses \subsup@flag, box\z@, box\tw@ + \fi +% \end{macrocode} +% The reason for adding a null last line here is that the last +% line will contain parfillskip in addition to rightskip, and a final +% penalty of $10000$ instead of $-1000N$ +% ($1\leq N\leq 9$), which would interfere with the usual +% processing. Setting a null last line and discarding it dodges +% this complication. The penalty value $-10001$ is a no-op case +% in the case statement of \cs{eq@repacka}. +% \begin{macrocode} + \penalty-\@Mi\z@rule\@@par + \setbox\z@\lastbox \unskip\unpenalty +%%{\showboxbreadth\maxdimen\showboxdepth99\showlists}% +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\lrss@reattach} +% +% Well, for a small self-contained computation, carefully +% hand-allocated dimens should be safe enough. But let the +% maintainer beware! This code cannot be arbitrarily transplanted +% or shaken up without regard to grouping and interaction with other +% hand-allocated dimens. +% \begin{macrocode} +\dimendef\sub@depth=8 \dimendef\sup@base=6 +\dimendef\prelim@sub@depth=4 \dimendef\prelim@sup@base=2 +\def\sym@xheight{\fontdimen5\textfont\tw@} +\def\sup@base@one{\fontdimen13\textfont\tw@} +\def\sub@base@one{\fontdimen16\textfont\tw@} +\def\sub@base@two{\fontdimen17\textfont\tw@} +% \end{macrocode} +% Note that only \cs{sup@drop} and \cs{sub@drop} come from +% the next smaller math style. +% \begin{macrocode} +\def\sup@drop{\fontdimen18\scriptfont\tw@} +\def\sub@drop{\fontdimen19\scriptfont\tw@} +% \end{macrocode} +% Provide a mnemonic name for the math axis fontdimen, if it's not +% already defined. +% \begin{macrocode} +\providecommand{\mathaxis}{\fontdimen22\textfont\tw@} +% \end{macrocode} +% +% Assumes box 2 contains the sub/sup and box 0 contains the left-right +% box. This is just a repeat of the algorithm in \fn{tex.web}, +% with some modest simplifications from knowing that this is only going to +% be called at top level in a displayed equation, thus always mathstyle = +% uncramped displaystyle. +% \begin{macrocode} +\def\lrss@reattach{% + \begingroup + % "The TeXbook" Appendix G step 18: + \setlength\prelim@sup@base{\ht\z@-\sup@drop}% + \setlength\prelim@sub@depth{\dp\z@ +\sub@drop}% + \unhbox\z@ + \ifcase\subsup@flag % case 0: this can't happen + \or \lr@subscript % case 1: subscript only + \or \lr@superscript % case 2: superscript only + \else \lr@subsup % case 3: sub and superscript both + \fi + \endgroup +} +% \end{macrocode} +% \begin{macrocode} +\def\lr@subscript{% + \sub@depth\sub@base@one + \ifdim\prelim@sub@depth>\sub@depth \sub@depth\prelim@sub@depth\fi + \setlength\dim@a{\ht\tw@ -.8\sym@xheight}% + \ifdim\dim@a>\sub@depth \sub@depth=\dim@a \fi + \twang@adjust\sub@depth + \lower\sub@depth\box\tw@ +} +% \end{macrocode} +% +% \begin{macrocode} +\def\lr@superscript{% + \sup@base\sup@base@one + \ifdim\prelim@sup@base>\sup@base \sup@base\prelim@sup@base\fi + \setlength\dim@a{\dp\tw@ -.25\sym@xheight}% + \ifdim\dim@a>\sup@base \sup@base\dim@a \fi + \twang@adjust\sup@base + \raise\sup@base\box\tw@ +} +% \end{macrocode} +% +% \begin{macrocode} +\def\lr@subsup{% + \sub@depth\sub@base@two + \ifdim\prelim@sub@depth>\sub@depth \sub@depth\prelim@sub@depth \fi + \twang@adjust\sub@depth + \lower\sub@depth\box\tw@ +} +% \end{macrocode} +% +% For delimiters that curve top and bottom, the twang factor allows +% horizontal shifting of the sub and superscripts so they don't +% fall too far away (or too close for that matter). This is +% accomplished by arranging for (\eg ) \verb"\right\rangle" to leave +% a penalty $N$ in the math list before the subsup penalty that triggers +% \cs{lrss@reattach}, where $N$ is the mathcode of +% \cs{rangle} (ignoring \dquoted{small} variant). +% \begin{macrocode} +\def\twang@adjust#1{% + \begingroup + \@ifundefined{twang@\right@delim@code}{}{% + \setlength\dim@d{#1-\mathaxis}% + % put an upper limit on the adjustment + \ifdim\dim@d>1em \dim@d 1em \fi + \kern\csname twang@\right@delim@code\endcsname\dim@d + }% + \endgroup +} +% \end{macrocode} +% The method used to apply a \dquoted{twang} adjustment is just an +% approximate solution to a complicated problem. +% We make the following assumptions that hold true, approximately, +% for the most common kinds of delimiters: +% \begin{enumerate} +% \item +% The right delimiter is symmetrical top to bottom. +% +% +% \item There is an upper limit on the size of the adjustment. +% +% +% \item When we have a superscript, the amount of left-skew that we +% want to apply is linearly proportional to the distance of the bottom +% left corner of the superscript from the math axis, with the ratio +% depending on the shape of the delimiter symbol. +% +% +% \end{enumerate} +% . +% By symmetry, Assumption 3 is true also for subscripts (upper left +% corner). +% Assumption 2 is more obviously true for parens and braces, where the +% largest super-extended versions consist of truly vertical parts with +% slight bending on the ends, than it is for a \cs{rangle}. +% But suppose for the sake of expediency that it is +% approximately true for rangle symbols also. +% +% +% Here are some passable twang factors for the most common types of +% delimiters in \fn{cmex10}, as determined by rough measurements from +% magnified printouts. +% \begin{literalcode} +% vert bar, double vert: 0 +% square bracket: -.1 +% curly brace: -.25 +% parenthesis: -.33 +% rangle: -.4 +% \end{literalcode} +% Let's provide a non-private command for changing the twang factor of +% a given symbol. +% \begin{macrocode} +\newcommand{\DeclareTwang}[2]{% + \ifcat.\@nx#1\begingroup + \lccode`\~=`#1\lowercase{\endgroup \DeclareTwang{~}}{#2}% + \else + \@xp\decl@twang#1?\@nil{#2}% + \fi +} +% \end{macrocode} +% Note that this is dependent on a fixed interpretation of the +% mathgroup number \arg4 . +% \begin{macrocode} +\def\decl@twang#1#2#3#4#5#6#7\@nil#8{% + \@namedef{twang@\number"#4#5#6}{#8}% +} +\DeclareTwang{\rangle}{-.4} +\DeclareTwang{)}{-.33} +\DeclareTwang{\rbrace}{-.25} +% \end{macrocode} +% \end{macro} +% +% +% +% \section{Series of expressions} +% The \env{dseries} environment is for a display +% containing a series of expressions of the form \quoted{A, B} or \quoted{A and +% B} or \quoted{A, B, and C} and so on. Typically the expressions +% are separated by a double quad of space. If the expressions in a +% series don't all fit in a single line, they are continued onto extra +% lines in a ragged-center format. +% \begin{macrocode} +\newenvironment{dseries}{\let\eq@hasNumber\@True \@optarg\@dseries{}}{}% +\def\enddseries#1{\check@punct@or@qed}% +% \end{macrocode} +% +% And the unnumbered version of same. +% \begin{macrocode} +\newenvironment{dseries*}{\let\eq@hasNumber\@False \@optarg\@dseries{}}{}% +\@namedef{enddseries*}#1{\check@punct@or@qed}% +\@namedef{end@dseries*}{\end@dseries}% +\def\@dseries[#1]{% +% \end{macrocode} +% Turn off the special breaking behavior of mathrels \etc for math +% formulas embedded in a \env{dseries} environment. +% +%BRM: DS Expermient: Use alternative display setup. +% \begin{macrocode} +% \def\display@setup{\displaystyle}% + \let\display@setup\dseries@display@setup + % Question: should this be the default for dseries??? +% \let\eq@centerlines\@True + \global\eq@wdCond\z@ +% \end{macrocode} +% BRM: use special layout for dseries +% \begin{macrocode} +% \@dmath[#1]% + \@dmath[layout={M},#1]% + \mathsurround\z@\@@math \penalty\@Mi + \let\endmath\ends@math + \def\premath{% +% \end{macrocode} +% BRM: Tricky to cleanup space OR add space ONLY BETWEEN math! +% \begin{macrocode} + \ifdim\lastskip<.3em \unskip + \else\ifnum\lastpenalty<\@M \dquad\fi\fi +}% +% \end{macrocode} +%BRM: Tricky; if a subformula breaks, we'd like to start the next on new line! +% \begin{macrocode} + \def\postmath{\unpenalty\eq@addpunct \penalty\intermath@penalty \dquad \@ignoretrue}% +\ignorespaces +} +\def\end@dseries{% + \unskip\unpenalty + \@@endmath \mathsurround\z@ \end@dmath +} +% \end{macrocode} +% BRM: Try this layout for dseries: Essentially layout i, but w/o +% limit to 1 line. And no fallback! +% \begin{macrocode} +\def\eq@try@layout@M{% + \edef\@parshape{\parshape 1 0pt \the\eq@linewidth\relax}% + \eq@trial@b{M}{}% +} +% \end{macrocode} +% BRM: Tricky to get right value here. +% Prefer breaks between formula if we've got to break at all. +% \begin{macrocode} +%\def\intermath@penalty{-201}% +\def\intermath@penalty{-221}% +% \end{macrocode} +% BRM: A bit tighter than it was ( 1em minus.25em ) +% \begin{macrocode} +%\newcommand\dquad{\hskip0.4em} +\newcommand\dquad{\hskip0.6em minus.3em} +\newcommand\premath{}\newcommand\postmath{} +% \end{macrocode} +% +% Change the \env{math} environment to add +% \cs{premath} and \cs{postmath}. They are no-ops except +% inside a \env{dseries} environment. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Redefinition of math environment to take advantage of dseries env. +% \begin{macrocode} +\renewenvironment{math}{% + \leavevmode \premath + \ifmmode\@badmath\else\@@math\fi +}{% + \ifmmode\@@endmath\else\@badmath\fi +} +\def\ends@math#1{\check@punct@or@qed} +\def\end@math{% + \ifmmode\@@endmath\else\@badmath\fi + \postmath +} +% \end{macrocode} +% +% +% +% +% \section{Equation groups} +% For many equation groups the strategy is easy: just center each +% equation individually following the normal rules for a single +% equation. In some groups, each equation gets its own number; in +% others, a single number applies to the whole group (and may need to be +% vertically centered on the height of the group). In still other +% groups, the equations share a parent number but get individual equation +% numbers consisting of parent number plus a letter. +% +% If the main relation symbols in a group of equations are to be +% aligned, then the final alignment computations cannot be done until the +% end of the group \mdash \ie , the horizontal positioning of the first +% $n - 1$ equations cannot be done immediately. Yet because of +% the automatic line breaking, we cannot calculate an initial value of +% RHS-max over the whole group unless we do a trial run on each equation +% first to find an RHS-max for that equation. Once we know RHS-group-max +% and LHS-group-max we must redo the trial set of each equation because +% they may affect the line breaks. If the second trial for an +% equation fails (one of its lines exceeds the available width), but +% the first one succeeded, fall back to the first trial, \ie let that +% equation fall out of alignment with the rest of the group. +% +% +% All right then, here is the general idea of the whole algorithm for +% group alignment. +% To start with, ignore the possibility of equation numbers so that +% our equation group has the form: +% \begin{literalcode} +% LHS[1] RHS[1,1] RHS[1,2] ... RHS[1,n[1]] +% LHS[2] RHS[2,1] RHS[2,2] ... RHS[2,n[2]] +% ... +% LHS[3] RHS[3,1] RHS[3,2] ... RHS[3,n[3]] +% \end{literalcode} +% The number of RHS's might not be the same for all of the +% equations. +% First, accumulate all of the equation contents in a queue, checking +% along the way to find the maximum width of all the LHS's and the maximum +% width of all the RHS's. +% Call these widths maxwd\_L and maxwd\_R. +% Clearly if maxwd\_L + maxwd\_R is less than or equal to the available +% equation width then aligning all of the equations is going to be simple. +% +% +% Otherwise we are going to have to break at least one of the RHS's +% and/or at least one of the LHS's. +% The first thing to try is using maxwd\_L for the LHS's and breaking +% all the RHS's as needed to fit in the remaining space. +% However, this might be a really dumb strategy if one or more of the +% LHS's is extraordinarily wide. +% So before trying that we check whether maxwd\_L exceeds some +% threshold width beyond which it would be unsensible not to break the LHS. +% Such as, max(one-third of the available width; six ems), or +% something like that. +% Or how about this? +% Compare the average LHS width and RHS width and divide up the available +% width in the same ratio for line breaking purposes. +% +% +% BRM: Fairly broad changes; it mostly didn't work before (for me). +% +% \begin{description} +% \item[\cs{begin}\csarg{dgroup} produces a `numbered' group] +% The number is the next equation number. +% There are 2 cases: +% \begin{itemize} +% \item If ANY contained equations are numbered (|\begin{dmath}|), +% then they will be subnumbered: eg 1.1a +% and the group number is not otherwise displayed. +% \item If ALL contained equations are unnumbered (|\begin{dmath*}|) +% then the group, as a whole, gets a number displayed, +% using the same number placement as for equations. +% \end{itemize} +% \item[\cs{begin}\csarg{dgroup*} produces an unnumbered group.] +% Contained equations are numbered, or not, as normal. +% But note that in the mixed case, it's too late to +% force the unnumbered eqns to \cs{retry@with@number} +% We'll just do a simple check of dimensions, after the fact, +% and force a shiftnumber if we're stuck. +% +% NOTE: Does this work for dseries, as well? (alignment?) +% +% NOTE: Does \cs{label} attach to the expected thing? +% +% \item[For number placement] We use shiftnumber placement on ALL equations +% if ANY equations need it, or if an unnumbered equation is too +% wide to be aligned, given that the group or other eqns are numbered. +% [does this latter case interract with the chosen alignment?] +% +% \item[For Alignment] +% As currently coded, it tries to align on relations, by default. +% If LHS's are not all present, or too long, it switches to left-justify. +% Maybe there are other cases that should switch? +% Should there be a case for centered? +% +% NOTE: Should there be some options to choose alignment? +% \end{description} +% +% \begin{macro}{\eq@group} +% \begin{macro}{\GRP@top} +% +% \begin{macrocode} +\let\eq@group\@False +\let\grp@shiftnumber\@False +\let\grp@hasNumber\@False +\let\grp@eqs@numbered\@False +\let\grp@aligned\@True +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Definition of the \env{dgroup} environment. +% \begin{macrocode} +\newenvironment{dgroup}{% + \let\grp@hasNumber\@True\@optarg\@dgroup{}% +}{% + \end@dgroup +} +% \end{macrocode} +% And the. +% \begin{macrocode} +\newtoks\GRP@queue +\newenvironment{dgroup*}{% + \let\grp@hasNumber\@False\@optarg\@dgroup{}% +}{% + \end@dgroup +} +\def\@dgroup[#1]{% +%<trace> \breqn@debugmsg{=== DGROUP ==================================================}% + \let\eq@group\@True \global\let\eq@GRP@first@dmath\@True + \global\GRP@queue\@emptytoks \global\setbox\GRP@box\box\voidb@x + \global\let\GRP@label\@empty + \global\grp@wdL\z@\global\grp@wdR\z@\global\grp@wdT\z@ + \global\grp@linewidth\z@\global\grp@wdNum\z@ + \global\let\grp@eqs@numbered\@False + \global\let\grp@aligned\@True + \global\let\grp@shiftnumber\@False + \eq@prelim + \setkeys{breqn}{#1}% + \if\grp@hasNumber \grp@setnumber \fi +} +\def\end@dgroup{% + \EQ@displayinfo \grp@finish + \if\grp@hasNumber\grp@resetnumber\fi +} +% \end{macrocode} +% If the \pkg{amsmath} package is not loaded the parentequation +% counter will not be defined. +% \begin{macrocode} +\@ifundefined{c@parentequation}{\newcounter{parentequation}}{} +% \end{macrocode} +% Init. +% \begin{macrocode} +\global\let\GRP@label\@empty +\def\add@grp@label{% + \ifx\@empty\GRP@label + \else \GRP@label \global\let\GRP@label\@empty + \fi +} +% \end{macrocode} +% Before sending down the `equation' counter to the subordinate level, +% set the current number in \cs{EQ@numbox}. The +% \cs{eq@setnumber} function does everything we need here. If +% the child equations are unnumbered, \cs{EQ@numbox} will retain the +% group number at the end of the group. +% \begin{macrocode} +\def\grp@setnumber{% + \global\let\GRP@label\next@label \global\let\next@label\@empty + % Trick \eq@setnumber to doing our work for us. + \let\eq@hasNumber\@True + \eq@setnumber +% \end{macrocode} +% Define \cn{theparentequation} equivalent to current +% \cn{theequation}. \cn{edef} is necessary to expand the +% current value of the equation counter. This might in rare cases +% cause something to blow up, in which case the user needs to add +% \cn{protect}. +% \begin{macrocode} + \global\sbox\GRP@numbox{\unhbox\EQ@numbox}% + \grp@wdNum\eq@wdNum + \let\eq@hasNumber\@False + \let\eq@number\@empty + \eq@wdNum\z@ +% + \protected@edef\theparentequation{\theequation}% + \setcounter{parentequation}{\value{equation}}% +% \end{macrocode} +% And set the equation counter to 0, so that the normal incrementing +% processes will produce the desired results if the child equations are +% numbered. +% \begin{macrocode} + \setcounter{equation}{0}% + \def\theequation{\theparentequation\alph{equation}}% +%<trace> \breqn@debugmsg{Group Number \theequation}% +} +% \end{macrocode} +% At the end of a group, need to reset the equation counter. +% \begin{macrocode} +\def\grp@resetnumber{% + \setcounter{equation}{\value{parentequation}}% +} +\newbox\GRP@box +\newbox\GRP@wholebox +% \end{macrocode} +% Save data for this equation in the group +% \begin{itemize} +% \item push the trial data onto end of \cs{GRP@queue}. +% \item push an hbox onto the front of \cs{GRP@box} containing: +% \cs{EQ@box}, \cs{EQ@copy}, \cs{penalty} 1 and \cs{EQ@numbox}. +% \end{itemize} +% \begin{macro}{\grp@push} +% +% For putting the equation on a queue. +% \begin{macrocode} +\def\grp@push{% + \global\GRP@queue\@xp\@xp\@xp{\@xp\the\@xp\GRP@queue + \@xp\@elt\@xp{\EQ@trial}% + }% + \global\setbox\GRP@box\vbox{% + \hbox{\box\EQ@box\box\EQ@copy\penalty\@ne\copy\EQ@numbox}% + \unvbox\GRP@box + }% + \EQ@trial + \if\eq@isIntertext\else + \ifdim\eq@wdL>\grp@wdL \global\grp@wdL\eq@wdL \fi + \ifdim\eq@wdT>\grp@wdT \global\grp@wdT\eq@wdT \fi + \setlength\dim@a{\eq@wdT-\eq@wdL}% + \ifdim\dim@a>\grp@wdR \global\grp@wdR\dim@a \fi + \ifdim\eq@linewidth>\grp@linewidth \global\grp@linewidth\eq@linewidth\fi + \if\eq@hasNumber + \global\let\grp@eqs@numbered\@True + \ifdim\eq@wdNum>\grp@wdNum\global\grp@wdNum\eq@wdNum\fi + \fi + \if\EQ@hasLHS\else\global\let\grp@aligned\@False\fi + \if D\eq@layout \global\let\grp@aligned\@False\fi % Layout D (usually) puts rel on 2nd line. + \if\eq@shiftnumber\global\let\grp@shiftnumber\@True\fi % One eq shifted forces all. + \fi +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\grp@finish} +% +% Set accumulated equations from a \env{dgroup} environment. +% +% BRM: Questionable patch!! +% When processing the \cs{GRP@queue}, put it into a \cs{vbox}, then \cs{unvbox} it. +% This since there's a bizarre problem when the \cs{output} routine +% gets invoked at an inopportune moment: All the not-yet-processed +% \cs{GRP@queue} ends up in the \cs{@freelist} and bad name clashes happen. +% Of course, it could be due to some other problem entirely!!! +% \begin{macrocode} +\def\grp@finish{% +% \debug@box\GRP@box +% \breqn@debugmsg{\GRP@queue: \the\GRP@queue}% +% \end{macrocode} +% == Now that we know the collective measurements, make final decision +% about alignment \& shifting. Check if alignment is still possible +% \begin{macrocode} + \setlength\dim@a{\grp@wdL+\grp@wdR-4em}% Allowance for shrink? + \if\grp@aligned + \ifdim\dim@a>\grp@linewidth + \global\let\grp@aligned\@False + \fi + \fi +% \end{macrocode} +% If we're adding an unshifted group number that equations didn't know +% about, re-check shifting +% \begin{macrocode} + \addtolength\dim@a{\grp@wdNum }% Effective length + \if\grp@shiftnumber + \else + \if\@And{\grp@hasNumber}{\@Not\grp@eqs@numbered} + \ifdim\dim@a>\grp@linewidth + \global\let\grp@shiftnumber\@True + \fi + \fi + \fi +% \end{macrocode} +% If we can still align, total width is sum of maximum LHS \& RHS +% \begin{macrocode} + \if\grp@aligned + \global\grp@wdT\grp@wdL + \global\advance\grp@wdT\grp@wdR + \fi +%<*trace> + \breqn@debugmsg{======= DGROUP Formatting + \MessageBreak==== \grp@wdL=\the\grp@wdL, \grp@wdR=\the\grp@wdR + \MessageBreak==== Shift Number=\theb@@le\grp@shiftnumber, Eqns. numbered=\theb@@le\grp@eqs@numbered + \MessageBreak==== Aligned=\theb@@le\grp@aligned + \MessageBreak==== \grp@wdNum=\the\grp@wdNum}% +%</trace> +% \end{macrocode} +% BRM: Originally this stuff was dumped directly, without capturing it +% in a \cs{vbox} +% \begin{macrocode} + \setbox\GRP@wholebox\vbox{% + \let\@elt\eqgrp@elt + \the\GRP@queue + }% +% \end{macrocode} +% If we're placing a group number (not individual eqn numbers) +% NOTE: For now, just code up LM number +% NOTE: Come back and handle other cases. +% NOTE: Vertical spacing is off, perhaps because of inter eqn. glue +% +% A bit of a hack to get the top spacing correct. Fix this logic +% properly some day. Also, we do the calculation in a group for +% maximum safety. +% \begin{macrocode} + \global\let\eq@GRP@first@dmath\@True + \begingroup + \dmath@first@leftskip + \eq@topspace{\vskip\parskip}% + \endgroup + \if\@And{\grp@hasNumber}{\@Not{\grp@eqs@numbered}}% +% \eq@topspace{\vskip\parskip}% + \if\grp@shiftnumber + \copy\GRP@numbox \penalty\@M + \kern\eqlineskip + \else + \setlength\dim@a{% + (\ht\GRP@wholebox+\dp\GRP@wholebox+\ht\GRP@numbox-\dp\GRP@numbox)/2}% + \setlength\skip@c{\dim@a-\ht\GRP@numbox}% + \vglue\skip@c% NON discardable + \copy\GRP@numbox \penalty\@M +%<*trace> +\breqn@debugmsg{GROUP NUMBER: preskip:\the\skip@c, postkern:\the\dim@a, height:\the\ht\GRP@wholebox, + \MessageBreak==== box height:\the\ht\GRP@numbox, box depth:\the\dp\GRP@numbox}% +%</trace> + \kern-\dim@a + \kern-\abovedisplayskip % To cancel the topspace above the first eqn. + \fi + \fi +%<*trace> +%\debug@box\GRP@wholebox +%</trace> + \unvbox\GRP@wholebox + \let\@elt\relax +% \end{macrocode} +% We'd need to handle shifted, right number here, too!!! +% \begin{macrocode} + \eq@botspace % not needed unless bottom number? +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\eqgrp@elt} +% +% Mission is to typeset the next equation from the group queue. +% +% The arg is an \cs{EQ@trial} +% \begin{macrocode} +\def\eqgrp@elt#1{% + \global\setbox\GRP@box\vbox{% + \unvbox\GRP@box + \setbox\z@\lastbox + \setbox\tw@\hbox{\unhbox\z@ + \ifnum\lastpenalty=\@ne + \else + \global\setbox\EQ@numbox\lastbox + \fi + \unpenalty + \global\setbox\EQ@copy\lastbox + \global\setbox\EQ@box\lastbox + }% + }% + \begingroup \let\eq@botspace\relax + #1% + \if\eq@isIntertext + \vskip\belowdisplayskip + \unvbox\EQ@copy + \else + \grp@override + \eq@finish + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% Override the \cs{eq@trial} data as needed for this equation in this group +% NOTE: w/ numbering variations (see above), we may need to tell +% \cs{eq@finish} to allocate space for a number, but not actually have one +% \begin{macrocode} +\def\grp@override{% +% \end{macrocode} +% For aligned (possibly becomes an option?) +% For now ASSUMING we started out as CLM!!! +% \begin{macrocode} + \def\eqindent{I}% +% \end{macrocode} +% compute nominal left for centering the group +% \begin{macrocode} + \setlength\dim@a{(\grp@linewidth-\grp@wdT)/2}% +% \end{macrocode} +% Make sure L+R not too wide; should already have unset alignment +% \begin{macrocode} + \ifdim\dim@a<\z@\dim@a=\z@\fi + \dim@b\if L\eqnumside\grp@wdNum\else\z@\fi +% \end{macrocode} +% make sure room for number on left, if needed. +% \begin{macrocode} + \if\grp@shiftnumber\else + \ifdim\dim@b>\dim@a\dim@a\dim@b\fi + \fi + \if\grp@aligned + \addtolength\dim@a{\grp@wdL-\eq@wdL}% + \fi + \mathindent\dim@a + \ifdim\dim@b>\dim@a + \let\eq@shiftnumber\@True + \fi +% \end{macrocode} +% Could set |\def\eqnumplace{T}| (or even (m) if indentation is enough). +% +% NOTE: Work out how this should interact with the various formats!!! +% NOTE: should recognize the case where the LHS's are a bit Wild, +% and then do simple left align (not on relation) +% \begin{macrocode} +} +% \end{macrocode} +% +% +% +% \section{The \env{darray} environment} +% There are two potential applications for darray. One +% is like eqnarray where the natural structure of the material crosses the +% table cell boundaries, and math operator spacing needs to be preserved +% across cell boundaries. And there is also the feature of +% attaching an equation number to each row. The other application +% is like a regular array but with automatic displaystyle math in each +% cell and better interline spacing to accommodate outsize cell +% contents. In this case it is difficult to keep the vert ruling +% capabilities of the standard \env{array} environment without +% redoing the implementation along the lines of Arseneau's +% \pkg{tabls} package. Because the vert ruling feature is at +% cross purposes with the feature of allowing interline stretch and page +% breaks within a multiline array of equations, the \env{darray} +% environment is targeted primarily as an alternative to +% \env{eqnarray}, and does not support vertical ruling. +% +% Overall strategy for \env{darray} is to use +% \cs{halign} for the body. In the case of a group, use a +% single halign for the whole group! +% \begin{aside} +% What about intertext? +% \end{aside} +% +% That's the most reliable way +% to get accurate column widths. Don't spread the halign to the +% column width, just use the natural width. Then, if we repack the +% contents of the halign into \cs{EQ@box} and \cs{EQ@copy}, as +% done for dmath, and twiddle a bit with the widths of the first and last +% cell in each row, we can use the same algorithms for centering and +% equation number placement as dmath! As well as handling footnotes +% and vadjust objects the same way. +% +% We can't just use \cs{arraycolsep} for \env{darray}, if +% we want to be able to change it without screwing up interior arrays. +% So let's make a new colsep variable. The initial value is +% \quoted{2em, but let it shrink if necessary}. +% \begin{macrocode} +\newskip\darraycolsep \darraycolsep 20pt plus1fil minus12pt +% \end{macrocode} +% Let's make a nice big default setup with eighteen columns, split up +% into six sets of lcr like \env{eqnarray}. +% \begin{macrocode} +\newcount\cur@row \newcount\cur@col +\def\@tempa#1#2#3{% + \cur@col#1 \hfil + \setbox\z@\hbox{$\displaystyle####\m@th$}\@nx\col@box + \tabskip\z@skip + &\cur@col#2 \hfil + \setbox\z@\hbox{$\displaystyle\mathord{}####\mathord{}\m@th$}\@nx\col@box + \hfil + &\cur@col#3 \setbox\z@\hbox{$\displaystyle####\m@th$}\@nx\col@box + \hfil\tabskip\darraycolsep +} +\xdef\darray@preamble{% + \@tempa 123&\@tempa 456&\@tempa 789% + &\@tempa{10}{11}{12}&\@tempa{13}{14}{15}&\@tempa{16}{17}{18}% + \cr +} +\@ifundefined{Mathstrut@}{\let\Mathstrut@\strut}{} +\def\darray@cr{\Mathstrut@\cr} +\def\col@box{% +%<*trace> +%\breqn@debugmsg{Col \number\cur@row,\number\cur@col: \the\wd\z@\space x \the\ht\z@+\the\dp\z@}% +%</trace> + \unhbox\z@ +} +\newenvironment{darray}{\@optarg\@darray{}}{} +\def\@darray[#1]{% +%<trace> \breqn@debugmsg{=== DARRAY ==================================================}% + \if\eq@group\else\eq@prelim\fi +% \end{macrocode} +% Init the halign preamble to empty, then unless the \quoted{cols} key is +% used to provide a non-null preamble just use the +% default darray preamble which is a multiple lcr. +% \begin{macrocode} + \global\let\@preamble\@empty + \setkeys{breqn}{#1}% + \the\eqstyle \eq@setnumber + \ifx\@preamble\@empty \global\let\@preamble\darray@preamble \fi + \check@mathfonts + % \let\check@mathfonts\relax % tempting, but too risky + \@xp\let\csname\string\ \endcsname\darray@cr + \setbox\z@\vbox\bgroup + \everycr{\noalign{\global\advance\cur@row\@ne}}% + \tabskip\z@skip \cur@col\z@ + \global\cur@row\z@ + \penalty\@ne % flag for \dar@repack + \halign\@xp\bgroup\@preamble +} +% \end{macrocode} +% Assimilate following punctuation. +% \begin{macrocode} +\def\enddarray#1{\check@punct@or@qed} +\def\end@darray{% + \ifvmode\else \eq@addpunct \Mathstrut@\fi\crcr \egroup + \dar@capture + \egroup +} +% \end{macrocode} +% +% The \cs{dar@capture} function steps back through the +% list of row boxes and grinds them up in the best possible way. +% \begin{macrocode} +\def\dar@capture{% +%% \showboxbreadth\maxdimen\showboxdepth99\showlists + \eq@wdL\z@ \eq@wdRmax\z@ + \dar@repack +} +% \end{macrocode} +% +% The \cs{dar@repack} function is a variation of +% \cs{eq@repack}. +% \begin{macrocode} +\def\dar@repack{% + \unpenalty + \setbox\tw@\lastbox +%\batchmode{\showboxbreadth\maxdimen\showboxdepth99\showbox\tw@}\errorstopmode + \global\setbox\EQ@box\hbox{% + \hbox{\unhcopy\tw@\unskip}\penalty-\@M \unhbox\EQ@box}% + \global\setbox\EQ@copy\hbox{% + \hbox{\unhbox\tw@\unskip}\penalty-\@M \unhbox\EQ@copy}% + \unskip + \ifcase\lastpenalty \else\@xp\@gobble\fi + \dar@repack +} +% \end{macrocode} +% +% +% +% +% \section{Miscellaneous} +% The \cs{condition} command. With +% the star form, set the argument in math mode instead of text mode. +% In a series of conditions, use less space between members of the +% series than between the conditions and the main equation body. +% +% WSPR: tidied/fixed things up as it made sense to me but might have +% broken something else! +% \begin{macrocode} +\newskip\conditionsep \conditionsep=10pt minus5pt% +\newcommand{\conditionpunct}{,} +% \end{macrocode} +% \begin{macro}{\condition} +% \begin{macrocode} +\newcommand\condition{% + \begingroup\@tempswatrue + \@ifstar{\@tempswafalse \condition@a}{\condition@a}} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\condition@a} +% \begin{macrocode} +\newcommand\condition@a[2][\conditionpunct]{% + \unpenalty\unskip\unpenalty\unskip % BRM Added + \hbox{#1}% + \penalty -201\relax\hbox{}% Penalty to allow breaks here. + \hskip\conditionsep + \setbox\z@\if@tempswa\hbox{#2}\else\hbox{$\textmath@setup #2$}\fi +% \end{macrocode} +% BRM's layout is achieved with this line commented out but it has the nasty side-effect of shifting the equation number to the next line: +% \begin{macrocode} +% \global\eq@wdCond\wd\z@ + \usebox\z@ + \endgroup} +% \end{macrocode} +% \end{macro} +% +% The \env{dsuspend} environment. First the old one that didn't work. +% \begin{macrocode} +\newenvironment{XXXXdsuspend}{% + \global\setbox\EQ@box\vbox\bgroup \@parboxrestore +% \end{macrocode} +% If we are inside a list environment, \cs{displayindent} and +% \cs{displaywidth} give us \cs{@totalleftmargin} and +% \cs{linewidth}. +% \begin{macrocode} + \parshape 1 \displayindent \displaywidth\relax + \hsize=\columnwidth \noindent\ignorespaces +}{% + \par\egroup +% \end{macrocode} +% Let's try giving \cs{EQ@box} the correct height for the first +% line and \cs{EQ@copy} the depth of the last line. +% \begin{macrocode} + \global\setbox\GRP@box\vbox{% + \vbox{\copy\EQ@box\vtop{\unvbox\EQ@box}}% + \unvbox\GRP@box + }% +% \end{macrocode} +% Need to add a dummy element to \cs{GRP@queue}. +% \begin{macrocode} + \global\GRP@queue\@xp{\the\GRP@queue + \@elt{\gdef\EQ@trial{}}% + }% +} +% \end{macrocode} +% And then the one that does work. +% \begin{macrocode} +\newenvironment{dsuspend}{% + \global\setbox\EQ@box\vbox\bgroup \@parboxrestore + \parshape 1 \displayindent \displaywidth\relax + \hsize=\columnwidth \noindent\ignorespaces +}{% + \par\egroup + \global\setbox\GRP@box\vbox{% + \hbox{\copy\EQ@box\vtop{\unvbox\EQ@box}}% + \unvbox\GRP@box + }% + \global\GRP@queue\@xp{\the\GRP@queue +% \@elt{\gdef\EQ@trial{\let\eq@isIntertext\@True}}% + \@elt{\let\eq@isIntertext\@True}% + }% +} +% \end{macrocode} +% Allow \cn{intertext} as a short form of the \env{dsuspend} +% environment; it's more convenient to write, but it doesn't support +% embedded verbatim because it reads the material as a macro argument. +% To support simultaneous use of \pkg{amsmath} and +% \pkg{breqn}, the user command \cs{intertext} is left alone +% until we enter a \pkg{breqn} environment. +% \begin{macrocode} +\newcommand\breqn@intertext[1]{\dsuspend#1\enddsuspend} +% \end{macrocode} +% +% +% \begin{macro}{\*} +% \begin{macro}{\discretionarytimes} +% Discretionary times sign. Standard \latex definition +% serves only for inline math. Should the thin space be +% included? Not sure. +% \begin{macrocode} +\renewcommand{\*}{% + \if@display +% \end{macrocode} +% Since \cs{eq@binoffset} is mu-glue, we can't use it directly +% with \cs{kern} but have to measure it separately in a box. +% \begin{macrocode} + \setbox\z@\hbox{\mathsurround\z@$\mkern\eq@binoffset$}% + \discretionary{}{% + \kern\the\wd\z@ \textchar\discretionarytimes + }{}% + \thinspace + \else + \discretionary{\thinspace\textchar\discretionarytimes}{}{}% + \fi +} +% \end{macrocode} +% This is only the symbol; it can be changed to some other symbol if +% desired. +% \begin{macrocode} +\newcommand{\discretionarytimes}{\times} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\nref} +% +% This is like \cs{ref} but doesn't apply font changes or other +% guff if the reference is undefined. +% And it is fully expandable for use as a label value. +% \begin{aside} +% +% Can break with Babel if author uses active characters in label key; +% need to address that \begin{dn} +% mjd,1999/01/21 +% \end{dn} +% . +% \end{aside} +% +% \begin{macrocode} +\def\nref#1{\@xp\@nref\csname r@#1\endcsname} +\def\@nref#1#2{\ifx\relax#1??\else \@xp\@firstoftwo#1\fi} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \section{Wrap-up} +% The usual endinput. +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% +% +% \section{To do} +% \begin{enumerate} +% \item Alignment for equation groups. +% +% +% \item +% Use dpc's code for package options in keyval form. +% +% \item +% Encapsulate \dquoted{break math} into a subroutine taking suitable +% arguments. +% +% \item +% Need a density check for layout S when linewidth is very small. +% +% \item +% Make \verb":=" trigger a warning about using \cs{coloneq} +% instead. +% +% \item Ill-centered multiline equation (three-line case) in +% test008. +% +% \item Attaching a single group number. +% +% +% \item +% Make sure to dump out box registers after done using them. +% +% \item Do the implementation for \cs{eq@resume@parshape}. +% +% +% \item Check on stackrel and buildrel and relbar and ???. +% +% +% \item Test math symbols at the beginning of array cells. +% +% \item Test \dbslash cmd in and out of delims. +% +% \item Framing the equation body: the parshape and number placement +% need adjusting when a frame is present. +% +% +% \item Cascading line widths in list env. +% +% +% \item Noalign option for dmath = multline arrangement? +% +% +% \item Nocompact option, suggested 1998/05/19 by Andrew +% Swann. +% +% +% \item \cs{delbreak} cmd to add discretionary space at a break +% within delimiters. +% +% +% \item Reduce above/below skip when the number is shifted. +% +% +% \item Need a \cs{middelim} command for marking a delimiter symbol +% as nondirectional if it has an innate directionality \verb"()[]" \etc . +% +% +% \item +% \cs{xrightarrow} from amsmath won't participate in line +% breaking unless something extra is done. +% Make \cs{BreakingRel} and \cs{BreakingBin} functions? +% +% \item Placement of number in an indented quotation or +% abstract. +% +% \item If $LHSwd > 2em$, it might be a good idea to try with +% eq@indentstep = 2em before shifting the number. Currently this +% doesn't happen if the first trial pass (without the number) +% succeeds with $indentstep = LHSwd > 2em$. +% +% +% \item Read past \verb"\end{enumerate}" when checking +% for \verb"\end{proof}"? +% +% \item +% Look into using a \dquoted{qed-list} of environment names instead of +% checking the existence of \cs{proofqed}. +% +% \item Pick up the vadjust\slash footnote\slash mark handling. +% +% +% \item Forcing\slash prohibiting page breaks after\slash before +% an equation. +% +% +% \item Adding a spanner brace on the left and individual numbers on +% the right (indy-numbered cases). +% +% +% \item Provide \cs{shiftnumber}, \cs{holdnumber} to +% override the decision. +% +% \item Provide a mechanism for adjusting the vertical position of +% the number. Here a version-specific selection macro would be +% useful. +% \begin{literalcode} +% \begin{dmath}[ +% style={\foredition{1}{\raisenumber{13pt}}} +% ] +% \end{literalcode} +% +% +% \item +% Add an alignleft option for an equation group to mean, break and +% align to a ladder layout as usual within the equations, but for the +% group alignment used the leftmost point (for equations that don't +% have an LHS, this makes no difference). +% +% \item +% Test with Arseneau's wrapfig for parshape\slash everypar +% interaction. +% +% +% \item Fix up the macro/def elements. +% +% \item Convert the literal examples in section \quoted{Equation types and +% forms} to typeset form. +% +% +% \item Compile comparison-examples: \eg , a standard equation +% env with big left-right objects that don't shrink, versus how shrinking +% can allow it to fit. +% +% +% \item Frame the \dquoted{figures} since they are mostly +% text. +% +% \end{enumerate} +% +% +% +% Possible enhancements: +% \begin{enumerate} +% \item Provide a \opt{pull} option meaning to pull the first +% and last lines out to the margin, like the \env{multline} +% environment of the \pkg{amsmath} package. Maybe this should +% get an optional argument, actually, to specify the amount of space left +% at the margin. +% +% \item With the draft option, one would like to see the equation +% labels in the left margin. Need to check with the +% \pkg{showkeys} package. +% +% +% \item Options for break preferences: if there's not enough room, do +% we first shift the number, or first try to break up the equation +% body?. In an aligned group, does sticking to the group alignment +% take precedence over minimizing the number of line breaks needed for +% individual equations?. And the general preferences probably need +% to be overridable for individual instances. +% +% \item Extend suppress-breaks-inside-delimiters support to inline +% math (suggestion of Michael Doob). +% +% \item Use belowdisplayshortskip above a dsuspend fragment if the +% fragment is only one line and short enough compared to the equation line +% above it. +% +% +% \item Add \cs{eqfuzz} distinct from \cs{hfuzz}. +% Make use of it in the measuring phase. +% +% +% \item Provision for putting in a \quoted{continued} note. +% +% \item Conserve box mem: modify frac, sub, sup, overline, underline, +% sqrt, to turn off \cs{bin@break} and (less urgently) +% \cs{rel@break}. +% +% +% \item More explicit support for Russian typesetting conventions (cf +% Grinchuk article). +% +% +% \item With package option \opt{refnumbers}, +% leave unnumbered all uncited equations, even if they are not done with +% the star form (Bertolazzi's easyeqn idea). +% +% \item In an equation group, use a vertical bracket with the +% equation number to mark the lines contained in that equation. +% +% +% \item For a two-line multline thingamabob, try to +% make sure that the lines overlap in the middle by 2 em or whatever +% (settable design variable). +% +% \item Provide a separate vertical column for the principal mathrel +% symbols and center them within the column if they aren't all the same +% width. Maybe an option for \env{dmath}: relwidth=x, so that two +% passes are not required to get the max width of all the mathrels. +% Or, no, just require it to be an halign or provide a macro to be +% applied to all the shorter rels: +% \begin{literalcode} +% lhs \widerel{19pt}{=} ... +% \xrightarrow{foo} ... +% \end{literalcode} +% +% +% \item try to use vadjust for keepglue +% +% \end{enumerate} +% +% \PrintIndex +% +% \Finale + diff --git a/Master/texmf-dist/source/latex/breqn/flexisym.dtx b/Master/texmf-dist/source/latex/breqn/flexisym.dtx new file mode 100644 index 00000000000..45e16f3d4c6 --- /dev/null +++ b/Master/texmf-dist/source/latex/breqn/flexisym.dtx @@ -0,0 +1,1603 @@ +% \iffalse meta-comment +% +% Copyright (C) 1997-2003 by Michael J. Downes +% Copyright (C) 2007-2008 by Morten Hoegholm +% Copyright (C) 2007-2014 by Lars Madsen +% Copyright (C) 2007-2014 by Will Robertson +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 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 2005/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% This Current Maintainer of this work is Will Robertson. +% +% This work consists of the main source file flexisym.dtx +% and the derived files +% flexisym.sty, flexisym.pdf, flexisym.ins, +% cmbase.sym, mathpazo.sym, mathptmx.sym, msabm.sym. +% +% Distribution: +% CTAN:macros/latex/contrib/mh/flexisym.dtx +% CTAN:macros/latex/contrib/mh/flexisym.pdf +% +% Unpacking: +% (a) If flexisym.ins is present: +% tex flexisym.ins +% (b) Without flexisym.ins: +% tex flexisym.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{flexisym.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% Programm calls to get the documentation (example): +% pdflatex flexisym.dtx +% makeindex -s gind.ist flexisym.idx +% pdflatex flexisym.dtx +% makeindex -s gind.ist flexisym.idx +% pdflatex flexisym.dtx +% +% Installation: +% TDS:tex/latex/breqn/flexisym.sty +% TDS:tex/latex/breqn/cmbase.sym +% TDS:tex/latex/breqn/mathpazo.sym +% TDS:tex/latex/breqn/mathptmx.sym +% TDS:tex/latex/breqn/msabm.sym +% TDS:doc/latex/breqn/flexisym.pdf +% TDS:source/latex/breqn/flexisym.dtx +% +%<*ignore> +\begingroup + \def\x{LaTeX2e} +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: flexisym 2014/06/10 v0.97c Flexisym (MH)} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 1997-2003 by Michael J. Downes +Copyright (C) 2007-2010 by Morten Hoegholm +Copyright (C) 2007-2014 by Lars Madsen +Copyright (C) 2007-2014 by Will Robertson + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 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 2005/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +The Current Maintainer of this work is Will Robertson. + +This work consists of the main source file flexisym.dtx +and the derived files + flexisym.sty, flexisym.pdf, flexisym.ins, + cmbase.sym, mathpazo.sym, mathptmx.sym, msabm.sym. + +\endpreamble + +\generate{% + \file{flexisym.ins}{\from{flexisym.dtx}{install}}% + \usedir{tex/latex/breqn}% + \file{flexisym.sty}{\from{flexisym.dtx}{package}}% + \file{cmbase.sym}{\from{flexisym.dtx}{cmbase}}% + \file{mathpazo.sym}{\from{flexisym.dtx}{mathpazo}}% + \file{mathptmx.sym}{\from{flexisym.dtx}{mathptmx}}% + \file{msabm.sym}{\from{flexisym.dtx}{msabm}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by TeX:} +\Msg{*} +\Msg{* flexisym.sty, cmbase.sym, mathpazo.sym, mathptmx.sym, msabm.sym} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +%<*driver> +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{flexisym.drv}% + [2014/06/10 v0.97c flexisym (MH)] +\documentclass{ltxdoc} +\CodelineIndex +\EnableCrossrefs +\setcounter{IndexColumns}{2} +%\providecommand*\meta[1]{\ensuremath\langle\textit{#1}\ensuremath\rangle} +\providecommand*\pkg[1]{\textsf{#1}} +\providecommand*\cls[1]{\textsf{#1}} +\providecommand*\opt[1]{\texttt{#1}} +\providecommand*\env[1]{\texttt{#1}} +\providecommand*\fn[1]{\texttt{#1}} +\makeatletter +\providecommand{\AmS}{{\protect\AmSfont + A\kern-.1667em\lower.5ex\hbox{M}\kern-.125emS}} +\providecommand{\AmSfont}{% + \usefont{OMS}{cmsy}{\if\expandafter\@car\f@series\@nil bb\else m\fi}{n}} +\makeatother +\newenvironment{aside}{\begin{quote}\bfseries}{\end{quote}} +\begin{document} + \DocInput{flexisym.dtx} +\end{document} +%</driver> +% \fi +% +% \title{The \textsf{flexisym} package} +% \date{2008/08/08 v0.97a} +% \author{Author: Morten H\o gholm\\ Inactively maintained by Will Robertson\\ Feedback: \texttt{https://github.com/wspr/breqn/issues}} +% +% \maketitle +% +% \part*{User's guide} +% +% For now, the user's guide is in breqn. +% +% \StopEventually{} +% \part*{Implementation} +% +% \section{flexisym} +% +% \begin{macrocode} +%<*package> +\RequirePackage{expl3}[2009/08/05] +\ProvidesExplPackage{flexisym}{2013/03/16}{0.97c}{Make math characters macros} + +\edef\do{% + \noexpand\AtEndOfPackage{% + \catcode\number`\"=\number\catcode`\" + \relax + }% +} +\do \let\do\relax +\catcode`\"=12 +\let\@sym\@gobble +\DeclareOption{robust}{% + \def\@sym#1{% + \ifx\protect\@typeset@protect \else\protect#1\exp_after:wN\use_none:nnnn\fi + }% +} +% \end{macrocode} +% The math groups (mg) here relate to |\textfont|$n$. +% \begin{macrocode} +\def\mg@bin{2}% binary operators +\def\mg@rel{2}% relations +%%\def\mg@nre{B}% negated relations +\def\mg@del{3}% delimiters +%%\def\mg@arr{B}% arrows +\def\mg@acc{0}% accents +\def\mg@cop{3}% cumulative operators (sum, int) +\def\mg@latin{1}% (Latin) letters +\def\mg@greek{1}% (lowercase) Greek +\def\mg@Greek{0}% (capital) Greek +%%\def\mg@bflatin{4}% bold upright Latin letters ? +%%\def\mg@Bbb{B}% blackboard bold +\def\mg@cal{2}% script/calligraphic +%%\def\mg@frak{5}% Fraktur letters +\def\mg@digit{0}% decimal digits % 1 = oldstyle, 0 = capital +% \end{macrocode} +% This is how we insert mathchars. The command has three arguments: +% class, fam and slot postion and so it is always given as +% hexadecimal. This way of separating things should make it easier +% to get this to work with XeTeX et al.\ which have many more slot +% positions +% \begin{macrocode} +\cs_set_protected:Nn \math_char:NNn { + \tex_mathchar:D \__int_eval:w " #1#2#3 \__int_eval_end: +} +% \end{macrocode} +% Delimiters and radicals are similar except here we have both small +% and large variant. Radicals have no class. +% \begin{macrocode} +\cs_set_protected:Nn \math_delimiter:NNnNn { + \tex_delimiter:D \__int_eval:w " #1#2#3#4#5 \__int_eval_end: +} +\cs_set_protected:Nn \math_radical:NnNn { + \tex_radical:D \__int_eval:w " #1#2#3#4 \__int_eval_end: +} +\cs_set_protected:Nn \math_accent:NNnn { + \tex_mathaccent:D \__int_eval:w " #1 #2 #3 \__int_eval_end: {#4} +} + +\let\sumlimits\displaylimits +\let\intlimits\nolimits +\let\namelimits\displaylimits +% \end{macrocode} +% \TeX\ defines eight types of atoms. +% \begin{enumerate}\addtocounter{enumi}{-1} +% \item Ordinary +% \item Operators +% \item Binary +% \item Relation +% \item Open +% \item Close +% \item Punctuation +% \item Inner +% \end{enumerate} +% \TeX\ defines eight math classes. +% \begin{enumerate}\addtocounter{enumi}{-1} +% \item Ordinary +% \item Operators +% \item Binary +% \item Relation +% \item Open +% \item Close +% \item Punctuation +% \item Variable family +% \end{enumerate} +% flexisym/breqn extends this to types of classes. +% \begin{enumerate}\addtocounter{enumi}{-1} +% \item Ordinary: (Ord), Bidirectional delimiters (DeB), Radicals +% (Rad), Accented items (Acc) +% \item Operators: Cumulative Operators sum-like (COs), Cumulative +% Operators integral-like (COi) +% \item Binary: (Bin) +% \item Relation: (Rel), Arrow delimiters (DeA) +% \item Open: (DeL) +% \item Close (DeR) +% \item Punctuation: (Pun) +% \item Variable family: (Var) +% \end{enumerate} +% +% Here's an overview of what we are about to do. Math chars of each +% type as defined by us need a basic operation for inserting it. We +% will call that function |\math_bsym_|\meta{type}|:Nn|. Next there +% are compund symbols for each type which we name +% |\math_bcsym_|\meta{type}|:Nn|. Also, there is inline mode and +% display mode which are different. We will call them for +% |\math_isym_|\meta{type}|:Nn| |\math_icsym_|\meta{type}|:Nn| for +% inline mode and |\math_dsym_|\meta{type}|:Nn| and +% |\math_dcsym_|\meta{type}|:Nn|. The code uses the terms +% |\math_sym_|\meta{type}|:Nn| and |\math_csym_|\meta{type}|:Nn| for +% the current meaning of things. First up the basic definitions. |#1| +% is the math group it is from and |#2| is the slot position. +% \begin{macrocode} +\cs_new:Npn \math_bsym_Ord:Nn {\math_char:NNn 0 }% \m@Ord +\cs_new:Npn \math_bsym_Var:Nn {\math_char:NNn 7 }% \m@Var +\cs_new:Npn \math_bsym_Bin:Nn {\math_char:NNn 2 }% \m@Bin +\cs_new:Npn \math_bsym_Rel:Nn {\math_char:NNn 3 }% \m@Bin +\cs_new:Npn \math_bsym_Pun:Nn {\math_char:NNn 6 }% \m@Pun +\cs_new:Nn \math_bsym_COs:Nn { \math_char:NNn 1 #1 {#2} \sumlimits }% \m@COs +\cs_new:Nn \math_bsym_COi:Nn { \math_char:NNn 1 #1 {#2} \intlimits }% \m@COi +\cs_new:Nn \math_bsym_DeL:Nn { \math_sd_del_aux:Nnn 4 #1{#2} }% \m@DeL +\cs_new:Nn \math_bsym_DeR:Nn { \math_sd_del_aux:Nnn 5 #1{#2} }% \m@DeR +\cs_new:Nn \math_bsym_DeB:Nn { \math_sd_del_aux:Nnn 0 #1{#2} }% \m@DeB +\cs_new:Nn \math_bsym_DeA:Nn { \math_sd_del_aux:Nnn 3 #1{#2} }% \m@DeA +\cs_new:Nn \math_bsym_Rad:Nn { \math_sd_rad_aux:Nn #1{#2} }% \m@Rad +\cs_new:Npn \math_bsym_Acc:Nn #1#2#3#4 {\math_accent:NNnn #1#2{#3}{#4}}% name is wrong + +% \end{macrocode} +% Next is somewhat complicated internally. The way it is done is that +% delimiters and radicals need information about the smallest version +% of the symbol. If this smallest delimiter (SD) is defined, then use +% it. We have these functions to help us return the number. Extract +% the numbers to use and stick a function in front of it. +% +% Code changed because now we require the smallest delimiter to be +% defined (it may be the same, no problem in that). So the two +% arguments present in |\math_bsym_DeL:Nn| are the location of +% extensible version (where the font will do the rest for us +% automatically). For each delimiter, a pointer is defined using the +% extensible characters family and slot as name and value equal to +% family and position of the smallest version. For |(| in standard +% \LaTeX\ this is |{del}{00}| and |{OT1}{28}| respectively. Hence, +% |\math_bsym_DeL:Nn \mg@del {00}| must expand to +% |\math_delimiter:NNnNn 4 \mg@OT1 {28}\mg@del{00}|. So first expand +% away to get to the smallest version. Then call next function which +% shuffles the arguments around. +% \begin{macrocode} +\cs_set:Npn \math_sd_del_aux:Nnn #1#2#3{ + \exp_args:Nf \math_sd_del_auxi:nN {\use:c{sd@#2#3}} #1 #2{#3} +} +\cs_set:Npn \math_sd_del_auxi:nN #1#2{ \math_delimiter:NNnNn #2 #1 } +% \end{macrocode} +% Same for radicals. +% \begin{macrocode} +\cs_set:Npn \math_sd_rad_aux:Nn #1#2{ + \exp_args:Nf \math_sd_rad_auxi:n {\use:c{sd@#1#2}} #1 {#2} +} +\cs_set:Npn \math_sd_rad_auxi:n #1{ \math_radical:NnNn #1 } + + +% \cs_set:Npn \math_sd_aux:nn #1#2 { +% %\exp_args:Nnf \use:nn { #1} { \math_sd_auxi:Nn #2 } +% \exp_args:Nnf \use:nn { #1} { \use:c{sd@\use:nn#2} } +% } +% \cs_set:Npn \math_sd_auxi:Nn #1#2 { +% \cs_if_free:cTF {sd@#1#2} +% { #1{#2} } +% { \use:c{sd@#1#2} } +% } +% \end{macrocode} +% compound symbols here +% \begin{macrocode} +\cs_set_protected:Npn \math_bcsym_Ord:Nn #1#2 { \@symtype \mathord { \OrdSymbol {#2} } }%\@symOrd +\cs_set_protected:Npn \math_bcsym_Var:Nn #1#2 { \@symtype \mathord { \OrdSymbol {#2} } }%\@symVar +\cs_set_protected:Npn \math_bcsym_Bin:Nn #1#2 { \@symtype \mathbin { \OrdSymbol {#2} } }%\@symBin +\cs_set_protected:Npn \math_bcsym_Rel:Nn #1#2 { \@symtype \mathrel { \OrdSymbol {#2} } }%\@symRel +\cs_set_protected:Npn \math_bcsym_Pun:Nn #1#2 { \@symtype \mathpunct { \OrdSymbol {#2} } }%\@symPun +\cs_set_protected:Npn \math_bcsym_COi:Nn #1#2 { \@symtype \mathop { \OrdSymbol {#2} \intlimits } }%\@symCOi +\cs_set_protected:Npn \math_bcsym_COs:Nn #1#2 { \@symtype \mathop { \OrdSymbol {#2} \sumlimits } }%\@symCOs +\cs_set_protected:Npn \math_bcsym_DeL:Nn #1#2 { \@symtype \mathopen { \OrdSymbol {#2} } }%\@symDeL +\cs_set_protected:Npn \math_bcsym_DeR:Nn #1#2 { \@symtype \mathclose { \OrdSymbol {#2} } }%\@symDeR +\cs_set_protected:Npn \math_bcsym_DeB:Nn #1#2 { \@symtype \mathord { \OrdSymbol {#2} } }%\@symDeB +\cs_set_protected:Npn \math_bcsym_DeA:Nn #1#2 { \@symtype \mathrel { \OrdSymbol {#2} } }%\@symDeA +\cs_set_protected:Npn \math_bcsym_Acc:Nn {\@sym}%\@symAcc FIX! +% These three? +\cs_set_protected:Npn \math_bcsym_Ope:Nn #1#2{\@symtype\mathopen{\OrdSymbol{#2}}}%\@symVar +\cs_set_protected:Npn \math_bcsym_Clo:Nn #1#2{\@symtype\mathclose{\OrdSymbol{#2}}}%\@symVar +\cs_set_protected:Npn \math_bcsym_Inn:Nn #1#2{\@symtype\mathinner{\OrdSymbol{#2}}}%\@symVar + +\let\@symtype\@firstofone +\let\sym@global\global +% \end{macrocode} +% +% +% +% +% The inline variants, using the basic operations. Currently we do not +% do anything to inline math. +% \begin{macrocode} +\cs_new:Npn \math_isym_Ord:Nn { \math_bsym_Ord:Nn }% \m@Ord +\cs_new:Npn \math_isym_Var:Nn { \math_bsym_Var:Nn }% \m@Var +\cs_new:Npn \math_isym_Bin:Nn { \math_bsym_Bin:Nn }% \m@Bin +\cs_new:Npn \math_isym_Rel:Nn { \math_bsym_Rel:Nn }% \m@Bin +\cs_new:Npn \math_isym_Pun:Nn { \math_bsym_Pun:Nn }% \m@Pun +\cs_new:Npn \math_isym_COs:Nn { \math_bsym_COs:Nn }% \m@COs +\cs_new:Npn \math_isym_COi:Nn { \math_bsym_COi:Nn }% \m@COi +\cs_new:Npn \math_isym_DeL:Nn { \math_bsym_DeL:Nn }% \m@DeL +\cs_new:Npn \math_isym_DeR:Nn { \math_bsym_DeR:Nn }% \m@DeR +\cs_new:Npn \math_isym_DeB:Nn { \math_bsym_DeB:Nn }% \m@DeB +\cs_new:Npn \math_isym_DeA:Nn { \math_bsym_DeA:Nn }% \m@DeA +\cs_new:Npn \math_isym_Rad:Nn { \math_bsym_Rad:Nn }% \m@Rad +\cs_new:Npn \math_isym_Acc:Nn { \math_bsym_DeL:Nn }% name is wrong +% inline compound +\cs_set_protected:Npn \math_icsym_Ord:Nn { \math_bcsym_Ord:Nn } +\cs_set_protected:Npn \math_icsym_Var:Nn { \math_bcsym_Var:Nn } +\cs_set_protected:Npn \math_icsym_Bin:Nn { \math_bcsym_Bin:Nn } +\cs_set_protected:Npn \math_icsym_Rel:Nn { \math_bcsym_Rel:Nn } +\cs_set_protected:Npn \math_icsym_Pun:Nn { \math_bcsym_Pun:Nn } +\cs_set_protected:Npn \math_icsym_COi:Nn { \math_bcsym_COi:Nn } +\cs_set_protected:Npn \math_icsym_COs:Nn { \math_bcsym_COs:Nn } +\cs_set_protected:Npn \math_icsym_DeL:Nn { \math_bcsym_DeL:Nn } +\cs_set_protected:Npn \math_icsym_DeR:Nn { \math_bcsym_DeR:Nn } +\cs_set_protected:Npn \math_icsym_DeB:Nn { \math_bcsym_DeB:Nn } +\cs_set_protected:Npn \math_icsym_DeA:Nn { \math_bcsym_DeA:Nn } +\cs_set_protected:Npn \math_icsym_Acc:Nn { \math_bcsym_Acc:Nn } +\cs_set_protected:Npn \math_icsym_Ope:Nn { \math_bcsym_Ope:Nn } +\cs_set_protected:Npn \math_icsym_Clo:Nn { \math_bcsym_Clo:Nn } +\cs_set_protected:Npn \math_icsym_Inn:Nn { \math_bcsym_Inn:Nn } +% \end{macrocode} +% +% The display variants, using the basic operations. Currently we do +% not do anything to inline math. +% \begin{macrocode} +\cs_new:Npn \math_dsym_Ord:Nn { \math_bsym_Ord:Nn } +\cs_new:Npn \math_dsym_Var:Nn { \math_bsym_Var:Nn } +\cs_new:Npn \math_dsym_Bin:Nn { \math_bsym_Bin:Nn } +\cs_new:Npn \math_dsym_Rel:Nn { \math_bsym_Rel:Nn } +\cs_new:Npn \math_dsym_Pun:Nn { \math_bsym_Pun:Nn } +\cs_new:Npn \math_dsym_COs:Nn { \math_bsym_COs:Nn } +\cs_new:Npn \math_dsym_COi:Nn { \math_bsym_COi:Nn } +\cs_new:Npn \math_dsym_DeL:Nn { \math_bsym_DeL:Nn } +\cs_new:Npn \math_dsym_DeR:Nn { \math_bsym_DeR:Nn } +\cs_new:Npn \math_dsym_DeB:Nn { \math_bsym_DeB:Nn } +\cs_new:Npn \math_dsym_DeA:Nn { \math_bsym_DeA:Nn } +\cs_new:Npn \math_dsym_Rad:Nn { \math_bsym_Rad:Nn } +\cs_new:Npn \math_dsym_Acc:Nn { \math_bsym_DeL:Nn } +% inline compound +\cs_set_protected:Npn \math_dcsym_Ord:Nn { \math_bcsym_Ord:Nn } +\cs_set_protected:Npn \math_dcsym_Var:Nn { \math_bcsym_Var:Nn } +\cs_set_protected:Npn \math_dcsym_Bin:Nn { \math_bcsym_Bin:Nn } +\cs_set_protected:Npn \math_dcsym_Rel:Nn { \math_bcsym_Rel:Nn } +\cs_set_protected:Npn \math_dcsym_Pun:Nn { \math_bcsym_Pun:Nn } +\cs_set_protected:Npn \math_dcsym_COi:Nn { \math_bcsym_COi:Nn } +\cs_set_protected:Npn \math_dcsym_COs:Nn { \math_bcsym_COs:Nn } +\cs_set_protected:Npn \math_dcsym_DeL:Nn { \math_bcsym_DeL:Nn } +\cs_set_protected:Npn \math_dcsym_DeR:Nn { \math_bcsym_DeR:Nn } +\cs_set_protected:Npn \math_dcsym_DeB:Nn { \math_bcsym_DeB:Nn } +\cs_set_protected:Npn \math_dcsym_DeA:Nn { \math_bcsym_DeA:Nn } +\cs_set_protected:Npn \math_dcsym_Acc:Nn { \math_bcsym_Acc:Nn } +\cs_set_protected:Npn \math_dcsym_Ope:Nn { \math_bcsym_Ope:Nn } +\cs_set_protected:Npn \math_dcsym_Clo:Nn { \math_bcsym_Clo:Nn } +\cs_set_protected:Npn \math_dcsym_Inn:Nn { \math_bcsym_Inn:Nn } +% \end{macrocode} +% Almost ready now! Now just need two commands to initialize these +% settings. +% +% \begin{macrocode} +\cs_set:Npn \math_setup_inline_symbols: + { + \cs_set_eq:NN \math_sym_Ord:Nn \math_isym_Ord:Nn + \cs_set_eq:NN \math_sym_Var:Nn \math_isym_Var:Nn + \cs_set_eq:NN \math_sym_Bin:Nn \math_isym_Bin:Nn + \cs_set_eq:NN \math_sym_Rel:Nn \math_isym_Rel:Nn + \cs_set_eq:NN \math_sym_Pun:Nn \math_isym_Pun:Nn + \cs_set_eq:NN \math_sym_COs:Nn \math_isym_COs:Nn + \cs_set_eq:NN \math_sym_COi:Nn \math_isym_COi:Nn + \cs_set_eq:NN \math_sym_DeL:Nn \math_isym_DeL:Nn + \cs_set_eq:NN \math_sym_DeR:Nn \math_isym_DeR:Nn + \cs_set_eq:NN \math_sym_DeB:Nn \math_isym_DeL:Nn + \cs_set_eq:NN \math_sym_DeA:Nn \math_isym_DeA:Nn + \cs_set_eq:NN \math_sym_Rad:Nn \math_isym_Rad:Nn + \cs_set_eq:NN \math_sym_Acc:Nn \math_isym_DeL:Nn + \cs_set_eq:NN \math_csym_Ord:Nn \math_icsym_Ord:Nn + \cs_set_eq:NN \math_csym_Var:Nn \math_icsym_Var:Nn + \cs_set_eq:NN \math_csym_Bin:Nn \math_icsym_Bin:Nn + \cs_set_eq:NN \math_csym_Rel:Nn \math_icsym_Rel:Nn + \cs_set_eq:NN \math_csym_Pun:Nn \math_icsym_Pun:Nn + \cs_set_eq:NN \math_csym_COi:Nn \math_icsym_COi:Nn + \cs_set_eq:NN \math_csym_COs:Nn \math_icsym_COs:Nn + \cs_set_eq:NN \math_csym_DeL:Nn \math_icsym_DeL:Nn + \cs_set_eq:NN \math_csym_DeR:Nn \math_icsym_DeR:Nn + \cs_set_eq:NN \math_csym_DeB:Nn \math_icsym_DeB:Nn + \cs_set_eq:NN \math_csym_DeA:Nn \math_icsym_DeA:Nn + \cs_set_eq:NN \math_csym_Acc:Nn \math_icsym_Acc:Nn + \cs_set_eq:NN \math_csym_Ope:Nn \math_icsym_Ope:Nn + \cs_set_eq:NN \math_csym_Clo:Nn \math_icsym_Clo:Nn + \cs_set_eq:NN \math_csym_Inn:Nn \math_icsym_Inn:Nn + } + +\cs_set:Npn \math_setup_display_symbols: + { + \cs_set_eq:NN \math_sym_Ord:Nn \math_dsym_Ord:Nn + \cs_set_eq:NN \math_sym_Var:Nn \math_dsym_Var:Nn + \cs_set_eq:NN \math_sym_Bin:Nn \math_dsym_Bin:Nn + \cs_set_eq:NN \math_sym_Rel:Nn \math_dsym_Rel:Nn + \cs_set_eq:NN \math_sym_Pun:Nn \math_dsym_Pun:Nn + \cs_set_eq:NN \math_sym_COs:Nn \math_dsym_COs:Nn + \cs_set_eq:NN \math_sym_COi:Nn \math_dsym_COi:Nn + \cs_set_eq:NN \math_sym_DeL:Nn \math_dsym_DeL:Nn + \cs_set_eq:NN \math_sym_DeR:Nn \math_dsym_DeR:Nn + \cs_set_eq:NN \math_sym_DeB:Nn \math_dsym_DeL:Nn + \cs_set_eq:NN \math_sym_DeA:Nn \math_dsym_DeA:Nn + \cs_set_eq:NN \math_sym_Rad:Nn \math_dsym_Rad:Nn + \cs_set_eq:NN \math_sym_Acc:Nn \math_dsym_DeL:Nn + \cs_set_eq:NN \math_csym_Ord:Nn \math_dcsym_Ord:Nn + \cs_set_eq:NN \math_csym_Var:Nn \math_dcsym_Var:Nn + \cs_set_eq:NN \math_csym_Bin:Nn \math_dcsym_Bin:Nn + \cs_set_eq:NN \math_csym_Rel:Nn \math_dcsym_Rel:Nn + \cs_set_eq:NN \math_csym_Pun:Nn \math_dcsym_Pun:Nn + \cs_set_eq:NN \math_csym_COi:Nn \math_dcsym_COi:Nn + \cs_set_eq:NN \math_csym_COs:Nn \math_dcsym_COs:Nn + \cs_set_eq:NN \math_csym_DeL:Nn \math_dcsym_DeL:Nn + \cs_set_eq:NN \math_csym_DeR:Nn \math_dcsym_DeR:Nn + \cs_set_eq:NN \math_csym_DeB:Nn \math_dcsym_DeB:Nn + \cs_set_eq:NN \math_csym_DeA:Nn \math_dcsym_DeA:Nn + \cs_set_eq:NN \math_csym_Acc:Nn \math_dcsym_Acc:Nn + \cs_set_eq:NN \math_csym_Ope:Nn \math_dcsym_Ope:Nn + \cs_set_eq:NN \math_csym_Clo:Nn \math_dcsym_Clo:Nn + \cs_set_eq:NN \math_csym_Inn:Nn \math_dcsym_Inn:Nn + } +% \end{macrocode} +% Phew, that was it. +% +% Well, almost. We need to set them up for use properly. Should they +% be added to |\everymath|? Probably, for math within +% displays. However, this is a lot of extra processing which we could +% tackle in the display setup. +% \begin{macrocode} +\math_setup_inline_symbols: +% \end{macrocode} +% +% Need an active character for a second. Don't rely on |~| being +% active! +% \begin{macrocode} +\edef\tmp{\catcode\z@=\the\catcode\z@} +\catcode\z@=\active +\def\DeclareFlexSymbol#1#2#3#4{% + \begingroup + \cs_set_protected:Npx\@tempb{ + \exp_not:N\@sym\exp_not:N#1\exp_not:c{math_sym_#2:Nn} + \exp_not:c{mg@#3}{#4} + } + \ifcat\exp_not:N#1\relax + \sym@global\let#1\@tempb + \else + \sym@global\mathcode`#1="8000\relax + \lccode\z@=`#1\relax + \lowercase{\sym@global\let^^@\@tempb}% zero char + \fi + \endgroup +} +\tmp % restore catcode +\cs_set:Npn \DeclareFlexDelimiter #1#2#3#4#5#6{ + \DeclareFlexSymbol{#1}{#2}{#3}{#4} + \cs_gset:cpx{sd@\use:c{mg@#3}#4}{\exp_not:c{mg@#5}{#6}} +} + +% \end{macrocode} +% |\DeclareFlexCompoundSymbol{\cdots}{Inn}{\cdotp\cdotp\cdotp}| +% |\def\@symInn#1#2{\@symtype\mathinner{\OrdSymbol{#2}}}| +% |\@symtype \mathinner{\OrdSymbol{\cdtop\cdotp\cdotp}}| +% \begin{macrocode} +\def\DeclareFlexCompoundSymbol#1#2#3{% + \exp_args:NNo \DeclareRobustCommand#1{\csname math_csym_#2:Nn\endcsname#1{#3}}% + \sym@global\let#1#1\relax +} +\DeclareRobustCommand\textchar{\text@char\textfont} +\DeclareRobustCommand\scriptchar{\text@char\scriptfont}% +% \end{macrocode} +% Simplified the next bit because now the slot is read as one argument +% so no afterassignment and what have you. Just drop the char +% directly. +% \begin{macrocode} +\def\text@char@sym#1#2#3#4{% #3=fam, #4=slot + \begingroup + \cs_set_eq:NN \@sym \prg_do_nothing: % defense against infinite loops +% \end{macrocode} +% the next line will result in |\scriptfont|\meta{num}, where |#3| +% provides the \meta{num}. +% \begin{macrocode} + \the\text@script@char#3% + \char"#4\endgroup +} +\edef\tmp{\catcode\z@=\the\catcode\z@} +\catcode\z@=\active +\def\text@char#1#2{\begingroup + \check@mathfonts + \cs_set_eq:NN \text@script@char #1 + \cs_set_eq:NN \@sym \text@char@sym + \cs_set_eq:NN \@symtype \use_ii:nn + \cs_set_eq:NN \OrdSymbol \use:n + \cs_set_eq:NN \ifmmode \iftrue + \everymath{$\use_none:n}%$ + \def\mkern{\muskip\z@} + \cs_set_eq:NN\mskip\mkern + \ifcat\relax\noexpand#2% true if #2 is a cs. + #2% + \else + \lccode\z@=\expandafter`\string#2\relax + \lowercase{^^@}% + \fi + \endgroup +} +\tmp % restore catcode +\providecommand\textprime{} +\DeclareRobustCommand\textprime{\leavevmode + \raise.8ex\hbox{\text@char\scriptfont\prime}% +} +\@ifundefined{resetMathstrut@}{}{% + \def\resetMathstrut@{% + \setbox\z@\hbox{\textchar\vert}% + \ht\Mathstrutbox@\ht\z@ \dp\Mathstrutbox@\dp\z@ + }% +} +% \end{macrocode} +% Arrow fills. changed to 7mu as in amsmath +% \begin{macrocode} +\@ifundefined{rightarrowfill@}{}{% + \def\rightarrowfill@#1{\m@th\setboxz@h{$#1\relbar$}\ht\z@\z@ + $#1\copy\z@\mkern-7mu\cleaders + \hbox{$#1\mkern-2mu\box\z@\mkern-2mu$}\hfill + \mkern-6mu\OrdSymbol{\rightarrow}$} + \def\leftarrowfill@#1{\m@th\setboxz@h{$#1\relbar$}\ht\z@\z@ + $#1\OrdSymbol{\leftarrow}\mkern-6mu\cleaders + \hbox{$#1\mkern-2mu\copy\z@\mkern-2mu$}\hfill + \mkern-7mu\box\z@$} + \def\leftrightarrowfill@#1{\m@th\setboxz@h{$#1\relbar$}\ht\z@\z@ + $#1\OrdSymbol{\leftarrow}\mkern-6mu\cleaders + \hbox{$#1\mkern-2mu\box\z@\mkern-2mu$}\hfill + \mkern-6mu\OrdSymbol{\rightarrow}$} +} +% \end{macrocode} +% hey, this looks like a simple case switch... +% \begin{macrocode} +\def\binrel@sym#1#2#3#4{% + \xdef\binrel@@##1{% + \ifx\math_sym_Ord:Nn #2 \math_csym_Ord:Nn + \else\ifx\math_sym_Var:Nn#2 \math_csym_Var:Nn + \else\ifx\math_sym_COs:Nn#2 \math_csym_COs:Nn + \else\ifx\math_sym_COi:Nn#2 \math_csym_COi:Nn + \else\ifx\math_sym_Bin:Nn#2 \math_csym_Bin:Nn + \else\ifx\math_sym_Rel:Nn#2 \math_csym_Rel:Nn + \else\ifx\math_sym_Pun:Nn#2 \math_csym_Pun:Nn + \else\exp_not:N\@symErr \fi\fi\fi\fi\fi\fi\fi + ?{\exp_not:N\OrdSymbol{##1}}}% +} + +\def\binrel@a{% + \def\math_sym_Ord:Nn##1##2{\gdef\binrel@@####1{\math_sym_Ord:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_Var:Nn##1##2{\gdef\binrel@@####1{\math_sym_Var:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_COs:Nn##1##2{\gdef\binrel@@####1{\math_sym_COs:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_COi:Nn##1##2{\gdef\binrel@@####1{\math_sym_COi:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_Bin:Nn##1##2{\gdef\binrel@@####1{\math_sym_Bin:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_Rel:Nn##1##2{\gdef\binrel@@####1{\math_sym_Rel:Nn##1{\OrdSymbol{####1}}}}% + \def\math_sym_Pun:Nn##1##2{\gdef\binrel@@####1{\math_sym_Pun:Nn##1{\OrdSymbol{####1}}}}% +} +\def\binrel@#1{% + \setbox\z@\hbox{$% + \let\mathchoice\@gobblethree + \let\@sym\binrel@sym \binrel@a + #1$}% +} +\def\@symextension{sym} +\newcommand\usesymbols[1]{% + \clist_map_variable:nNn{#1}\@tempb{% + \exp_args:No\@onefilewithoptions{\@tempb}[][]\@symextension + }% +} +% Need to introduce \ProvidesExplFile somehow +\newcommand\ProvidesSymbols[1]{\ProvidesFile{#1.sym}} +\DeclareRobustCommand{\not}[1]{\math_csym_Rel:Nn\not{\OrdSymbol{\notRel#1}}} +\DeclareRobustCommand{\OrdSymbol}[1]{% + \begingroup\mathchars@reset#1\endgroup +} +\def\mathchars@reset{\let\@sym\@sym@ord \let\@symtype\@symtype@ord + \let\OrdSymbol\relax} +\def\@symtype@ord#1#{}% a strange sort of \@gobble +\def\@sym@ord#1#2{\exp_after:wN\@sym@ord@a\string#2\@nil}% +% \end{macrocode} +% Read delimited argument here. We want to find first character of +% DeA, Bin, etc. and the control sequence checked agains is |\m@DeL|, +% |\m@Pun|, etc. The lccode trick makes the . into an @ with catcode +% 12. This is what results when the code is called with +% |\string|. Beware of this when we change internal names for math +% groups! If a Delimiter is found, insert it with class 0 but use the +% smallest version available. Otherwise just insert math char of class +% 0. The code here is not pretty and it indicates it should be tackled +% differently! +% \begin{macrocode} +\begingroup +\lccode`\.=`\_ \lowercase{\endgroup +\def\@sym@ord@a#1.#2.}#3#4\@nil#5#6{% + \if D#3 + %\math_ord_delim_aux:Nn #5{#6} + \math_sd_del_aux:Nnn 0 #5{#6}% check if this works! + \else + \math_char:NNn 0 #5{#6} + \fi +} +\cs_set:Nn \math_ord_delim_aux:Nn { + \math_sd_aux:nn { \math_char:NNn 0 } {#1{#2}} +} +% \end{macrocode} +% +% +% Before declaring any math characters active, we have to take care of +% a small problem with \pkg{amsmath} v2.x, if it is loaded before +% \pkg{flexisym}. \cs{std@minus} and \cs{std@equal} are defined as +% \begin{verbatim} +% \mathchardef\std@minus\mathcode`\-\relax +% \mathchardef\std@equal\mathcode`\=\relax +% \end{verbatim} +% in \fn{amsmath.sty} and again \cs{AtBeginDocument}. The +% latter is because +% \begin{quote} +% In case some alternative math fonts are loaded +% later. [\fn{amsmath.dtx}] +% \end{quote} +% The problem arises because \pkg{flexisym} sets the mathcode of all +% symbols to $32768$ which is illegal for a \cs{mathchardef}. +% +% We have to remove the assignments from the \cs{AtBeginDocument} hook +% as they will cause an error there. +% \begin{macrocode} +\@ifpackageloaded{amsmath}{% + \begingroup +% \end{macrocode} +% Split the contents of \cs{@begindocumenthook} by reading what we +% search for as a delimited argument and ensure these two assignments +% do not take place. It is questionable if anything reasonable can be +% done to them. In the case of a package such as \pkg{mathpazo} which defines +% \begin{verbatim} +%\DeclareMathSymbol{=}{\mathrel}{upright}{"3D} +% \end{verbatim} +% the \cs{Relbar} will look wrong if we don't use the correct +% symbol. The way to solve this is define additional \fn{.sym} files +% which contain the definition of \cs{relbar} and \cs{Relbar} +% needed. We need those additional files anyway for things like +% \cs{joinord}. +% \begin{macrocode} + \long\def\next#1\mathchardef\std@minus\mathcode`\-\relax + \mathchardef\std@equal\mathcode`\=\relax#2\flexi@stop{% + \toks@{#1#2}% + \xdef\@begindocumenthook{\the\toks@}% + }% + \expandafter\next\@begindocumenthook\flexi@stop + \endgroup +}{} +% \end{macrocode} +% +% There is problem when using \cs{DeclareMathOperator} as the +% operators defined call a command \cs{newmcodes@} which relies on the +% mathcode of \texttt{-} being less than 32768. We delay the +% definition \cs{AtBeginDocument} in case \pkg{amssymb} hasn't been +% loaded yet. +% \begin{macrocode} +\AtBeginDocument{% +\def\newmcodes@{% + \mathcode `\'39\space + \mathcode `\*42\space + \mathcode `\."613A\space + \ifnum\mathcode`\-=45\space + \else +% \end{macrocode} +% The extra check. Don't do anything if \texttt{-} is math active. +% \begin{macrocode} + \ifnum\mathcode`\-=32768\space + \else + \mathchardef \std@minus \mathcode `\-\relax + \fi + \fi + \mathcode `\-45\space + \mathcode `\/47\space + \mathcode `\:"603A\space\relax +}% +} +% \end{macrocode} +% +% And we then continue with the options. +% \begin{macrocode} +\DeclareOption{mathstyleoff}{% + \PassOptionsToPackage{noactivechars}{mathstyle}} +\DeclareOption{cmbase}{\usesymbols{cmbase}} +\DeclareOption{mathpazo}{\usesymbols{mathpazo}} +\DeclareOption{mathptmx}{\usesymbols{mathptmx}} +\ExecuteOptions{cmbase} +\ProcessOptions\relax +\renewcommand{\lnot}{\neg} +\renewcommand{\land}{\wedge} +\renewcommand{\lor}{\vee} +\renewcommand{\le}{\leq} +\renewcommand{\ge}{\geq} +\renewcommand{\ne}{\neq} +\renewcommand{\owns}{\ni} +\renewcommand{\gets}{\leftarrow} +\renewcommand{\to}{\rightarrow} +\renewcommand{\|}{\Vert} +\RequirePackage{mathstyle} +%</package>\endinput +% \end{macrocode} +% +% \section{cmbase, mathpazo, mathptmx} +% +% +% For each math font package we define a corresponding symbol file +% with extension \fn{sym}. The Computer Modern base is called +% \opt{cmbase} and \opt{mathpazo} and \opt{mathptmx} corresponds to +% the packages. The definitions are almost identical as they mostly +% concern the positions in the math font encodings. Look for +% differences in \cs{joinord}, \cs{relbar} and \cs{Relbar}. If you +% inspect the source code, you'll see that the support for +% \pkg{mathptmx} didn't require any work but I thought it better to +% create a \fn{sym} file to maintain a uniform interface. +% +% \begin{aside} +% Open question on \verb"!" and \verb"?": maybe they +% should have type `Pun' instead of `DeR'. Need to +% search for uses in math in AMS archives. Or, maybe add a special +% `Clo' type for them: non-extensible closing delimiter. +% \end{aside} +% +% +% +% Default mathgroup setup. +% \changes{v0.3}{2010/07/11}{fixed bugs regarding capital greek +% letters in mathpazo and mathptmx} +% \begin{macrocode} +%<*cmbase|mathpazo|mathptmx> +%<cmbase>\ProvidesSymbols{cmbase}[2007/12/19 v0.92] +%<mathpazo>\ProvidesSymbols{mathpazo}[2010/07/11 v0.3] +%<mathptmx>\ProvidesSymbols{mathptmx}[2010/07/11 v0.3] +\ExplSyntaxOn +\cs_gset:cpx {mg@OT1} {\hexnumber@\symoperators} +\cs_gset:cpx {mg@OML} {\hexnumber@\symletters} +\cs_gset:cpx {mg@OMS} {\hexnumber@\symsymbols} +\cs_gset:cpx {mg@OMX} {\hexnumber@\symlargesymbols} +\cs_gset:Npx \mg@bin {\mg@OMS} +\cs_gset:Npx \mg@del {\mg@OMX} +\cs_gset:Npx \mg@digit {\exp_not:c{mg@OT1}} +\cs_gset:Npn \mg@latin {\mg@OML} +\cs_gset_eq:NN \mg@Latin \mg@latin +\cs_gset_eq:NN \mg@greek \mg@latin +%<cmbase|mathptmx>\cs_gset_eq:NN\mg@Greek\mg@digit +% \end{macrocode} +% Mathpazo takes the upper case greeks from the letter font if +% slantedGreek is in effect, but from \emph{upright} if not. Mathptmx +% also takes the slanted greek from the letter font. +% \begin{macrocode} +%<mathpazo>\@ifpackagewith{mathpazo}{slantedGreek}{% +%<mathpazo> \cs_gset_eq:NN\mg@Greek\mg@latin +%<mathpazo>}{% +%<mathpazo> \cs_gset:cpx{mg@Greek}{\hexnumber@\symupright} +%<mathpazo>} +%<mathptmx>\@ifpackagewith{mathptmx}{slantedGreek}{% +%<mathptmx> \cs_gset_eq:NN\mg@Greek\mg@latin +%<mathptmx>}{} +\cs_gset_eq:NN \mg@rel \mg@bin +\cs_gset_eq:NN \mg@ord \mg@bin +\cs_gset_eq:NN \mg@cop \mg@del +% \end{macrocode} +% +% +% Symbols from the 128-character \fn{cmr} encoding. +% Paren and square bracket delimiters from this encoding are covered +% by the definitions in the \fn{cmex} section, however. +% \begin{macrocode} +\DeclareFlexSymbol{!} {Pun}{OT1}{21} +\DeclareFlexSymbol{+} {Bin}{OT1}{2B} +\DeclareFlexSymbol{:} {Rel}{OT1}{3A} +\DeclareFlexSymbol{\colon}{Pun}{OT1}{3A} +\DeclareFlexSymbol{;} {Pun}{OT1}{3B} +\DeclareFlexSymbol{=} {Rel}{OT1}{3D} +\DeclareFlexSymbol{?} {Pun}{OT1}{3F} +% \end{macrocode} +% \AmS\TeX, and therefore the \pkg{amsmath} package, make the +% uppercase Greek letters class 0 (nonvariable) instead of 7 +% (variable), to eliminate the glaring inconsistency with lowercase +% Greek. (In plain \TeX , \verb"{\bf\Delta}" works, while +% \verb"{\bf\delta}" doesn't.) Let us try to make them both +% variable (fonts permitting) instead of nonvariable. +% \begin{macrocode} +\DeclareFlexSymbol{\Gamma} {Var}{Greek}{00} +\DeclareFlexSymbol{\Delta} {Var}{Greek}{01} +\DeclareFlexSymbol{\Theta} {Var}{Greek}{02} +\DeclareFlexSymbol{\Lambda} {Var}{Greek}{03} +\DeclareFlexSymbol{\Xi} {Var}{Greek}{04} +\DeclareFlexSymbol{\Pi} {Var}{Greek}{05} +\DeclareFlexSymbol{\Sigma} {Var}{Greek}{06} +\DeclareFlexSymbol{\Upsilon}{Var}{Greek}{07} +\DeclareFlexSymbol{\Phi} {Var}{Greek}{08} +\DeclareFlexSymbol{\Psi} {Var}{Greek}{09} +\DeclareFlexSymbol{\Omega} {Var}{Greek}{0A} +% \end{macrocode} +% Decimal digits. +% \begin{macrocode} +\DeclareFlexSymbol{0}{Var}{digit}{30} +\DeclareFlexSymbol{1}{Var}{digit}{31} +\DeclareFlexSymbol{2}{Var}{digit}{32} +\DeclareFlexSymbol{3}{Var}{digit}{33} +\DeclareFlexSymbol{4}{Var}{digit}{34} +\DeclareFlexSymbol{5}{Var}{digit}{35} +\DeclareFlexSymbol{6}{Var}{digit}{36} +\DeclareFlexSymbol{7}{Var}{digit}{37} +\DeclareFlexSymbol{8}{Var}{digit}{38} +\DeclareFlexSymbol{9}{Var}{digit}{39} +% \end{macrocode} +% Symbols from the 128-character \fn{cmmi} encoding. +% \begin{macrocode} +\DeclareFlexSymbol{,}{Pun}{OML}{3B} +\DeclareFlexSymbol{.}{Ord}{OML}{3A} +\DeclareFlexSymbol{/}{Ord}{OML}{3D} +\DeclareFlexSymbol{<}{Rel}{OML}{3C} +\DeclareFlexSymbol{>}{Rel}{OML}{3E} +% \end{macrocode} +% To do: make the Var property of lc Greek work properly. +% \begin{macrocode} +\DeclareFlexSymbol{\alpha} {Var}{greek}{0B} +\DeclareFlexSymbol{\beta} {Var}{greek}{0C} +\DeclareFlexSymbol{\gamma} {Var}{greek}{0D} +\DeclareFlexSymbol{\delta} {Var}{greek}{0E} +\DeclareFlexSymbol{\epsilon} {Var}{greek}{0F} +\DeclareFlexSymbol{\zeta} {Var}{greek}{10} +\DeclareFlexSymbol{\eta} {Var}{greek}{11} +\DeclareFlexSymbol{\theta} {Var}{greek}{12} +\DeclareFlexSymbol{\iota} {Var}{greek}{13} +\DeclareFlexSymbol{\kappa} {Var}{greek}{14} +\DeclareFlexSymbol{\lambda} {Var}{greek}{15} +\DeclareFlexSymbol{\mu} {Var}{greek}{16} +\DeclareFlexSymbol{\nu} {Var}{greek}{17} +\DeclareFlexSymbol{\xi} {Var}{greek}{18} +\DeclareFlexSymbol{\pi} {Var}{greek}{19} +\DeclareFlexSymbol{\rho} {Var}{greek}{1A} +\DeclareFlexSymbol{\sigma} {Var}{greek}{1B} +\DeclareFlexSymbol{\tau} {Var}{greek}{1C} +\DeclareFlexSymbol{\upsilon} {Var}{greek}{1D} +\DeclareFlexSymbol{\phi} {Var}{greek}{1E} +\DeclareFlexSymbol{\chi} {Var}{greek}{1F} +\DeclareFlexSymbol{\psi} {Var}{greek}{20} +\DeclareFlexSymbol{\omega} {Var}{greek}{21} +\DeclareFlexSymbol{\varepsilon}{Var}{greek}{22} +\DeclareFlexSymbol{\vartheta} {Var}{greek}{23} +\DeclareFlexSymbol{\varpi} {Var}{greek}{24} +\DeclareFlexSymbol{\varrho} {Var}{greek}{25} +\DeclareFlexSymbol{\varsigma} {Var}{greek}{26} +\DeclareFlexSymbol{\varphi} {Var}{greek}{27} +% \end{macrocode} +% Note that in plain \TeX\ \cs{imath} and \cs{jmath} are +% not variable-font. But if a \verb"j" changes font to, let's +% say, sans serif or calligraphic, a dotless \verb"j" in the same +% context should change font in the same way. +% \begin{macrocode} +\DeclareFlexSymbol{\imath} {Var}{OML}{7B} +\DeclareFlexSymbol{\jmath} {Var}{OML}{7C} +\DeclareFlexSymbol{\ell} {Ord}{OML}{60} +\DeclareFlexSymbol{\wp} {Ord}{OML}{7D} +\DeclareFlexSymbol{\partial} {Ord}{OML}{40} +\DeclareFlexSymbol{\flat} {Ord}{OML}{5B} +\DeclareFlexSymbol{\natural} {Ord}{OML}{5C} +\DeclareFlexSymbol{\sharp} {Ord}{OML}{5D} +\DeclareFlexSymbol{\triangleleft} {Bin}{OML}{2F} +\DeclareFlexSymbol{\triangleright} {Bin}{OML}{2E} +\DeclareFlexSymbol{\star} {Bin}{OML}{3F} +\DeclareFlexSymbol{\smile} {Rel}{OML}{5E} +\DeclareFlexSymbol{\frown} {Rel}{OML}{5F} +\DeclareFlexSymbol{\leftharpoonup} {Rel}{OML}{28} +\DeclareFlexSymbol{\leftharpoondown} {Rel}{OML}{29} +\DeclareFlexSymbol{\rightharpoonup} {Rel}{OML}{2A} +\DeclareFlexSymbol{\rightharpoondown}{Rel}{OML}{2B} +% \end{macrocode} +% Latin +% \begin{macrocode} +\DeclareFlexSymbol{a}{Var}{latin}{61} +\DeclareFlexSymbol{b}{Var}{latin}{62} +\DeclareFlexSymbol{c}{Var}{latin}{63} +\DeclareFlexSymbol{d}{Var}{latin}{64} +\DeclareFlexSymbol{e}{Var}{latin}{65} +\DeclareFlexSymbol{f}{Var}{latin}{66} +\DeclareFlexSymbol{g}{Var}{latin}{67} +\DeclareFlexSymbol{h}{Var}{latin}{68} +\DeclareFlexSymbol{i}{Var}{latin}{69} +\DeclareFlexSymbol{j}{Var}{latin}{6A} +\DeclareFlexSymbol{k}{Var}{latin}{6B} +\DeclareFlexSymbol{l}{Var}{latin}{6C} +\DeclareFlexSymbol{m}{Var}{latin}{6D} +\DeclareFlexSymbol{n}{Var}{latin}{6E} +\DeclareFlexSymbol{o}{Var}{latin}{6F} +\DeclareFlexSymbol{p}{Var}{latin}{70} +\DeclareFlexSymbol{q}{Var}{latin}{71} +\DeclareFlexSymbol{r}{Var}{latin}{72} +\DeclareFlexSymbol{s}{Var}{latin}{73} +\DeclareFlexSymbol{t}{Var}{latin}{74} +\DeclareFlexSymbol{u}{Var}{latin}{75} +\DeclareFlexSymbol{v}{Var}{latin}{76} +\DeclareFlexSymbol{w}{Var}{latin}{77} +\DeclareFlexSymbol{x}{Var}{latin}{78} +\DeclareFlexSymbol{y}{Var}{latin}{79} +\DeclareFlexSymbol{z}{Var}{latin}{7A} +\DeclareFlexSymbol{A}{Var}{Latin}{41} +\DeclareFlexSymbol{B}{Var}{Latin}{42} +\DeclareFlexSymbol{C}{Var}{Latin}{43} +\DeclareFlexSymbol{D}{Var}{Latin}{44} +\DeclareFlexSymbol{E}{Var}{Latin}{45} +\DeclareFlexSymbol{F}{Var}{Latin}{46} +\DeclareFlexSymbol{G}{Var}{Latin}{47} +\DeclareFlexSymbol{H}{Var}{Latin}{48} +\DeclareFlexSymbol{I}{Var}{Latin}{49} +\DeclareFlexSymbol{J}{Var}{Latin}{4A} +\DeclareFlexSymbol{K}{Var}{Latin}{4B} +\DeclareFlexSymbol{L}{Var}{Latin}{4C} +\DeclareFlexSymbol{M}{Var}{Latin}{4D} +\DeclareFlexSymbol{N}{Var}{Latin}{4E} +\DeclareFlexSymbol{O}{Var}{Latin}{4F} +\DeclareFlexSymbol{P}{Var}{Latin}{50} +\DeclareFlexSymbol{Q}{Var}{Latin}{51} +\DeclareFlexSymbol{R}{Var}{Latin}{52} +\DeclareFlexSymbol{S}{Var}{Latin}{53} +\DeclareFlexSymbol{T}{Var}{Latin}{54} +\DeclareFlexSymbol{U}{Var}{Latin}{55} +\DeclareFlexSymbol{V}{Var}{Latin}{56} +\DeclareFlexSymbol{W}{Var}{Latin}{57} +\DeclareFlexSymbol{X}{Var}{Latin}{58} +\DeclareFlexSymbol{Y}{Var}{Latin}{59} +\DeclareFlexSymbol{Z}{Var}{Latin}{5A} +% \end{macrocode} +% The \cs{ldotPun} glyph is used in constructing the +% \cs{ldots} symbol. It is just a period with a different math +% symbol class. \cs{lhookRel} and \cs{rhookRel} are used +% in a similar way for building hooked arrow symbols. +% \begin{macrocode} +\DeclareFlexSymbol{\ldotPun}{Pun}{OML}{3A} +\def\ldotp{\ldotPun} +\DeclareFlexSymbol{\lhookRel}{Rel}{OML}{2C} +\DeclareFlexSymbol{\rhookRel}{Rel}{OML}{2D} +% \end{macrocode} +% Symbols from the 128-character \fn{cmsy} encoding. +% \begin{macrocode} +\DeclareFlexSymbol{*} {Bin}{bin}{03} % \ast +\DeclareFlexSymbol{-} {Bin}{bin}{00} +\DeclareFlexSymbol{|} {Ord}{OMS}{6A} +\DeclareFlexSymbol{\aleph} {Ord}{ord}{40} +\DeclareFlexSymbol{\Re} {Ord}{ord}{3C} +\DeclareFlexSymbol{\Im} {Ord}{ord}{3D} +\DeclareFlexSymbol{\infty} {Ord}{ord}{31} +\DeclareFlexSymbol{\prime} {Ord}{ord}{30} +\DeclareFlexSymbol{\emptyset} {Ord}{ord}{3B} +\DeclareFlexSymbol{\nabla} {Ord}{ord}{72} +\DeclareFlexSymbol{\top} {Ord}{ord}{3E} +\DeclareFlexSymbol{\bot} {Ord}{ord}{3F} +\DeclareFlexSymbol{\triangle} {Ord}{ord}{34} +\DeclareFlexSymbol{\forall} {Ord}{ord}{38} +\DeclareFlexSymbol{\exists} {Ord}{ord}{39} +\DeclareFlexSymbol{\neg} {Ord}{ord}{3A} +\DeclareFlexSymbol{\clubsuit} {Ord}{ord}{7C} +\DeclareFlexSymbol{\diamondsuit}{Ord}{ord}{7D} +\DeclareFlexSymbol{\heartsuit} {Ord}{ord}{7E} +\DeclareFlexSymbol{\spadesuit} {Ord}{ord}{7F} +\DeclareFlexSymbol{\smallint} {COs}{OMS}{73} +% \end{macrocode} +% Binary operators. +% \begin{macrocode} +\DeclareFlexSymbol{\bigtriangleup} {Bin}{bin}{34} +\DeclareFlexSymbol{\bigtriangledown}{Bin}{bin}{35} +\DeclareFlexSymbol{\wedge} {Bin}{bin}{5E} +\DeclareFlexSymbol{\vee} {Bin}{bin}{5F} +\DeclareFlexSymbol{\cap} {Bin}{bin}{5C} +\DeclareFlexSymbol{\cup} {Bin}{bin}{5B} +\DeclareFlexSymbol{\ddagger} {Bin}{bin}{7A} +\DeclareFlexSymbol{\dagger} {Bin}{bin}{79} +\DeclareFlexSymbol{\sqcap} {Bin}{bin}{75} +\DeclareFlexSymbol{\sqcup} {Bin}{bin}{74} +\DeclareFlexSymbol{\uplus} {Bin}{bin}{5D} +\DeclareFlexSymbol{\amalg} {Bin}{bin}{71} +\DeclareFlexSymbol{\diamond} {Bin}{bin}{05} +\DeclareFlexSymbol{\bullet} {Bin}{bin}{0F} +\DeclareFlexSymbol{\wr} {Bin}{bin}{6F} +\DeclareFlexSymbol{\div} {Bin}{bin}{04} +\DeclareFlexSymbol{\odot} {Bin}{bin}{0C} +\DeclareFlexSymbol{\oslash} {Bin}{bin}{0B} +\DeclareFlexSymbol{\otimes} {Bin}{bin}{0A} +\DeclareFlexSymbol{\ominus} {Bin}{bin}{09} +\DeclareFlexSymbol{\oplus} {Bin}{bin}{08} +\DeclareFlexSymbol{\mp} {Bin}{bin}{07} +\DeclareFlexSymbol{\pm} {Bin}{bin}{06} +\DeclareFlexSymbol{\circ} {Bin}{bin}{0E} +\DeclareFlexSymbol{\bigcirc} {Bin}{bin}{0D} +\DeclareFlexSymbol{\setminus} {Bin}{bin}{6E} +\DeclareFlexSymbol{\cdot} {Bin}{bin}{01} +\DeclareFlexSymbol{\ast} {Bin}{bin}{03} +\DeclareFlexSymbol{\times} {Bin}{bin}{02} +% \end{macrocode} +% Relation symbols. +% \begin{macrocode} +\DeclareFlexSymbol{\propto} {Rel}{rel}{2F} +\DeclareFlexSymbol{\sqsubseteq} {Rel}{rel}{76} +\DeclareFlexSymbol{\sqsupseteq} {Rel}{rel}{77} +\DeclareFlexSymbol{\parallel} {Rel}{rel}{6B} +\DeclareFlexSymbol{\mid} {Rel}{rel}{6A} +\DeclareFlexSymbol{\dashv} {Rel}{rel}{61} +\DeclareFlexSymbol{\vdash} {Rel}{rel}{60} +\DeclareFlexSymbol{\nearrow} {Rel}{rel}{25} +\DeclareFlexSymbol{\searrow} {Rel}{rel}{26} +\DeclareFlexSymbol{\nwarrow} {Rel}{rel}{2D} +\DeclareFlexSymbol{\swarrow} {Rel}{rel}{2E} +\DeclareFlexSymbol{\Leftrightarrow}{Rel}{rel}{2C} +\DeclareFlexSymbol{\Leftarrow} {Rel}{rel}{28} +\DeclareFlexSymbol{\Rightarrow} {Rel}{rel}{29} +\DeclareFlexSymbol{\leq} {Rel}{rel}{14} +\DeclareFlexSymbol{\geq} {Rel}{rel}{15} +\DeclareFlexSymbol{\succ} {Rel}{rel}{1F} +\DeclareFlexSymbol{\prec} {Rel}{rel}{1E} +\DeclareFlexSymbol{\approx} {Rel}{rel}{19} +\DeclareFlexSymbol{\succeq} {Rel}{rel}{17} +\DeclareFlexSymbol{\preceq} {Rel}{rel}{16} +\DeclareFlexSymbol{\supset} {Rel}{rel}{1B} +\DeclareFlexSymbol{\subset} {Rel}{rel}{1A} +\DeclareFlexSymbol{\supseteq} {Rel}{rel}{13} +\DeclareFlexSymbol{\subseteq} {Rel}{rel}{12} +\DeclareFlexSymbol{\in} {Rel}{rel}{32} +\DeclareFlexSymbol{\ni} {Rel}{rel}{33} +\DeclareFlexSymbol{\gg} {Rel}{rel}{1D} +\DeclareFlexSymbol{\ll} {Rel}{rel}{1C} +\DeclareFlexSymbol{\leftrightarrow}{Rel}{rel}{24} +\DeclareFlexSymbol{\leftarrow} {Rel}{rel}{20} +\DeclareFlexSymbol{\rightarrow} {Rel}{rel}{21} +\DeclareFlexSymbol{\sim} {Rel}{rel}{18} +\DeclareFlexSymbol{\simeq} {Rel}{rel}{27} +\DeclareFlexSymbol{\perp} {Rel}{rel}{3F} +\DeclareFlexSymbol{\equiv} {Rel}{rel}{11} +\DeclareFlexSymbol{\asymp} {Rel}{rel}{10} +% \end{macrocode} +% The \cs{notRel} glyph is a special zero-width glyph intended only +% for use in constructing negated symbols. \cs{mapstoRel} and +% \cs{cdotPun} have similar but more restricted applications. +% \begin{macrocode} +\DeclareFlexSymbol{\notRel} {Rel}{rel}{36} +\DeclareFlexSymbol{\mapstoOrd}{Ord}{OMS}{37} +\DeclareFlexSymbol{\cdotOrd} {Ord}{OMS}{01} +\cs_set:Npn\cdotp{\mathpunct{\cdotOrd}} +% \end{macrocode} +% Symbols from the 128-character \fn{cmex} encoding. +% \verb"COs" stands for `cumulative operator +% (sum-like)'. +% \verb"COi" stands for `cumulative operator +% (integral-like)'. These typically differ only in the +% default placement of limits. \verb"cop" stands for +% `cumulative operator math group'. +% \begin{macrocode} +\DeclareFlexSymbol{\coprod} {COs}{cop}{60} +\DeclareFlexSymbol{\bigvee} {COs}{cop}{57} +\DeclareFlexSymbol{\bigwedge} {COs}{cop}{56} +\DeclareFlexSymbol{\biguplus} {COs}{cop}{55} +\DeclareFlexSymbol{\bigcap} {COs}{cop}{54} +\DeclareFlexSymbol{\bigcup} {COs}{cop}{53} +\DeclareFlexSymbol{\int} {COi}{cop}{52} +\DeclareFlexSymbol{\prod} {COs}{cop}{51} +\DeclareFlexSymbol{\sum} {COs}{cop}{50} +\DeclareFlexSymbol{\bigotimes}{COs}{cop}{4E} +\DeclareFlexSymbol{\bigoplus} {COs}{cop}{4C} +\DeclareFlexSymbol{\bigodot} {COs}{cop}{4A} +\DeclareFlexSymbol{\oint} {COi}{cop}{48} +\DeclareFlexSymbol{\bigsqcup} {COs}{cop}{46} +% \end{macrocode} +% Delimiter symbols. +% \verb"DeL" stands for `delimiter (left)'. +% \verb"DeR" stands for `delimiter (right)'. +% \verb"DeB" stands for `delimiter (bidirectional)'. +% The principal encoding point for an extensible delimiter is the +% first link in the list of linked sizes as specified in the font metric +% information. +% For a math encoding such as OT1/OML/OMS/OMX where not all sizes of a +% given delimiter reside in a given font, the extra encoding point for the +% smallest delimiter must be supplied by defining +% \begin{verbatim} +% \sd@GXX +% \end{verbatim} +% where G is the mathgroup and XX is the hexadecimal glyph +% position. |\DeclareFlexDelimiter| does that for us. +% \begin{macrocode} +\DeclareFlexDelimiter{\rangle}{DeR}{del}{0B}{OMS}{69} +\DeclareFlexDelimiter{\langle}{DeL}{del}{0A}{OMS}{68} +\DeclareFlexDelimiter{\rbrace}{DeR}{del}{09}{OMS}{67} +\DeclareFlexDelimiter{\lbrace}{DeL}{del}{08}{OMS}{66} +\DeclareFlexDelimiter{\rceil} {DeR}{del}{07}{OMS}{65} +\DeclareFlexDelimiter{\lceil} {DeL}{del}{06}{OMS}{64} +\DeclareFlexDelimiter{\rfloor}{DeR}{del}{05}{OMS}{63} +\DeclareFlexDelimiter{\lfloor}{DeL}{del}{04}{OMS}{62} +\DeclareFlexDelimiter{(} {DeL}{del}{00}{OT1}{28} +\DeclareFlexDelimiter{)} {DeR}{del}{01}{OT1}{29} +\DeclareFlexDelimiter{[} {DeL}{del}{02}{OT1}{5B} +\DeclareFlexDelimiter{]} {DeR}{del}{03}{OT1}{5D} +\DeclareFlexDelimiter{\lVert} {DeL}{del}{0D}{OMS}{6B} +\DeclareFlexDelimiter{\rVert} {DeR}{del}{0D}{OMS}{6B} +\DeclareFlexDelimiter{\lvert} {DeL}{del}{0C}{OMS}{6A} +\DeclareFlexDelimiter{\rvert} {DeR}{del}{0C}{OMS}{6A} +\DeclareFlexDelimiter{\Vert} {DeB}{del}{0D}{OMS}{6B} +\DeclareFlexDelimiter{\vert} {DeB}{del}{0C}{OMS}{6A} +% \end{macrocode} +% Maybe make the vert bars mathord instead of delimiter, to discourage +% poor usage. +% \begin{macrocode} +\DeclareFlexDelimiter{|}{DeB}{del}{0C}{OMS}{6A} +\DeclareFlexDelimiter{/}{DeB}{del}{0E}{OML}{3D} +% \end{macrocode} +% +% +% These wacky delimiters need to be supported I guess for +% compabitility reasons. +% The DeA delimiter type is a special case used only for these +% arrows. +% \begin{macrocode} +\DeclareFlexDelimiter{\lmoustache} {DeL}{del}{40}{del}{7A} +\DeclareFlexDelimiter{\rmoustache} {DeR}{del}{41}{del}{7B} +\DeclareFlexDelimiter{\lgroup} {DeL}{del}{3A}{del}{3A} +\DeclareFlexDelimiter{\rgroup} {DeR}{del}{3B}{del}{3B} +\DeclareFlexDelimiter{\bracevert} {DeB}{del}{3E}{del}{3E} +\DeclareFlexDelimiter{\arrowvert} {DeB}{del}{3C}{OMS}{6A} +\DeclareFlexDelimiter{\Arrowvert} {DeB}{del}{3D}{OMS}{6B} +\DeclareFlexDelimiter{\uparrow} {DeA}{del}{78}{OMS}{22} +\DeclareFlexDelimiter{\downarrow} {DeA}{del}{79}{OMS}{23} +\DeclareFlexDelimiter{\updownarrow}{DeA}{del}{3F}{OMS}{6C} +\DeclareFlexDelimiter{\Uparrow} {DeA}{del}{7E}{OMS}{2A} +\DeclareFlexDelimiter{\Downarrow} {DeA}{del}{7F}{OMS}{2B} +\DeclareFlexDelimiter{\Updownarrow}{DeA}{del}{77}{OMS}{6D} +\DeclareFlexDelimiter{\backslash} {DeB}{del}{0F}{OMS}{6E} +% \end{macrocode} +% +% +% +% +% \section{Some compound symbols} +% The following symbols are not robust in standard \LaTeX\ +% because they use \verb"#" or \cs{mathpalette} (which is not +% robust and contains a \verb"#" in its expansion): \cs{angle}, +% \cs{cong}, \cs{notin}, \cs{rightleftharpoons}. +% +% In this definition of \cs{hbar}, the symbol is cobbled together +% from a math italic h and the cmr overbar accent glyph. +% \begin{macrocode} +\DeclareFlexSymbol{\hbarOrd}{Ord}{OT1}{16} +\DeclareFlexCompoundSymbol{\hbar}{Ord}{\hbarOrd\mkern-9mu h} +% \end{macrocode} +% For \cs{surd}, the interior symbol gets math class 1 +% (cumulative operator) to make the glyph vertically centered on the +% math axis, but the desired horizontal spacing is the spacing for a +% mathord. (Couldn't it just be class mathopen, though?) +% \begin{macrocode} +\DeclareFlexSymbol{\surdOrd}{Ord}{OMS}{70} +\DeclareFlexCompoundSymbol{\surd}{Ord}{\mathop{\surdOrd}} +% \end{macrocode} +% As shown in this definition of \cs{angle}, rule dimens are not +% allowed to use math-units, unfortunately. +% \begin{macrocode} +\DeclareFlexCompoundSymbol{\angle}{Ord}{% + \vbox{\ialign{% + $\m@th\scriptstyle##$\crcr + \notRel\mathrel{\mkern14mu}\crcr + \noalign{\nointerlineskip}% + \mkern2.5mu\leaders\hrule \@height.34pt\hfill\mkern2.5mu\crcr + }}% +} +% \end{macrocode} +% The \cs{not} function, which is defined in the \pkg{flexisym} +% package, requires a suitably defined \cs{notRel} symbol. +% \begin{macrocode} +\DeclareFlexCompoundSymbol{\neq}{Rel}{\not{=}} +% \end{macrocode} +% . +% \begin{macrocode} +\DeclareFlexCompoundSymbol{\mapsto}{Rel}{\mapstoOrd\rightarrow} +% \end{macrocode} +% The \cs{@vereq} function ends by centering the whole +% construction on the math axis, unlike \cs{buildrel} where the base +% symbol remains at its normal altitude. Furthermore, +% \cs{@vereq} leaves the math style of the top symbol as given +% instead of downsizing to scriptstyle. +% \begin{macrocode} +\DeclareFlexCompoundSymbol{\cong}{Rel}{\mathpalette\@vereq\sim} +% \end{macrocode} +% The \cs{m@th} in the \fn{fontmath.ltx} definition of +% \cs{notin} is superfluous unless \cs{c@ncel} doesn't include +% it (which was perhaps true in an older version of +% \fn{plain.tex}?). +% \begin{macrocode} +\providecommand*\joinord{} +%<cmbase|mathptmx>\renewcommand*\joinord{\mkern-3mu } +%<mathpazo>\renewcommand*\joinord{\mkern-3.45mu } +\DeclareFlexCompoundSymbol{\notin}{Rel}{\mathpalette\c@ncel\in} +\DeclareFlexCompoundSymbol{\rightleftharpoons}{Rel}{\mathpalette\rlh@{}} +\DeclareFlexCompoundSymbol{\doteq}{Rel}{\buildrel\textstyle.\over=} +\DeclareFlexCompoundSymbol{\hookrightarrow}{Rel}{\lhookRel\joinord\rightarrow} +\DeclareFlexCompoundSymbol{\hookleftarrow}{Rel}{\leftarrow\joinord\rhookRel} +\DeclareFlexCompoundSymbol{\bowtie}{Rel}{\triangleright\joinord\triangleleft} +\DeclareFlexCompoundSymbol{\models}{Rel}{\vert\joinord=} +\DeclareFlexCompoundSymbol{\Longrightarrow}{Rel}{\Relbar\joinord\Rightarrow} +\DeclareFlexCompoundSymbol{\longrightarrow}{Rel}{\relbar\joinord\rightarrow} +\DeclareFlexCompoundSymbol{\Longleftarrow}{Rel}{\Leftarrow\joinord\Relbar} +\DeclareFlexCompoundSymbol{\longleftarrow}{Rel}{\leftarrow\joinord\relbar} +\DeclareFlexCompoundSymbol{\longmapsto}{Rel}{\mapstochar\longrightarrow} +\DeclareFlexCompoundSymbol{\longleftrightarrow}{Rel}{\leftarrow\joinord\rightarrow} +\DeclareFlexCompoundSymbol{\Longleftrightarrow}{Rel}{\Leftarrow\joinord\Rightarrow} +% \end{macrocode} +% Here is what you get from the old definition of \cs{iff}. +% \begin{verbatim} +% \glue 2.77771 plus 2.77771 +% \glue(\thickmuskip) 2.77771 plus 2.77771 +% \OMS/cmsy/m/n/10 ( +% \hbox(0.0+0.0)x-1.66663 +% .\kern -1.66663 +% \OMS/cmsy/m/n/10 ) +% \penalty 500 +% \glue 2.77771 plus 2.77771 +% \glue(\thickmuskip) 2.77771 plus 2.77771 +% \end{verbatim} +% Looks like it could be simplified slightly. But it's not so +% easy as it looks to do it without screwing up the line breaking +% possibilities. +% \begin{macrocode} +\renewcommand*\iff{% + \mskip\thickmuskip\Longleftrightarrow\mskip\thickmuskip +} +% \end{macrocode} +% Some dotly symbols. +% \begin{macrocode} +\DeclareFlexCompoundSymbol{\cdots}{Inn}{\cdotp\cdotp\cdotp}% +\DeclareFlexCompoundSymbol{\vdots}{Ord}{% + \vbox{\baselineskip4\p@ \lineskiplimit\z@ + \kern6\p@\hbox{.}\hbox{.}\hbox{.}}} +\DeclareFlexCompoundSymbol{\ddots}{Inn}{% + \mkern1mu\raise7\p@ + \vbox{\kern7\p@\hbox{.}}\mkern2mu% + \raise4\p@\hbox{.}\mkern2mu\raise\p@\hbox{.}\mkern1mu% +} +% \end{macrocode} +% . +% \begin{macrocode} +\def\relbar{\begingroup \def\smash@{tb}% in case amsmath is loaded + \mathpalette\mathsm@sh{\mathchar"200 }\endgroup} +% \end{macrocode} +% For \cs{Relbar} we take an equal sign of class $0$ (Ord) from the +% operator family. For \fn{cmr} and \pkg{mathptmx} we know this is +% family $0$. +% \begin{macrocode} +%<cmbase|mathptmx>\def\Relbar{\mathchar"3D } +% \end{macrocode} +% For the \pkg{mathpazo} setup we need to use the equal sign from +% \fn{cmr} and so must insert class $0$ and use the symbol from the +% upright symbols. +% \begin{macrocode} +%<mathpazo>\edef\Relbar{\mathchar\string"\hexnumber@\symupright3D } +% \end{macrocode} +% Done. +% \begin{macrocode} +\ExplSyntaxOff +%</cmbase|mathpazo|mathptmx> +% \end{macrocode} +% Various synonyms such as \cs{le} for \cs{leq} and +% \cs{to} for \cs{rightarrow} are defined in +% \pkg{flexisym} with \cs{def} instead of \cs{let}, for +% slower execution speed but smaller chance of synchronization +% problems. +% +% +% +% \begin{macrocode} +%<*msabm> +\ProvidesSymbols{msabm}[2001/09/08 v0.91] +\ExplSyntaxOn +% \end{macrocode} +% \begin{macrocode} +\RequirePackage{amsfonts}\relax +% \end{macrocode} +% \begin{macrocode} +\cs_gset:cpx{mg@MSA}{\hexnumber@\symAMSa}% +\cs_gset:cpx{mg@MSB}{\hexnumber@\symAMSb}% +% \end{macrocode} +% \begin{macrocode} +\DeclareFlexSymbol{\boxdot} {Bin}{MSA}{00} +\DeclareFlexSymbol{\boxplus} {Bin}{MSA}{01} +\DeclareFlexSymbol{\boxtimes} {Bin}{MSA}{02} +\DeclareFlexSymbol{\square} {Ord}{MSA}{03} +\DeclareFlexSymbol{\blacksquare} {Ord}{MSA}{04} +\DeclareFlexSymbol{\centerdot} {Bin}{MSA}{05} +\DeclareFlexSymbol{\lozenge} {Ord}{MSA}{06} +\DeclareFlexSymbol{\blacklozenge} {Ord}{MSA}{07} +\DeclareFlexSymbol{\circlearrowright} {Rel}{MSA}{08} +\DeclareFlexSymbol{\circlearrowleft} {Rel}{MSA}{09} +% \end{macrocode} +% In amsfonts.sty: +% \begin{macrocode} +%%\DeclareFlexSymbol{\rightleftharpoons}{Rel}{MSA}{0A} +\DeclareFlexSymbol{\leftrightharpoons} {Rel}{MSA}{0B} +\DeclareFlexSymbol{\boxminus} {Bin}{MSA}{0C} +\DeclareFlexSymbol{\Vdash} {Rel}{MSA}{0D} +\DeclareFlexSymbol{\Vvdash} {Rel}{MSA}{0E} +\DeclareFlexSymbol{\vDash} {Rel}{MSA}{0F} +\DeclareFlexSymbol{\twoheadrightarrow} {Rel}{MSA}{10} +\DeclareFlexSymbol{\twoheadleftarrow} {Rel}{MSA}{11} +\DeclareFlexSymbol{\leftleftarrows} {Rel}{MSA}{12} +\DeclareFlexSymbol{\rightrightarrows} {Rel}{MSA}{13} +\DeclareFlexSymbol{\upuparrows} {Rel}{MSA}{14} +\DeclareFlexSymbol{\downdownarrows} {Rel}{MSA}{15} +\DeclareFlexSymbol{\upharpoonright} {Rel}{MSA}{16} + \let\restriction\upharpoonright +\DeclareFlexSymbol{\downharpoonright} {Rel}{MSA}{17} +\DeclareFlexSymbol{\upharpoonleft} {Rel}{MSA}{18} +\DeclareFlexSymbol{\downharpoonleft} {Rel}{MSA}{19} +\DeclareFlexSymbol{\rightarrowtail} {Rel}{MSA}{1A} +\DeclareFlexSymbol{\leftarrowtail} {Rel}{MSA}{1B} +\DeclareFlexSymbol{\leftrightarrows} {Rel}{MSA}{1C} +\DeclareFlexSymbol{\rightleftarrows} {Rel}{MSA}{1D} +\DeclareFlexSymbol{\Lsh} {Rel}{MSA}{1E} +\DeclareFlexSymbol{\Rsh} {Rel}{MSA}{1F} +\DeclareFlexSymbol{\rightsquigarrow} {Rel}{MSA}{20} +\DeclareFlexSymbol{\leftrightsquigarrow}{Rel}{MSA}{21} +\DeclareFlexSymbol{\looparrowleft} {Rel}{MSA}{22} +\DeclareFlexSymbol{\looparrowright} {Rel}{MSA}{23} +\DeclareFlexSymbol{\circeq} {Rel}{MSA}{24} +\DeclareFlexSymbol{\succsim} {Rel}{MSA}{25} +\DeclareFlexSymbol{\gtrsim} {Rel}{MSA}{26} +\DeclareFlexSymbol{\gtrapprox} {Rel}{MSA}{27} +\DeclareFlexSymbol{\multimap} {Rel}{MSA}{28} +\DeclareFlexSymbol{\therefore} {Rel}{MSA}{29} +\DeclareFlexSymbol{\because} {Rel}{MSA}{2A} +\DeclareFlexSymbol{\doteqdot} {Rel}{MSA}{2B} + \let\Doteq\doteqdot +\DeclareFlexSymbol{\triangleq} {Rel}{MSA}{2C} +\DeclareFlexSymbol{\precsim} {Rel}{MSA}{2D} +\DeclareFlexSymbol{\lesssim} {Rel}{MSA}{2E} +\DeclareFlexSymbol{\lessapprox} {Rel}{MSA}{2F} +\DeclareFlexSymbol{\eqslantless} {Rel}{MSA}{30} +\DeclareFlexSymbol{\eqslantgtr} {Rel}{MSA}{31} +\DeclareFlexSymbol{\curlyeqprec} {Rel}{MSA}{32} +\DeclareFlexSymbol{\curlyeqsucc} {Rel}{MSA}{33} +\DeclareFlexSymbol{\preccurlyeq} {Rel}{MSA}{34} +\DeclareFlexSymbol{\leqq} {Rel}{MSA}{35} +\DeclareFlexSymbol{\leqslant} {Rel}{MSA}{36} +\DeclareFlexSymbol{\lessgtr} {Rel}{MSA}{37} +\DeclareFlexSymbol{\backprime} {Ord}{MSA}{38} +\DeclareFlexSymbol{\risingdotseq} {Rel}{MSA}{3A} +\DeclareFlexSymbol{\fallingdotseq} {Rel}{MSA}{3B} +\DeclareFlexSymbol{\succcurlyeq} {Rel}{MSA}{3C} +\DeclareFlexSymbol{\geqq} {Rel}{MSA}{3D} +\DeclareFlexSymbol{\geqslant} {Rel}{MSA}{3E} +\DeclareFlexSymbol{\gtrless} {Rel}{MSA}{3F} +% \end{macrocode} +% in amsfonts.sty +% \begin{macrocode} +%% \DeclareFlexSymbol{\sqsubset} {Rel}{MSA}{40} +%% \DeclareFlexSymbol{\sqsupset} {Rel}{MSA}{41} +\DeclareFlexSymbol{\vartriangleright} {Rel}{MSA}{42} +\DeclareFlexSymbol{\vartriangleleft} {Rel}{MSA}{43} +\DeclareFlexSymbol{\trianglerighteq} {Rel}{MSA}{44} +\DeclareFlexSymbol{\trianglelefteq} {Rel}{MSA}{45} +\DeclareFlexSymbol{\bigstar} {Ord}{MSA}{46} +\DeclareFlexSymbol{\between} {Rel}{MSA}{47} +\DeclareFlexSymbol{\blacktriangledown} {Ord}{MSA}{48} +\DeclareFlexSymbol{\blacktriangleright} {Rel}{MSA}{49} +\DeclareFlexSymbol{\blacktriangleleft} {Rel}{MSA}{4A} +\DeclareFlexSymbol{\vartriangle} {Rel}{MSA}{4D} +\DeclareFlexSymbol{\blacktriangle} {Ord}{MSA}{4E} +\DeclareFlexSymbol{\triangledown} {Ord}{MSA}{4F} +\DeclareFlexSymbol{\eqcirc} {Rel}{MSA}{50} +\DeclareFlexSymbol{\lesseqgtr} {Rel}{MSA}{51} +\DeclareFlexSymbol{\gtreqless} {Rel}{MSA}{52} +\DeclareFlexSymbol{\lesseqqgtr} {Rel}{MSA}{53} +\DeclareFlexSymbol{\gtreqqless} {Rel}{MSA}{54} +\DeclareFlexSymbol{\Rrightarrow} {Rel}{MSA}{56} +\DeclareFlexSymbol{\Lleftarrow} {Rel}{MSA}{57} +\DeclareFlexSymbol{\veebar} {Bin}{MSA}{59} +\DeclareFlexSymbol{\barwedge} {Bin}{MSA}{5A} +\DeclareFlexSymbol{\doublebarwedge} {Bin}{MSA}{5B} +% \end{macrocode} +% In amsfonts.sty +% \begin{macrocode} +%%\DeclareFlexSymbol{\angle} {Ord}{MSA}{5C} +\DeclareFlexSymbol{\measuredangle} {Ord}{MSA}{5D} +\DeclareFlexSymbol{\sphericalangle} {Ord}{MSA}{5E} +\DeclareFlexSymbol{\varpropto} {Rel}{MSA}{5F} +\DeclareFlexSymbol{\smallsmile} {Rel}{MSA}{60} +\DeclareFlexSymbol{\smallfrown} {Rel}{MSA}{61} +\DeclareFlexSymbol{\Subset} {Rel}{MSA}{62} +\DeclareFlexSymbol{\Supset} {Rel}{MSA}{63} +\DeclareFlexSymbol{\Cup} {Bin}{MSA}{64} + \let\doublecup\Cup +\DeclareFlexSymbol{\Cap} {Bin}{MSA}{65} + \let\doublecap\Cap +\DeclareFlexSymbol{\curlywedge} {Bin}{MSA}{66} +\DeclareFlexSymbol{\curlyvee} {Bin}{MSA}{67} +\DeclareFlexSymbol{\leftthreetimes} {Bin}{MSA}{68} +\DeclareFlexSymbol{\rightthreetimes} {Bin}{MSA}{69} +\DeclareFlexSymbol{\subseteqq} {Rel}{MSA}{6A} +\DeclareFlexSymbol{\supseteqq} {Rel}{MSA}{6B} +\DeclareFlexSymbol{\bumpeq} {Rel}{MSA}{6C} +\DeclareFlexSymbol{\Bumpeq} {Rel}{MSA}{6D} +\DeclareFlexSymbol{\lll} {Rel}{MSA}{6E} + \let\llless\lll +\DeclareFlexSymbol{\ggg} {Rel}{MSA}{6F} + \let\gggtr\ggg +\DeclareFlexSymbol{\circledS} {Ord}{MSA}{73} +\DeclareFlexSymbol{\pitchfork} {Rel}{MSA}{74} +\DeclareFlexSymbol{\dotplus} {Bin}{MSA}{75} +\DeclareFlexSymbol{\backsim} {Rel}{MSA}{76} +\DeclareFlexSymbol{\backsimeq} {Rel}{MSA}{77} +\DeclareFlexSymbol{\complement} {Ord}{MSA}{7B} +\DeclareFlexSymbol{\intercal} {Bin}{MSA}{7C} +\DeclareFlexSymbol{\circledcirc} {Bin}{MSA}{7D} +\DeclareFlexSymbol{\circledast} {Bin}{MSA}{7E} +\DeclareFlexSymbol{\circleddash} {Bin}{MSA}{7F} +% \end{macrocode} +% Begin AMSb declarations +% \begin{macrocode} +\DeclareFlexSymbol{\lvertneqq} {Rel}{MSB}{00} +\DeclareFlexSymbol{\gvertneqq} {Rel}{MSB}{01} +\DeclareFlexSymbol{\nleq} {Rel}{MSB}{02} +\DeclareFlexSymbol{\ngeq} {Rel}{MSB}{03} +\DeclareFlexSymbol{\nless} {Rel}{MSB}{04} +\DeclareFlexSymbol{\ngtr} {Rel}{MSB}{05} +\DeclareFlexSymbol{\nprec} {Rel}{MSB}{06} +\DeclareFlexSymbol{\nsucc} {Rel}{MSB}{07} +\DeclareFlexSymbol{\lneqq} {Rel}{MSB}{08} +\DeclareFlexSymbol{\gneqq} {Rel}{MSB}{09} +\DeclareFlexSymbol{\nleqslant} {Rel}{MSB}{0A} +\DeclareFlexSymbol{\ngeqslant} {Rel}{MSB}{0B} +\DeclareFlexSymbol{\lneq} {Rel}{MSB}{0C} +\DeclareFlexSymbol{\gneq} {Rel}{MSB}{0D} +\DeclareFlexSymbol{\npreceq} {Rel}{MSB}{0E} +\DeclareFlexSymbol{\nsucceq} {Rel}{MSB}{0F} +\DeclareFlexSymbol{\precnsim} {Rel}{MSB}{10} +\DeclareFlexSymbol{\succnsim} {Rel}{MSB}{11} +\DeclareFlexSymbol{\lnsim} {Rel}{MSB}{12} +\DeclareFlexSymbol{\gnsim} {Rel}{MSB}{13} +\DeclareFlexSymbol{\nleqq} {Rel}{MSB}{14} +\DeclareFlexSymbol{\ngeqq} {Rel}{MSB}{15} +\DeclareFlexSymbol{\precneqq} {Rel}{MSB}{16} +\DeclareFlexSymbol{\succneqq} {Rel}{MSB}{17} +\DeclareFlexSymbol{\precnapprox} {Rel}{MSB}{18} +\DeclareFlexSymbol{\succnapprox} {Rel}{MSB}{19} +\DeclareFlexSymbol{\lnapprox} {Rel}{MSB}{1A} +\DeclareFlexSymbol{\gnapprox} {Rel}{MSB}{1B} +\DeclareFlexSymbol{\nsim} {Rel}{MSB}{1C} +\DeclareFlexSymbol{\ncong} {Rel}{MSB}{1D} +\DeclareFlexSymbol{\diagup} {Ord}{MSB}{1E} +\DeclareFlexSymbol{\diagdown} {Ord}{MSB}{1F} +\DeclareFlexSymbol{\varsubsetneq} {Rel}{MSB}{20} +\DeclareFlexSymbol{\varsupsetneq} {Rel}{MSB}{21} +\DeclareFlexSymbol{\nsubseteqq} {Rel}{MSB}{22} +\DeclareFlexSymbol{\nsupseteqq} {Rel}{MSB}{23} +\DeclareFlexSymbol{\subsetneqq} {Rel}{MSB}{24} +\DeclareFlexSymbol{\supsetneqq} {Rel}{MSB}{25} +\DeclareFlexSymbol{\varsubsetneqq} {Rel}{MSB}{26} +\DeclareFlexSymbol{\varsupsetneqq} {Rel}{MSB}{27} +\DeclareFlexSymbol{\subsetneq} {Rel}{MSB}{28} +\DeclareFlexSymbol{\supsetneq} {Rel}{MSB}{29} +\DeclareFlexSymbol{\nsubseteq} {Rel}{MSB}{2A} +\DeclareFlexSymbol{\nsupseteq} {Rel}{MSB}{2B} +\DeclareFlexSymbol{\nparallel} {Rel}{MSB}{2C} +\DeclareFlexSymbol{\nmid} {Rel}{MSB}{2D} +\DeclareFlexSymbol{\nshortmid} {Rel}{MSB}{2E} +\DeclareFlexSymbol{\nshortparallel} {Rel}{MSB}{2F} +\DeclareFlexSymbol{\nvdash} {Rel}{MSB}{30} +\DeclareFlexSymbol{\nVdash} {Rel}{MSB}{31} +\DeclareFlexSymbol{\nvDash} {Rel}{MSB}{32} +\DeclareFlexSymbol{\nVDash} {Rel}{MSB}{33} +\DeclareFlexSymbol{\ntrianglerighteq}{Rel}{MSB}{34} +\DeclareFlexSymbol{\ntrianglelefteq} {Rel}{MSB}{35} +\DeclareFlexSymbol{\ntriangleleft} {Rel}{MSB}{36} +\DeclareFlexSymbol{\ntriangleright} {Rel}{MSB}{37} +\DeclareFlexSymbol{\nleftarrow} {Rel}{MSB}{38} +\DeclareFlexSymbol{\nrightarrow} {Rel}{MSB}{39} +\DeclareFlexSymbol{\nLeftarrow} {Rel}{MSB}{3A} +\DeclareFlexSymbol{\nRightarrow} {Rel}{MSB}{3B} +\DeclareFlexSymbol{\nLeftrightarrow} {Rel}{MSB}{3C} +\DeclareFlexSymbol{\nleftrightarrow} {Rel}{MSB}{3D} +\DeclareFlexSymbol{\divideontimes} {Bin}{MSB}{3E} +\DeclareFlexSymbol{\varnothing} {Ord}{MSB}{3F} +\DeclareFlexSymbol{\nexists} {Ord}{MSB}{40} +\DeclareFlexSymbol{\Finv} {Ord}{MSB}{60} +\DeclareFlexSymbol{\Game} {Ord}{MSB}{61} +% \end{macrocode} +% In amsfonts.sty: +% \begin{macrocode} +%%\DeclareFlexSymbol{\mho} {Ord}{MSB}{66} +\DeclareFlexSymbol{\eth} {Ord}{MSB}{67} +\DeclareFlexSymbol{\eqsim} {Rel}{MSB}{68} +\DeclareFlexSymbol{\beth} {Ord}{MSB}{69} +\DeclareFlexSymbol{\gimel} {Ord}{MSB}{6A} +\DeclareFlexSymbol{\daleth} {Ord}{MSB}{6B} +\DeclareFlexSymbol{\lessdot} {Bin}{MSB}{6C} +\DeclareFlexSymbol{\gtrdot} {Bin}{MSB}{6D} +\DeclareFlexSymbol{\ltimes} {Bin}{MSB}{6E} +\DeclareFlexSymbol{\rtimes} {Bin}{MSB}{6F} +\DeclareFlexSymbol{\shortmid} {Rel}{MSB}{70} +\DeclareFlexSymbol{\shortparallel} {Rel}{MSB}{71} +\DeclareFlexSymbol{\smallsetminus} {Bin}{MSB}{72} +\DeclareFlexSymbol{\thicksim} {Rel}{MSB}{73} +\DeclareFlexSymbol{\thickapprox} {Rel}{MSB}{74} +\DeclareFlexSymbol{\approxeq} {Rel}{MSB}{75} +\DeclareFlexSymbol{\succapprox} {Rel}{MSB}{76} +\DeclareFlexSymbol{\precapprox} {Rel}{MSB}{77} +\DeclareFlexSymbol{\curvearrowleft} {Rel}{MSB}{78} +\DeclareFlexSymbol{\curvearrowright} {Rel}{MSB}{79} +\DeclareFlexSymbol{\digamma} {Ord}{MSB}{7A} +\DeclareFlexSymbol{\varkappa} {Ord}{MSB}{7B} +\DeclareFlexSymbol{\Bbbk} {Ord}{MSB}{7C} +\DeclareFlexSymbol{\hslash} {Ord}{MSB}{7D} +% \end{macrocode} +% In amsfonts.sty: +% \begin{macrocode} +%%\DeclareFlexSymbol{\hbar} {Ord}{MSB}{7E} +\DeclareFlexSymbol{\backepsilon} {Rel}{MSB}{7F} +\ExplSyntaxOff +%</msabm> +% \end{macrocode} +% +% \PrintIndex +% +% \Finale diff --git a/Master/texmf-dist/source/latex/breqn/mathstyle.dtx b/Master/texmf-dist/source/latex/breqn/mathstyle.dtx new file mode 100644 index 00000000000..98dac625363 --- /dev/null +++ b/Master/texmf-dist/source/latex/breqn/mathstyle.dtx @@ -0,0 +1,487 @@ +% \iffalse meta-comment +% +% Copyright (C) 1997-2003 by Michael J. Downes +% Copyright (C) 2007-2008 by Morten Hoegholm +% Copyright (C) 2007-2014 by Lars Madsen +% Copyright (C) 2007-2014 by Will Robertson +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 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 2005/12/01 or later. +% +% This work has the LPPL maintenance status "maintained". +% +% The Current Maintainer of this work is Will Robertson. +% +% This work consists of the main source file mathstyle.dtx +% and the derived files +% mathstyle.sty, mathstyle.pdf, mathstyle.ins, mathstyle.drv. +% +% Distribution: +% CTAN:macros/latex/contrib/mh/mathstyle.dtx +% CTAN:macros/latex/contrib/mh/mathstyle.pdf +% +% Unpacking: +% (a) If mathstyle.ins is present: +% tex mathstyle.ins +% (b) Without mathstyle.ins: +% tex mathstyle.dtx +% (c) If you insist on using LaTeX +% latex \let\install=y\input{mathstyle.dtx} +% (quote the arguments according to the demands of your shell) +% +% Documentation: +% The class ltxdoc loads the configuration file ltxdoc.cfg +% if available. Here you can specify further options, e.g. +% use A4 as paper format: +% \PassOptionsToClass{a4paper}{article} +% +% Programm calls to get the documentation (example): +% pdflatex mathstyle.dtx +% makeindex -s gind.ist mathstyle.idx +% pdflatex mathstyle.dtx +% makeindex -s gind.ist mathstyle.idx +% pdflatex mathstyle.dtx +% +% Installation: +% TDS:tex/latex/breqn/mathstyle.sty +% TDS:doc/latex/breqn/mathstyle.pdf +% TDS:source/latex/breqn/mathstyle.dtx +% +%<*ignore> +\begingroup + \def\x{LaTeX2e} +\expandafter\endgroup +\ifcase 0\ifx\install y1\fi\expandafter + \ifx\csname processbatchFile\endcsname\relax\else1\fi + \ifx\fmtname\x\else 1\fi\relax +\else\csname fi\endcsname +%</ignore> +%<*install> +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation for package: mathstyle} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\preamble + +This is a generated file. + +Copyright (C) 1997-2003 by Michael J. Downes +Copyright (C) 2007-2011 by Morten Hoegholm et al +Copyright (C) 2007-2014 by Lars Madsen +Copyright (C) 2007-2014 by Will Robertson + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 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 2005/12/01 or later. + +This work has the LPPL maintenance status "maintained". + +The Current Maintainer of this work is Will Robertson. + +This work consists of the main source file mathstyle.dtx +and the derived files + mathstyle.sty, mathstyle.pdf, mathstyle.ins. + +\endpreamble + +\generate{% + \file{mathstyle.ins}{\from{mathstyle.dtx}{install}}% + \usedir{tex/latex/breqn}% + \file{mathstyle.sty}{\from{mathstyle.dtx}{package}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* file into a directory searched by TeX:} +\Msg{*} +\Msg{* mathstyle.sty} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endbatchfile +%</install> +%<*ignore> +\fi +%</ignore> +% +%<*driver> +\ProvidesFile{mathstyle.drv} +%</driver> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{mathstyle} +%<*package|driver> + [2014/06/10 v0.90a Tracking mathstyle implicitly] +%</package|driver> +%<*driver> +\documentclass{ltxdoc} +\CodelineIndex +\EnableCrossrefs +\setcounter{IndexColumns}{2} +\providecommand*\pkg[1]{\textsf{#1}} +\begin{document} + \DocInput{mathstyle.dtx} +\end{document} +%</driver> +% \fi +% +% \GetFileInfo{mathstyle.drv} +% \title{The \textsf{mathstyle} package} +% \date{\filedate\quad\fileversion} +% \author{Author: Morten H\o gholm\\ Inactively maintained by Will Robertson\\ Feedback: \texttt{https://github.com/wspr/breqn/issues}} +% +% +% \maketitle +% +% \part*{User's guide} +% +% This package exists for two reasons: +% \begin{itemize} +% \item The primitive operations for creating a super- or subscript in +% \TeX\ work almost as if \verb|^| and \verb|_| are macros taking an +% argument. However, that is not quite the case, and +% some things that you'd expect to work don't (e.g., \verb|^\cong|) +% whereas others which you'd think shouldn't work actually +% do (such as |^\mathsf{s}|). We do everyone a favor if it behaves +% consistently, i.e., if the superscript and subscript operations +% act as if they are macros taking exactly one argument. +% +% \item Because the \TeX\ math typesetting engine uses infix notation +% for fractions, one has to use \cs{mathchoice} or \cs{mathpalette} +% whenever trying to do anything requiring boxing or measuring +% math. This creates problems for loading fonts on demand as the +% font loading mechanism has to load fonts for all styles without +% even knowing if the font is going to be used. Getting the timing +% of \cs{mathchoice} right can be tricky as well. Since \LaTeX\ does +% not promote the primitive infix notation, this package keeps track +% of a current mathstyle parameter. +% \end{itemize} +% +% +% \section{Some usage tips} +% +% If you want to use this package with \pkg{amsmath}, it is important +% \pkg{mathstyle} is loaded \emph{after} \pkg{amsmath}. +% +% The current mathstyle is stored in the variable \cs{mathstyle}. The +% command \cs{currentmathstyle} can be used to switch to the mode +% currently active. Below is shown how the macro \cs{mathrlap} from +% \pkg{mathtools} is implemented without knowing about the current +% mathstyle using \cs{mathpalette}. +% \begin{verbatim} +% \providecommand*\mathrlap[1][]{% +% \ifx\@empty#1\@empty +% \expandafter \mathpalette \expandafter \@mathrlap +% \else +% \expandafter \@mathrlap \expandafter #1% +% \fi} +% \providecommand*\@mathrlap #1#2{{}\rlap{$\m@th#1{#2}$}} +% \end{verbatim} +% The same definition using \cs{currentmathstyle} from this package. +% \begin{verbatim} +% \providecommand*\mathrlap[2][]{% +% #1 {}\rlap{$\m@th \currentmathstyle {#2}$}} +% \end{verbatim} +% +% \subsection{Package options} +% +% This package has one set of options affecting the \verb|_| and \verb|^| characters: +% +% \begin{itemize} +% \item\verb|\usepackage[mathactivechars]{mathstyle}| +% +% This is the default behaviour. Here, \verb|_| and \verb|^| are made into harmless +% characters in text mode and behave as expected (for entering sub/superscript) when +% inside math mode. +% Certain code that assumes the catcodes of these characters may get confused about +% this; see below for a possible fix. +% +% \item\verb|\usepackage[activechars]{mathstyle}| +% +% With this option, \verb|_| and \verb|^| are made into active characters for +% entering sub/superscript mode in all cases---therefore, in text mode they will +% produce a regular error (`Missing \$ inserted') indicating they are being used +% out of place. +% +% \item\verb|\usepackage[noactivechars]{mathstyle}| +% +% This is the option most like to solve any compatibility problems. Here, +% \verb|_| and \verb|^| retain their regular catcodes at all times and behave +% in their default fashion. \textbf{However}, certain other features of this +% package (such as \cs{currentmathstyle} inside a subscript) will then fail +% to work, so only use this option as a last resort. +% \end{itemize} +% +% \StopEventually{} +% \part*{Implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macro}{\@saveprimitive} +% A straight copy from \pkg{breqn}, see implementation details +% there. Of course, with a recent pdf\TeX\ (v1.40+), one can just +% use \cs{primitive} to get the original. We will implement that +% some day. +% \begin{macrocode} +\providecommand\@saveprimitive[2]{% + \begingroup + \edef\@tempa{\string#1}\edef\@tempb{\meaning#1}% + \ifx\@tempa\@tempb \global\let#2#1% + \else + \edef\@tempb{\meaning#2}% + \ifx\@tempa\@tempb + \else \@saveprimitive@a#1#2% + \fi + \fi + \endgroup +} +\providecommand\@saveprimitive@a[2]{% + \begingroup + \def\@tempb##1#1##2{\edef\@tempb{##2}\@car{}}% + \@tempb\nullfont{select font nullfont}% + \topmark{\string\topmark:}% + \firstmark{\string\firstmark:}% + \botmark{\string\botmark:}% + \splitfirstmark{\string\splitfirstmark:}% + \splitbotmark{\string\splitbotmark:}% + #1{\string#1}% + \@nil % for the \@car + \edef\@tempa{\expandafter\strip@prefix\meaning\@tempb}% + \edef\@tempb{\meaning#1}% + \ifx\@tempa\@tempb \global\let#2#1% + \else + \PackageError{mathstyle}% + {Unable to properly define \string#2; primitive + \noexpand#1no longer primitive}\@eha + \fi + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\everydisplay} +% We need to keep track of whether we're in inline or display maths, and the only +% way to do that is to add a switch inside \verb|\everydisplay|. +% We act sensibly and preserve any of the previous contents of that token register +% before adding our own code here. +% \begin{macrocode} +\everydisplay=\expandafter{\the\everydisplay\chardef\mathstyle\z@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mathstyle} +% A counter for the math style: 0--display, 1--text, 2--script, 3--scriptscript. +% The logic is that display maths will explicitly +% set \verb|\mathstyle| to zero (see above), so by default it is set to the +% `text' maths style. +% \begin{macrocode} +\chardef\mathstyle\@ne +% \end{macrocode} +% \end{macro} +% +% Save the four style changing primitives, \cs{mathchoice} and the +% fraction commands. +% \begin{macrocode} +\@saveprimitive\displaystyle\@@displaystyle +\@saveprimitive\textstyle\@@textstyle +\@saveprimitive\scriptstyle\@@scriptstyle +\@saveprimitive\scriptscriptstyle\@@scriptscriptstyle +\@saveprimitive\mathchoice\@@mathchoice +\@saveprimitive\over\@@over +\@saveprimitive\atop\@@atop +\@saveprimitive\above\@@above +\@saveprimitive\overwithdelims\@@overwithdelims +\@saveprimitive\atopwithdelims\@@atopwithdelims +\@saveprimitive\abovewithdelims\@@abovewithdelims +% \end{macrocode} +% Then we redeclare the four style changing primitives. +% \begin{macrocode} +\DeclareRobustCommand{\displaystyle}{% + \@@displaystyle \chardef\mathstyle\z@} +\DeclareRobustCommand{\textstyle}{% + \@@textstyle \chardef\mathstyle\@ne} +\DeclareRobustCommand{\scriptstyle}{% + \@@scriptstyle \chardef\mathstyle\tw@} +\DeclareRobustCommand{\scriptscriptstyle}{% + \@@scriptscriptstyle \chardef\mathstyle\thr@@} +% \end{macrocode} +% First we get the primitive operations. These should have been +% control sequences in \TeX\ just like operations for begin math, end +% math, begin display, end display. +% \begin{macrocode} +\begingroup \catcode`\^=7\relax \catcode`\_=8\relax % just in case +\lowercase{\endgroup +\let\@@superscript=^ \let\@@subscript=_ +}% +\begingroup \catcode`\^=12\relax \catcode`\_=12\relax % just in case +\lowercase{\endgroup +\let\@@superscript@other=^ \let\@@subscript@other=_ +}% +% \end{macrocode} +% If we enter a sub- or superscript the \cs{mathstyle} must be +% adjusted. Since all is happening in a group, we do not have to worry +% about resetting. +% \begin{macrocode} +\def\subsupstyle{% + \ifnum\mathstyle<\tw@ \chardef\mathstyle\tw@ + \else \chardef\mathstyle\thr@@ + \fi +} +% \end{macrocode} +% Provide commands with meaningful names for the two primitives, cf.\ +% \cs{mathrel}. +% \begin{macrocode} +\let\mathsup=\@@superscript +\let\mathsub=\@@subscript +% \end{macrocode} +% \cs{sb} and \cs{sp} are then defined as macros. +% \begin{macrocode} +\def\sb#1{\mathsub{\protect\subsupstyle#1}}% +\def\sp#1{\mathsup{\protect\subsupstyle#1}}% +% \end{macrocode} +% +% \begin{macro}{\mathchoice} +% \cs{mathchoice} is now just a switch. Note that this redefinition +% does not allow the arbitrary \meta{filler} of the \TeX\ +% primitive. Very rarely used anyway. +% \begin{macrocode} +\def\mathchoice{% + \relax\ifcase\mathstyle + \expandafter\@firstoffour + \or + \expandafter\@secondoffour + \or + \expandafter\@thirdoffour + \else + \expandafter\@fourthoffour + \fi +} +% \end{macrocode} +% Helper macros. +% \begin{macrocode} +\providecommand\@firstoffour[4]{#1} +\providecommand\@secondoffour[4]{#2} +\providecommand\@thirdoffour[4]{#3} +\providecommand\@fourthoffour[4]{#4} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\genfrac} +% The fractions. Note that this uses the same names as in +% \pkg{amsmath}. Much the same except here they call \cs{fracstyle}. +% \begin{macrocode} +\DeclareRobustCommand\genfrac[6]{% + {#1\fracstyle + {\begingroup #5\endgroup + \csname @@\ifx\maxdimen#4\maxdimen over\else above\fi + \if @#2@\else withdelims\fi\endcsname #2#3#4\relax + #6}% + }% +} +% \end{macrocode} +% \changes{v0.90}{2011/08/03}{\cs{fracstyle} must be called \emph{after} +% changing to the required style} +% \end{macro} +% +% \begin{macrocode} +\renewcommand{\frac}{\genfrac{}{}{}{}} +\providecommand{\dfrac}{} +\providecommand{\tfrac}{} +\renewcommand{\dfrac}{\genfrac\displaystyle{}{}{}} +\renewcommand{\tfrac}{\genfrac\textstyle{}{}{}} +\providecommand{\binom}{} +\providecommand{\tbinom}{} +\providecommand{\dbinom}{} +\renewcommand{\binom}{\genfrac{}(){0pt}} +\renewcommand{\dbinom}{\genfrac\displaystyle(){0pt}} +\renewcommand{\tbinom}{\genfrac\textstyle(){0pt}} +% \end{macrocode} +% The \cs{fracstyle} command is a switch to go one level down but no +% further than three. +% \begin{macrocode} +\def\fracstyle{\ifcase\mathstyle + \chardef\mathstyle=\@ne + \or + \chardef\mathstyle=\tw@ + \else + \chardef\mathstyle=\thr@@ + \fi +} +% \end{macrocode} +% The \cs{currentmathstyle} checks the value of \cs{mathstyle} and +% switches to it so it is in essence the opposite of \cs{displaystyle} +% and friends. +% \begin{macrocode} +\def\currentmathstyle{% + \ifcase\mathstyle + \@@displaystyle + \or + \@@textstyle + \or + \@@scriptstyle + \or + \@@scriptscriptstyle + \fi} +% \end{macrocode} +% Finally, we declare the package options. +% \changes{v0.89}{2010/11/17}{Options should only change catcodes at +% begin document, not straight away} +% \begin{macrocode} +\DeclareOption{mathactivechars}{% + % \catcode`\^=12\relax + % \catcode`\_=12\relax +\AtBeginDocument{\catcode`\^=12\relax \catcode`\_=12\relax}% +} +\DeclareOption{activechars}{% + % \catcode`\^=13\relax + % \catcode`\_=13\relax +\AtBeginDocument{\catcode`\^=13\relax \catcode`\_=13\relax}% +} +\DeclareOption{noactivechars}{% + % \catcode`\^=7\relax + % \catcode`\_=8\relax +\AtBeginDocument{\catcode`\^=7\relax \catcode`\_=8\relax}% +} +\ExecuteOptions{mathactivechars} +\ProcessOptions\relax +% \end{macrocode} +% WSPR: Set up the active behaviours: (this is set even in the +% |noactivechars| case but they are never activated. no worries?) +% \begin{macrocode} +\ifnum\catcode`\^=13\relax + \let^=\sp \let_=\sb +\else + \mathcode`\^="8000\relax + \mathcode`\_="8000\relax + \begingroup + \catcode`\^=\active + \catcode`\_=\active + \global\let^=\sp + \global\let_=\sb + \endgroup +\fi +%</package> +% \end{macrocode} +% +% \PrintIndex +% +% \Finale |