[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Context variables and equations
From: |
Ludovic Courtès |
Subject: |
Context variables and equations |
Date: |
Sun, 18 Feb 2007 20:52:21 +0100 |
User-agent: |
Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) |
Hi,
Below is a patch that implements address@hidden' and address@hidden' and
uses it in order to implement the equation layout styles described in
``The TeXbook'', Chapter 17. Two test files are available at:
http://www.laas.fr/~lcourtes/software/lout/set-context.lout
http://www.laas.fr/~lcourtes/software/lout/eq.lout
Unfortunately, the context mechanism is still somewhat buggy (more one
that below).
The objects returned by address@hidden' are manifested using the context
current at the address@hidden' invocation point, but using the style
current at the address@hidden' point. Example:
@SetContext key { "some-key" } value { "the outer one" } {
@SetContext key { "stuff" } value { @GetContext "some-key" } {
@SetContext key { "some-key" } value { "the inner one" } {
This should be the outer value, in bold: @B @GetContext "stuff" .
}
}
}
The value returned by address@hidden "stuff"' here is "the outer one" and
gets printed in bold face. I believe this is the behavior one expects.
The `eq' package implements the equations display styles described by
Knuth for fractions, superscripts and subscripts, etc. However, it
can't implement the non-display styles for sums and integrals without
breaking compatibility or without adding new symbols. In non-display
styles, the boundaries of sums and integrals are to be printed to the
right of the sigma or integral sign, rather than below and above it.
However, since `eq' currently defines `from' and `to' as separate
symbols instead of named parameters of `sum' and `integral', obtaining
this layout is impossible.
The patch contains two new symbols, `inlinesum' and `inlineintegral',
that show how to obtain the desired layout. These two symbols cannot be
renamed to `sum' and `integral' because they use named parameters for
`from' and `to', which introduces a slight syntactic difference. With
the current `from' and `to', one can write:
sum from x to y ...
With `from' and `to' as named parameters, one has to enclose their value
in braces:
sum from { x } to { y }
Hence the need for new symbols like `inlineintegral' and `inlinesum'.
In order to obtain an equation laid out "in-line" within a paragraph
(what Knuth calls the "text" style), one has to use the following
incantation:
@Eq initialstyle { "text" } { ... }
The address@hidden' symbol could be changed to do that. However, that would
also
break compatibility (because documents using address@hidden' may have made
special
arrangements to have equations look in-line). So I think a new macro
(e.g., address@hidden') needs to be introduced.
The patch includes other changes making `eq' more independent from the
"Symbol" font. However, more work is needed to allow the use of other
fonts (such as the Latin Modern or Computer Modern math fonts). In
particular, since the set of glyphs available in other fonts may differ
from that of "Symbol", a new Lout primitive must be introduced to allow
for a glyph to be looked up in another font if it cannot be found. For
instance, "LMMathItalic10-Italic" has fewer glyphs than "Symbol" (e.g.,
it lacks several Greek capital letters) so some glyphs that are provided
by "Symbol" would need to be provided by some other font when
"LMMathItalic10-Italic" is used. But that's another story...
Last but not least, the context mechanism is still (slightly) buggy.
The bug shows up when running Lout on the `eq.lout' test document with
`-ddom': at some point, an invalid gap object is caught. Without
`-ddom', the error is not detected, but the spacing between objects
within equations is incorrect (for instance, changing the `else' branch
of address@hidden' doesn't make any difference). Valgrind doesn't
help here since Lout uses memory pools, and I haven't been able to find
useful clues so far. So suggestions are welcomed, and I hope we'll be
able to fix it!
Thanks,
Ludovic.
--- orig/externs.h
+++ mod/externs.h
@@ -635,7 +635,22 @@
/* */
/*****************************************************************************/
-typedef struct
+/* A key-value pair. */
+typedef struct context_type
+{
+ union rec *okey; /* name of a context variable */
+ union rec *ovalue; /* associated value */
+ union rec *oenv; /* environment for this value */
+ struct style_type *ostyle; /* style for this value */
+} CONTEXT;
+
+#define context_key(x) (x).okey
+#define context_value(x) (x).ovalue
+#define context_env(x) (x).oenv
+#define context_style(x) (x).ostyle
+
+
+typedef struct style_type
{
GAP oline_gap; /* separation between lines */
GAP ospace_gap; /* separation induced by white space */
@@ -663,6 +678,7 @@
BOOLEAN ostrut : 1; /* strut char metrics */
BOOLEAN oligatures : 1; /* use ligatures */
BOOLEAN omarginkerning : 1; /* perform margin kerning */
+ CONTEXT ocontext; /* context stack */
} STYLE;
#define line_gap(x) (x).oline_gap
@@ -691,34 +707,36 @@
#define strut(x) (x).ostrut
#define ligatures(x) (x).oligatures
#define marginkerning(x)(x).omarginkerning
+#define context(x) (x).ocontext
-#define StyleCopy(x, y)
\
-( GapCopy(line_gap(x), line_gap(y)), \
- GapCopy(space_gap(x), space_gap(y)), \
- yunit(x) = yunit(y), \
- zunit(x) = zunit(y), \
- outdent_len(x) = outdent_len(y), \
- smallcaps_len(x) = smallcaps_len(y), \
- font(x) = font(y), \
- colour(x) = colour(y), \
- texture(x) = texture(y), \
- blanklinescale(x) = blanklinescale(y), \
- language(x) = language(y), \
- vadjust(x) = vadjust(y), \
- hadjust(x) = hadjust(y), \
- padjust(x) = padjust(y), \
- small_caps(x) = small_caps(y), \
- space_style(x) = space_style(y), \
- hyph_style(x) = hyph_style(y), \
- fill_style(x) = fill_style(y), \
- display_style(x) = display_style(y), \
- outline(x) = outline(y), \
- nobreakfirst(x) = nobreakfirst(y), \
- nobreaklast(x) = nobreaklast(y), \
- baselinemark(x) = baselinemark(y), \
- strut(x) = strut(y), \
- ligatures(x) = ligatures(y), \
- marginkerning(x) = marginkerning(y) \
+#define StyleCopy(x, y) \
+( GapCopy(line_gap(x), line_gap(y)), \
+ GapCopy(space_gap(x), space_gap(y)), \
+ yunit(x) = yunit(y), \
+ zunit(x) = zunit(y), \
+ outdent_len(x) = outdent_len(y), \
+ smallcaps_len(x) = smallcaps_len(y), \
+ font(x) = font(y), \
+ colour(x) = colour(y), \
+ texture(x) = texture(y), \
+ blanklinescale(x) = blanklinescale(y), \
+ language(x) = language(y), \
+ vadjust(x) = vadjust(y), \
+ hadjust(x) = hadjust(y), \
+ padjust(x) = padjust(y), \
+ small_caps(x) = small_caps(y), \
+ space_style(x) = space_style(y), \
+ hyph_style(x) = hyph_style(y), \
+ fill_style(x) = fill_style(y), \
+ display_style(x) = display_style(y), \
+ outline(x) = outline(y), \
+ nobreakfirst(x) = nobreakfirst(y), \
+ nobreaklast(x) = nobreaklast(y), \
+ baselinemark(x) = baselinemark(y), \
+ strut(x) = strut(y), \
+ ligatures(x) = ligatures(y), \
+ marginkerning(x) = marginkerning(y), \
+ context(x) = context(y) \
)
@@ -2206,7 +2224,9 @@
#define EXT_GALL 153 /* an external galley
*/
#define CR_LIST 154 /* a list of cross
references */
#define SCOPE_SNAPSHOT 155 /* a scope snapshot
*/
-#define DISPOSED 156 /* a disposed record
*/
+#define SET_CONTEXT 156
+#define GET_CONTEXT 157
+#define DISPOSED 158 /* a disposed record
*/
#define is_indefinite(x) ((x) >= CLOSURE && (x) <= HEAD)
#define is_header(x) ((x) >= BEGIN_HEADER && (x) <= CLEAR_HEADER)
@@ -2226,20 +2246,20 @@
/*****************************************************************************/
/* sides of a mark */
-#define BACK 157 /* means lies to left of mark
*/
-#define ON 158 /* means lies on mark
*/
-#define FWD 159 /* means lies to right of mark
*/
+#define BACK 159 /* means lies to left of mark
*/
+#define ON 160 /* means lies on mark
*/
+#define FWD 161 /* means lies to right of mark
*/
/* constraint statuses */
-#define PROMOTE 160 /* this component may be
promoted */
-#define CLOSE 161 /* must close dest before
promoting */
-#define BLOCK 162 /* cannot promote this
component */
-#define CLEAR 163 /* this constraint is now
satisfied */
+#define PROMOTE 162 /* this component may be
promoted */
+#define CLOSE 163 /* must close dest before
promoting */
+#define BLOCK 164 /* cannot promote this
component */
+#define CLEAR 165 /* this constraint is now
satisfied */
/* gap increment types */
-#define GAP_ABS 164 /* absolute, e.g. 3p
*/
-#define GAP_INC 165 /* increment, e.g. +3p
*/
-#define GAP_DEC 166 /* decrement, e.g. -3p
*/
+#define GAP_ABS 166 /* absolute, e.g. 3p
*/
+#define GAP_INC 167 /* increment, e.g. +3p
*/
+#define GAP_DEC 168 /* decrement, e.g. -3p
*/
/* gap modes occupying mode(x) */
#define NO_MODE 0 /* for error detection: no mode
*/
@@ -2570,6 +2590,8 @@
#define KW_WEEKDAY AsciiToFull("@WeekDay")
#define KW_YEARDAY AsciiToFull("@YearDay")
#define KW_DAYLIGHTSAVING AsciiToFull("@DaylightSaving")
+#define KW_SET_CONTEXT AsciiToFull("@SetContext")
+#define KW_GET_CONTEXT AsciiToFull("@GetContext")
/*@::GetMem(), New(), NewWord()@**********************************************/
/* */
@@ -3049,6 +3071,9 @@
extern BOOLEAN Kern;
extern BOOLEAN SafeExecution;
extern BOOLEAN AltErrorFormat;
+extern OBJECT SetContextKeyTag;
+extern OBJECT SetContextValueTag;
+
extern int TotalWordCount;
extern BOOLEAN InitializeAll;
#if LOCALE_ON
@@ -3207,6 +3232,7 @@
/***** z18.c Galley Transfer **************************************/
extern STYLE InitialStyle;
+extern CONTEXT InitialContext;
extern OBJECT InitialEnvironment;
extern void TransferInit(OBJECT InitEnv);
extern OBJECT TransferBegin(OBJECT x);
--- orig/include/eqf
+++ mod/include/eqf
@@ -7,11 +7,6 @@
# Version 2.0 by Jeffrey H. Kingston, 22 December 1992. #
# Version 3.0 by Jeffrey H. Kingston and Robert Marsa, March 1996. #
# #
-# This package makes extensive use of the Adobe Systems Symbol font, and #
-# it assumes that the font has not been recoded. It could be rewritten #
-# using the @Char symbol to be made independent of any recoding, but since #
-# there seems no reason to ever recode this font, I haven't bothered. #
-# #
# See "Eq - a Lout package for typesetting mathematics" for user #
# information. Acknowledgement: the @Eq language is based closely on #
# the Eqn language of B. W. Kernighan and L. L. Cherry; the spacing rules #
@@ -64,6 +59,9 @@
sum prod coprod int oint bcap bcup bvee bwedge bodot botimes
boplus buplus
+ # FIXME: Experimental inline variants of sums.
+ inlinesum inlineintegral
+
"+" "-" "+-" "-+" setminus cdot times "*" circ div cap cup uplus
sqcap sqcup triangleleft triangleright
wr bigcirc bigtriangleup bigtriangledown vee wedge oplus ominus
@@ -106,7 +104,11 @@
matrix pmatrix bmatrix brmatrix fmatrix cmatrix amatrix
def @Eq
- named initzunit { 1f }
+ named symbolfont { Symbol Base }
+ named basefont { Base }
+ named initialstyle { "display" }
+ named initiallycramped { "No" }
+ named initialspace { compress 0.01f }
body @Body
@Begin
@@ -116,64 +118,205 @@
# Context-sensitive format changes. #
# #
# Equation formatting (according to Knuth) demands changes in #
- # the appearance of equations depending on context. These are: #
+ # the appearance of equations depending on context. Knuth #
+ # distinguishes four major styles (the TeXbook, Ch. 17): #
+ # #
+ # display style (formulas displayed on lines by themselves) #
+ # text style (formulas embedded in the text) #
+ # script style (formulas used as superscripts or subscripts) #
+ # scriptscript (second-order superscripts or subscripts) #
# #
- # @Smaller x Superscripts and subscripts are to be set #
- # in a smaller font size. The @Smaller #
- # symbol implements this by changing the #
- # f unit. #
+ # Each style has its own font size and spacing rules. #
# #
- # @HSqueeze x The horizontal space surrounding binary #
- # operators and relations is to be reduced #
- # within superscripts and subscripts, etc. #
- # The @HSqueeze symbol implements this by #
- # changing the y unit, which is not used by #
- # Lout but which is used by symbols @ThinGap, #
- # @MedGap and @ThickGap. #
+ # Additionally, each of these styles can be ``cramped'', #
+ # meaning that exponents are not raised as much. #
# #
- # @VSqueeze x The vertical space taken by superscripts #
- # and subscripts is to be reduced within #
- # built-up fractions and under root signs. #
- # The @VSqueeze symbol implements this by #
- # changing the z unit, which is not used by #
- # Lout but is used by the @SupGap symbol. #
+ ###################################################################
+
+ macro @CurrStyleVar { "EqCurrStyle" }
+ macro @CrampedVar { "EqCramped?" }
+
+ def @CurrStyle { { @GetContext @CurrStyleVar } }
+ def @Cramped { { @GetContext @CrampedVar } }
+
+ def @EqDebug
+ {
+ # Uncomment the following line to get debugging information.
+ #{ { Helvetica Base 0.7f } @Font @CurrStyle } |0.2f
+ @Null
+ }
+
+ def @WithStyle
+ named style { "display" }
+ named cramped { "No" }
+ right x
+ {
+ def @NewFontSize
+ {
+ @CurrStyle @Case {
+ "scriptscript" @Yield 1.0f # can't be smaller
+ "script" @Yield {
+ style @Case {
+ "script" @Yield 1.0f
+ else @Yield 0.8f } }
+ "text" @Yield {
+ style @Case {
+ "text" @Yield 1.0f
+ else @Yield 0.7f } }
+ "display" @Yield {
+ style @Case {
+ # display and text styles yield the same font size
+ { "display" "text" } @Yield 1.0f
+ else @Yield 0.7f } }
+ }
+ }
+
+
+ #{ Helvetica Base 0.4f } @Font { @CurrStyle -> style } |0.2f
+ @NewFontSize @Font
+ @SetContext key { @CurrStyleVar } value { style } {
+ @SetContext key { @CrampedVar } value { cramped } {
+ { @EqDebug x }
+ }
+ }
+ }
+
+ def @CurrSuperScriptGap
+ {
+ @Cramped @Case {
+ "Yes" @Yield 0.26fk
+ "No" @Yield 0.40fk
+ }
+ }
+
+ def @SubScriptGap { 0.35fk }
+
+
+ ###################################################################
# #
- # Knuth also recommends some changes that depend on whether the #
- # equation is displayed or inline; these are not implemented, #
- # except that the @E symbol for inline equations (defined as #
- # a macro at the bottom of this file) includes a @VSqueeze. #
+ # Spacing rules. #
# #
###################################################################
- def @SpaceGap { 0.05f }
+ # Space around binary operators.
+ def @CurrBinarySpaceGap
+ {
+ @CurrStyle @Case {
+ { "display" "text" } @Yield 0.20f
+ # Knuth: ``TeX puts no space around `+' signs in script styles.''
+ else @Yield 0.00c
+ }
+ }
+
+ # Space around relational operators.
+ def @CurrRelSpaceGap
+ {
+ @CurrStyle @Case {
+ { "display" "text" } @Yield 0.25f
+ else @Yield 0.00c
+ }
+ }
- def @Smaller right x { 0.7f @Font @SpaceGap @Space x }
+ # Space around punctuation marks, including matrix braces.
+ def @CurrPunctSpaceGap
+ {
+ @CurrStyle @Case {
+ { "display" "text" } @Yield 0.15f
+ else @Yield 0.00c
+ }
+ }
- def @HSqueeze right x { 0.2f @YUnit x }
+ def "`" { &@CurrPunctSpaceGap }
+ def "``" { &@CurrBinarySpaceGap }
+ def "```" { &@CurrRelSpaceGap }
+ def bin right x { `` x `` }
+ def rel right x { ``` x ``` }
+ def punct right x { x ` }
- def @VSqueeze right x { 0.7f @ZUnit x }
+ # Gap above/below math expressions (see, e.g., `to' and `from').
+ def @AboveGap { 0.15f }
+ def @BelowGap { 0.15f }
def @SkewGap { 0.05f }
- def @SupGap { 0.43zk }
- def @ThinGap { 0.15y }
- def @MedGap { 0.20y }
- def @ThickGap { 0.25y }
def @ColGap { 0.8f }
def @RowGap { 0.5f }
- def "`" { &@ThinGap }
- def "``" { &@MedGap }
- def "```" { &@ThickGap }
- def bin right x { `` x `` }
- def rel right x { ``` x ``` }
- def punct right x { x ` }
- def non right x { 0c @YUnit x }
- def big right x { 1.3f @Font @SpaceGap @Space x }
- def small right x { 0.6f @Font @SpaceGap @Space x }
+ ###################################################################
+ # #
+ # Major styles: scripts, fractions, and square roots. #
+ # #
+ ###################################################################
+
+ def @ScriptStyle
+ named level { "sup" }
+ right script
+ {
+ @WithStyle
+ style { @CurrStyle @Case {
+ { "display" "text" } @Yield "script"
+ { "script" "scriptscript" } @Yield "scriptscript" } }
+ cramped { level @Case {
+ "sub" @Yield "Yes"
+ "sup" @Yield @Cramped } }
+ { script }
+ }
+
+ def @SuperScriptStyle right superscript
+ {
+ @ScriptStyle level { "sup" } superscript
+ }
+
+ def @SubScriptStyle right subscript
+ {
+ @ScriptStyle level { "sub" } subscript
+ }
- def @Base right x { Base @Font x }
- def @Sym right x { {Symbol Base} @Font x }
+
+ def @FractionStyle
+ named level { "numerator" }
+ right x
+ {
+ @WithStyle
+ style { @CurrStyle @Case {
+ "display" @Yield "text"
+ "text" @Yield "script"
+ { "script" "scriptscript" } @Yield "scriptscript" } }
+ cramped { level @Case {
+ "numerator" @Yield @Cramped
+ "denominator" @Yield "Yes"} }
+ { x }
+ }
+
+ def @NumeratorStyle right x
+ {
+ @FractionStyle level { "numerator" } x
+ }
+
+ def @DenominatorStyle right x
+ {
+ @FractionStyle level { "denominator" } x
+ }
+
+ def @SquareRootStyle right x
+ {
+ @WithStyle style { @CurrStyle } cramped { "Yes" } x
+ }
+
+
+ ###################################################################
+ # #
+ # Utilities: `big', `small', address@hidden', etc. #
+ # #
+ ###################################################################
+
+ # XXX: Certainly not the best way to implement `non'.
+ def non right x { @SetContext key { @CurrStyleVar } value { "script" }
x }
+ def big right x { 1.3f @Font x }
+ def small right x { 0.6f @Font x }
+
+ def @Base right x { basefont @Font x }
+ def @Sym right x { symbolfont @Font x }
def @HLine
named line { @BackEnd @Case { PostScript @Yield { "0.05 ft
setlinewidth" } PDF @Yield { "__mul(__loutf, 0.05) w" } } }
@@ -228,203 +371,204 @@
# #
###################################################################
- def space { @Sym "\040" }
- def exclam { @Sym "\041" }
- def universal { @Sym "\042" }
- def numbersign { @Sym "\043" }
- def existential { @Sym "\044" }
- def percent { @Sym "\045" }
- def ampersand { @Sym "\046" }
- def suchthat { @Sym "\047" }
- def parenleft { @Sym "\050" }
- def parenright { @Sym "\051" }
- def asteriskmath { @Sym "\052" }
- def plus { @Sym "+" }
- def comma { @Sym "\054" }
- def minus { @Sym "-" }
- def period { @Sym "\056" }
- def slash { @Sym "\057" }
- def zero { @Sym "\060" }
- def one { @Sym "\061" }
- def two { @Sym "\062" }
- def three { @Sym "\063" }
- def four { @Sym "\064" }
- def five { @Sym "\065" }
- def six { @Sym "\066" }
- def seven { @Sym "\067" }
- def eight { @Sym "\070" }
- def nine { @Sym "\071" }
- def colon { @Sym "\072" }
- def semicolon { @Sym "\073" }
- def less { @Sym "\074" }
- def equal { @Sym "\075" }
- def greater { @Sym "\076" }
- def question { @Sym "\077" }
- def congruent { @Sym "\100" }
- def Alpha { @Sym "\101" }
- def Beta { @Sym "\102" }
- def Chi { @Sym "\103" }
- def Delta { @Sym "\104" }
- def Epsilon { @Sym "\105" }
- def Phi { @Sym "\106" }
- def Gamma { @Sym "\107" }
- def Eta { @Sym "\110" }
- def Iota { @Sym "\111" }
- def thetaone { @Sym "\112" }
- def Kappa { @Sym "\113" }
-
- def Lambda { @Sym "\114" }
- def Mu { @Sym "\115" }
- def Nu { @Sym "\116" }
- def Omicron { @Sym "\117" }
- def Pi { @Sym "\120" }
- def Theta { @Sym "\121" }
- def Rho { @Sym "\122" }
- def Sigma { @Sym "\123" }
- def Tau { @Sym "\124" }
- def Upsilon { @Sym "\125" }
- def sigmaone { @Sym "\126" }
- def Omega { @Sym "\127" }
- def Xi { @Sym "\130" }
- def Psi { @Sym "\131" }
- def Zeta { @Sym "\132" }
- def bracketleft { @Sym "\133" }
- def therefore { @Sym "\134" }
- def bracketright { @Sym "\135" }
- def perpendicular { @Sym "\136" }
- def underscore { @Sym "\137" }
- def radicalex { @Sym "\140" }
- def alpha { @Sym "\141" }
- def beta { @Sym "\142" }
- def chi { @Sym "\143" }
- def delta { @Sym "\144" }
- def epsilon { @Sym "\145" }
- def phi { @Sym "\146" }
- def gamma { @Sym "\147" }
- def eta { @Sym "\150" }
- def iota { @Sym "\151" }
- def phione { @Sym "\152" }
- def kappa { @Sym "\153" }
- def lambda { @Sym "\154" }
- def mu { @Sym "\155" }
- def nu { @Sym "\156" }
-
- def omicron { @Sym "\157" }
- def pi { @Sym "\160" }
- def theta { @Sym "\161" }
- def rho { @Sym "\162" }
- def sigma { @Sym "\163" }
- def tau { @Sym "\164" }
- def upsilon { @Sym "\165" }
- def omegaone { @Sym "\166" }
- def omega { @Sym "\167" }
- def xi { @Sym "\170" }
- def psi { @Sym "\171" }
- def zeta { @Sym "\172" }
- def braceleft { @Sym "\173" }
- def bar { @Sym "\174" }
- def braceright { @Sym "\175" }
- def similar { @Sym "\176" }
- def Upsilonone { @Sym "\241" }
- def minute { @Sym "\242" }
- def lessequal { @Sym "\243" }
- def fraction { @Sym "\244" }
- def infinity { "1.2f" @Font @Sym "\245" }
- def florin { @Sym "\246" }
- def club { @Sym "\247" }
- def diamond { @Sym "\250" }
- def heart { @Sym "\251" }
- def spade { @Sym "\252" }
- def arrowboth { @Sym "\253" }
- def arrowleft { @Sym "\254" }
- def arrowup { @Sym "\255" }
- def arrowright { @Sym "\256" }
- def arrowdown { @Sym "\257" }
- def degree { @Sym "\260" }
- def plusminus { @Sym "\261" }
- def second { @Sym "\262" }
- def greaterequal { @Sym "\263" }
-
- def multiply { @Sym "\264" }
- def proportional { @Sym "\265" }
- def partialdiff { @Sym "\266" }
- def bullet { @Sym "\267" }
- def divide { @Sym "\270" }
- def notequal { @Sym "\271" }
- def equivalence { @Sym "\272" }
- def approxequal { @Sym "\273" }
- def ellipsis { @Sym "\274" }
- def arrowvertex { @Sym "\275" }
- def arrowhorizex { @Sym "\276" }
- def carriagereturn { @Sym "\277" }
- def aleph { @Sym "\300" }
- def Ifraktur { @Sym "\301" }
- def Rfraktur { @Sym "\302" }
- def weierstrass { @Sym "\303" }
- def circlemultiply { @Sym "\304" }
- def circleplus { @Sym "\305" }
- def emptyset { @Sym "\306" }
- def intersection { @Sym "\307" }
- def union { @Sym "\310" }
- def propersuperset { @Sym "\311" }
- def reflexsuperset { @Sym "\312" }
- def notsubset { @Sym "\313" }
- def propersubset { @Sym "\314" }
- def reflexsubset { @Sym "\315" }
- def element { @Sym "\316" }
- def notelement { @Sym "\317" }
- def angle { @Sym "\320" }
- def gradient { @Sym "\321" }
- def registerserif { @Sym "\322" }
- def copyrightserif { @Sym "\323" }
- def trademarkserif { @Sym "\324" }
- def product { @Sym "\325" }
- def radical { @Sym "\326" }
- def dotmath { @Sym "\327" }
+ def space { @Sym @Char "space" }
+ def exclam { @Sym @Char "exclam" }
+ def universal { @Sym @Char "universal" }
+ def numbersign { @Sym @Char "numbersign" }
+ def existential { @Sym @Char "existential" }
+ def percent { @Sym @Char "percent" }
+ def ampersand { @Sym @Char "ampersand" }
+ def suchthat { @Sym @Char "suchthat" }
+ def parenleft { @Sym @Char "parenleft" }
+ def parenright { @Sym @Char "parenright" }
+ def asteriskmath { @Sym @Char "asteriskmath" }
+ def plus { @Sym @Char "plus" }
+ def comma { @Sym @Char "comma" }
+ def minus { @Sym @Char "minus" }
+ def period { @Sym @Char "period" }
+ def slash { @Sym @Char "slash" }
+ def zero { @Sym @Char "zero" }
+ def one { @Sym @Char "one" }
+ def two { @Sym @Char "two" }
+ def three { @Sym @Char "three" }
+ def four { @Sym @Char "four" }
+ def five { @Sym @Char "five" }
+ def six { @Sym @Char "six" }
+ def seven { @Sym @Char "seven" }
+ def eight { @Sym @Char "eight" }
+ def nine { @Sym @Char "nine" }
+ def colon { @Sym @Char "colon" }
+ def semicolon { @Sym @Char "semicolon" }
+ def less { @Sym @Char "less" }
+ def equal { @Sym @Char "equal" }
+ def greater { @Sym @Char "greater" }
+ def question { @Sym @Char "question" }
+ def congruent { @Sym @Char "congruent" }
+ def Alpha { @Sym @Char "Alpha" }
+ def Beta { @Sym @Char "Beta" }
+ def Chi { @Sym @Char "Chi" }
+ def Delta { @Sym @Char "Delta" }
+ def Epsilon { @Sym @Char "Epsilon" }
+ def Phi { @Sym @Char "Phi" }
+ def Gamma { @Sym @Char "Gamma" }
+ def Eta { @Sym @Char "Eta" }
+ def Iota { @Sym @Char "Iota" }
+ def thetaone { @Sym @Char "thetaone" }
+ def Kappa { @Sym @Char "Kappa" }
+
+ def Lambda { @Sym @Char "Lambda" }
+ def Mu { @Sym @Char "Mu" }
+ def Nu { @Sym @Char "Nu" }
+ def Omicron { @Sym @Char "Omicron" }
+ def Pi { @Sym @Char "Pi" }
+ def Theta { @Sym @Char "Theta" }
+ def Rho { @Sym @Char "Rho" }
+ def Sigma { @Sym @Char "Sigma" }
+ def Tau { @Sym @Char "Tau" }
+ def Upsilon { @Sym @Char "Upsilon" }
+ def sigmaone { @Sym @Char "sigmaone" }
+ def Omega { @Sym @Char "Omega" }
+ def Xi { @Sym @Char "Xi" }
+ def Psi { @Sym @Char "Psi" }
+ def Zeta { @Sym @Char "Zeta" }
+ def bracketleft { @Sym @Char "bracketleft" }
+ def therefore { @Sym @Char "therefore" }
+ def bracketright { @Sym @Char "bracketright" }
+ def perpendicular { @Sym @Char "perpendicular" }
+ def underscore { @Sym @Char "underscore" }
+ def radicalex { @Sym @Char "radicalex" }
+ def alpha { @Sym @Char "alpha" }
+ def beta { @Sym @Char "beta" }
+ def chi { @Sym @Char "chi" }
+ def delta { @Sym @Char "delta" }
+ def epsilon { @Sym @Char "epsilon" }
+ def phi { @Sym @Char "phi" }
+ def gamma { @Sym @Char "gamma" }
+ def eta { @Sym @Char "eta" }
+ def iota { @Sym @Char "iota" }
+ def phione { @Sym @Char "phione" }
+ def kappa { @Sym @Char "kappa" }
+ def lambda { @Sym @Char "lambda" }
+ def mu { @Sym @Char "mu" }
+ def nu { @Sym @Char "nu" }
+
+ def omicron { @Sym @Char "omicron" }
+ def pi { @Sym @Char "pi" }
+ def theta { @Sym @Char "theta" }
+ def rho { @Sym @Char "rho" }
+ def sigma { @Sym @Char "sigma" }
+ def tau { @Sym @Char "tau" }
+ def upsilon { @Sym @Char "upsilon" }
+ def omegaone { @Sym @Char "omegaone" }
+ def omega { @Sym @Char "omega" }
+ def xi { @Sym @Char "xi" }
+ def psi { @Sym @Char "psi" }
+ def zeta { @Sym @Char "zeta" }
+ def braceleft { @Sym @Char "braceleft" }
+ def bar { @Sym @Char "bar" }
+ def braceright { @Sym @Char "braceright" }
+ def similar { @Sym @Char "similar" }
+ def Upsilonone { @Sym @Char "Upsilonone" }
+ def minute { @Sym @Char "minute" }
+ def lessequal { @Sym @Char "lessequal" }
+ def fraction { @Sym @Char "fraction" }
+ # For Adobe Symbol, `infinity' used to be "1.2f @Font { ... }"
+ def infinity { @Sym @Char "infinity" }
+ def florin { @Sym @Char "florin" }
+ def club { @Sym @Char "club" }
+ def diamond { @Sym @Char "diamond" }
+ def heart { @Sym @Char "heart" }
+ def spade { @Sym @Char "spade" }
+ def arrowboth { @Sym @Char "arrowboth" }
+ def arrowleft { @Sym @Char "arrowleft" }
+ def arrowup { @Sym @Char "arrowup" }
+ def arrowright { @Sym @Char "arrowright" }
+ def arrowdown { @Sym @Char "arrowdown" }
+ def degree { @Sym @Char "degree" }
+ def plusminus { @Sym @Char "plusminus" }
+ def second { @Sym @Char "second" }
+ def greaterequal { @Sym @Char "greaterequal" }
+
+ def multiply { @Sym @Char "multiply" }
+ def proportional { @Sym @Char "proportional" }
+ def partialdiff { @Sym @Char "partialdiff" }
+ def bullet { @Sym @Char "bullet" }
+ def divide { @Sym @Char "divide" }
+ def notequal { @Sym @Char "notequal" }
+ def equivalence { @Sym @Char "equivalence" }
+ def approxequal { @Sym @Char "approxequal" }
+ def ellipsis { @Sym @Char "ellipsis" }
+ def arrowvertex { @Sym @Char "arrowvertex" }
+ def arrowhorizex { @Sym @Char "arrowhorizex" }
+ def carriagereturn { @Sym @Char "carriagereturn" }
+ def aleph { @Sym @Char "aleph" }
+ def Ifraktur { @Sym @Char "Ifraktur" }
+ def Rfraktur { @Sym @Char "Rfraktur" }
+ def weierstrass { @Sym @Char "weierstrass" }
+ def circlemultiply { @Sym @Char "circlemultiply" }
+ def circleplus { @Sym @Char "circleplus" }
+ def emptyset { @Sym @Char "emptyset" }
+ def intersection { @Sym @Char "intersection" }
+ def union { @Sym @Char "union" }
+ def propersuperset { @Sym @Char "propersuperset" }
+ def reflexsuperset { @Sym @Char "reflexsuperset" }
+ def notsubset { @Sym @Char "notsubset" }
+ def propersubset { @Sym @Char "propersubset" }
+ def reflexsubset { @Sym @Char "reflexsubset" }
+ def element { @Sym @Char "element" }
+ def notelement { @Sym @Char "notelement" }
+ def angle { @Sym @Char "angle" }
+ def gradient { @Sym @Char "gradient" }
+ def registerserif { @Sym @Char "registerserif" }
+ def copyrightserif { @Sym @Char "copyrightserif" }
+ def trademarkserif { @Sym @Char "trademarkserif" }
+ def product { @Sym @Char "product" }
+ def radical { @Sym @Char "radical" }
+ def dotmath { @Sym @Char "dotmath" }
def @PureDot # dot with no extra space
{
@HContract { &0io 0.4w @HShift dotmath }
}
- def logicalnot { @Sym "\330" }
- def logicaland { @Sym "\331" }
- def logicalor { @Sym "\332" }
- def arrowdblboth { @Sym "\333" }
- def arrowdblleft { @Sym "\334" }
- def arrowdblup { @Sym "\335" }
- def arrowdblright { @Sym "\336" }
- def arrowdbldown { @Sym "\337" }
- def lozenge { @Sym "\340" }
- def angleleft { @Sym "\341" }
- def registersans { @Sym "\342" }
- def copyrightsans { @Sym "\343" }
- def trademarksans { @Sym "\344" }
- def summation { @Sym "\345" }
- def parenlefttp { @Sym "\346" }
- def parenleftex { @Sym "\347" }
- def parenleftbt { @Sym "\350" }
- def bracketlefttp { @Sym "\351" }
- def bracketleftex { @Sym "\352" }
- def bracketleftbt { @Sym "\353" }
- def bracelefttp { @Sym "\354" }
- def braceleftmid { @Sym "\355" }
- def braceleftbt { @Sym "\356" }
- def braceex { @Sym "\357" }
- def angleright { @Sym "\361" }
- def integral { @Sym "\362" }
- def integraltp { @Sym "\363" }
- def integralex { @Sym "\364" }
- def integralbt { @Sym "\365" }
- def parenrighttp { @Sym "\366" }
- def parenrightex { @Sym "\367" }
- def parenrightbt { @Sym "\370" }
- def bracketrighttp { @Sym "\371" }
- def bracketrightex { @Sym "\372" }
- def bracketrightbt { @Sym "\373" }
- def bracerighttp { @Sym "\374" }
- def bracerightmid { @Sym "\375" }
- def bracerightbt { @Sym "\376" }
+ def logicalnot { @Sym @Char "logicalnot" }
+ def logicaland { @Sym @Char "logicaland" }
+ def logicalor { @Sym @Char "logicalor" }
+ def arrowdblboth { @Sym @Char "arrowdblboth" }
+ def arrowdblleft { @Sym @Char "arrowdblleft" }
+ def arrowdblup { @Sym @Char "arrowdblup" }
+ def arrowdblright { @Sym @Char "arrowdblright" }
+ def arrowdbldown { @Sym @Char "arrowdbldown" }
+ def lozenge { @Sym @Char "lozenge" }
+ def angleleft { @Sym @Char "angleleft" }
+ def registersans { @Sym @Char "registersans" }
+ def copyrightsans { @Sym @Char "copyrightsans" }
+ def trademarksans { @Sym @Char "trademarksans" }
+ def summation { @Sym @Char "summation" }
+ def parenlefttp { @Sym @Char "parenlefttp" }
+ def parenleftex { @Sym @Char "parenleftex" }
+ def parenleftbt { @Sym @Char "parenleftbt" }
+ def bracketlefttp { @Sym @Char "bracketlefttp" }
+ def bracketleftex { @Sym @Char "bracketleftex" }
+ def bracketleftbt { @Sym @Char "bracketleftbt" }
+ def bracelefttp { @Sym @Char "bracelefttp" }
+ def braceleftmid { @Sym @Char "braceleftmid" }
+ def braceleftbt { @Sym @Char "braceleftbt" }
+ def braceex { @Sym @Char "braceex" }
+ def angleright { @Sym @Char "angleright" }
+ def integral { @Sym @Char "integral" }
+ def integraltp { @Sym @Char "integraltp" }
+ def integralex { @Sym @Char "integralex" }
+ def integralbt { @Sym @Char "integralbt" }
+ def parenrighttp { @Sym @Char "parenrighttp" }
+ def parenrightex { @Sym @Char "parenrightex" }
+ def parenrightbt { @Sym @Char "parenrightbt" }
+ def bracketrighttp { @Sym @Char "bracketrighttp" }
+ def bracketrightex { @Sym @Char "bracketrightex" }
+ def bracketrightbt { @Sym @Char "bracketrightbt" }
+ def bracerighttp { @Sym @Char "bracerighttp" }
+ def bracerightmid { @Sym @Char "bracerightmid" }
+ def bracerightbt { @Sym @Char "bracerightbt" }
###################################################################
@@ -632,6 +776,43 @@
def boplus { 1.3f @Font circleplus }
def buplus { & 1.3f @Font @HContract { &0.5rt 0.7f @Font plus ^/0.2fo
union } }
+ # In ``The TeXbook'', Knuth provides examples of sums and integrals
+ # in styles other than display, showing that their `from' and `to'
+ # parts should not appear around the sign sum (i.e., above and
+ # below) but rather to its right (Chapter 17).
+ #
+ # Unfortunately, we are not able to have the `sum' symbol
+ # automatically do the right thing when in `text' mode because
+ # `from' and `to' are separate symbols and can hardly be changed to
+ # achieve this. (FIXME)
+
+ def inlinesum
+ precedence 58
+ named symbol { summation }
+ named from { "" }
+ named to { "" }
+ {
+ 0.7w @VShift {
+ 0c @VShift @OneCol @OneRow {
+ { 1w @VShift symbol }
+ ^|{ @CurrPunctSpaceGap }
+ { 1w @VShift @OneRow @SubScriptStyle from }
+ }
+ |0fo
+ { 0w @VShift @SuperScriptStyle to }
+ }
+ |1fe
+ |{ @CurrPunctSpaceGap }
+ }
+
+ def inlineintegral
+ precedence 58
+ named from { "" }
+ named to { "" }
+ {
+ inlinesum symbol { integral } from { from } to { to }
+ }
+
###################################################################
# #
# Group 7 (binary operations) #
@@ -1227,27 +1408,30 @@
precedence 60
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" } # FIXME: Handle this
right y
{
@HContract @VContract
- { | 0.45w @VShift @Smaller @HSqueeze @VSqueeze y
- ^/gap x
+ { | @SuperScriptStyle y
+ ^/{ @CurrSuperScriptGap } x
}
+# {
+# x { { @SuperScriptStyle y } ^/{ @CurrSuperScriptGap } }
+# }
}
def sub
precedence 60
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" } # FIXME: Handle this
right y
{
@HContract @VContract
{
# x
"." @KernShrink x
- /gap | @Smaller @HSqueeze @VSqueeze y
+ /{ @SubScriptGap } | @SubScriptStyle y
}
}
@@ -1255,13 +1439,13 @@
precedence 60
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" } # FIXME: Handle this
right y
{
@HContract @VContract
{
x
- /gap | &0io 0.2f @HShift @Smaller @HSqueeze @VSqueeze y
+ /gap | &0io 0.2f @HShift @SubScriptStyle y
}
}
@@ -1269,12 +1453,13 @@
precedence 60
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" } # FIXME: Handle this
right y
{
@HContract @VContract
{
- { ^/gap x /gap } | y
+ { ^/{ @CurrSuperScriptGap } x /{ @CurrSuperScriptGap } }
+ | y
}
}
@@ -1282,22 +1467,22 @@
precedence 61
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" }
right y
{
- @Smaller @HSqueeze @VSqueeze x ^/ /
- @Smaller @HSqueeze @VSqueeze y
+ { @SuperScriptStyle x } ^/ /
+ { @SubScriptStyle y }
}
def ton
precedence 61
associativity left
left x
- named gap { @SupGap }
+ named gap { "dft" }
right y
{
- @Smaller @HSqueeze @VSqueeze x ^/ /
- &0io 0.3f @HShift @Smaller @HSqueeze @VSqueeze y
+ @SuperScriptStyle x ^/ /
+ &0io 0.3f @HShift @SubScriptStyle y
}
def frac
@@ -1307,8 +1492,10 @@
named gap { 0.2f }
right y
{
- @HContract @VContract @Smaller @HSqueeze @VSqueeze
- { 1w @VShift { x /gap } | fraction &0io | 0w @VShift { |gap y }
+ @HContract @VContract
+ { 1w @VShift { @SuperScriptStyle { x } /gap }
+ | fraction &0io
+ | 0w @VShift { |gap @SubScriptStyle { y } }
}
}
@@ -1319,27 +1506,57 @@
precedence 54
associativity left
left x
- named gap { 0.2f }
+ named gap { "dft" }
+ named belowgap { "dft" }
right y
{
+ def @AboveLineGap
+ {
+ gap @Case {
+ "dft" @Yield {
+ @CurrStyle @Case {
+ "display" @Yield 0.20f
+ else @Yield 0.10f
+ }
+ }
+ else @Yield gap
+ }
+ }
+
+ def @BelowLineGap
+ {
+ belowgap @Case {
+ "dft" @Yield {
+ @CurrStyle @Case {
+ "display" @Yield 0.15f
+ else @Yield 0.09f
+ }
+ }
+ else @Yield belowgap
+ }
+ }
+
@HContract @VContract
- { |0.5rt @OneCol @VSqueeze x
- ^//gap @HLine
- //gap |0.5rt @OneCol @VSqueeze @Strut y
- }
+ { |0.1f
+ { |0.5rt @OneCol @NumeratorStyle x
+ ^//@AboveLineGap @HLine
+ //@BelowLineGap |0.5rt @OneCol @DenominatorStyle @Strut y
+ }
+ |0.1f
+ }
}
def from
precedence 58
associativity left
left x
- named gap { @ThinGap }
+ named gap { @BelowGap }
named skew { 0c }
right y
{
@HContract @VContract
{ |0.5rt x
- //gap |0.5rt &skew @Smaller @HSqueeze @VSqueeze y
+ //gap |0.5rt &skew @SubScriptStyle y
}
}
@@ -1347,12 +1564,12 @@
precedence 58
associativity left
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
named skew { 0c }
right y
{
@HContract @VContract
- { |0.5rt &skew @Smaller @HSqueeze @VSqueeze y
+ { |0.5rt &skew @SuperScriptStyle y
^//gap |0.5rt x
}
}
@@ -1361,7 +1578,7 @@
precedence 58
associativity left
left x
- named gap { @ThinGap }
+ named gap { @BelowGap }
right y
{
@HContract @VContract
@@ -1374,7 +1591,7 @@
precedence 58
associativity left
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
right y
{
@HContract @VContract
@@ -1386,7 +1603,7 @@
def dot
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } .
}
@@ -1394,7 +1611,7 @@
def dotdot
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } ..
}
@@ -1402,7 +1619,7 @@
def hat
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } @Base "^"
}
@@ -1410,7 +1627,7 @@
def tilde
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } @Base "~"
}
@@ -1418,7 +1635,7 @@
def vec
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } arrowright
}
@@ -1426,7 +1643,7 @@
def dyad
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
x to gap { gap } skew { @SkewGap } arrowboth
}
@@ -1434,22 +1651,23 @@
def overbar
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @AboveGap }
{
- x wideto gap { gap } minus
+ { @WithStyle style { @CurrStyle } cramped { "Yes" } x }
+ wideto gap { gap } minus
}
def underbar
precedence 62
left x
- named gap { @ThinGap }
+ named gap { @BelowGap }
{
x widefrom gap { gap } minus
}
def sqrt
precedence 56
- named gap { @ThinGap }
+ named gap { @AboveGap }
right x
{
@BackEnd @Case {
@@ -1459,7 +1677,7 @@
@VScale surd | @OneRow
{
@HLine line { "0.03 ft setlinewidth 2 setlinecap" }
- ^//gap |gap @VSqueeze @Strut x # //gap
+ ^//gap |gap @SquareRootStyle @Strut x # //gap
}
}
}
@@ -1477,7 +1695,7 @@
@VScale surd | @OneRow
{
@HLine line { "__mul(__loutf, 0.03) w 2 J" }
- ^//gap |gap @VSqueeze @Strut x # //gap
+ ^//gap |gap @SquareRootStyle @Strut x # //gap
}
}
}
@@ -1497,7 +1715,7 @@
left x
right y
{
- def zsup right x { "+0.3f" @VShift 0.5f @Font @Space x }
+ def zsup right x { "+0.3f" @VShift 0.5f @Font x }
"-0.4f" @HShift { 1w @HShift { zsup x } } &0co sqrt y
}
@@ -1559,7 +1777,7 @@
export row axisrow col lcol ccol rcol mcol
def matrix
precedence 100
- named gap { @MedGap }
+ named gap { @CurrBinarySpaceGap }
named strut
named no { }
named No { }
@@ -1676,12 +1894,12 @@
}
@HContract @VContract {
- delim atleft &@ThinGap
+ delim atleft &@CurrPunctSpaceGap
userow @Case {
{Yes yes} @Yield @HContract @VContract {^//gap @OneRow x //gap}
else @Yield vctr @HContract @VContract { //gap x //gap }
}
- &@ThinGap delim atright
+ &@CurrPunctSpaceGap delim atright
}
}
@@ -1692,9 +1910,13 @@
macro cmatrix { matrix atleft { blceil } atright { brceil } }
macro amatrix { matrix atleft { blangle } atright { brangle } }
- { Slope xheight2mark nostrut } @Font { separate @SpaceGap } @Space
- initzunit @ZUnit 1f @YUnit @Body
+ { Slope xheight2mark nostrut } @Font { initialspace } @Space
+ @SetContext key { @CurrStyleVar } value { initialstyle } {
+ @SetContext key { @CrampedVar } value { initiallycramped } {
+ @Body
+ }
+ }
@End @Eq
-macro @E { @OneCol @Eq initzunit { 0.7f } }
+macro @E { @Eq }
--- orig/z01.c
+++ mod/z01.c
@@ -239,6 +239,9 @@
BE_PDF
} BE_TYPE;
+/* Named parameters for address@hidden'. */
+OBJECT SetContextKeyTag = nilobj, SetContextValueTag = nilobj;
+
static void run(int argc, char *argv[], int run_num, int *runs_to_do,
FULL_CHAR *lib)
{ int i, len; FULL_CHAR *arg;
@@ -838,6 +841,7 @@
load(KW_FORCE_CROSS, FORCE_CROSS, TRUE, TRUE, FALSE, CROSSOP_PREC);
load(KW_NULL, NULL_CLOS, FALSE, FALSE, TRUE, NO_PREC );
load(KW_PAGE_LABEL, PAGE_LABEL, FALSE, TRUE, TRUE, DEFAULT_PREC);
+ load(KW_GET_CONTEXT, GET_CONTEXT, FALSE, TRUE, FALSE, DEFAULT_PREC);
#define setcat(s, mk, jn) has_mark(s)=mk, has_join(s)=jn
@@ -852,6 +856,33 @@
s=load(KW_ACAT_NJ, ACAT, TRUE, TRUE, FALSE, ACAT_PREC); setcat(s,FALSE,TRUE);
s=load(KW_ACAT_MJ, ACAT, TRUE, TRUE, FALSE, ACAT_PREC); setcat(s,TRUE, TRUE);
+ /* initialize address@hidden' */
+ { OBJECT setcontext_tag, rpar;
+ setcontext_tag = InsertSym( KW_SET_CONTEXT, LOCAL, no_fpos, DEFAULT_PREC,
+ FALSE, FALSE, SET_CONTEXT,
+ StartSym, nilobj);
+ /* right parameter */
+ rpar = InsertSym( AsciiToFull("pb"), RPAR, no_fpos, DEFAULT_PREC,
+ FALSE, FALSE, 0, setcontext_tag, nilobj);
+ is_compulsory(rpar) = TRUE;
+
+ /* named parameters */
+ SetContextKeyTag = InsertSym( AsciiToFull("key"), NPAR, no_fpos,
+ DEFAULT_PREC, FALSE, FALSE, 0,
+ setcontext_tag, nilobj);
+ visible(SetContextKeyTag) = TRUE;
+ is_compulsory(SetContextKeyTag) = TRUE;
+
+ SetContextValueTag = InsertSym( AsciiToFull("value"), NPAR, no_fpos,
+ DEFAULT_PREC, FALSE, FALSE, 0,
+ setcontext_tag, nilobj);
+ visible(SetContextValueTag) = TRUE;
+ is_compulsory(SetContextValueTag) = TRUE;
+
+ has_par(s) = TRUE;
+ right_assoc(s) = TRUE;
+ }
+
/* intialize fonts and load @FontDef symbol */
FontInit();
--- orig/z04.c
+++ mod/z04.c
@@ -236,7 +236,9 @@
case LUSE:
case LEO:
case LVIS:
-
+ case SET_CONTEXT:
+ case GET_CONTEXT:
+
return actual(x) != nilobj ? SymName(actual(x)) : Image(type(x));
--- orig/z05.c
+++ mod/z05.c
@@ -303,6 +303,7 @@
case LINK_DEST_NULL:
case LINK_URL:
case NOT_REVEALED:
+ case GET_CONTEXT:
NextToken(t, res);
break;
@@ -374,6 +375,7 @@
return;
+ case SET_CONTEXT:
case CLOSURE:
xsym = actual(t);
--- orig/z06.c
+++ mod/z06.c
@@ -470,6 +470,7 @@
case OPEN:
case RAW_VERBATIM:
case VERBATIM:
+ case GET_CONTEXT:
if( has_rpar(actual(op)) )
{ s2 = PopObj();
@@ -514,6 +515,7 @@
break;
+ case SET_CONTEXT:
case CLOSURE:
if( has_rpar(actual(op)) )
@@ -1071,6 +1073,7 @@
case LINK_SOURCE:
case LINK_DEST:
case LINK_URL:
+ case GET_CONTEXT:
/* clean up left context of t (these ops are all right associative) */
Shift(t, precedence(t), RIGHT_ASSOC,
@@ -1313,6 +1316,7 @@
/* NB NO BREAK! */
+ case SET_CONTEXT: /* FIXME: Is this correct? */
case CLOSURE:
x = t; xsym = actual(x);
--- orig/z07.c
+++ mod/z07.c
@@ -313,7 +313,9 @@
case HCAT:
case ACAT:
case ENV_OBJ:
-
+ case SET_CONTEXT:
+ case GET_CONTEXT:
+
New(res, type(x));
for( link = Down(x); link != x; link = NextDown(link) )
{ Child(y, link);
--- orig/z08.c
+++ mod/z08.c
@@ -1588,6 +1588,145 @@
break;
+ case GET_CONTEXT:
+ assert( Down(x) != x, "Manifest: GET_CONTEXT!" );
+ Child(y, Down(x));
+ y = ReplaceWithTidy(y, WORD_TIDY);
+
+ { OBJECT value_env = env;
+
+ if( is_word(type(y)) )
+ { STYLE *s; OBJECT value = nilobj; int found = 0;
+
+ debug1(DOM, D, " @GetContext %s", string(y));
+
+ /* iterate over the contexts until one that contains the key being */
+ /* looked for (currently Y) is found. */
+ for( s = style; s != NULL; )
+ {
+ CONTEXT *ctx = &context(*s);
+ if( !ctx )
+ { s = NULL;
+ }
+ else if( context_key(*ctx) != nilobj
+ && (StringEqual(string(context_key(*ctx)), string(y))) )
+ {
+ value = context_value(*ctx), found = 1;
+
+ /* VALUE is to be manifested with the style associated to CTX */
+ StyleCopy(new_style, *style);
+ context(new_style) = context(*context_style(*ctx));
+ debug3(DOM, D, " @GetContext %s -> value has type %s (%p)",
string(y),
+ Image(type(value)), value);
+
+ /* same for the environment */
+ value_env = context_env(*ctx);
+ break;
+ }
+ else s = context_style(*ctx);
+ }
+
+ if( !found )
+ { Error(8, 33, "no value for context variable `%s', using the empty
string",
+ WARN, &fpos(x), string(y));
+ res = MakeWord(WORD, STR_EMPTY, &fpos(x));
+ StyleCopy(new_style, *style);
+ }
+ else res = CopyObject(value, &fpos(value));
+ }
+ else
+ { Error(8, 33, "%s dropped (right parameter is not a simple word)",
+ WARN, &fpos(x), KW_GET_CONTEXT);
+ res = MakeWord(WORD, STR_EMPTY, &fpos(x));
+ StyleCopy(new_style, *style);
+ }
+
+ ReplaceNode(res, x);
+ DisposeObject(x);
+
+ /* manifest the context value under the style and environment that */
+ /* were in effect at the address@hidden' invocation point. */
+ x = Manifest(res, value_env, &new_style, bthr, fthr, target, crs, ok,
FALSE, enclose, fcr);
+ break;
+ }
+
+ case SET_CONTEXT:
+ {
+ OBJECT key = nilobj, value = nilobj, rpar = nilobj;
+
+ debug0(DOM, D, " entering @SetContext");
+ while (1)
+ {
+ Child(y, Down(x));
+ if( type(y) == PAR )
+ {
+ Child(z, Down(y));
+ if( actual(y) == SetContextKeyTag )
+ {
+ z = Manifest(z, env, style, nbt, nft, &ntarget, crs, FALSE,
FALSE, &nenclose, fcr);
+ z = ReplaceWithTidy(z, WORD_TIDY);
+ if( !is_word(type(z)) )
+ Error(8, 33, "@SetContext: key is not a simple word",
+ FATAL, &fpos(z));
+
+ debug1(DOM, D, " @SetContext: `key' argument: %s", string(z));
+ key = MakeWord(WORD, string(z), &fpos(z));
+ DisposeChild(Down(x));
+ }
+ else if( actual(y) == SetContextValueTag )
+ {
+ debug1(DOM, D, " @SetContext: `value' argument: type %s",
+ Image(type(z)));
+ value = CopyObject(z, &fpos(z));
+ DisposeChild(Down(x));
+ }
+ else if( type(actual(y)) == RPAR )
+ {
+ debug0(DOM, D, " @SetContext: got rpar");
+ rpar = y;
+ break;
+ }
+ else assert1( FALSE, "@SetContext: invalid argument" ,
+ Image(type(y)) );
+
+ }
+ else if( y == x ) break;
+ }
+
+ if( key == nilobj )
+ Error(8, 33, "@SetContext: no key at this point",
+ FATAL, &fpos(x));
+ else if( value == nilobj )
+ Error(8, 33, "@SetContext: no value for key `%s' at this point",
+ FATAL, &fpos(x), string(key));
+
+ /* right parameter (body) */
+ if( rpar == nilobj )
+ Error(8, 33, "@SetContext: no right parameter for key `%s'",
+ FATAL, &fpos(x), string(key));
+
+ assert( key != nilobj && is_word(type(key)),
+ "@SetContext/key: not a word!" );
+
+ debug0(DOM, D, " @SetContext: parameters fetched");
+
+ /* get the right parameter's value */
+ Child(z, Down(rpar));
+
+ /* memorize the key, value, style and environment for use when */
+ /* manifesting VALUE in address@hidden'. */
+ StyleCopy(new_style, *style);
+ context_key(context(new_style)) = key;
+ context_value(context(new_style)) = value;
+ context_style(context(new_style)) = style;
+ context_env(context(new_style)) = env;
+
+ ReplaceNode(z, x);
+ DisposeObject(x);
+ x = Manifest(z, env, &new_style, bthr, fthr, target, crs, ok, FALSE,
enclose, fcr);
+ }
+ break;
+
case CURR_LANG:
if( language(*style) == 0 )
--- orig/z18.c
+++ mod/z18.c
@@ -36,6 +36,8 @@
static CONSTRAINT constraints[MAX_DEPTH]; /* their COLM constraints */
static int itop; /* stack top */
static CONSTRAINT initial_constraint; /* initial COLM constraint */
+ CONTEXT InitialContext = /* initial context */
+ { (CONTEXT *)0, nilobj, nilobj };
STYLE InitialStyle; /* initial style */
OBJECT InitialEnvironment; /* initial environment */
@@ -94,6 +96,7 @@
baselinemark(InitialStyle) = FALSE; /* i.e. not baseline */
strut(InitialStyle) = FALSE; /* i.e. not strutted */
ligatures(InitialStyle) = TRUE; /* i.e. ligatures */
+ context(InitialStyle) = InitialContext;
/* construct destination for root galley */
New(up_hd, HEAD);
--- orig/z25.c
+++ mod/z25.c
@@ -763,6 +763,9 @@
case TAGGED:
case ENV_OBJ:
+ case SET_CONTEXT: /* FIXME: The right place? */
+ case GET_CONTEXT:
+
/* print enclosing left brace if needed */
braces_needed = (DEFAULT_PREC <= outer_prec);
--- orig/z26.c
+++ mod/z26.c
@@ -219,6 +219,8 @@
case CURR_FACE: return KW_CURR_FACE;
case CURR_YUNIT: return KW_CURR_YUNIT;
case CURR_ZUNIT: return KW_CURR_ZUNIT;
+ case SET_CONTEXT: return KW_SET_CONTEXT;
+ case GET_CONTEXT: return KW_GET_CONTEXT;
case COMMON: return KW_COMMON;
case RUMP: return KW_RUMP;
case MELD: return KW_MELD;
--- orig/z31.c
+++ mod/z31.c
@@ -243,6 +243,8 @@
zz_lengths[ CURR_FACE ] =
zz_lengths[ CURR_YUNIT ] =
zz_lengths[ CURR_ZUNIT ] =
+ zz_lengths[ GET_CONTEXT ] =
+ zz_lengths[ SET_CONTEXT ] =
zz_lengths[ COMMON ] =
zz_lengths[ RUMP ] =
zz_lengths[ MELD ] =
--- orig/z41.c
+++ mod/z41.c
@@ -555,6 +555,8 @@
case CURR_FACE: name = KW_CURR_FACE; goto SETC;
case CURR_YUNIT: name = KW_CURR_YUNIT; goto SETC;
case CURR_ZUNIT: name = KW_CURR_ZUNIT; goto SETC;
+ case SET_CONTEXT: name = KW_SET_CONTEXT; goto SETC;
+ case GET_CONTEXT: name = KW_GET_CONTEXT; goto SETC;
case COMMON: name = KW_COMMON; goto SETC;
case RUMP: name = KW_RUMP; goto SETC;
case MELD: name = KW_MELD; goto SETC;
- Context variables and equations,
Ludovic Courtès <=