<> <> <> <> DIRECTORY MathExpr, MathRules, MathDB, MathTypes, MathBox, Imager, Rope, Vector, MathConstructors; MathExprClassesDecoration: CEDAR PROGRAM IMPORTS MathBox, MathRules, MathExpr, MathDB, MathConstructors ~ BEGIN <> EXPR: TYPE ~ MathExpr.EXPR; BOX: TYPE ~ MathBox.BOX; ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector.VEC; CompoundBoxProc: TYPE ~ MathRules.CompoundBoxProc; CompositionProc: TYPE ~ MathRules.CompositionProc; Alignment2D: TYPE ~ MathRules.Alignment2D; Offset: TYPE ~ MathRules.Offset; Size: TYPE ~ MathRules.Size; Argument: TYPE ~ MathExpr.Argument; Symbol: TYPE ~ MathExpr.Symbol; CompoundClass: TYPE ~ MathExpr.CompoundClass; FormatClass: TYPE ~ MathTypes.FormatClass; Style: TYPE ~ MathTypes.Style; <> MakeArgument: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size] RETURNS[Argument] ~ MathExpr.MakeArgument; MakeSymbol: PROC[name: ATOM, aliases: LIST OF ATOM, size: Size, value: EXPR] RETURNS[Symbol] ~ MathExpr.MakeSymbol; MakeCompoundClass: PROC[name: ATOM, formatClass: FormatClass, description: ROPE, args: LIST OF Argument, syms: LIST OF Symbol, boxRule: CompoundBoxProc, compBox: CompositionProc, cvtAS, cvtReduce, cvtSMP, cvtOther: ROPE _ NIL] RETURNS[CompoundClass] ~ MathExpr.MakeCompoundClass; <> smallGap: REAL = 0.05; medGap: REAL = 0.10; bigGap: REAL = 0.25; <> FixedSizeBoxRule: CompoundBoxProc ~ { <> RETURN[boxes]; }; BoxBoxRule: CompoundBoxProc ~ { <> <> argBox: BOX _ MathBox.GetBox[$arg, boxes]; topBox: BOX _ MathBox.GetBox[$top, boxes]; bottomBox: BOX _ MathBox.GetBox[$bottom, boxes]; leftSideBox: BOX _ MathBox.GetBox[$leftSide, boxes]; rightSideBox: BOX _ MathBox.GetBox[$rightSide, boxes]; topSpaceBox: BOX _ MathBox.GetBox[$topSpace, boxes]; bottomSpaceBox: BOX _ MathBox.GetBox[$bottomSpace, boxes]; leftSpaceBox: BOX _ MathBox.GetBox[$leftSpace, boxes]; rightSpaceBox: BOX _ MathBox.GetBox[$rightSpace, boxes]; <> scale: REAL _ ( argBox.Width[] + leftSideBox.Width[] +rightSideBox.Width[] + leftSpaceBox.Width[] +rightSpaceBox.Width[] ) / topBox.Width[]; topBox _ MathBox.Scale[topBox, [scale, 1.0]]; bottomBox _ MathBox.Scale[bottomBox, [scale, 1.0]]; topSpaceBox _ MathBox.Scale[topSpaceBox, [scale, 1.0]]; bottomSpaceBox _ MathBox.Scale[bottomSpaceBox, [scale, 1.0]]; <> scale _ ( argBox.Height[] + topBox.Height[] + bottomBox.Height[] + topSpaceBox.Height[] + bottomSpaceBox.Height[] ) / leftSideBox.Height[]; leftSideBox _ MathBox.Scale[leftSideBox, [1.0, scale]]; rightSideBox _ MathBox.Scale[rightSideBox, [1.0, scale]]; leftSpaceBox _ MathBox.Scale[leftSpaceBox, [1.0, scale]]; rightSpaceBox _ MathBox.Scale[rightSpaceBox, [1.0, scale]]; RETURN[LIST[argBox, topBox, bottomBox, leftSideBox, rightSideBox, topSpaceBox, bottomSpaceBox, leftSpaceBox, rightSpaceBox]]; }; <> PostfixUnaryOpCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[ [$aliasSpace, [$aliasUnaryOp, [right], [left]], [$aliasUnaryOp, [origin], [origin]]], [$aliasA, [$aliasSpace, [right], [left]], [$aliasSpace, [origin], [origin]]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$aliasUnaryOp, [origin]], [$aliasUnaryOp, [origin]]]; RETURN[tempBox, tempBoxes]; }; SubscriptCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; vertOffsetSubscript, vertOffsetBase: Offset; alignments: LIST OF Alignment2D _ NIL; IF MathBox.GetBox[$base, boxes].Height[] > MathBox.GetBox[$subscript, boxes].Height[] THEN { vertOffsetSubscript _ [top, -0.2]; vertOffsetBase _ [bottom]; } ELSE { vertOffsetSubscript _ [top]; vertOffsetBase _ [bottom, +0.2]; }; alignments _ LIST[ [$subscript, [$base, [left], [right]], [$base, vertOffsetSubscript, vertOffsetBase]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]]; <> tempBox _ tempBox.ChangeSuperHint[MathBox.GetBox[$base, tempBoxes]]; RETURN[tempBox, tempBoxes]; }; SuperscriptCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; vertOffsetExponent, vertOffsetBase, horizOffsetBase: Offset; alignments: LIST OF Alignment2D _ NIL; baseBox: BOX _ MathBox.GetBox[$base, boxes]; superscriptBox: BOX _ MathBox.GetBox[$superscript, boxes]; hintBox: BOX _ baseBox.SuperscriptHint[]; -- hint about where to place subscript w/i base IF hintBox # NIL THEN { <> horizOffsetBase _ [origin, hintBox.Offset[].x + hintBox.Extents[].rightExtent]; IF (hintBox.Height[] * baseBox.Height[]) > superscriptBox.Height[] THEN { vertOffsetExponent _ [bottom, 0.2]; <> vertOffsetBase _ [origin, hintBox.Offset[].y + hintBox.Extents[].ascent]; } ELSE { vertOffsetExponent _ [bottom]; <<0.8 way up on hint box>> vertOffsetBase _ [origin, 0.8 * (hintBox.Offset[].y + hintBox.Extents[].ascent)]; }; } ELSE { <> horizOffsetBase _ [right]; IF baseBox.Height[] > superscriptBox.Height[] THEN { vertOffsetExponent _ [bottom, 0.2]; vertOffsetBase _ [top]; } ELSE { vertOffsetExponent _ [bottom]; vertOffsetBase _ [top, -0.2]; }; }; alignments _ LIST[ [$superscript, [$base, [left], horizOffsetBase], [$base, vertOffsetExponent, vertOffsetBase]]]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]]; RETURN[tempBox, tempBoxes]; }; AboveCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[ [$bottomSpace, [$bottomArg, [center], [center]], [$bottomArg, [bottom], [top]]], [$topSpace, [$bottomArg, [center], [center]], [$bottomSpace, [bottom], [top]]], [$topArg, [$bottomArg, [center], [center]], [$topSpace, [bottom], [top]]] ]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$topArg, [origin]], [$bottomSpace, [top]]]; RETURN[tempBox, tempBoxes]; }; HatCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[ [$bottomSpace, [$base, [center], [center]], [$base, [bottom], [top]]], [$hat, [$base, [center], [center]], [$bottomSpace, [bottom], [top]]] ]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$base, [origin]], [$base, [origin]]]; RETURN[tempBox, tempBoxes]; }; BoxCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[ [$topSpace, [$arg, [center], [center]], [$arg, [bottom], [top]]], [$top, [$topSpace, [center], [center]], [$topSpace, [bottom], [top]]], [$bottomSpace, [$arg, [center], [center]], [$arg, [top], [bottom]]], [$bottom, [$bottomSpace, [center], [center]], [$bottomSpace, [top], [bottom]]], [$leftSpace, [$arg, [right], [left]], [$arg, [center], [center]]], [$leftSide, [$leftSpace, [right], [left]], [$leftSpace, [center], [center]]], [$rightSpace, [$arg, [left], [right]], [$arg, [center], [center]]], [$rightSide, [$rightSpace, [left], [right]], [$rightSpace, [center], [center]]] ]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$arg, [origin]], [$arg, [origin]]]; RETURN[tempBox, tempBoxes]; }; <> MakePostFixUnaryOpClass: PUBLIC PROC[class, op, arg: ATOM, operation: EXPR, description: ROPE, cvtAS: ROPE] RETURNS[CompoundClass] ~ { <> << The alignment is "operation arg"; alignment is thru baselines. >> << Both op, arg are of fixed size "normal".>> <<>> argArg: Argument _ MakeArgument[arg, LIST[$aliasA, $aliasHot], normal]; spaceSym: Symbol _ MakeSymbol[$Space, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$medium]]; unaryOpSym: Symbol _ MakeSymbol[op, LIST[$aliasUnaryOp], normal, operation]; RETURN[MakeCompoundClass[class, unaryOp, description, LIST[argArg], LIST[unaryOpSym, spaceSym], FixedSizeBoxRule, PostfixUnaryOpCompRule, cvtAS]]; }; <> wrongBoxType: PUBLIC ERROR = CODE; <> InstallDecorationClassesAA: PROC [] ~ { <> subscriptClass, aboveClass, hatClass, superscriptClass, primeClass, boxClass: CompoundClass; baseArg, subscriptArg, superscriptArg, hatArg, topArg, bottomArg, boxArg: Argument; numerSpSym, denomSpSym: Symbol; leftSideSym, rightSideSym, topSym, bottomSym: Symbol; leftSpaceSym, rightSpaceSym, topSpaceSym, bottomSpaceSym: Symbol; baseArg _ MakeArgument[$base, LIST[$aliasA, $aliasHot], normal]; subscriptArg _ MakeArgument[$subscript, LIST[$aliasB], script]; superscriptArg _ MakeArgument[$superscript, LIST[$aliasB], script]; hatArg _ MakeArgument[$hat, LIST[$aliasB], script]; <> boxArg _ MakeArgument[$arg, LIST[$aliasA, $aliasHot], normal]; leftSideSym _ MakeSymbol[$leftSide, NIL, normal, MathConstructors.MakePlainSym['\174] ]; rightSideSym _ MakeSymbol[$rightSide, NIL, normal, MathConstructors.MakePlainSym['\174] ]; topSym _ MakeSymbol[$top, NIL, normal, MathConstructors.MakeLine[]]; bottomSym _ MakeSymbol[$bottom, NIL, normal, MathConstructors.MakeLine[]]; leftSpaceSym _ MakeSymbol[$leftSpace, NIL, normal, MathConstructors.MakeSpace[$medium]]; rightSpaceSym _ MakeSymbol[$rightSpace, NIL, normal, MathConstructors.MakeSpace[$medium]]; topSpaceSym _ MakeSymbol[$topSpace, NIL, normal, MathConstructors.MakeSpace[$medium]]; bottomSpaceSym _ MakeSymbol[$bottomSpace, NIL, normal, MathConstructors.MakeSpace[$medium]]; <> topArg _ MakeArgument[$topArg, LIST[$aliasA, $aliasHot], normal]; bottomArg _ MakeArgument[$bottomArg, LIST[$aliasB], normal]; numerSpSym _ MakeSymbol[$topSpace, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$thin]]; denomSpSym _ MakeSymbol[$bottomSpace, LIST[$aliasSpace], normal, MathConstructors.MakeSpace[$thin]]; boxClass _ MakeCompoundClass[$box, other, "box a", LIST[boxArg], LIST[leftSideSym, rightSideSym, topSym, bottomSym, leftSpaceSym, rightSpaceSym, topSpaceSym, bottomSpaceSym], BoxBoxRule, BoxCompRule, "box $arg"]; subscriptClass _ MakeCompoundClass[$subscript, other, "a sub b", LIST[baseArg, subscriptArg], NIL, FixedSizeBoxRule, SubscriptCompRule, "$baseSub$subscript"]; superscriptClass _ MakeCompoundClass[$superscript, other, "a super b", LIST[baseArg, superscriptArg], NIL, FixedSizeBoxRule, SuperscriptCompRule, "$baseSuper$superscript"]; hatClass _ MakeCompoundClass[$hat, other, "a hat b", LIST[baseArg, hatArg], LIST[denomSpSym], FixedSizeBoxRule, HatCompRule, "$baseHat$hat"]; aboveClass _ MakeCompoundClass[$above, over, "a above b", LIST[topArg, bottomArg], LIST[numerSpSym, denomSpSym], FixedSizeBoxRule, AboveCompRule, "$topArg above $bottomArg"]; primeClass _ MakePostFixUnaryOpClass[$prime, $prime, $a, MathConstructors.MakePlainSym[''], "a prime", "$aPrime"]; MathDB.InstallCompoundClass[subscriptClass]; MathDB.AddOperator[subscriptClass, $Decoration]; MathDB.InstallCompoundClass[superscriptClass]; MathDB.AddOperator[superscriptClass, $Decoration]; MathDB.InstallCompoundClass[hatClass]; MathDB.AddOperator[hatClass, $Decoration]; MathDB.InstallCompoundClass[aboveClass]; MathDB.AddOperator[aboveClass, $Decoration]; MathDB.InstallCompoundClass[primeClass]; MathDB.AddOperator[primeClass, $Decoration]; MathDB.InstallCompoundClass[boxClass]; MathDB.AddOperator[boxClass, $Decoration]; }; <> InstallDecorationClassesAA[]; END.