-- NodeStyleImpl.mesa
-- Written by Bill Paxton, January 1981
-- Last changed by Bill Paxton, 3-Jun-81 13:42:24

-- Implements JaM commands for style rules
-- and commands to load styles

DIRECTORY
NodeStyle,
NodeStyleExtra,
TextNode,
TextLooks,
TiogaJaM,
JaMFnsDefs,
JaMOtherDefs;

NodeS
tyleImpl: PROGRAM
IMPORTS TiogaJaM, JaMFnsDefs, JaMOtherDefs, NodeStyleExtra
EXPORTS NodeStyle =
BEGIN
OPEN NodeStyle, NodeStyleExtra, JaMFnsDefs,
tjI:TiogaJaM,
nodeI:TextNode,
looksI:TextLooks;

StyleError: PUBLIC ERROR = CODE;

LoadProc: TYPE = PROC;
SetRealProc: TYPE = PROC [amount:REAL];
AddRealProc: TYPE = PROC [inc:REAL];
PercentProc: TYPE = PROC [percent:REAL];
SetNameProc: TYPE = PROC [name:tjI.JaMName];

Ops: TYPE = REF OpsRec;
OpsRec: TYPE = RECORD [
Load: LoadProc, SetReal: SetRealProc, AddReal: AddRealProc,
Percent: PercentProc, SetName: SetNameProc ];

SetRealError: SetRealProc = { ERROR StyleError };
AddRealError: AddRealProc = { ERROR StyleError };
PercentError: PercentProc = { ERROR StyleError };
SetNameError: SetNameProc = { ERROR StyleError };

style
: PUBLIC Ref; -- the current style parameters

Style
Parameter: PROC [ops: Ops] =
BEGIN OPEN ops;
nameflag: BOOLEAN;
name: tjI.JaMName;
amount: REAL;
[nameflag, name, amount] ← PopNameOrReal[];
IF ~nameflag THEN SetReal[amount]
ELSE SELECT name FROM
the => Load[];
bigger =>
BEGIN
[nameflag, name, amount] ← PopNameOrReal[];
IF ~nameflag THEN AddReal[amount]
ELSE IF name=percent THEN Percent[PopReal[]]
ELSE ERROR StyleError;
END;
smaller =>
BEGIN
[nameflag, name, amount] ← PopNameOrReal[];
IF ~nameflag THEN AddReal[-amount]
ELSE IF name=percent THEN Percent[-PopReal[]]
ELSE ERROR StyleError;
END;
ENDCASE => SetName[name];
END;


-- **** Font Face ****

FontF
aceOp: PROC = { StyleParameter[fontFaceOps] };

fontFaceOps: Ops ← NEW [OpsRec ← [FontFaceLoad, SetRealError,
AddRealError, PercentError, FontFaceSetName]];

FontFaceLoad: LoadProc = {
PushName[SELECT style.fontFace FROM
Regular => regular,
Bold => bold,
Italic => italic,
BoldItalic => bolditalic,
ENDCASE => ERROR]
};

FontFaceSetName: SetNameProc = {
FontFaceArray: TYPE = ARRAY FontFace OF FontFace;
minusBold: FontFaceArray = [Regular, Regular, Italic, Italic];
minusItalic: FontFaceArray = [Regular, Bold, Regular, Bold];
plusBold: FontFaceArray = [Bold, Bold, BoldItalic, BoldItalic];
plusItalic: FontFaceArray = [Italic, BoldItalic, Italic, BoldItalic];
style.fontFace ← SELECT name FROM
regular => Regular,
bold => Bold,
italic => Italic,
bolditalic => BoldItalic,
plusbold => plusBold[style.fontFace],
plusitalic => plusItalic[style.fontFace],
minusbold => minusBold[style.fontFace],
minusitalic => minusItalic[style.fontFace],
ENDCASE => ERROR StyleError };


-- **** Font Alphabets ****

FontA
lphabetsOp: PROC = { StyleParameter[fontAlphabetsOps] };

fontAlphabetsOps: Ops ← NEW [OpsRec ← [FontAlphabetsLoad, SetRealError, AddRealError, PercentError, FontAlphabetsSetName]];

FontAlphabetsLoad: LoadProc = {
PushName[SELECT style.fontAlphabets FROM
CapsAndLower => capsAndLower,
CapsAndSmallCaps => capsAndSmallCaps,
LowerOnly => lowerOnly,
CapsOnly => capsOnly,
ENDCASE => ERROR]
};

