DIRECTORY Atom, FileWriter, FS, InterFile, IO, NodeProps, Rope, RopeReader, RunReader, TextLooks, TextNode; PutInterFileImpl: CEDAR PROGRAM IMPORTS Atom, FileWriter, FS, npI:NodeProps, Rope, RopeReader, RunReader, TextLooks, TextNode EXPORTS InterFile = BEGIN OPEN InterFile, TextNode; ToRope: PUBLIC PROC [node: Ref, flatten: BOOL _ TRUE] RETURNS [output: ROPE] = { data: FileWriter.Ref = FileWriter.ToRope[FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; output _ FileWriter.Close[NIL,NIL,data,FALSE].output; }; ToStream: PUBLIC PROC [stream: IO.STREAM, node: Ref, flatten: BOOL _ TRUE] RETURNS [count: Offset] = { data: FileWriter.Ref = FileWriter.ToStream[stream,FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; count _ FileWriter.Close[NIL,NIL,data,FALSE].count; }; ToFile: PUBLIC PROC [fileName: ROPE, node: Ref, start: Offset _ 0, flatten: BOOL _ TRUE] RETURNS [count: Offset] = { file: FS.OpenFile = FS.Open[fileName, write]; data: FileWriter.Ref = FileWriter.OpenC[file,start,FALSE].data; Header[data]; Finish[data,node,flatten]; Trailer[data]; count _ FileWriter.Close[NIL,NIL,data,FALSE].count; FS.Close[file]; }; Header: PROC [data: FileWriter.Ref] = { WC['{,data]; FileWriter.WriteText["Interdoc/Interchange/0.0",data]; WC[15C,data]; }; Trailer: PROC [data: FileWriter.Ref] = { WC['},data] }; WC: PROC [c: CHAR, data: FileWriter.Ref] = { FileWriter.WriteChar[c,data] }; Finish: PROC [data: FileWriter.Ref, root: Ref, flatten: BOOL, runReader: RunReader.Ref _ NIL, ropeReader: RopeReader.Ref _ NIL, nameText: REF TEXT _ NIL, indent: NAT _ 0] = { WriteChar: PROC [c: CHAR] = { FileWriter.WriteChar[c,data] }; WriteAtom: PROC [atom: ATOM] = { WriteRope[Atom.GetPName[atom]] }; WriteRope: PROC [r: ROPE, start: INT _ 0, len: INT _ INT.LAST] = { WriteChar['<]; WriteSimpleRope[r, start, len]; WriteChar['>] }; WriteSimpleRope: PROC [r: ROPE, start: INT _ 0, len: INT _ INT.LAST] = { size: INT ~ Rope.Size[r]; rem: INT ~ size-start; RopeReader.SetPosition[ropeReader, r, start]; THROUGH [0..MIN[len, rem]) DO char: CHAR ~ RopeReader.Get[ropeReader]; SELECT char FROM '>, '# => WriteInt[char]; ENDCASE => FileWriter.WriteChar[char,data]; ENDLOOP; }; WriteInt: PROC [c: CHAR] = { i: [0..255] _ LOOPHOLE[c]; WriteChar['#]; WriteChar['A + i/16]; WriteChar['A + i MOD 16]; WriteChar['#] }; WriteLooks: PROC [lks: TextLooks.Looks] = { Look: TYPE = TextLooks.Look; WriteRope["looks=<"]; FOR c:Look IN Look DO IF lks[c] THEN WriteChar[c]; ENDLOOP; WriteChar['>] }; WriteProp: PROC [name: ATOM, value: REF] RETURNS [BOOL] = { WritePropName: PROC = { WriteAtom[name]; WriteChar['=] }; WITH value SELECT FROM x:Ref => { -- prop value is a node WritePropName; Finish[data,x,flatten, runReader,ropeReader,nameText,indent+nesting]; LineBreak }; ENDCASE => { -- write specs as a rope specs: ROPE _ npI.GetSpecs[name,value]; IF specs # NIL THEN { WritePropName; WriteRope[specs]; LineBreak }}; RETURN [FALSE] }; LineBreak: PROC = { WriteChar[15C]; FOR i: NAT IN [0..indent) DO WriteChar[' ]; ENDLOOP }; nesting: NAT = 4; -- number of spaces per level of nesting formatName: ATOM; terminal: BOOL; node,nodeChild: Ref; freeRunReader, freeRopeReader: BOOL _ TRUE; IF runReader=NIL THEN runReader _ RunReader.GetRunReader[] ELSE freeRunReader _ FALSE; IF ropeReader=NIL THEN ropeReader _ RopeReader.GetRopeReader[] ELSE freeRopeReader _ FALSE; IF nameText=NIL THEN nameText _ NEW[TEXT[32]]; node _ root; DO -- start the node rope: ROPE; size: Offset; runs: TextLooks.Runs; LineBreak; WriteChar['{]; IF (formatName _ node.formatName) # NIL THEN { WriteRope[Atom.GetPName[formatName]]; LineBreak[] }; IF node.props # NIL THEN [] _ npI.MapProps[node,WriteProp]; IF flatten THEN { -- flatten rope and runs node.rope _ Rope.Flatten[node.rope]; node.runs _ TextLooks.Flatten[node.runs] }; rope _ node.rope; size _ Rope.Size[rope]; IF (runs _ node.runs) = NIL THEN WriteRope[rope] ELSE { -- write each run separately loc, cnt, numRuns: Offset _ 0; [numRuns,,] _ TextLooks.CountRuns[runs,0,size]; RunReader.SetPosition[runReader,runs,0]; WHILE (cnt_cnt+1) <= numRuns DO looks: TextLooks.Looks; len: Offset; [len,looks] _ RunReader.MergedGet[runReader]; IF looks = TextLooks.noLooks THEN WriteRope[rope, loc, len] ELSE { WriteChar['{]; WriteLooks[looks]; WriteRope[rope, loc, len]; WriteChar['}] }; loc _ loc+len; ENDLOOP; IF loc # size THEN ERROR }; terminal _ (nodeChild_FirstChild[node])=NIL; IF ~terminal THEN { node _ nodeChild; indent _ indent+nesting } ELSE { -- node has no children WriteChar['}]; DO IF node=root THEN GOTO Finis; IF ~IsLastSibling[node] THEN { node _ Next[node]; EXIT }; node _ Parent[node]; WriteChar['}]; indent _ indent-nesting; ENDLOOP }; REPEAT Finis => { IF freeRunReader THEN RunReader.FreeRunReader[runReader]; IF freeRopeReader THEN RopeReader.FreeRopeReader[ropeReader] }; ENDLOOP; }; END. ®PutInterFileImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. written by Paxton. May 1981 McGregor. September 10, 1982 1:17 pm Maxwell, January 5, 1983 12:59 pm Russ Atkinson, July 25, 1983 2:58 pm Doug Wyatt, March 5, 1985 9:33:17 am PST Plass, March 14, 1985 1:27:50 pm PST Rick Beach, March 27, 1985 1:05:30 pm PST -- write format -- write node props -- now write contents -- move to the next node ʺ˜codešœ™Kšœ Ïmœ1™K˜ K˜K˜Kšœžœžœžœ˜3Kšœ˜K˜—š œžœž˜Kš œ žœ)žœžœžœ˜`Kšœžœ žœ˜-Kšœ3žœ˜?K˜ K˜K˜Kšœžœžœžœ˜3Kšžœ ˜Kšœ˜K˜—š œžœ˜'Kšžœ ˜ K˜6Kšžœ ˜ Kšœ˜K˜—š œžœ˜(Kšžœ ˜K˜—Kšžœžœžœ;˜LK˜š œžœ,žœ˜=Kšœžœžœ˜AKš œ žœžœžœ žœ ˜.K˜Kš  œžœžœ%˜=K˜š  œžœžœ˜ K˜!K˜—š  œžœžœ žœ žœžœžœ˜BK˜?K˜—š œžœžœ žœ žœžœžœ˜HKšœžœ˜Kšœžœ˜K˜-šžœžœ ž˜Kšœžœ˜(šžœž˜K˜Kšžœ$˜+—Kšžœ˜—šœ˜K˜——š œžœžœ˜Kšœžœ˜K˜K˜Kšœžœ˜K˜K˜—š  œžœ˜+Kšœžœ˜K˜Kš žœžœžœžœžœžœ˜;K˜K˜—š   œžœžœ žœžœžœ˜;š  œžœ˜K˜K˜—šžœžœž˜šœ Ïc˜"K˜˜K˜.—K˜ —šžœ¡˜%Kšœžœ˜'šžœ žœžœ˜K˜K˜K˜ ———Kšžœžœ˜K˜—š  œžœ˜K˜Kš žœžœžœ žœžœ˜6K˜—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šžœžœžœ˜0šžœ¡˜#K˜K˜/K˜(šžœž˜K˜K˜ K˜-Kšžœžœ˜;šžœ˜K˜K˜K˜K˜—K˜Kšžœ˜—Kšžœ žœžœ˜—Kšœ™Kšœ(žœ˜-Kšžœ žœ.˜?šžœ¡˜K˜šžœžœ žœžœ˜ Kšžœžœžœ˜9K˜