DIRECTORY Ascii, NodeStyle, NodeStyleExtra, NodeStyleObject, TextNode, TextLooks, NameSymbolTable, Real, SafeStorage, JaMOps, JaMBasic; NodeStyleTabsImpl: CEDAR PROGRAM IMPORTS Ascii, JaMOps, NodeStyle, NodeStyleExtra, NodeStyleObject, Real, TextNode EXPORTS NodeStyle, NodeStyleExtra = BEGIN OPEN R:Real, NodeStyle, NodeStyleExtra, NodeStyleObject; RulesTabCount: PUBLIC PROC [stop: RulesTabStop] RETURNS [count: INTEGER] = { RETURN [stop.array.length/2] }; RulesTabInfo: PUBLIC PROC [stop: RulesTabStop, num: INTEGER] RETURNS [weight, vshift: REAL] = TRUSTED { ObjectToReal: PROC [ob: JaMBasic.Object] RETURNS [Real] = TRUSTED { WITH ob:ob SELECT FROM integer => RETURN[ob.ivalue]; real => RETURN[ob.rvalue]; ENDCASE => ERROR }; weight _ ObjectToReal[JaMOps.AGet[stop.array, num*2]]; vshift _ ObjectToReal[JaMOps.AGet[stop.array, num*2+1]] }; RulesTabInfoI: PUBLIC PROC [stop: RulesTabStop, num: INTEGER] RETURNS [weight, vshift: INTEGER] = TRUSTED { ObjectToInteger: PROC [ob: JaMBasic.Object] RETURNS [INTEGER] = TRUSTED { WITH ob:ob SELECT FROM integer => RETURN[ob.ivalue]; real => RETURN[R.RoundI[ob.rvalue]]; ENDCASE => ERROR }; weight _ ObjectToInteger[JaMOps.AGet[stop.array, num*2]]; vshift _ ObjectToInteger[JaMOps.AGet[stop.array, num*2+1]] }; GetTabRealCode: PROC [ref: Ref, stop: TabStop, which: TabRealParam, value: Real] RETURNS [code: RealCode] = { code _ EnterReal[value ! realTableOverflow => { code _ overflow; ref.dataList _ qZone.NEW[DataEntry _ [ ref.dataList, tab[stop, which, value, IntegerValue[value]]]]; CONTINUE }] }; GetTabOverflow: PUBLIC PROC [ref: Ref, stop: TabStop, which: TabRealParam] RETURNS [value: Real] = { FOR x: DataList _ ref.dataList, x.next UNTIL x=NIL DO xx: REF DataEntry.tab = NARROW[x]; IF xx.tabStop=stop AND xx.which=which THEN RETURN [xx.value]; ENDLOOP; ERROR -- failed to find it on the data list -- }; GetTabIntOverflow: PUBLIC PROC [ref: Ref, stop: TabStop, which: TabRealParam] RETURNS [value: INTEGER] = { FOR x: DataList _ ref.dataList, x.next UNTIL x=NIL DO xx: REF DataEntry.tab = NARROW[x]; IF xx.tabStop=stop AND xx.which=which THEN RETURN [xx.valueI]; ENDLOOP; ERROR -- failed to find it on the data list -- }; RelativeTabStopsOp: PUBLIC PROC [frame: Frame] = { ref: Ref _ StyleForFrame[frame]; name: Name; ok: BOOLEAN; [name, ok] _ TryToPopName[frame]; IF ~ok THEN { -- restore name to stack and return default PushText[frame,"illegal value for tabStops: should be fixed or relative"]; StyleError[frame,1] }; SELECT name FROM fixed => ref.fixedTabs _ TRUE; relative => ref.fixedTabs _ FALSE; ENDCASE => { -- restore name to stack and return default PushName[frame, name]; PushText[frame,"illegal value for tabStops: should be fixed or relative"]; StyleError[frame,2] }}; DefaultTabStopsOp: PUBLIC PROC [frame: Frame] = { ref: Ref _ StyleForFrame[frame]; tabStop: TabStop _ TabSpec[ref, frame]; tabStop.loc _ GetTabRealCode[ref, tabStop, loc, PopReal[frame]]; ref.defaultTabStops _ tabStop }; TabStopOp: PUBLIC PROC [frame: Frame] = { ref: Ref _ StyleForFrame[frame]; tabStop: TabStop _ TabSpec[ref, frame]; loc: Real; tabStop.loc _ GetTabRealCode[ref, tabStop, loc, PopReal[frame]]; loc _ GetTabLoc[tabStop, ref]; ref.numTabStops _ ref.numTabStops+1; IF ref.tabStops = NIL OR GetTabLoc[ref.tabStops.first, ref] <= loc THEN ref.tabStops _ TextNode.pZone.CONS[tabStop, ref.tabStops] ELSE { -- copy list up to first with smaller loc old: LIST OF TabStop _ ref.tabStops; new: LIST OF TabStop _ TextNode.pZone.CONS[old.first, NIL]; ref.tabStops _ new; FOR lst: LIST OF TabStop _ old.rest, lst.rest DO IF lst=NIL OR GetTabLoc[lst.first, ref] <= loc THEN { -- insert here new.rest _ TextNode.pZone.CONS[tabStop, lst]; EXIT }; new.rest _ TextNode.pZone.CONS[lst.first, NIL]; new _ new.rest; ENDLOOP }}; TabSpec: PROC [ref: Ref, frame: Frame] RETURNS [tabStop: TabStop] = { -- parse tab specs looks: TextLooks.Looks _ TabLooksSpec[frame]; breakIfPast: BOOL _ TabPastSpec[frame]; tabStop _ TabPattern[ref, frame]; tabStop.looks _ looks; tabStop.breakIfPast _ breakIfPast; TabAlign[tabStop, frame] }; TabLooksSpec: PROC [frame: Frame] RETURNS [lks: TextLooks.Looks] = TRUSTED { name: Name; ok: BOOLEAN; SetLookBit: PROC [look: CHAR] RETURNS [quit: BOOL] = TRUSTED { look _ Ascii.Lower[look]; IF look IN ['a..'z] THEN lks[look] _ TRUE; RETURN [FALSE] }; lks _ TextLooks.noLooks; [name, ok] _ TryToPopName[frame]; IF ~ok THEN RETURN; IF name # looks THEN { PushName[frame, name]; RETURN }; JaMOps.StringForAll[JaMOps.PopString[frame.opstk], SetLookBit]; }; TabPastSpec: PROC [frame: Frame] RETURNS [break: BOOL] = { name: Name; ok: BOOLEAN; [name, ok] _ TryToPopName[frame]; IF ~ok THEN RETURN; SELECT name FROM breakIfPast => break _ TRUE; spaceIfPast => break _ FALSE; ENDCASE => { -- restore name to stack and return default PushName[frame, name]; break _ FALSE }}; TabPattern: PROC [ref: Ref, frame: Frame] RETURNS [tabStop: TabStop] = { name: Name; ok: BOOLEAN; [name, ok] _ TryToPopName[frame]; IF ~ok THEN { tabStop _ TextNode.pZone.NEW[blank TabStopRec]; RETURN }; SELECT name FROM blank => tabStop _ TextNode.pZone.NEW[blank TabStopRec]; leaders => { leaderChar: BOOL _ FALSE; string: string JaMBasic.Object; value: Real; SetLeaderChar: PROC [c: CHAR] RETURNS [quit: BOOL] = { IF leaderChar THEN { PushText[frame,"Cannot specify more than one character for tab leaders"]; StyleError[frame,1] }; leaderChar _ TRUE; ldrStop.char _ c }; ldrStop: LeaderTabStop _ TextNode.pZone.NEW[leaders TabStopRec]; tabStop _ ldrStop; [name, ok] _ TryToPopName[frame]; IF ~ok THEN ldrStop.congruent _ TRUE ELSE SELECT name FROM centered => ldrStop.congruent _ FALSE; congruent => ldrStop.congruent _ TRUE; ENDCASE => { PushName[frame,name]; PushText[frame,"is not legal as value for tab leaders: congruent or centered"]; StyleError[frame,2] }; [value, ok] _ TryToPopReal[frame]; ldrStop.spacing _ GetTabRealCode[ref, tabStop, spacing, IF ok THEN value ELSE 0.0]; [string, ok] _ TryToPopString[frame]; IF ok THEN TRUSTED {JaMOps.StringForAll[string, SetLeaderChar]} ELSE { PushText[frame,"Must specify character for leaders"]; StyleError[frame,1] }}; rule => { ruleStop: RuleTabStop _ TextNode.pZone.NEW[rule TabStopRec]; tabStop _ ruleStop; ruleStop.vshift _ GetTabRealCode[ref, tabStop, vshift, PopReal[frame]]; ruleStop.weight _ GetTabRealCode[ref, tabStop, weight, PopReal[frame]] }; rules => { rulesStop: RulesTabStop _ TextNode.pZone.NEW[rules TabStopRec]; tabStop _ rulesStop; TRUSTED {rulesStop.array _ JaMOps.PopArray[frame.opstk] }}; ENDCASE => { -- restore name to stack and return default PushName[frame, name]; tabStop _ TextNode.pZone.NEW[blank TabStopRec] }}; MissingChar: PROC [frame: Frame] = { PushText[frame,"Cannot specify more than one character for tab alignment"]; StyleError[frame,1] }; TabAlign: PROC [tabStop: TabStop, frame: Frame] = { name: Name; ok: BOOLEAN; [name, ok] _ TryToPopName[frame]; IF ~ok THEN { tabStop.alignment _ FlushLeft; RETURN }; SELECT name FROM flushLeft => tabStop.alignment _ FlushLeft; flushRight => tabStop.alignment _ FlushRight; centered => tabStop.alignment _ Centered; aligned => { alignmentChar: BOOL _ FALSE; string: string JaMBasic.Object; SetAlignmentChar: PROC [c: CHAR] RETURNS [quit: BOOL] = { IF alignmentChar THEN { PushText[frame,"Cannot specify more than one character for tab alignment"]; StyleError[frame,1] }; alignmentChar _ TRUE; tabStop.alignmentChar _ c }; tabStop.alignment _ Character; [string, ok] _ TryToPopString[frame]; IF ok THEN TRUSTED {JaMOps.StringForAll[string, SetAlignmentChar]} ELSE { PushText[frame,"Must specify character for tab alignment"]; StyleError[frame,1] }}; ENDCASE => { PushName[frame, name]; tabStop.alignment _ FlushLeft }}; END... ˆ-- NodeStyleTabsImpl.mesa -- Written by Bill Paxton, December 1981 -- Last changed by Bill Paxton, December 1, 1982 7:38 am -- Implements JaM commands for tab specifications Last Edited by: Maxwell, January 6, 1983 10:15 am Last Edited by: Plass, April 12, 1983 2:42 pm Last Edited by: Paul Rovner, August 10, 1983 4:42 pm Rules tabs procs For num in [0..RulesTabCount), returns the weight and vshift values for that rule. Real table overflow for tab reals Miscellaneous commands Parsing tab specs Insert in list of tab stops. kept sorted by decreasing location, i.e., from right to left on page this may result in a slight decrease in efficiency for the formatters, but it substantially reduces allocations during the creation of the list since styles tend to define tab stops in increasing order, so can add to start of list and list additions must be non-destructive of the previous list Êá˜JšÏc™Jš(™(Jš8™8J˜š1™1J™1J™-J™4—šÏk ˜ J˜J˜ J˜J˜J˜ J˜ J˜J˜J˜ J˜J˜ J˜—Jšœž ˜ JšžœJ˜QJšžœ˜#Jšžœžœžœ2˜>J˜J˜J™™š Ïn œžœžœžœ žœ˜LJšžœ˜J˜—šŸ œžœžœžœ˜Jšžœ˜—Jšžœ(œ˜1J˜——™J™šŸœžœžœ˜2J˜ Jšœ ˜ Jšœžœ˜ J˜!šžœžœ+˜9J˜JJšœž˜—šžœž˜Jšœžœ˜Jšœžœ˜"šžœ+˜8Jšœ˜J˜JJšœ˜——J˜—šŸœžœžœ˜1J˜ Jšœ'˜'J˜@Jšœ ˜ —J™—™J™šŸ œžœžœ˜)J˜ Jšœ'˜'J˜ J˜@šœD™bJš¦™¦—J˜Jšœ$˜$šžœžœžœ+ž˜GJšœžœ˜9—šžœ)˜0Jšœžœžœ˜$Jš œžœžœžœ žœ˜;Jšœ˜šžœžœžœž˜0š žœžœžœ"žœ˜DJšœžœžœ˜5—Jšœžœ žœ˜/J˜Jšžœ˜ ——J˜—šŸœžœžœ˜XJšœ-˜-Jšœ žœ˜'Jšœ!˜!Jšœ˜Jšœ"˜"J˜J˜—šŸ œžœžœžœ˜LJšœ ˜ Jšœžœ˜ š Ÿ œžœžœžœžœžœ˜>Jšœ˜Jšžœžœ žœ žœ˜*Jšžœžœ˜—J˜J˜!Jšžœžœžœ˜Jšžœžœžœ˜7Jšœ?˜?J˜J˜—šŸ œžœžœ žœ˜:Jšœ ˜ Jšœžœ˜ J˜!Jšžœžœžœ˜šžœž˜Jšœžœ˜Jšœžœ˜šžœ+˜8Jšœ˜Jšœžœ˜——J˜—šŸ œžœžœ˜HJšœ ˜ Jšœžœ˜ J˜!Jšžœžœžœžœ˜GJšžœž˜Jšœ"žœ˜8˜ Jšœ žœžœ˜J˜J˜ š Ÿ œžœžœžœžœ˜6šžœ žœ˜J˜IJ˜—Jšœ žœ˜Jšœ˜—Jšœ(žœ˜@J˜J˜!Jšžœžœž˜$šžœžœž˜Jšœ žœ˜&Jšœ!žœ˜&šžœ˜ J˜J˜OJ˜——J˜"Jšœ8žœžœžœ˜SJ˜%Jšžœžœžœ-˜?šžœ˜Jšœ5˜5Jšœ˜——˜ Jšœ'žœ˜