FontAlphabetsSetName: SetNameProc = {
style.fontAlphabets ← SELECT name FROM
capsAndLower => CapsAndLower,
capsAndSmallCaps => CapsAndSmallCaps,
lowerOnly => LowerOnly,
capsOnly => CapsOnly,
ENDCASE => ERROR StyleError };


-- **** Underlining ****

Under
liningOp: PROC = { StyleParameter[underliningOps] };

underliningOps: Ops ← NEW [OpsRec ← [UnderliningLoad, SetRealError,
AddRealError, PercentError, UnderliningSetName]];

UnderliningLoad: LoadProc = {
PushName[SELECT style.underlining FROM
None => none,
LettersAndDigits => lettersAndDigits,
Visible => visible,
All => all,
ENDCASE => ERROR]
};

UnderliningSetName: SetNameProc = {
style.underlining ← SELECT name FROM
none => None,
lettersAndDigits => LettersAndDigits,
visible => Visible,
all => All,
ENDCASE => ERROR StyleError };


-- **** Line Formatting ****

Forma
ttingOp: PROC = {
name: tjI.JaMName;
ok: BOOLEAN;
[name, ok] ← TryToPopName[];
IF ok AND name # line THEN PushName[name];
StyleParameter[formattingOps] };

formattingOps: Ops ← NEW [OpsRec ← [FormattingLoad, SetRealError,
AddRealError, PercentError, FormattingSetName]];

FormattingLoad: LoadProc = {
PushName[SELECT style.lineFormatting FROM
Justified => justified,
FlushLeft => flushLeft,
FlushRight => flushRight,
Centered => centered,
ENDCASE => ERROR]
};

FormattingSetName: SetNameProc = {
style.lineFormatting ← SELECT name FROM
justified => Justified,
flushLeft => FlushLeft,
flushRight => FlushRight,
centered => Centered,
ENDCASE => ERROR StyleError };


-- **** Style Name ****

Style
NameOp: PROC = { StyleParameter[styleOps] };

styleOps: Ops ← NEW [OpsRec ← [StyleNameLoad, SetRealError,
AddRealError, PercentError, StyleNameSetName]];

StyleNameLoad: LoadProc = { PushName[tjI.StyleToJaM[style.styleName]] };

StyleNameSetName: SetNameProc = { style.styleName ← tjI.JaMToStyle[name] };


-- **** Font Family ****

FontF
amilyOp: PROC = { StyleParameter[fontFamilyOps] };

fontFamilyOps: Ops ← NEW [OpsRec ← [FontFamilyLoad, SetRealError,
AddRealError, PercentError, FontFamilySetName]];

FontFamilyLoad: LoadProc = { PushName[style.fontFamily] };

FontFamilySetName: SetNameProc = { style.fontFamily ← name };


-- **** Font Size ****

FontS
izeOp: PROC = { StyleParameter[fontSizeOps] };

fontSizeOps: Ops ← NEW [OpsRec ← [FontSizeLoad, FontSizeSetReal, FontSizeAddReal, FontSizePercent, SetNameError]];

FontSizeLoad: LoadProc = { PushReal[style.fontSize] };

FontSizeSetReal: SetRealProc = { style.fontSize ← amount };

FontSizeAddReal: AddRealProc = { style.fontSize ← style.fontSize+inc };

FontSizePercent: PercentProc = {
val: REAL ← style.fontSize; style.fontSize ← val+(percent/100)*val };


-- **** Indent ****

Inden
tOp: PROC = { SELECT PopName[] FROM
left => LeftIndentOp[];
right => RightIndentOp[];
first => FirstIndentOp[];
body => BodyIndentOp[];
top => TopIndentOp[];
bottom => BottomIndentOp[];
ENDCASE => ERROR StyleError };


-- **** Left Indent ****

LeftI
ndentOp: PROC = { StyleParameter[leftIndentOps] };

leftIndentOps: Ops ← NEW [OpsRec ← [LeftIndentLoad, LeftIndentSetReal,
LeftIndentAddReal, LeftIndentPercent, SetNameError]];

LeftIndentLoad: LoadProc = { PushReal[style.leftIndent] };

LeftIndentSetReal: SetRealProc = { style.leftIndent ← amount };

LeftIndentAddReal: AddRealProc =
{ style.leftIndent ← style.leftIndent+inc };

LeftIndentPercent: PercentProc = {
val: REAL ← style.leftIndent;
style.leftIndent ← val+(percent/100)*val };


-- **** Right Indent ****

Right
IndentOp: PROC = { StyleParameter[rightIndentOps] };

