DIRECTORY Atom, CharOps, NodeProps, Prop, RefText, Rope, RuntimeError, TEditDocument, TEditInput, TEditSelection, TEditSelectionOps, TextNode, Tioga, TiogaAccess, TiogaAccessViewers, TiogaOps, ViewerClasses, ViewerOps; EditPropertiesImpl: CEDAR PROGRAM IMPORTS Atom, CharOps, NodeProps, Prop, RefText, Rope, RuntimeError, TEditInput, TEditSelection, TEditSelectionOps, TextNode, TiogaAccess, TiogaAccessViewers, TiogaOps, ViewerOps ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Viewer: TYPE ~ ViewerClasses.Viewer; TranslateToOpenProperties: PROC [reader: TiogaAccess.Reader, writer: TiogaAccess.Writer, rootOnly: BOOL ¬ FALSE] ~ { t: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 0C, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL]; node: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 15C, looks: ALL[FALSE], format: $code, comment: FALSE, endOfNode: TRUE, deltaLevel: 0, propList: NIL]; nest: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 15C, looks: ALL[FALSE], format: $code, comment: FALSE, endOfNode: TRUE, deltaLevel: 1, propList: NIL]; outc: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 0C, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL]; PutRope: PROC [rope: ROPE] ~ { FOR i: INT IN [0..Rope.Size[rope]) DO outc.char ¬ Rope.Fetch[rope, i]; TiogaAccess.Put[writer, outc]; ENDLOOP; }; PutOctal: PROC [b: [0..256)] ~ { outc.char ¬ '0+b/64; TiogaAccess.Put[writer, outc]; outc.char ¬ '0+(b/8) MOD 8; TiogaAccess.Put[writer, outc]; outc.char ¬ '0+b MOD 8; TiogaAccess.Put[writer, outc]; }; PutPropName: PROC [atom: ATOM] ~ { save: Tioga.Looks ¬ outc.looks; outc.looks['n] ¬ TRUE; PutRope[Atom.GetPName[atom]]; outc.looks ¬ save; PutRope[": "]; }; PutKey: PROC [rope: ROPE] ~ { save: Tioga.Looks ¬ outc.looks; outc.looks['k] ¬ TRUE; outc.looks['b] ¬ TRUE; PutRope[rope]; outc.looks ¬ save; }; PutProperties: PROC [propList: Prop.PropList] ~ { action: Prop.MapAction ~ { PutProperty[NARROW[key], val] }; [] ¬ Prop.Map[propList, action]; }; PutProperty: PROC [key: ATOM, value: REF] ~ { IF value # NIL THEN { rope: ROPE ~ TiogaAccess.GetExternalProp[key, value]; PutPropName[key]; IF rope = NIL OR NodeProps.Is[key, $ClientOnly] THEN { save: Tioga.Looks ¬ outc.looks; savedPropList: Prop.PropList ~ node.propList; outc.looks['c] ¬ TRUE; PutRope["(opaque)"]; outc.looks ¬ save; node.propList ¬ Prop.Put[node.propList, $OpaqueValue, value]; TiogaAccess.Put[writer, node]; node.propList ¬ savedPropList; } ELSE { PutRope[rope]; TiogaAccess.Put[writer, node]; }; }; }; TranslateNodeContents: PROC ~ { UNTIL t.endOfNode DO looks: Tioga.Looks ~ t.looks; propList: Prop.PropList ~ t.propList; IF t.charSet = 0 AND t.char IN [' ..'~] THEN { PutPropName[$Text]; WHILE NOT t.endOfNode AND t.charSet = 0 AND t.char IN [' ..'~] AND t.looks=looks AND t.propList = propList DO save: Tioga.Looks ¬ outc.looks; outc.char ¬ t.char; outc.looks['o] ¬ TRUE; TiogaAccess.Put[writer, outc]; outc.looks ¬ save; t ¬ TiogaAccess.Get[reader]; ENDLOOP; } ELSE { PutPropName[$Char]; PutRope["("]; PutOctal[t.charSet]; PutRope["|"]; PutOctal[ORD[t.char]]; PutRope[")"]; t ¬ TiogaAccess.Get[reader]; }; TiogaAccess.Put[writer, node]; IF looks # ALL[FALSE] THEN { TiogaAccess.Nest[writer, 1]; PutKey["LOOKS"]; PutRope["("]; FOR c: Tioga.Look IN Tioga.Look DO IF looks[c] THEN {outc.char ¬ c; TiogaAccess.Put[writer, outc]}; ENDLOOP; PutRope[")"]; TiogaAccess.Put[writer, node]; TiogaAccess.Nest[writer, -1]; }; IF propList # NIL THEN { TiogaAccess.Nest[writer, 1]; PutProperties[propList]; TiogaAccess.Nest[writer, -1]; }; ENDLOOP; }; UNTIL TiogaAccess.EndOf[reader] DO t ¬ TiogaAccess.Get[reader]; PutKey[IF rootOnly THEN "BEGIN ROOT NODE" ELSE "BEGIN NODE"]; TiogaAccess.Put[writer, nest]; IF NOT t.endOfNode THEN { PutKey["CONTENTS"]; TiogaAccess.Put[writer, nest]; TranslateNodeContents[]; TiogaAccess.Nest[writer, -1]; }; PutKey["PROPERTIES"]; TiogaAccess.Put[writer, nest]; PutProperty[$Comment, NodeProps.ValueFromBool[t.comment]]; PutProperty[$Format, NodeProps.ValueFromAtom[t.format]]; PutProperties[t.propList]; TiogaAccess.Nest[writer, -1]; PutKey["END NODE"]; TiogaAccess.Put[writer, node]; TiogaAccess.Nest[writer, t.deltaLevel-1]; IF rootOnly THEN EXIT; ENDLOOP; UNTIL TiogaAccess.EndOf[reader] DO [] ¬ TiogaAccess.CopyNode[writer: writer, reader: reader]; ENDLOOP; }; Cant: ERROR ~ CODE; TranslateFromOpenProperties: PROC [reader: TiogaAccess.Reader, writer: TiogaAccess.Writer, doRoot: BOOL] ~ { Must: PROC [assertion: BOOL] ~ {IF NOT assertion THEN Cant[]}; break: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 0C, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL]; Match: PROC [rope: ROPE] RETURNS [BOOL] ~ { targetLen: INT ~ Rope.Size[rope]; input: ROPE ~ TiogaAccess.PeekRope[reader]; matchLen: INT ~ Rope.Run[s1: rope, s2: input, case: TRUE]; IF matchLen=targetLen THEN { FOR i: INT IN [0..targetLen) DO [] ¬ TiogaAccess.Get[reader] ENDLOOP; RETURN [TRUE]; }; RETURN [FALSE]; }; level: INT ¬ 0; MatchBreak: PROC RETURNS [BOOL] ~ { IF TiogaAccess.Peek[reader].endOfNode THEN { break ¬ TiogaAccess.Get[reader]; level ¬ level + break.deltaLevel; RETURN [TRUE]; }; RETURN [FALSE]; }; MustNest: PROC ~ {Must[MatchBreak[] AND break.deltaLevel = 1]}; GetOctal3: PROC RETURNS [[0..256)] ~ { v: CARDINAL ¬ 0; FOR i: NAT IN [0..3) DO t: TiogaAccess.TiogaChar ¬ TiogaAccess.Get[reader]; Must[t.char IN ['0..'8) AND t.charSet = 0]; v ¬ v*8 + (t.char-'0); ENDLOOP; Must[v IN [0..256)]; RETURN [v]; }; RopeToEnd: PROC RETURNS [ROPE] ~ { rope: ROPE ¬ TiogaAccess.PeekRope[reader]; FOR i: INT IN [0..Rope.Size[rope]) DO [] ¬ TiogaAccess.Get[reader] ENDLOOP; RETURN [rope]; }; ParseProp: PROC RETURNS [Prop.Pair] ~ { keyText: REF TEXT ~ RefText.ObtainScratch[100]; t: TiogaAccess.TiogaChar ¬ TiogaAccess.Get[reader]; key: ATOM ¬ NIL; rope: ROPE ¬ NIL; value: REF; WHILE t.charSet = 0 AND CharOps.AlphaNumeric[t.char] DO Must[keyText.length < keyText.maxLength]; keyText[keyText.length] ¬ t.char; keyText.length ¬ keyText.length + 1; t ¬ TiogaAccess.Get[reader]; ENDLOOP; Must[keyText.length > 0]; Must[t.charSet = 0 AND t.char = ':]; Must[Match[" "]]; rope ¬ RopeToEnd[]; Must[MatchBreak[]]; key ¬ Atom.MakeAtomFromRefText[keyText]; value ¬ Prop.Get[break.propList, $OpaqueValue]; IF value = NIL THEN value ¬ TiogaAccess.GetInternalProp[key, rope]; RefText.ReleaseScratch[keyText]; RETURN [[key: key, val: value]]; }; first: BOOL ¬ TRUE; IF doRoot THEN { node: TextNode.Ref ~ TiogaAccess.GetLocation[reader].node; parent: TextNode.Ref ~ TextNode.Parent[node]; Must[TextNode.Parent[parent]=NIL AND TextNode.Next[node]=NIL]; -- no siblings allowed! }; UNTIL TiogaAccess.EndOf[reader] DO IF (NOT doRoot AND Match["BEGIN NODE"]) OR (doRoot AND Match["BEGIN ROOT NODE"]) THEN { node: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 15C, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: TRUE, deltaLevel: 0, propList: NIL]; nodeTail: Prop.PropList ¬ NIL; level ¬ 0; MustNest[]; IF Match["CONTENTS"] THEN { MustNest[]; WHILE level >= 2 DO outc: TiogaAccess.TiogaChar ¬ [charSet: 0, char: 0C, looks: ALL[FALSE], format: NIL, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL]; outcTail: Prop.PropList ¬ NIL; rope: ROPE ¬ NIL; Must[level = 2]; IF Match["Text: "] THEN rope ¬ RopeToEnd[] ELSE { Must[Match["Char: ("]]; outc.charSet ¬ GetOctal3[]; Must[Match["|"]]; rope ¬ Rope.FromChar[VAL[GetOctal3[]]]; Must[Match[")"]]; }; Must[MatchBreak[]]; WHILE level >= 3 DO Must[level = 3]; IF Match["LOOKS("] THEN { t: TiogaAccess.TiogaChar ¬ TiogaAccess.Peek[reader]; WHILE t.charSet = 0 AND t.char IN Tioga.Look DO t ¬ TiogaAccess.Get[reader]; outc.looks[t.char] ¬ TRUE; t ¬ TiogaAccess.Peek[reader]; ENDLOOP; Must[Match[")"]]; Must[MatchBreak[]]; } ELSE { pair: Prop.Pair ~ ParseProp[]; last: Prop.PropList ~ LIST[pair]; IF outcTail=NIL THEN outc.propList ¬ last ELSE outcTail.rest ¬ last; outcTail ¬ last; }; ENDLOOP; IF rope # NIL THEN { action: Rope.ActionType = { outc.char ¬ c; TiogaAccess.Put[writer, outc] }; [] ¬ Rope.Map[base: rope, action: action]; }; ENDLOOP; }; IF Match["PROPERTIES"] THEN { MustNest[]; WHILE level >= 2 DO pair: Prop.Pair; Must[level = 2]; pair ¬ ParseProp[]; SELECT pair.key FROM $Comment => node.comment ¬ NodeProps.BoolFromValue[pair.val]; $Format => node.format ¬ NodeProps.AtomFromValue[pair.val]; ENDCASE => { last: Prop.PropList ~ LIST[pair]; IF nodeTail=NIL THEN node.propList ¬ last ELSE nodeTail.rest ¬ last; nodeTail ¬ last; }; ENDLOOP; }; Must[level = 1]; Must[Match["END NODE"]]; Must[MatchBreak[]]; node.deltaLevel ¬ level; TiogaAccess.Put[writer, node]; } ELSE { Must[NOT first]; Must[TiogaAccess.CopyNode[writer, reader].nodeEnd]; }; first ¬ FALSE; ENDLOOP; }; MakeNodeSelection: PROC RETURNS [useRootViewer: Viewer ¬ NIL] ~ { tSel: TEditDocument.Selection; IF TEditSelection.pSel=NIL OR TEditSelection.pSel.viewer=NIL THEN RETURN; tSel ¬ TEditSelection.Alloc[]; TEditSelection.Copy[source: TEditSelection.pSel, dest: tSel]; IF tSel.start.pos.node = tSel.data.text.child AND tSel.start.pos.where = 0 AND tSel.insertion = before THEN { useRootViewer ¬ tSel.viewer; TEditSelection.Free[tSel]; RETURN; }; SELECT tSel.granularity FROM point, char, word => { tSel.start.pos.where ¬ 0; tSel.end.pos.where ¬ TextNode.EndPos[tSel.end.pos.node]; tSel.granularity ¬ node; }; ENDCASE => NULL; TEditSelection.MakeSelection[new: tSel]; TEditSelection.Free[tSel] }; OpenPropertiesOp: TEditInput.CommandProc ~ { OpenProperties: PROC [root: TiogaOps.Ref] ~ { reader: TiogaAccess.Reader ¬ NIL; writer: TiogaAccess.Writer ¬ NIL; useRootViewer: Viewer ~ MakeNodeSelection[]; reader ¬ IF useRootViewer#NIL THEN TiogaAccessViewers.FromViewer[useRootViewer] ELSE TiogaAccessViewers.FromSelection[]; writer ¬ TiogaAccess.Create[]; TranslateToOpenProperties[reader, writer, useRootViewer#NIL]; IF useRootViewer#NIL THEN { TiogaAccessViewers.WriteViewer[writer: writer, viewer: useRootViewer]; ViewerOps.SetNewVersion[viewer]; } ELSE TiogaAccessViewers.WriteSelection[writer]; }; TiogaOps.CallWithLocks[OpenProperties]; quit ¬ TRUE; }; SomethingBadHappenedProceedToDebug: SIGNAL ~ CODE; ClosePropertiesOp: TEditInput.CommandProc ~ { errorPosition: INT ¬ -1; CloseProperties: PROC [root: TiogaOps.Ref] ~ { reader: TiogaAccess.Reader ¬ NIL; writer: TiogaAccess.Writer ¬ NIL; useRootViewer: Viewer ~ MakeNodeSelection[]; IF useRootViewer#NIL THEN { reader ¬ TiogaAccessViewers.FromViewer[useRootViewer]; [] ¬ TiogaAccess.Get[reader]; -- discard actual root } ELSE { reader ¬ TiogaAccessViewers.FromSelection[] }; writer ¬ TiogaAccess.Create[]; TranslateFromOpenProperties[reader, writer, useRootViewer#NIL ! Cant => {errorPosition ¬ TiogaAccess.GetPosition[reader]} ]; IF useRootViewer#NIL THEN { TiogaAccessViewers.WriteViewer[writer: writer, viewer: useRootViewer]; ViewerOps.SetNewVersion[viewer]; } ELSE TiogaAccessViewers.WriteSelection[writer]; }; error: {none, cant, uncaught} ¬ none; TiogaOps.CallWithLocks[CloseProperties ! Cant => {error ¬ cant; CONTINUE}; RuntimeError.UNCAUGHT => {error ¬ uncaught; CONTINUE}; ]; SELECT error FROM none => IF errorPosition # -1 THEN ERROR; cant => { TEditSelectionOps.ShowGivenPosition[viewer: viewer, pos: errorPosition, skipCommentNodes: TRUE]; ViewerOps.BlinkViewer[viewer, 200]; }; uncaught => { SIGNAL SomethingBadHappenedProceedToDebug; CloseProperties[NIL]; -- do it again without lock for easy debug }; ENDCASE => ERROR; quit ¬ TRUE; }; TEditInput.Register[name: $OpenProperties, proc: OpenPropertiesOp, before: TRUE]; TEditInput.Register[name: $CloseProperties, proc: ClosePropertiesOp, before: TRUE]; END. > EditPropertiesImpl.mesa Copyright Σ 1986, 1989, 1991, 1992 by Xerox Corporation. All rights reserved. Hal Murray, December 22, 1986 4:02:22 pm PST Michael Plass, August 11, 1988 4:19:41 pm PDT Doug Wyatt, February 25, 1992 4:37 pm PST Emit a run of printable ascii characters, all with the same looks and properties Emit a single XC character Emit the looks that apply to the previous text or character Emit the properties that apply to the previous text or character PROC [viewer: ViewerClasses.Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE]; Κτ•NewlineDelimiter –(cedarcode) style™code™Kšœ ΟeœC™NK™,K™-K™)—K˜KšΟk œΡ˜ΪK˜KšΟnœžœž˜!Kšžœ«˜²šœž˜K˜Kšžœžœžœ˜šœžœ˜$K˜—K˜šŸœžœDžœžœ˜tKš œ9žœžœ žœ žœ žœžœ˜’Kš œ=žœžœžœ žœžœ˜—Kš œ=žœžœžœ žœžœ˜—Kš œ<žœžœ žœ žœ žœžœ˜•šŸœžœžœ˜šžœžœžœž˜%Kšœ ˜ Kšœ˜Kšžœ˜—Kšœ˜—šŸœžœ˜ Kšœ˜Kšœ˜Kšœžœ˜Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜—šŸ œžœžœ˜"Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœžœžœ˜Kšœ˜Kšœžœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜—šŸ œžœ˜1Kšœ'žœ˜;K˜ Kšœ˜—šŸ œžœžœ žœ˜-šžœ žœžœ˜Kšœžœ+˜5Kšœ˜šžœžœžœ˜/šžœ˜Kšœ˜Kšœ-˜-Kšœžœ˜K˜Kšœ˜Kšœ=˜=Kšœ˜Kšœ˜K˜—šžœ˜Kšœ˜Kšœ˜K˜——Kšœ˜—Kšœ˜—šŸœžœ˜šžœ ž˜Kšœ˜Kšœ%˜%šžœžœžœ ˜'šžœ˜K™PKšœ˜šžœžœ žœžœžœ žœžœž˜mKšœ˜Kšœ˜Kšœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—Kšœ˜—šžœ˜K™Kšœ˜K˜ Kšœ˜K˜ Kšœ žœ ˜K˜ Kšœ˜Kšœ˜——Kšœ˜šžœ žœžœžœ˜K™;Kšœ˜Kšœ˜Kšœ ˜ šžœžœ ž˜"Kšžœ žœ0˜@Kšžœ˜—Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜—šžœ žœžœ˜K™@Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšžœ˜—Kšœ˜—šžœž˜"Kšœ˜šœ\˜\šžœžœžœ˜šœ2˜2Kšœ˜—Kšœ˜Kšœ˜—šœ4˜4Kšœ:˜:Kšœ8˜8Kšœ˜Kšœ˜—Kšœ˜Kšœ˜Kšœ)˜)—Kšžœ žœžœ˜Kšžœ˜—šžœž˜"K•StartOfExpansion[[writer: TiogaAccess.Writer, reader: TiogaAccess.Reader, maxLength: INT _ 2147483647]šœ:˜:Kšžœ˜—K˜K˜—KšŸœžœžœ˜šŸœžœBžœ˜lKš Ÿœžœ žœžœžœ žœ ˜>Kš œ=žœžœ žœ žœ žœžœ˜–š Ÿœžœžœžœžœ˜+Kšœ žœ˜!K–O[s1: ROPE, pos1: INT _ 0, s2: ROPE, pos2: INT _ 0, case: BOOL _ TRUE]šœžœ ˜+Kšœ žœ'žœ˜:šžœžœ˜Kš žœžœžœžœžœ˜EKšžœžœ˜Kšœ˜—Kšžœžœ˜Kšœ˜—Kšœžœ˜šŸ œžœžœžœ˜#šžœ$žœ˜,Kšœ ˜ Kšœ!˜!Kšžœžœ˜Kšœ˜—Kšžœžœ˜Kšœ˜—KšŸœžœžœ˜?šŸ œžœžœ˜&Kšœžœ˜šžœžœžœž˜Kšœ3˜3Kšœ žœ žœ˜+Kšœ˜Kšžœ˜—Kšœžœ ˜Kšžœ˜ Kšœ˜—šŸ œžœžœžœ˜"Kšœžœ ˜*Kš žœžœžœžœžœ˜KKšžœ˜Kšœ˜—šŸ œžœžœ˜'Kšœ žœžœ˜/Kšœ3˜3Kšœžœžœ˜Kšœžœžœ˜Kšœžœ˜ šžœžœž˜7Kšœ)˜)Kšœ!˜!Kšœ$˜$Kšœ˜Kšžœ˜—Kšœ˜Kšœžœ˜$Kšœ˜Kšœ˜Kšœ˜Kšœ(˜(Kšœ/˜/Kšžœ žœžœ0˜CKšœ ˜ Kšžœ˜ Kšœ˜—Kšœžœžœ˜šžœžœ˜Kšœ:˜:Kšœ-˜-KšœžœžœžœΟc˜VKšœ˜—šžœž˜"š žœžœžœžœ žœ˜Pšžœ˜Kš œ=žœžœ žœ žœ žœžœ˜•Kšœžœ˜Kšœ ˜ Kšœ ˜ šžœžœ˜Kšœ ˜ šžœ ž˜Kš œ<žœžœ žœ žœ žœžœ˜•Kšœžœ˜Kšœžœžœ˜Kšœ˜šžœ˜Kšžœ˜šžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœ˜'Kšœ˜Kšœ˜——Kšœ˜šžœ ž˜Kšœ˜šžœžœ˜Kšœ4˜4šžœžœžœ ž˜/Kšœ˜Kšœžœ˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜Kšœ˜—šžœ˜Kšœ˜Kšœžœ˜!Kšžœ žœžœžœ˜DK˜Kšœ˜—Kšžœ˜—šžœžœžœ˜K–* -- [c: CHAR] RETURNS [quit: BOOL _ FALSE]šœK˜KK–T[base: ROPE, start: INT _ 0, len: INT _ 2147483647, action: Rope.ActionType]šœ*˜*Kšœ˜—Kšžœ˜—Kšœ˜—šžœžœ˜Kšœ ˜ šžœ ž˜Kšœ˜K˜Kšœ˜šžœ ž˜K˜=K˜;šžœ˜ Kšœžœ˜!Kšžœ žœžœžœ˜DKšœ˜K˜——Kšžœ˜—K˜—Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šžœ˜Kšœžœ˜Kšœ3˜3Kšœ˜——Kšœžœ˜Kšžœ˜—K˜K˜—šŸœžœžœžœ˜AK˜Kš žœžœžœžœžœžœ˜IK˜K˜=šžœ,žœžœžœ˜mKšœ˜K˜Kšžœ˜Kšœ˜—šžœž˜šœ˜K˜K˜8Kšœ˜Kšœ˜—Kšžœžœ˜—K˜(K˜Kšœ˜K˜—šŸœ˜,–^ -- [viewer: ViewerClasses.Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE]šŸœžœ˜-Kšœžœ˜!Kšœžœ˜!Kšœ,˜,Kš œžœžœžœ.žœ$˜xKšœ˜Kšœ8žœ˜=šžœž˜šžœ˜KšœF˜FKšœ ˜ Kšœ˜—Kšžœ+˜/—Kšœ˜—Kšœ'˜'Kšœžœ˜ K˜K˜—KšŸ"œžœžœ˜2šŸœ˜-Kšžœ!žœžœžœžœžœžœ™`Kšœžœ˜šŸœžœ˜.Kšœžœ˜!Kšœžœ˜!Kšœ,˜,šžœž˜šžœ˜Kšœ6˜6Kšœ ˜4Kšœ˜—Kšžœ1˜5—Kšœ˜šœ:žœ˜?Kšœ9˜9Kšœ˜—šžœž˜šžœ˜KšœF˜FKšœ ˜ Kšœ˜—Kšžœ+˜/—Kšœ˜—K–^ -- [viewer: ViewerClasses.Viewer _ NIL] RETURNS [recordAtom: BOOL _ TRUE, quit: BOOL _ FALSE]˜%šœ(˜(Kšœžœ˜!Kšœ žœžœ˜6Kšœ˜—šžœž˜Kšœžœžœžœ˜)šœ ˜ K–M[viewer: ViewerClasses.Viewer, pos: INT, skipCommentNodes: BOOL _ TRUE]šœZžœ˜`Kšœ#˜#Kšœ˜—šœ ˜ Kšžœ$˜*Kšœžœ *˜@K˜—Kšžœžœ˜—Kšœžœ˜ K˜K˜—K–E[name: ATOM, proc: TEditInput.CommandProc, before: BOOL _ TRUE]šœKžœ˜QK–E[name: ATOM, proc: TEditInput.CommandProc, before: BOOL _ TRUE]šœMžœ˜S—K˜Kšžœ˜—…—-BAt