home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
lout2.lzh
/
LOUT2
/
DOC
/
TR.LOUT
/
ch4.01
< prev
next >
Wrap
Text File
|
1994-01-25
|
7KB
|
187 lines
@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 Eq user manual [{@Ref kingston92eq}], an equation is
entered in a format based on the one introduced by the eqn language of
Kernighan and Cherry [{@Ref kernighan75}]:
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 [{@Ref knuth84}].
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 commandeers the @Code v unit,
normally used for line gaps, and uses it for these spaces instead:
@ID @Code {
"def @MedGap { 0.20v }"
""
"def \"+\" { &@MedGap plus &@MedGap }"
""
"def @Smaller right x { 0.7f @Font 0c @Space 0.2f @Break x }"
}
The @Code "@Smaller" symbol is applied to all superscripts and subscripts,
reducing the font size and also reducing the @Code "v" unit,
thereby reducing the space around @Code "+" and similar symbols.
@PP
Some objects, notably matrices and large summation signs, must be
vertically centred in the sense that their axis must be placed halfway
down the object. This seems quite different to the usual kind of
centring of one object within another handled by the @Code "0.5rt" gap.
With the aid of the @Code w unit used with concatenation symbols (one
w.unit.example @SubIndex { example of use of }
@Code w is the size of the following object) and some ingenuity we find that
vctr.example @Index { @Code vctr example }
@ID @Code {
"def vctr right x"
"{ @OneRow { /0.5wo @OneRow { @OneRow x ^/ } }"
"}"
}
will vertically centre its parameter: @Code "@OneRow { @OneRow x ^/ }"
replaces {@Code x}'s mark by one mark along its lower boundary; then
@Code "/0.5wo" overstrikes the desired mark, and the outer @@OneRow
hides the lower mark. Unfortunately, although the parameter is
correctly placed and printed, the overstriking hides its top half, and
@ID @Code {
"vctr sum from i=0 to n i"
}
appears as
@ID @Eq {
@OneRow { /0.5wo @OneRow { @OneRow sum ^/ } }
from i=0 to n i
}
using this definition. The version of @Code "vctr" in Eq
overcomes this problem by overstriking two copies of the parameter, one
of which has been rotated twice by 180 degrees:
@ID @Code {
"def vctr right x"
"{ @OneRow"
" { -180d @Rotate { /0.5wo 180d @Rotate { / @OneRow @OneCol x } }"
" ^/ @OneRow { /0.5wo @OneRow { @OneRow @OneCol x ^/ } }"
" }"
"}"
}
This is very ugly and suggests that something is lacking from Lout's features.
@End @Section