rightIndentOps: Ops ← NEW [OpsRec ← [RightIndentLoad,
RightIndentSetReal, RightIndentAddReal, RightIndentPercent,
SetNameError]];

RightIndentLoad: LoadProc = { PushReal[style.rightIndent] };

RightIndentSetReal: SetRealProc = { style.rightIndent ← amount };

RightIndentAddReal: AddRealProc =
{ style.rightIndent ← style.rightIndent+inc };

RightIndentPercent: PercentProc = {
val: REAL ← style.rightIndent;
style.rightIndent ← val+(percent/100)*val };


-- **** First Indent ****

First
IndentOp: PROC = { StyleParameter[firstIndentOps] };

firstIndentOps: Ops ← NEW [OpsRec ← [FirstIndentLoad,
FirstIndentSetReal, FirstIndentAddReal,
FirstIndentPercent, SetNameError]];

FirstIndentLoad: LoadProc = { PushReal[style.firstIndent] };

FirstIndentSetReal: SetRealProc = { style.firstIndent ← amount };

FirstIndentAddReal: AddRealProc =
{ style.firstIndent ← style.firstIndent+inc };

FirstIndentPercent: PercentProc = {
val: REAL ← style.firstIndent;
style.firstIndent ← val+(percent/100)*val };


-- **** Body Indent ****

BodyI
ndentOp: PROC = { StyleParameter[bodyIndentOps] };

bodyIndentOps: Ops ← NEW [OpsRec ← [BodyIndentLoad,
BodyIndentSetReal, BodyIndentAddReal, BodyIndentPercent,
SetNameError]];

BodyIndentLoad: LoadProc = { PushReal[style.bodyIndent] };

BodyIndentSetReal: SetRealProc = { style.bodyIndent ← amount };

BodyIndentAddReal: AddRealProc =
{ style.bodyIndent ← style.bodyIndent+inc };

BodyIndentPercent: PercentProc = {
val: REAL ← style.bodyIndent;
style.bodyIndent ← val+(percent/100)*val };


-- **** Top Indent ****

TopIn
dentOp: PROC = { StyleParameter[topIndentOps] };

topIndentOps: Ops ← NEW [OpsRec ← [TopIndentLoad,
TopIndentSetReal, TopIndentAddReal, TopIndentPercent,
SetNameError]];

TopIndentLoad: LoadProc = { PushReal[style.topIndent] };

TopIndentSetReal: SetRealProc = { style.topIndent ← amount };

TopIndentAddReal: AddRealProc =
{ style.topIndent ← style.topIndent+inc };

TopIndentPercent: PercentProc = {
val: REAL ← style.topIndent;
style.topIndent ← val+(percent/100)*val };


-- **** Bottom Indent ****

Botto
mIndentOp: PROC = { StyleParameter[bottomIndentOps] };

bottomIndentOps: Ops ← NEW [OpsRec ← [BottomIndentLoad,
BottomIndentSetReal, BottomIndentAddReal, BottomIndentPercent,
SetNameError]];

BottomIndentLoad: LoadProc = { PushReal[style.bottomIndent] };

BottomIndentSetReal: SetRealProc = { style.bottomIndent ← amount };

BottomIndentAddReal: AddRealProc =
{ style.bottomIndent ← style.bottomIndent+inc };

BottomIndentPercent: PercentProc = {
val: REAL ← style.bottomIndent;
style.bottomIndent ← val+(percent/100)*val };


-- **** Leading ****

Leadi
ngOp: PROC = {
name: tjI.JaMName;
ok: BOOLEAN;
[name, ok] ← TryToPopName[];
IF ~ok OR name=line THEN LineLeadingOp[]
ELSE SELECT name FROM
top => TopLeadingOp[];
bottom => BottomLeadingOp[];
ENDCASE => { PushName[name]; LineLeadingOp[] };
};


-- **** LineLeading ****

LineL
eadingOp: PROC = { StyleParameter[leadingOps] };

leadingOps: Ops ← NEW [OpsRec ← [LineLeadingLoad,
LineLeadingSetReal, LineLeadingAddReal,
LineLeadingPercent, SetNameError]];

LineLeadingLoad: LoadProc = { PushReal[style.leading] };

LineLeadingSetReal: SetRealProc = { style.leading ← amount };

LineLeadingAddReal: AddRealProc = { style.leading ← style.leading+inc };

LineLeadingPercent: PercentProc = {
val: REAL ← style.leading;
style.leading ← val+(percent/100)*val };


-- **** Top Leading ****

TopLe
adingOp: PROC = { StyleParameter[topLeadingOps] };

