<> <> <> <> <> DIRECTORY MathExpr, MathRules, MathDB, MathTypes, MathBox, ImagerFont, ImagerTransformation, Imager, Rope, Real, Vector, Convert, MathConstructors; MathExprClassesObject: CEDAR PROGRAM IMPORTS MathBox, MathRules, ImagerFont, Imager, ImagerTransformation, MathExpr, MathDB, Convert, Rope, Real, MathConstructors ~ BEGIN <> EXPR: TYPE ~ MathExpr.EXPR; BOX: TYPE ~ MathBox.BOX; ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector.VEC; AtomBoxProc: TYPE ~ MathRules.AtomBoxProc; AtomPaintProc: TYPE ~ MathRules.AtomPaintProc; AtomToASRopeProc: TYPE ~ MathRules.AtomToASRopeProc; AtomClass: TYPE ~ MathExpr.AtomClass; AtomFlavor: TYPE ~ MathExpr.AtomFlavor; FormatClass: TYPE ~ MathTypes.FormatClass; MatrixClass: TYPE ~ MathExpr.MatrixClass; Style: TYPE ~ MathTypes.Style; 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; <> MakeAtomClass: PROC[name: ATOM, formatClass: FormatClass, flavor: AtomFlavor, style: Style, boxRule: AtomBoxProc, paintRule: AtomPaintProc, cvtASRule, cvtReduceRule, cvtSMPRule, cvtOtherRule: AtomToASRopeProc _ NIL] RETURNS[AtomClass] ~ MathExpr.MakeAtomClass; 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; <> GreekVarToASRope: AtomToASRopeProc ~ { IF value.Length[] < 1 THEN RETURN["unknown"] ELSE RETURN[MathConstructors.CharToGreekName[value.Fetch[0]]]; }; UnknownToASRope: AtomToASRopeProc ~ { RETURN["?"]; }; InfinityToASRope: AtomToASRopeProc ~ { RETURN["infinity"]; }; rightArrowToASRope: AtomToASRopeProc ~ { RETURN["rightArrow"]; }; barToASRope: AtomToASRopeProc ~ { RETURN["bar"]; }; perpToASRope: AtomToASRopeProc ~ { RETURN["perp"]; }; hatToASRope: AtomToASRopeProc ~ { RETURN["hat"]; }; <> LineBox: AtomBoxProc ~ { <> << Note that this is always a dummy value (dsa - because lines will always occur as part of a CompoundExpr, and the line will then be scaled appropriately by the CompoundExpr's BoxProc.)>> <> RETURN[[leftExtent: 0.0, rightExtent: 1.0, descent: 0.0, ascent: 0.03]]; }; CharBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; RETURN[ImagerFont.RopeBoundingBox[font, value]]; }; OverlayBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; farLeft, farRight, farUp, farDown: REAL _ 0.0; -- extreme edges of overlayed extents FOR i:INT IN [0..value.Length[]-1] DO box: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value.Substr[i, 1]]; farLeft _ MAX[farLeft, box.leftExtent]; farRight _ MAX[farRight, box.rightExtent]; farUp _ MAX[farUp, box.ascent]; farDown _ MAX[farDown, box.descent]; ENDLOOP; RETURN[[leftExtent: farLeft, rightExtent: farRight, descent: farDown, ascent: farUp]]; }; RopeBox: AtomBoxProc ~ { <> font: ImagerFont.Font _ ImagerFont.Scale[ImagerFont.Find[style.font], style.scale]; RETURN[ImagerFont.RopeBoundingBox[font, value]]; }; SpaceBox: AtomBoxProc ~ { <> size: ATOM _ Convert.AtomFromRope[value]; RETURN[ SELECT size FROM $null => [leftExtent: 0.0, rightExtent: 0.001, descent: 0.0, ascent: 0.001], $thin => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0], $medium => [leftExtent: 0.0, rightExtent: 0.12, ascent: 0.12, descent: 0.0], $thick => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.25, descent: 0.0], $veryThick => [leftExtent: 0.0, rightExtent: 0.4, ascent: 0.4, descent: 0.0], $matrix => [leftExtent: 0.0, rightExtent: 0.9, ascent: 0.65, descent: 0.0], $limit => [leftExtent: 0.0, rightExtent: 0.25, ascent: 0.12, descent: 0.0], $product => [leftExtent: 0.0, rightExtent: 0.001, ascent: 0.21, descent: -0.19] <> ENDCASE => [leftExtent: 0.0, rightExtent: 0.05, ascent: 0.05, descent: 0.0] ]; }; <> PaintChar: AtomPaintProc ~ { <> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value]; xFactor: REAL _ Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100; yFactor: REAL _ Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100; Imager.SetXY[context, absBox.Offset[]]; Imager.SetFont[context, ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]]; Imager.ShowRope[context, value]; }; }; PaintOverlay: AtomPaintProc ~ { <> << This is useful for things like negated symbols (/ slashed through)... >> <<>> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ OverlayBox[value, style]; xFactor: REAL _ Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100; yFactor: REAL _ Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100; <> font _ ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]; <> FOR i:INT IN [0..value.Length[]-1] DO char: ROPE _ value.Substr[i, 1]; box: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, char]; position: VEC _ [MathRules.AlignHorizontal[box, [center], absBox, [center]], MathRules.AlignVertical[box, [center], absBox, [center]]]; Imager.SetXY[context, position]; Imager.SetFont[context, font]; Imager.ShowRope[context, char]; ENDLOOP; }; }; PaintRope: AtomPaintProc ~ { <> <> IF (absBox.Type[] # absolute) THEN ERROR wrongBoxType ELSE { font: ImagerFont.Font _ ImagerFont.Find[style.font]; extents: ImagerFont.Extents _ ImagerFont.RopeBoundingBox[font, value]; xFactor: REAL _ Real.Float[Real.Fix[100*absBox.Width[] / (extents.rightExtent + extents.leftExtent)]]/100; yFactor: REAL _ Real.Float[Real.Fix[100*absBox.Height[] / (extents.ascent + extents.descent)]]/100; Imager.SetXY[context, absBox.Offset[]]; Imager.SetFont[context, ImagerFont.Modify[font, ImagerTransformation.Scale2[[xFactor, yFactor]]]]; Imager.ShowRope[context, value]; }; }; PaintLine: AtomPaintProc ~ { <> <> <> r: Imager.Rectangle _ [x: absBox.Offset[].x - absBox.Extents[].leftExtent, y: absBox.Offset[].y - absBox.Extents[].descent, w: absBox.Width[], h: absBox.Height[]]; Imager.MaskRectangle[context, r]; }; PaintSpace: AtomPaintProc ~ { <> RETURN; }; <> InstallAtomClasses: PROC [] ~ { xcs, xci: Style; integerClass, boolClass, realClass, variableClass, plainSymClass, overlaySymClass, smallMathSymClass, bigMathSymClass, italSymClass, mathItalSymClass, lineClass, placeholderClass, spaceClass, greekVarClass, infinityClass, rightArrowClass, barClass, perpClass, hatClass: AtomClass; <<>> <> xcs _ [font: "Xerox/XC1-2-2/Classic"]; xci _ [font: "Xerox/XC1-2-2/Classic-italic"]; <> integerClass _ MakeAtomClass[$integer, atom, argument, xcs, RopeBox, PaintRope]; boolClass _ MakeAtomClass[$bool, atom, argument, xcs, RopeBox, PaintRope]; realClass _ MakeAtomClass[$real, atom, argument, xcs, RopeBox, PaintRope]; variableClass _ MakeAtomClass[$variable, atom, argument, xci, RopeBox, PaintRope]; greekVarClass _ MakeAtomClass[$greekVar, atom, argument, xcs, RopeBox, PaintRope, GreekVarToASRope]; plainSymClass _ MakeAtomClass[$plainSym, atom, symbol, xcs, RopeBox, PaintRope]; -- MathConstructors.MakePlainSym overlaySymClass _ MakeAtomClass[$overlaySym, atom, symbol, xcs, OverlayBox, PaintOverlay]; -- MathConstructors.MakeOverlaySym bigMathSymClass _ MakeAtomClass[$bigMathSym, atom, symbol, xcs, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeBigMathSym smallMathSymClass _ MakeAtomClass[$smallMathSym, atom, symbol, xcs, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeSmallMathSym mathItalSymClass _ MakeAtomClass[$mathItalicSym, atom, symbol, xci, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeMathItalSym italSymClass _ MakeAtomClass[$italicSym, atom, symbol, xci, RopeBox, PaintRope, UnknownToASRope]; -- MathConstructors.MakeItalSym lineClass _ MakeAtomClass[$line, atom, symbol, xcs, LineBox, PaintLine]; placeholderClass _ MakeAtomClass[$placeholder, atom, placeholder, xcs, RopeBox, PaintRope, UnknownToASRope]; spaceClass _ MakeAtomClass[$space, atom, symbol, xcs, SpaceBox, PaintSpace]; infinityClass _ MakeAtomClass[$infinity, atom, argument, xcs, RopeBox, PaintRope, InfinityToASRope]; rightArrowClass _ MakeAtomClass[$rightArrow, atom, argument, xcs, RopeBox, PaintRope, rightArrowToASRope]; barClass _ MakeAtomClass[$bar, atom, argument, xcs, RopeBox, PaintRope, barToASRope]; perpClass _ MakeAtomClass[$perp, atom, argument, xcs, RopeBox, PaintRope, barToASRope]; hatClass _ MakeAtomClass[$hat, atom, argument, xcs, RopeBox, PaintRope, hatToASRope]; <> MathDB.InstallAtomClass[integerClass]; MathDB.InstallAtomClass[boolClass]; MathDB.InstallAtomClass[realClass]; MathDB.InstallAtomClass[variableClass]; MathDB.InstallAtomClass[greekVarClass]; MathDB.InstallAtomClass[plainSymClass]; MathDB.InstallAtomClass[overlaySymClass]; MathDB.InstallAtomClass[italSymClass]; MathDB.InstallAtomClass[smallMathSymClass]; MathDB.InstallAtomClass[bigMathSymClass]; MathDB.InstallAtomClass[mathItalSymClass]; MathDB.InstallAtomClass[lineClass]; MathDB.InstallAtomClass[placeholderClass]; MathDB.InstallAtomClass[spaceClass]; MathDB.InstallAtomClass[infinityClass]; MathDB.InstallAtomClass[rightArrowClass]; MathDB.InstallAtomClass[barClass]; MathDB.InstallAtomClass[perpClass]; MathDB.InstallAtomClass[hatClass]; }; <> FixedSizeBoxRule: CompoundBoxProc ~ { <> RETURN[boxes]; }; <> ComplexCompRule: CompositionProc ~ { <> tempBox: BOX; tempBoxes: LIST OF BOX; alignments: LIST OF Alignment2D _ LIST[ [$a, [$plus, [right], [left, -medGap]], [$plus, [origin], [origin]]], [$leftParen, [$a, [right], [left, -medGap]], [$plus, [origin], [origin]]], [$b, [$plus, [left], [right, medGap]], [$plus, [origin], [origin]]], [$i, [$b, [left], [right, medGap]], [$b, [origin], [origin]]], [$rightParen, [$i, [left], [right, medGap]], [$plus, [origin], [origin]]] ]; [tempBox, tempBoxes] _ MathRules.Compose[boxes, alignments, [$a, [origin]], [$plus, [origin]]]; RETURN[tempBox, tempBoxes]; }; <> InstallCompoundClasses: PROC [] ~ { <> complexClass: CompoundClass; realPartArg, imaginaryPartArg: Argument; plusSym, iSym, funLParenSym, funRParenSym: Symbol; <> realPartArg _ MakeArgument[$a, LIST[$aliasA, $aliasHot], normal]; imaginaryPartArg _ MakeArgument[$b, LIST[$aliasB], normal]; iSym _ MakeSymbol[$i, NIL, normal, MathConstructors.MakeItalSym['i]]; plusSym _ MakeSymbol[$plus, LIST[$aliasBinOp], normal, MathConstructors.MakePlainSym['+]]; <> funLParenSym _ MakeSymbol[$leftParen, NIL, normal, MathConstructors.MakePlainSym['[]]; funRParenSym _ MakeSymbol[$rightParen, NIL, normal, MathConstructors.MakePlainSym[']]]; <> <> complexClass _ MakeCompoundClass[$complex, other, "a + bi", LIST[realPartArg, imaginaryPartArg], LIST[funLParenSym, plusSym, iSym, funRParenSym], FixedSizeBoxRule, ComplexCompRule, "($a + $bi)"]; MathDB.InstallCompoundClass[complexClass]; }; <> InstallMatrixClasses: PROC [] ~ { setClass, pointClass, sequenceClass, vectorClass, matrixClass: MatrixClass; setClass _ MathExpr.MakeMatrixClass[$set, matrix, MathConstructors.MakePlainSym['{], MathConstructors.MakePlainSym['}], MathConstructors.MakeSpace[$matrix]]; -- brackets are { } pointClass _ MathExpr.MakeMatrixClass[$point, matrix, MathConstructors.MakePlainSym[')], MathConstructors.MakePlainSym[')], MathConstructors.MakeSpace[$matrix]]; -- brackets are ( ) sequenceClass _ MathExpr.MakeMatrixClass[$sequence, matrix, MathConstructors.MakePlainSym['<], MathConstructors.MakePlainSym['>], MathConstructors.MakeSpace[$matrix]]; -- brackets are < > vectorClass _ MathExpr.MakeMatrixClass[$vector, matrix, MathConstructors.MakePlainSym[']], MathConstructors.MakePlainSym[']], MathConstructors.MakeSpace[$matrix]]; -- brackets are [ ] matrixClass _ MathExpr.MakeMatrixClass[$matrix, matrix, MathConstructors.MakePlainSym['[], MathConstructors.MakePlainSym[']], MathConstructors.MakeSpace[$matrix]]; -- brackets are [ ] MathDB.InstallMatrixClass[setClass]; MathDB.InstallMatrixClass[pointClass]; MathDB.InstallMatrixClass[sequenceClass]; MathDB.InstallMatrixClass[vectorClass]; MathDB.InstallMatrixClass[matrixClass]; }; <> wrongAtomValueType: PUBLIC ERROR = CODE; wrongBoxType: PUBLIC ERROR = CODE; <> InstallAtomClasses[]; InstallCompoundClasses[]; InstallMatrixClasses[]; END.