<> <> <> <<>> DIRECTORY Convert USING [AppendInt], IO USING [PutChar, PutFR, PutRope, real, STREAM], IOClasses USING [Copy], IPBasic USING [Op, Rational], IPReader USING [Block, Close, Error, GetSkeleton, GetToken, LargeVector, Open, Reader, ReadInt, ReadLargeVector, ReadRational, ReadReal, Token], IPWriter USING [Close, Open, PutAnnotation, PutComment, PutIdentifier, PutInsertfile, PutInt, PutLargeVector, PutOp, PutRational, PutReal, PutString, Writer], IPUtils USING [], RefText USING [AppendRope, ObtainScratch, ReleaseScratch, TrustTextAsRope], Rope USING [ROPE]; IPUtilsImpl: CEDAR PROGRAM IMPORTS Convert, IO, IOClasses, IPReader, IPWriter, RefText EXPORTS IPUtils ~ BEGIN ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Op: TYPE ~ IPBasic.Op; Rational: TYPE ~ IPBasic.Rational; Block: TYPE ~ IPReader.Block; Token: TYPE ~ IPReader.Token; Reader: TYPE ~ IPReader.Reader; Writer: TYPE ~ IPWriter.Writer; ToWritten: PUBLIC PROC[from, to: ROPE, tick: PROC _ NIL] ~ { reader: Reader ~ IPReader.Open[from]; writer: Writer ~ IPWriter.Open[to, $Written]; Close: PROC ~ { reader.Close[]; writer.Close[] }; writer.PutAnnotation[from]; writer.stream.PutChar['\n]; ToWrittenInternal[reader, writer, tick ! UNWIND => Close[]]; Close[]; }; ToWrittenInternal: PROC[reader: Reader, writer: Writer, tick: PROC _ NIL] ~ { buffer: REF TEXT ~ NEW[TEXT[500]]; prevInt: INT _ -1; nest: INT _ 0; page: INT _ 0; AnnotateImagerVariable: PROC[writer: Writer, i: INT] ~ { writer.PutAnnotation[SELECT i FROM 0 => "DCScpx", 1 => "DCScpy", 2 => "correctMX", 3 => "correctMY", 4 => "T", 5 => "priorityImportant", 6 => "mediumXSize", 7 => "mediumYSize", 8 => "fieldXMin", 9 => "fieldYMin", 10 => "fieldXMax", 11 => "fieldYMax", 12 => "showVec", 13 => "color", 14 => "noImage", 15 => "strokeWidth", 16 => "strokeEnd", 17 => "underlineStart", 18 => "amplifySpace", 19 => "correctPass", 20 => "correctShrink", 21 => "correctTX", 22 => "correctTY", ENDCASE => "???"]; }; AnnotatePage: PROC[writer: Writer, page: INT] ~ { scratch: REF TEXT ~ RefText.ObtainScratch[100]; text: REF TEXT _ scratch; IF page=0 THEN text _ RefText.AppendRope[text, " Preamble "] ELSE { text _ RefText.AppendRope[to: text, from: " Page "]; text _ Convert.AppendInt[to: text, from: page]; text _ RefText.AppendRope[to: text, from: " "]; }; writer.PutAnnotation[RefText.TrustTextAsRope[text]]; RefText.ReleaseScratch[scratch]; }; AnnotateRational: PROC[writer: Writer, r: Rational] ~ { value: REAL ~ REAL[r.num]/REAL[r.den]; writer.PutAnnotation[IO.PutFR["(%g)", IO.real[value]]]; }; LineBreakAfter: PROC[op: Op] RETURNS[BOOL] ~ { SELECT op FROM fset, pset, iset, do, dosave, dosaveall, pop, copy, dup, roll, exch, mark, unmark, unmark0, nop, concatt, move, trans, show, showandxrel, setxy, setxyrel, setxrel, setyrel, setgray, setfont, maskfill, maskstroke, maskstrokeclosed, maskvector, maskrectangle, startunderline, maskunderline, masktrapezoidx, masktrapezoidy, maskpixel, clipoutline, cliprectangle, correctmask, correctspace, setcorrectmeasure, setcorrecttolerance, space, beginBody, endBody, beginBlock, endBlock, metricMaster, environmentMaster => RETURN[TRUE]; ENDCASE => RETURN[FALSE]; }; NewLine: PROC[stream: STREAM, nest: INT _ 0] ~ { stream.PutChar['\n]; THROUGH [0..nest) DO stream.PutRope[" "] ENDLOOP; }; DO token: Token; text: REF TEXT; [token, text] _ reader.GetToken[buffer: buffer, flushComments: FALSE]; IF token.type=eof THEN EXIT; SELECT token.op FROM iget, iset => IF prevInt>=0 THEN AnnotateImagerVariable[writer, prevInt]; ENDCASE; prevInt _ -1; SELECT token.type FROM op => writer.PutOp[token.op]; shortNumber => writer.PutInt[prevInt _ token.shortNumber]; integer => { i: INT ~ reader.ReadInt[token, text ! IPReader.Error => IF code=$overflow THEN GOTO Overflow]; writer.PutInt[prevInt _ i]; EXITS Overflow => writer.PutReal[reader.ReadReal[token, text]]; }; rational => { r: Rational ~ reader.ReadRational[token, text ! IPReader.Error => IF code=$overflow THEN GOTO Overflow]; writer.PutRational[r]; AnnotateRational[writer, r]; EXITS Overflow => writer.PutReal[reader.ReadReal[token, text]]; }; real => writer.PutReal[reader.ReadReal[token, text]]; identifier => writer.PutIdentifier[RefText.TrustTextAsRope[text]]; string => writer.PutString[RefText.TrustTextAsRope[text]]; comment => writer.PutComment[RefText.TrustTextAsRope[text]]; insertfile => writer.PutInsertfile[RefText.TrustTextAsRope[text]]; annotation => NULL; largeVector => { lv: IPReader.LargeVector ~ reader.ReadLargeVector[token]; Put: PROC[to: STREAM] ~ { IOClasses.Copy[from: lv.source, to: to] }; writer.PutLargeVector[Put, lv.bytesPerElement, lv.type]; }; ENDCASE => ERROR; SELECT token.op FROM beginBody => { IF nest=0 THEN AnnotatePage[writer, page]; nest _ nest+1 }; endBody => { nest _ nest-1; IF nest=0 THEN { page _ page+1; IF tick#NIL THEN tick[] } }; ENDCASE; IF LineBreakAfter[token.op] THEN NewLine[writer.stream, nest]; ENDLOOP; }; <> <> <> <0 DO>> <> <0 THEN to.PutBlock[block: buffer, count: bytes]>> <> <> <> <<};>> <<>> ToEncoded: PUBLIC PROC[from, to: ROPE, tick: PROC _ NIL] ~ { reader: Reader ~ IPReader.Open[from]; writer: Writer ~ IPWriter.Open[to, $Xerox]; Close: PROC ~ { IPReader.Close[reader]; IPWriter.Close[writer] }; ToXeroxInternal[reader, writer, tick ! UNWIND => Close[]]; Close[]; }; ToXeroxInternal: PROC[reader: Reader, writer: Writer, tick: PROC _ NIL] ~ { buffer: REF TEXT ~ NEW[TEXT[500]]; nest: INT _ 0; DO token: Token; text: REF TEXT; [token, text] _ IPReader.GetToken[reader: reader, buffer: buffer, flushComments: FALSE]; IF token.type=eof THEN EXIT; SELECT token.type FROM op => writer.PutOp[token.op]; shortNumber => writer.PutInt[token.shortNumber]; integer => writer.PutInt[reader.ReadInt[token, text]]; rational => writer.PutRational[reader.ReadRational[token, text]]; real => writer.PutReal[reader.ReadReal[token, text]]; identifier => writer.PutIdentifier[RefText.TrustTextAsRope[text]]; string => writer.PutString[RefText.TrustTextAsRope[text]]; insertfile => writer.PutInsertfile[RefText.TrustTextAsRope[text]]; comment => writer.PutComment[RefText.TrustTextAsRope[text]]; largeVector => { lv: IPReader.LargeVector ~ reader.ReadLargeVector[token]; Put: PROC[to: STREAM] ~ { IOClasses.Copy[from: lv.source, to: to] }; writer.PutLargeVector[Put, lv.bytesPerElement, lv.type]; }; annotation => NULL; ENDCASE => ERROR; SELECT token.op FROM beginBody => { nest _ nest+1 }; endBody => { nest _ nest-1; IF nest=0 THEN { IF tick#NIL THEN tick[] } }; ENDCASE; ENDLOOP; }; Skeleton: PROC[name: ROPE] RETURNS[Block] ~ { reader: Reader ~ IPReader.Open[name]; block: Block ~ reader.GetSkeleton[]; reader.Close[]; RETURN[block]; }; END.