topLeadingOps: Ops ← NEW [OpsRec ← [TopLeadingLoad,
TopLeadingSetReal, TopLeadingAddReal, TopLeadingPercent,
SetNameError]];

TopLeadingLoad: LoadProc = { PushReal[style.topLeading] };

TopLeadingSetReal: SetRealProc = { style.topLeading ← amount };

TopLeadingAddReal: AddRealProc = { style.topLeading ← style.topLeading+inc };

TopLeadingPercent: PercentProc = {
val: REAL ← style.topLeading;
style.topLeading ← val+(percent/100)*val };


-- **** Bottom Leading ****

Botto
mLeadingOp: PROC = { StyleParameter[bottomLeadingOps] };

bottomLeadingOps: Ops ← NEW [OpsRec ← [BottomLeadingLoad,
BottomLeadingSetReal, BottomLeadingAddReal,
BottomLeadingPercent, SetNameError]];

BottomLeadingLoad: LoadProc = { PushReal[style.bottomLeading] };

BottomLeadingSetReal: SetRealProc = { style.bottomLeading ← amount };

BottomLeadingAddReal: AddRealProc =
{ style.bottomLeading ← style.bottomLeading+inc };

BottomLeadingPercent: PercentProc = {
val: REAL ← style.bottomLeading;
style.bottomLeading ← val+(percent/100)*val };


-- **** VShift ****

VShif
tOp: PROC = { StyleParameter[vshiftOps] };

vshiftOps: Ops ← NEW [OpsRec ← [VShiftLoad,
VShiftSetReal, VShiftAddReal, VShiftPercent,
SetNameError]];

VShiftLoad: LoadProc = { PushReal[style.vshift] };

VShiftSetReal: SetRealProc = { style.vshift ← amount };

VShiftAddReal: AddRealProc = { style.vshift ← style.vshift+inc };

VShiftPercent: PercentProc = {
val: REAL ← style.vshift;
style.vshift ← val+(percent/100)*val };


-- **** MinGaps ****

MinGa
psOp: PROC = { StyleParameter[minGapsOps] };

minGapsOps: Ops ← NEW [OpsRec ← [MinGapsLoad,
MinGapsSetReal, MinGapsAddReal, MinGapsPercent,
SetNameError]];

MinGapsLoad: LoadProc = { PushReal[style.minGaps] };

MinGapsSetReal: SetRealProc = { style.minGaps ← amount };

MinGapsAddReal: AddRealProc = { style.minGaps ← style.minGaps+inc };

MinGapsPercent: PercentProc = {
val: REAL ← style.minGaps;
style.minGaps ← val+(percent/100)*val };


-- **** MinTabWidth ****

MinTa
bWidthOp: PROC = { StyleParameter[minTabWidthOps] };

minTabWidthOps: Ops ← NEW [OpsRec ← [MinTabWidthLoad,
MinTabWidthSetReal, MinTabWidthAddReal,
MinTabWidthPercent, SetNameError]];

MinTabWidthLoad: LoadProc = { PushReal[style.minTabWidth] };

MinTabWidthSetReal: SetRealProc = { style.minTabWidth ← amount };

MinTabWidthAddReal: AddRealProc =
{ style.minTabWidth ← style.minTabWidth+inc };

MinTabWidthPercent: PercentProc = {
val: REAL ← style.minTabWidth;
style.minTabWidth ← val+(percent/100)*val };


-- **** Tab ****

tabNumber: INTEGER;

TabOp
: PROC = {
name: tjI.JaMName;
ok: BOOLEAN;
[name, ok] ← TryToPopName[];
IF ~ok THEN {
IF (tabNumber ← PopInteger[]) ~IN [1..numTabs] THEN ERROR StyleError;
TabStopOp[] }
ELSE SELECT name FROM
min => MinTabWidthOp[];
each => EachTabStopOp[];
ENDCASE => ERROR StyleError;
};


-- **** TabStop ****

TabSt
opOp: PROC = { StyleParameter[tabStopOps] };

tabStopOps: Ops ← NEW [OpsRec ← [TabStopLoad,
TabStopSetReal, TabStopAddReal, TabStopPercent,
SetNameError]];

TabStopLoad: LoadProc = { PushReal[style.tabs[tabNumber]] };

TabStopSetReal: SetRealProc = { style.tabs[tabNumber] ← amount };

TabStopAddReal: AddRealProc =
{ style.tabs[tabNumber] ← style.tabs[tabNumber]+inc };

TabStopPercent: PercentProc = {
val: REAL ← style.tabs[tabNumber];
style.tabs[tabNumber] ← val+(percent/100)*val };


