aboutsummaryrefslogblamecommitdiffstats
path: root/doc/expert/exa_equa
blob: 67852b8a54ced68f65247c70edafb7f7eb499ea3 (plain) (tree)




















































































































































                                                                           
@Section
   @Title { An equation formatting package }
   @Tag { eq }
@Begin
@PP
In this section we describe the design and implementation of the Eq
eq. @Index { Eq equation formatting package }
equation formatting package.  Equation formatting makes a natural first
example, partly because its requirements have strongly influenced the
design of Lout, and partly because no cross references or galleys are
required.
@PP
To the author's knowledge, Eq is the first equation formatter to be
implemented as a collection of high-level definitions.  This approach
has significant advantages:  the basics of language and layout are
trivial, so the implementor can concentrate on fine-tuning; and the
definitions, being readily available, can be improved, extended, or even
replaced.
@PP
As described in the User's Guide @Cite { $kingston1995lout.user }, an
equation is entered in a format based on the one introduced by the eqn
language of Kernighan and Cherry @Cite { $kernighan1975eqn }:
kernighan.b @Index { Kernighan, B. }
cherry.l @Index { Cherry, L. }
@ID @Code {
"@Eq { { x sup 2  +  y sup 2 }  over  2 }"
}
The result is
@ID @Eq { { x sup 2  +  y sup 2 }  over  2 }
In outline, the definition of the @Code "@Eq" symbol is
eq.example @Index { @Code "@Eq" example }
@ID @Code {
"export  sup  over \"+\"  \"2\"  \"<=\""
"def @Eq"
"   body @Body"
"{"
"   def sup precedence 60 left x right y { ... }"
"   def over precedence 54 left x right y { ... }"
"   def \"2\" { Base @Font \"2\" }"
"   def \"+\" { {Symbol Base} @Font \"+\" }"
"   def \"<=\" { {Symbol Base} @Font \"\\243\" }"
"   ..."
""
"   Slope @Font 1.2f @Break 0c @Space @Body"
"}"
}
A body parameter is used to restrict the visibility of the equation
formatting symbols (there are hundreds of them).  The equation as a whole
is set in Slope (i.e. Italic) font, and symbols such as @Code "\"2\"" and
@Code "\"+\"" are defined when other fonts are needed.  Precedences are
used to resolve ambiguities such as {@Code "a sup b over c"}.  Eq takes
all spacing decisions on itself, so to prevent white space
typed by the user from interfering, the equation is enclosed in
{@Code "0c @Space"}.  We will discuss the {@Code "1.2f @Break"} later.
@PP
Thus have we disposed of the language design part of the equation
formatting problem; it remains now to define the twenty or so symbols
with parameters, and get the layout right.
@PP
Every equation has an {@I axis}:  an imaginary horizontal line through
the centre of variables, through the bar of built-up fractions, and so
on.  We can satisfy this requirement by ensuring that the result of each
symbol has a single row mark, on the axis.  For example, the
superscripting symbol is defined as follows:
sup.example @Index { @Code "sup" example }
@ID @Code {
"def sup"
"    precedence 60"
"    associativity left"
"    left x"
"    named gap { @SupGap }"
"    right y"
"{"
"    @HContract @VContract {"
"        |  @Smaller y"
"        ^/gap  x"
"    }"
"}"
}
The @Code "@VContract" and @Code "^/" symbols together ensure that the axis
of the result is the axis of the left parameter.  A @Code "gap"
parameter has been provided for varying the height of the superscript,
with default value @Code "@SupGap"  defined elsewhere as
{@Code "0.40fk"}.  It is important that such gaps be expressed in units
that vary with the font size, so that they remain correct when the size
changes.  Collecting the default values into symbols like @Code
"@SupGap" ensures consistency and assists when tuning the values.  Here
is another characteristic definition:
over.example @Index { @Code "over" example }
@ID @Code {
"def over"
"    precedence 54"
"    associativity left"
"    left x"
"    named gap { 0.2f }"
"    right y"
"{"
"    @HContract @VContract {"
"        |0.5rt  @OneCol x"
"        ^//gap  @HLine"
"        //gap  |0.5rt @OneCol y"
"    }"
"}"
}
Both parameters are centred, since we do not know which will be the
wider; we use @@OneCol to make sure that the entire parameter is
centred, not just its first column, and @@HContract ensures that the
fraction will never expand to fill all the available space, as Lout objects
have a natural tendency to do (Section {@NumberOf size}).  @Code "@HLine"
is a horizontal line of the width of the column:
hline.example @Index { @Code "@Hline" example }
@ID @Code {
"def @HLine"
"    named line { \"0.05 ft setlinewidth\" }"
"{  "
"    { \"0 0 moveto xsize 0 lineto\" line \"stroke\" } @Graphic {}"
"}"
}
Here we are relying on the expanding tendency just mentioned.
@PP
The remaining symbols are quite similar to these ones.  We conclude with
a few fine points of mathematical typesetting mentioned by a leading
authority, D. E. Knuth @Cite { $knuth1984tex }.
knuth.d @Index { Knuth, D. }
@PP
Some symbols, such as @Eq {lessequal} and @Eq { notequal }, should have a
thick space on each side; others, such as @Eq {plus} and @Eq {minus},
have a medium space; others have a thin space on the right only.  This
would be easy to do except that these spaces are not wanted in
superscripts and subscripts:
@ID @Eq { r sup n+1 - 1 }
In effect, the definition of such symbols changes depending on the
context; but Lout does not permit such a change.  Luckily, the so-called
`style' information set by the @@Font, @@Break, and @@Space symbols can
change in this way.  Accordingly, Eq uses the @Code y unit, which is
part of style, for these spaces:
@ID @Code {
"def @MedGap { 0.20y }"
""
"def \"+\" { &@MedGap plus &@MedGap }"
""
"def @HSqueeze right x { 0.2f @YUnit x }"
}
In the equation as a whole, the y unit is initially set to
{@Code 1f}, and so @Code "@MedGap" ordinarily supplies 20% of this
amount.  But superscripts and subscripts are enclosed in the
@Code "@HSqueeze" symbol, which, by changing the y unit, ensures that
any @Code "@MedGap" within them is much smaller than usual.
@End @Section