DIRECTORY FS USING [StreamOpen], Imager USING [Context, Create], IO USING [STREAM], IPBasic USING [ImagerVariable, Op, StrokeEnd], IPWriter USING [Close, Create, PutHeader, PutIdentifier, PutInt, PutOp, PutReal, PutString, Writer], IPOutput USING [], Rope USING [Index, ROPE, Size, Substr]; IPOutputImpl: CEDAR PROGRAM IMPORTS FS, Imager, IPWriter, Rope EXPORTS IPOutput ~ BEGIN ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Writer: TYPE ~ IPWriter.Writer; Op: TYPE ~ IPBasic.Op; Master: TYPE ~ REF MasterRep; MasterRep: PUBLIC TYPE ~ RECORD[ writer: Writer, page: INT _ 0, stack: LIST OF Op _ NIL, imager: Imager.Context _ NIL ]; Error: PUBLIC ERROR[explanation: ROPE] ~ CODE; Narrow: PUBLIC PROC[x: REF] RETURNS[Master] ~ { RETURN[NARROW[x]] }; BeginMaster: PUBLIC PROC[fileName: ROPE, encoding: ATOM _ NIL] RETURNS[Master] ~ { stream: STREAM ~ FS.StreamOpen[fileName, $create]; RETURN[BeginMasterFromStream[stream, encoding]]; }; BeginMasterFromStream: PUBLIC PROC[stream: STREAM, encoding: ATOM _ NIL] RETURNS[Master] ~ { self: Master ~ NEW[MasterRep _ []]; IF encoding=NIL THEN encoding _ $Xerox; self.writer _ IPWriter.Create[stream, encoding]; self.writer.PutHeader[]; self.writer.PutOp[$beginBlock]; RETURN[self]; }; Begin: PROC[self: Master, op: Op] ~ { top: LIST OF Op ~ self.stack; self.stack _ CONS[op, top]; }; End: PROC[self: Master, op: Op] ~ { top: LIST OF Op ~ self.stack; IF top.first=op THEN self.stack _ top.rest ELSE ERROR Error["Bodies improperly nested."]; }; BeginPreamble: PUBLIC PROC[self: Master] ~ { writer: Writer ~ self.writer; IF self.page#0 THEN ERROR Error["BeginPreamble misplaced."]; Begin[self, $nil]; writer.PutOp[$beginBody]; }; EndPreamble: PUBLIC PROC[self: Master] ~ { writer: Writer ~ self.writer; End[self, $nil]; writer.PutOp[$endBody]; self.page _ 1; }; BeginPage: PUBLIC PROC[self: Master] ~ { writer: Writer ~ self.writer; IF self.page=0 THEN ERROR Error["BeginPage misplaced."]; Begin[self, $nil]; writer.PutOp[$beginBody]; }; EndPage: PUBLIC PROC[self: Master] ~ { writer: Writer ~ self.writer; End[self, $nil]; writer.PutOp[$endBody]; self.page _ self.page+1; }; EndMaster: PUBLIC PROC[self: Master] ~ { writer: Writer ~ self.writer; writer.PutOp[$endBlock]; writer.Close[]; }; BeginBodyOp: PROC[self: Master, op: Op] ~ { writer: Writer ~ self.writer; Begin[self, op]; writer.PutOp[op]; writer.PutOp[$beginBody]; }; EndBodyOp: PROC[self: Master, op: Op] ~ { writer: Writer ~ self.writer; End[self, op]; writer.PutOp[$endBody]; }; Display: PUBLIC PROC[self: Master, action: PROC[Imager.Context]] ~ { IF self.imager=NIL THEN self.imager _ Imager.Create[$Interpress, self]; action[self.imager]; }; PutOp: PUBLIC PROC[self: Master, op: Op] ~ { writer: Writer ~ self.writer; writer.PutOp[op]; }; PutInt: PUBLIC PROC[self: Master, int: INT] ~ { writer: Writer ~ self.writer; writer.PutInt[int]; }; PutReal: PUBLIC PROC[self: Master, real: REAL] ~ { writer: Writer ~ self.writer; writer.PutReal[real]; }; PutIdentifier: PUBLIC PROC[self: Master, identifier: ROPE] ~ { writer: Writer ~ self.writer; writer.PutIdentifier[identifier]; }; PutName: PUBLIC PROC[self: Master, name: ROPE] ~ { writer: Writer ~ self.writer; size: INT ~ name.Size[]; start: INT _ 0; n: INT _ 0; DO stop: INT ~ name.Index[pos1: start, s2: "/"]; id: ROPE ~ name.Substr[start: start, len: stop-start]; writer.PutIdentifier[id]; n _ n+1; IF stopJ˜Jšœ!˜!Jšœ˜—šžœœœœ˜2J˜Jšœœ˜Jšœœ˜Jšœœ˜ š˜Jšœœ$˜-Jšœœ.˜6Jšœ"˜"Jšœ œœœ˜+Jšœ˜—J˜J˜Jšœ˜—šž œœœœ˜6J˜Jšœ˜Jšœ˜—J˜šžœœœœ˜*J˜Jšœ%˜%Jšœ˜—šž œœœœ˜3J˜Jšœ=˜=Jšœ˜—šžœœœœ˜.J˜Jšœ)˜)Jšœ˜—šžœœœ˜$J˜Jšœ˜Jšœ˜—šžœœœ˜&J˜Jšœ˜Jšœ˜—šžœœœœ˜0J˜Jšœ1˜1Jšœ˜—šžœœœœ˜-J˜Jšœ.˜.Jšœ˜—šž œœœ˜(J˜Jšœ˜Jšœ˜—J˜šžœœœ˜$J˜Jšœ˜Jšœ˜—šžœœœœ˜+J˜Jšœ&˜&Jšœ˜—šžœœœœ˜+J˜Jšœ&˜&Jšœ˜—šžœœœ˜%J˜Jšœ˜Jšœ˜—šžœœœ˜#J˜Jšœ˜Jšœ˜—šžœœœœ˜+J˜Jšœ&˜&Jšœ˜—šžœœœœ˜+J˜Jšœ&˜&Jšœ˜—šžœœœ˜"J˜Jšœ˜Jšœ˜—J˜šžœœœ˜'J˜Jšœ˜Jšœ˜—šžœœœ˜%J˜Jšœ˜Jšœ˜—J˜šž œœœ˜*Jšœ˜Jšœ˜—šž œœœ˜(Jšœ˜Jšœ˜—šžœœœ˜0Jšœ!˜!Jšœ˜—šžœœœ˜.Jšœ˜Jšœ˜—J˜šžœœœ˜!J˜Jšœ˜Jšœ˜—šžœœœ˜%J˜Jšœ˜Jšœ˜—šž œœœ˜(J˜Jšœ˜Jšœ˜—J˜šž œœœ˜*Jšœ˜Jšœ˜—šž œœœ˜(Jšœ˜Jšœ˜—šžœœœ˜.Jšœ˜Jšœ˜—šž œœœ˜,Jšœ˜Jšœ˜—šžœœœ˜1Jšœ"˜"Jšœ˜—šžœœœ˜/Jšœ ˜ Jšœ˜—šžœœœ˜4Jšœ%˜%Jšœ˜—šžœœœ˜2Jšœ#˜#Jšœ˜—J˜šžœœœ˜"J˜Jšœ˜Jšœ˜—šžœœœœ˜/J˜Jšœ*˜*Jšœ˜—šžœœœ˜"J˜Jšœ˜Jšœ˜—šžœœœ!œ˜:J˜JšœD˜DJšœ˜—šžœœœ˜#J˜Jšœ˜Jšœ˜—šžœœœœ˜+J˜Jšœ&˜&Jšœ˜—šžœœœœ˜-J˜Jšœ(˜(Jšœ˜—šžœœœ˜&J˜Jšœ˜Jšœ˜—šžœœœ˜$J˜Jšœ˜Jšœ˜—J˜šžœœœ˜&J˜Jšœ˜—šžœœœ˜$J˜Jšœ˜—šž œœœ˜*J˜Jšœ˜—šž œœœ˜(J˜Jšœ˜—J˜šžœœœ/˜@J˜Jšœœ˜,Jšœ˜—šžœœœ/˜@J˜Jšœœ˜,Jšœ˜—J˜šžœœœ"œ˜LJ˜Jšœœœœ$˜RJšœ˜—šžœœœœ˜@J˜Jšœ6˜6Jšœ˜—šž œœœ0˜IJ˜Jšœœ˜5Jšœ˜—šžœœœœ˜BJ˜Jšœ8˜8Jšœ˜—šžœœœœ˜DJ˜Jšœ:˜:Jšœ˜—J˜šžœœœ!œ˜˜>Jšœ˜—šžœœœ˜%J˜Jšœ˜Jšœ˜—J˜šžœœœ˜&J˜Jšœ˜Jšœ˜—šž œœœœ˜5J˜Jšœ?˜?Jšœ˜Jšœ˜—šžœœœœ˜/J˜Jšœ)˜)Jšœ˜Jšœ˜—šžœœœœ˜.J˜Jšœ(˜(Jšœ˜Jšœ˜—šžœœœœ˜4J˜Jšœ>˜>Jšœ˜Jšœ˜—šžœœœ˜#J˜Jšœ˜Jšœ˜—šžœœœ˜$J˜Jšœ˜Jšœ˜—J˜šžœœœœ˜1J˜Jšœ.˜.Jšœ˜—šž œœœœ˜8J˜Jšœ5˜5Jšœ˜—J˜šžœœœœ˜0J˜Jšœ;˜;Jšœ˜—šžœœœœ˜3J˜Jšœ>˜>Jšœ˜—šžœœœœ˜/J˜Jšœ*˜*Jšœ˜—šžœœœœ˜/J˜Jšœ*˜*Jšœ˜—J˜šžœœœœ˜0J˜Jšœ+˜+Jšœ˜—šž œœœœ˜4J˜Jšœ.˜.Jšœ˜—šžœœœœ˜J˜Jšœ%˜%Jšœ%˜%Jšœ˜Jšœ˜—šžœœœ˜-J˜Jšœ˜Jšœ˜—šž œœœœ˜9J˜JšœD˜DJšœ˜—J˜šžœœœœ˜3J˜Jšœ-˜-Jšœ˜—šž œœœ˜)J˜Jšœ˜Jšœ˜—š ž œœœœœ œ˜IJ˜Jšœ-˜-JšœG˜GJšœ&˜&Jšœ˜—šžœœœœ˜.J˜Jšœ)˜)Jšœ˜—J˜šž œœœ˜*J˜Jšœ˜Jšœ˜—šž œœœœ˜7J˜JšœB˜BJšœ˜—šž œœœ˜+J˜Jšœ˜—šž œœœ˜)J˜Jšœ˜—šžœœœœ˜J˜JšœI˜IJšœ˜—šžœœœœ˜-J˜Jšœ(˜(Jšœ˜—J˜Jšœ˜—…—>æTQ