MathToTioga.mesa
Carl Waldspurger, September 1, 1986 3:52:09 pm PDT
DIRECTORY
TEditFormat,
TextNode USING [Location],
NodeStyle USING [Ref],
NodeStyleOps USING [OfStyle],
NodeProps USING [PutProp],
Rope USING [ROPE, Cat, Find],
Convert USING [RopeFromReal, RealFromRope, Error],
Commander USING [Register, CommandProc],
TextEdit USING [GetCharProp],
Imager USING [DoSaveAll, Move, Context],
MathBox,
MathExpr USING [ExprFromRope, EXPR, parseError],
MathConstructors,
MathDisplayExpr USING [DisplayExpr, DisplayExprFromExpr, Format, Paint],
Evaluator,
AlgebraClasses,
ViewExpr;
MathToTioga: CEDAR PROGRAM
IMPORTS TEditFormat, TextEdit, Imager, Rope, MathBox, MathConstructors, MathExpr,
MathDisplayExpr, NodeProps, Convert, Commander, AlgebraClasses, Evaluator, ViewExpr ~
BEGIN
Abbreviations For Imported Types
ROPE: TYPE ~ Rope.ROPE;
BOX: TYPE ~ MathBox.BOX;
EXPR: TYPE ~ MathExpr.EXPR;
DisplayExpr: TYPE ~ MathDisplayExpr.DisplayExpr;
CharacterArtworkClass: TYPE ~ TEditFormat.CharacterArtworkClass;
CharacterArtworkClassRep: TYPE ~ TEditFormat.CharacterArtworkClassRep;
CharacterArtwork: TYPE ~ TEditFormat.CharacterArtwork;
CharacterArtworkRep: TYPE ~ TEditFormat.CharacterArtworkRep;
Private Type Defs (local to module)
PaintInfo: TYPE ~ REF PaintInfoRep;
PaintInfoRep: TYPE ~ RECORD [
expr: DisplayExpr ← NIL,
box: BOXNIL
];
Control evaluation
EvalFirst: BOOLFALSE;
Procedures
RegisterMathExprArtworkClass: PROC[] ~ {
effects: Registers $MeddleExpr as a Tioga character artwork class.
create the class
class: CharacterArtworkClass ← NEW[CharacterArtworkClassRep ←
[name: $MeddleExpr, format: FormatMathExpr, data: NIL]];
register it
TEditFormat.RegisterCharacterArtwork[class];
};
UnRegisterMathExprArtworkClass: PROC[] ~ {
effects: Unregisters $MeddleExpr as a Tioga character artwork class.
TEditFormat.UnregisterCharacterArtwork[$MeddleExpr];
};
FormatMathExpr: PROC[class: CharacterArtworkClass, loc: TextNode.Location, style: NodeStyle.Ref, styleOps: NodeStyleOps.OfStyle] RETURNS[CharacterArtwork] ~ {
effects: Formats math expression artwork represented by ROPE at loc.
Returns character artwork for formatted expression.
local declarations
TeXToTioga: REAL ~ 20.0; -- default scaling factor from unit-sized TeX Fonts to Tioga
mathExpr: EXPRNIL;
object: AlgebraClasses.Object;
displayExpr: DisplayExpr ← NIL;
displayBox: BOXNIL;
charArtwork: CharacterArtwork;
postfixValue, leading, topLeading, bottomLeading: ROPENIL; -- for postfix properties
pointSize: REAL ← TeXToTioga; -- point size to use when rendering MEDDLE expr
linearExpr: ROPENARROW[TextEdit.GetCharProp[node: loc.node, index: loc.where, name: $MeddleExpr]];
if the user specified a point size to use, get it and use it
exprPointSize: ROPENARROW[TextEdit.GetCharProp[node: loc.node, index: loc.where, name: $MeddlePtSize]];
IF exprPointSize # NIL THEN pointSize ← Convert.RealFromRope[exprPointSize ! Convert.Error => CONTINUE];
convert linear form of expression to internal form
mathExpr ← MathExpr.ExprFromRope[ViewExpr.StripHeader[linearExpr] ! MathExpr.parseError => {mathExpr ← MathConstructors.MakePlaceHolder[]; CONTINUE}];
check for evaluation flag
IF EvalFirst THEN {
object ← Evaluator.Eval[mathExpr];
mathExpr ← AlgebraClasses.ApplyLkpNoRecastExpr[$toExpr, object.class, LIST[object] ];
};
convert immutable expression to mutable display form
displayExpr ← MathDisplayExpr.DisplayExprFromExpr[mathExpr];
format expression and get box dimensions
displayBox ← displayExpr.Format[normal];
scale box dimensions from TeX unit sizes to some reasonable size
displayBox ← MathBox.Scale[displayBox, [pointSize, pointSize]];
compute appropriate postfix point values to place on current node
leading ← Convert.RopeFromReal[displayBox.Height[]];
topLeading ← Convert.RopeFromReal[displayBox.Extents[].ascent + 12.0];
bottomLeading ← Convert.RopeFromReal[displayBox.Extents[].descent + 12.0];
postfixValue ← Rope.Cat[leading, " pt leading ", topLeading, " pt topLeading "];
postfixValue ← Rope.Cat[postfixValue, topLeading, " pt topIndent "];
postfixValue ← Rope.Cat[postfixValue, bottomLeading, " pt bottomLeading "];
put Postfix properties on node containing displayExpr to insure proper spacing
NodeProps.PutProp[loc.node, $Postfix, postfixValue];
create artwork char
charArtwork ← NEW[CharacterArtworkRep ←
[paint: PaintMathExpr, extents: displayBox.Extents[], escapement: [displayBox.Width[], 0.0], data: NEW[PaintInfoRep ← [expr: displayExpr, box: displayBox]]]];
RETURN[charArtwork];
};
PaintMathExpr: PROC[charArtwork: CharacterArtwork, context: Imager.Context] ~ {
effects: Paints charArtwork onto context.
retrieve painting information
paintInfo: PaintInfo ← NARROW[charArtwork.data];
set offset to zero (context origin)
absBox: BOX ← MathBox.ChangeOffset[paintInfo.box, [0.0, 0.0]];
local procedure to do painting within a DoSaveAll
DoPaint: PROC[] ~ {
Imager.Move[context];
MathDisplayExpr.Paint[paintInfo.expr, context, absBox, NIL];
};
pretend that current x,y position in context is origin while actually painting
Imager.DoSaveAll[context, DoPaint];
};
DoIt: Commander.CommandProc ~ {
effects: If command line contains "off" then unregisters $MeddleExpr Artwork.
Otherwise registers $MeddleExpr Artwork.
IF Rope.Find[s1: cmd.commandLine, s2: "off", case: FALSE] # -1 THEN {
UnRegisterMathExprArtworkClass[];
[] ← TEditFormat.SetArtworkEnabled[FALSE];
}
ELSE {
RegisterMathExprArtworkClass[];
[] ← TEditFormat.SetArtworkEnabled[TRUE];
};
};
SetEval: Commander.CommandProc ~ {
effects: Turn on evaluation before painting Tioga doc
IF Rope.Find[s1: cmd.commandLine, s2: "on", case: FALSE] # -1 THEN
EvalFirst ← TRUE
ELSE
EvalFirst ← FALSE;
};
Start Code
register command to turn $MeddleExpr artwork on and off
Commander.Register[key: "MeddleArtwork", proc: DoIt, doc: "Turns MEDDLE Artwork Interpretation On/Off for Tioga"];
register command to turn evaluation before painting on and off
Commander.Register[key: "MathEval", proc: SetEval, doc: "Turns CaminoReal Math Evaluation On/Off for Tioga"];
END.