-- **** EachTabStop ****

EachT
abStopOp: PROC = { StyleParameter[eachTabStopOps] };

eachTabStopOps: Ops ← NEW [OpsRec ← [EachTabStopLoad,
EachTabStopSetReal, EachTabStopAddReal,
EachTabStopPercent, SetNameError]];

EachTabStopLoad: LoadProc = { ERROR StyleError };

EachTabStopSetReal: SetRealProc = {
FOR i: INTEGER IN [1..numTabs] DO style.tabs[i] ← amount*i; ENDLOOP };

EachTabStopAddReal: AddRealProc = {
FOR i: INTEGER IN [1..numTabs] DO
style.tabs[i] ← style.tabs[i]+inc; ENDLOOP };

EachTabStopPercent: PercentProc = {
frac: REAL ← percent/100;
FOR i: INTEGER IN [1..numTabs] DO
val: REAL ← style.tabs[i];
style.tabs[i] ← val+frac*val;
ENDLOOP };


-- **** User Parameters ****

UserP
aramOp: PROC =
{ userParam ← PopName[]; StyleParameter[userOps] };

userParam: tjI.JaMName;
userOps: Ops ← NEW [OpsRec ← [UserLoad, UserSetReal, UserAddReal,
UserPercent, UserSetName]];

UserLoad: LoadProc = { EvalName[userParam] };

UserSetReal: SetRealProc = {
PushName[userParam]; PushReal[amount]; ExecuteCommand[assign] };

UserAddReal: AddRealProc = {
PushName[userParam]; EvalName[userParam];
PushReal[PopReal[]+inc]; ExecuteCommand[assign] };

UserPercent: PercentProc = {
val: REAL; EvalName[userParam]; val ← PopReal[];
UserSetReal[val+(percent/100)*val] };

UserSetName: SetNameProc = {
PushName[userParam]; PushName[name]; ExecuteCommand[assign] };


-- Initialization

the, smaller, bigger, percent, left, right, first, body, top,
bottom, min, each, regular, bold, italic, bolditalic,
plusbold, plusitalic, minusbold, minusitalic, capsAndLower,
capsAndSmallCaps, lowerOnly, capsOnly, justified,
none, lettersAndDigits, visible, all,
flushLeft, flushRight, centered, line: tjI.JaMName;

Start
: PUBLIC PROCEDURE =
BEGIN

StyleCommand["size",FontSizeOp];
StyleCommand["face",FontFaceOp];
StyleCommand["alphabets",FontAlphabetsOp];
StyleCommand["underlining",UnderliningOp];
StyleCommand["formatting",FormattingOp];
StyleCommand["style",StyleNameOp];
StyleCommand["family",FontFamilyOp];
StyleCommand["indent",IndentOp];
StyleCommand["leading",LeadingOp];
StyleCommand["tab",TabOp];
StyleCommand["UserParam",UserParamOp];

the ← StyleLiteral["the"];
smaller ← StyleLiteral["smaller"];
bigger ← StyleLiteral["bigger"];
percent ← StyleLiteral["percent"];
left ← StyleLiteral["left"];
right ← StyleLiteral["right"];
first ← StyleLiteral["first"];
body ← StyleLiteral["body"];
top ← StyleLiteral["top"];
bottom ← StyleLiteral["bottom"];
min ← StyleLiteral["min"];
each ← StyleLiteral["each"];
regular ← StyleLiteral["Regular"];
bold ← StyleLiteral["Bold"];
italic ← StyleLiteral["Italic"];
bolditalic ← StyleLiteral["BoldItalic"];
plusbold ← StyleLiteral["+Bold"];
plusitalic ← StyleLiteral["+Italic"];
minusbold ← StyleLiteral["-Bold"];
minusitalic ← StyleLiteral["-Italic"];
capsAndLower ← StyleLiteral["CapsAndLower"];
capsAndSmallCaps ← StyleLiteral["CapsAndSmallCaps"];
lowerOnly ← StyleLiteral["LowerOnly"];
capsOnly ← StyleLiteral["CapsOnly"];
all ← StyleLiteral["All"];
visible ← StyleLiteral["Visible"];
lettersAndDigits ← StyleLiteral["LettersAndDigits"];
none ← StyleLiteral["None"];
justified ← StyleLiteral["Justified"];
flushLeft ← StyleLiteral["FlushLeft"];
flushRight ← StyleLiteral["FlushRight"];
centered ← StyleLiteral["Centered"];
line ← StyleLiteral["line"];

END;

END.