<> <<>> <> <> <<>> DIRECTORY Convert USING [AppendInt], IO USING [PutChar, PutFR, PutRope, real, STREAM], IPBasic USING [Op, Rational], IPReader USING [Block, Close, Error, GetSkeleton, GetToken, Open, Reader, ReadInt, ReadRational, ReadReal], IPWriter USING [Close, Open, PutAnnotation, PutComment, PutIdentifier, PutInsertfile, PutInt, PutOp, PutRational, PutReal, PutString, Writer], IPUtils USING [], RefText USING [AppendRope, ObtainScratch, ReleaseScratch, TrustTextAsRope], Rope USING [ROPE]; IPUtilsImpl: CEDAR PROGRAM IMPORTS Convert, IO, 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; 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] ~ { prevInt: INT _ -1; nest: INT _ 0; page: INT _ 0; PutDummy: PROC[writer: Writer, comment: ROPE] ~ { writer.PutIdentifier["dummy"]; writer.PutAnnotation[comment]; }; 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 reader.GetToken[flushComments: FALSE]; IF reader.token.type=eof THEN EXIT; SELECT reader.token.op FROM iget, iset => IF prevInt>=0 THEN AnnotateImagerVariable[writer, prevInt]; ENDCASE; prevInt _ -1; SELECT reader.token.type FROM op => writer.PutOp[reader.token.op]; shortNumber => writer.PutInt[prevInt _ reader.shortNumber]; integer => { i: INT ~ reader.ReadInt[! IPReader.Error => IF code=$overflow THEN GOTO Overflow]; writer.PutInt[prevInt _ i]; EXITS Overflow => writer.PutReal[reader.ReadReal[]]; }; rational => { r: Rational ~ reader.ReadRational[! IPReader.Error => IF code=$overflow THEN GOTO Overflow]; writer.PutRational[r]; AnnotateRational[writer, r]; EXITS Overflow => writer.PutReal[reader.ReadReal[]]; }; real => writer.PutReal[reader.ReadReal[]]; identifier => writer.PutIdentifier[RefText.TrustTextAsRope[reader.text]]; string => writer.PutString[RefText.TrustTextAsRope[reader.text]]; vector => writer.PutString["--vector--"]; comment => writer.PutComment[RefText.TrustTextAsRope[reader.text]]; insertfile => writer.PutInsertfile[RefText.TrustTextAsRope[reader.text]]; annotation => writer.PutAnnotation[RefText.TrustTextAsRope[reader.text]]; ENDCASE => ERROR; SELECT reader.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[reader.token.op] THEN NewLine[writer.stream, nest]; ENDLOOP; }; ToEncoded: PUBLIC PROC[from, to: ROPE, tick: PROC _ NIL] ~ { reader: Reader ~ IPReader.Open[from]; writer: Writer ~ IPWriter.Open[to, $Xerox]; Close: PROC ~ { reader.Close[]; writer.Close[] }; ToXeroxInternal[reader, writer, tick ! UNWIND => Close[]]; Close[]; }; ToXeroxInternal: PROC[reader: Reader, writer: Writer, tick: PROC _ NIL] ~ { nest: INT _ 0; PutDummy: PROC[writer: Writer, comment: ROPE] ~ { writer.PutIdentifier["dummy"]; writer.PutComment[comment]; }; DO reader.GetToken[flushComments: FALSE]; IF reader.token.type=eof THEN EXIT; SELECT reader.token.type FROM op => writer.PutOp[reader.token.op]; shortNumber => writer.PutInt[reader.shortNumber]; integer => writer.PutInt[reader.ReadInt[]]; rational => writer.PutRational[reader.ReadRational[]]; real => writer.PutReal[reader.ReadReal[]]; identifier => writer.PutIdentifier[RefText.TrustTextAsRope[reader.text]]; string => writer.PutString[RefText.TrustTextAsRope[reader.text]]; < writer.PutVector[reader.ReadVector[]];>> insertfile => writer.PutInsertfile[RefText.TrustTextAsRope[reader.text]]; comment => writer.PutComment[RefText.TrustTextAsRope[reader.text]]; annotation => NULL; ENDCASE => ERROR; SELECT reader.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.