lout-users
[Top][All Lists]
Advanced

[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;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]