DIRECTORY AIS, Commander, Convert, ConvertRasterObject, FileNames, FS, Imager, ImagerColor, ImagerColorES, ImagerFont, ImagerFontFilter, ImagerInterpress, ImagerPixelArray, ImagerPixel, ImagerSample, ImagerBitmapContext, ImagerRavenBitmapContext, ImagerBackdoor, ImagerSmoothContext, SF, CountedVM, VM, ImagerPress, ImagerTransformation, Interpress, IO, CESConverters, Process, Real, Rope, RopeFile, RuntimeError, ShowPress, XeroxCompress; CESConvertersCommand: CEDAR PROGRAM IMPORTS AIS, Commander, Convert, FileNames, FS, Imager, ImagerRavenBitmapContext, ImagerColor, ImagerColorES, ImagerFont, ImagerFontFilter, ImagerInterpress, ImagerPixel, ImagerPixelArray, ImagerPress, ImagerSample, ImagerTransformation, ImagerSmoothContext, Interpress, IO, Process, Real, Rope, RopeFile, RuntimeError, ShowPress, VM, XeroxCompress, ImagerBackdoor, ConvertRasterObject EXPORTS CESConverters ~ BEGIN OPEN CESConverters; ROPE: TYPE ~ Rope.ROPE; inch: REAL = 0.0254; -- inches->meters conversion factor ravenPPI: REAL = 300.0; -- pixels per inch on a Raven printer for compression ravenPPM: REAL = ravenPPI/inch; -- pixels per meters on a Raven printer for compression defaultPageWidth: REAL ¬ 8.5*inch; -- for normal sized paper defaultPageHeight: REAL ¬ 11*inch; -- for normal sized paper defaultAISPixelsPerInch: REAL = 72.0; -- for AIS files aisMargin: REAL ¬ 0.25*inch; -- offset of AIS images on regular-sized paper headerSampled: ROPE ¬ "Interpress/Xerox/3.0 "; -- IP header for sampled images aisCaptionFont: ROPE ¬ "xerox/pressfonts/helvetica-mir"; -- to put caption in AIS files aisCaptionLoc: Imager.VEC ¬ [72, 9]; -- where the caption should be in AIS files xcFontBase: Rope.ROPE ¬ "Xerox/xc1-2-2/"; -- prefix to be used for Xerox product fonts PressToInterpress: PUBLIC PROC [inputName: Rope.ROPE, interpress: ImagerInterpress.Ref, beginPage, endPage: ProgressProc, msg: IO.STREAM, useXCFonts: BOOL, verbose: BOOL] RETURNS [failed: BOOL ¬ FALSE] ~ { showPress: ShowPress.Handle = ShowPress.Open[FileNames.ResolveRelativePath[inputName]]; FOR i: INT IN [1..showPress.lastPart) DO Paint: PROC [context: Imager.Context] ~ { Process.CheckForAbort[]; failed ¬ beginPage[i, showPress.lastPart-1]; IF failed THEN RETURN; IF useXCFonts THEN context ¬ ImagerFontFilter.FilterFonts[context, xc1Map, msg, verbose]; Imager.SetPriorityImportant[context, TRUE]; ShowPress.DrawPressPage[context: context, show: showPress, pageNumber: i]; Process.CheckForAbort[]; failed ¬ endPage[i, showPress.lastPart-1]; }; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0E-5]; IF failed THEN EXIT; ENDLOOP; }; BrickValue: TYPE ~ ARRAY [0..4) OF PACKED ARRAY [0..4) OF [0..16); coarseBrickValues: BrickValue ¬ [ -- for compressed IP masters [00, 01, 13, 14], [08, 02, 03, 15], [09, 10, 04, 05], [07, 11, 12, 06] ]; MakeSimpleBrick: PROC [t: BrickValue] RETURNS [ImagerBitmapContext.Brick] ~ { b: ImagerSample.SampleMap ¬ ImagerSample.NewSampleMap[box: [max: [4, 4]], bitsPerSample: 8]; FOR s: NAT IN [0..4) DO FOR f: NAT IN [0..4) DO ImagerSample.Put[b, [s, f], t[s][f]]; ENDLOOP; ENDLOOP; RETURN [[maxSample: 15, sampleMap: b, phase: 0]] }; InterpressToCompressedIP: PUBLIC PROC [inputName: Rope.ROPE, interpress: ImagerInterpress.Ref, beginPage, endPage: ProgressProc, msg: IO.STREAM, pageWidth, pageHeight: REAL] RETURNS [failed: BOOL ¬ FALSE] ~ { Log: Interpress.LogProc ~ { IPReadLog[msg, class, code, explanation] }; input: Interpress.Master = Interpress.Open[FileNames.ResolveRelativePath[inputName], Log]; size: SF.Vec = [s: Real.Round[pageWidth*ravenPPM], f: Real.Round[pageHeight*ravenPPM]]; bitmap: ImagerSample.RasterSampleMap = ImagerSample.ObtainScratchMap[[max: size]]; bitmapAsPixelArray: ImagerPixelArray.PixelArray = ImagerPixelArray.FromPixelMap[pixelMap: ImagerPixel.MakePixelMap[bitmap], box: ImagerSample.GetBox[bitmap], scanMode: [slow: right, fast: up], immutable: FALSE]; bitmapContext: Imager.Context = ImagerRavenBitmapContext.Create[deviceSpaceSize: size, scanMode: [slow: right, fast: up], surfaceUnitsPerInch: [ravenPPI, ravenPPI], pixelUnits: FALSE, fontCacheName: $PrinterBitmap, deviceCode: $Raven300]; ImagerRavenBitmapContext.SetBitmap[context: bitmapContext, bitmap: bitmap]; ImagerRavenBitmapContext.SetBrick[context: bitmapContext, brick: MakeSimpleBrick[coarseBrickValues]]; WITH ImagerSample.GetRef[bitmap] SELECT FROM vm: CountedVM.Handle => TRUSTED { VM.SwapIn[interval: vm.interval, kill: TRUE] }; ENDCASE => NULL; FOR i: INT IN [1..input.pages] DO PageAction: PROC [context: Imager.Context] ~ { Imager.SetPriorityImportant[context, FALSE]; Imager.MaskPixel[context: context, pa: XeroxCompress.CompressPixelArray[bitmapAsPixelArray]] }; Process.CheckForAbort[]; failed ¬ beginPage[i, input.pages]; IF failed THEN EXIT; ImagerSample.Clear[bitmap]; Interpress.DoPage[master: input, page: i, context: bitmapContext, log: Log]; Process.CheckForAbort[]; ImagerInterpress.DoPage[interpress, PageAction, 0.0254/300.0]; Process.CheckForAbort[]; failed ¬ endPage[i, input.pages]; IF failed THEN EXIT; ENDLOOP; WITH ImagerSample.GetRef[bitmap] SELECT FROM vm: CountedVM.Handle => TRUSTED { VM.Kill[interval: vm.interval] }; ENDCASE => NULL; ImagerSample.ReleaseScratchMap[bitmap]; }; AISToInterpress: PUBLIC PROC [inputName: Rope.ROPE, interpress: ImagerInterpress.Ref, beginPage, endPage: ProgressProc, msg: IO.STREAM ¬ NIL, pageWidth, pageHeight: REAL, caption: ROPE] RETURNS [failed: BOOL ¬ FALSE] ~ { resolvedName: Rope.ROPE ¬ FileNames.ResolveRelativePath[inputName]; pa: Imager.PixelArray ¬ ImagerPixelArray.FromAIS[resolvedName]; maxSample: CARDINAL ~ ImagerPixelArray.MaxSampleValue[pa, 0]; rect: Imager.Rectangle ¬ ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]]; scale: REAL ¬ MIN[(pageWidth-2*aisMargin)/rect.w, (pageHeight-2*aisMargin)/rect.h]; fRef: AIS.FRef ¬ AIS.OpenFile[resolvedName]; Paint: PROC [context: Imager.Context] ~ { Caption: PROC ~ { Imager.ScaleT[context, inch/72]; Imager.SetFont[context, ImagerFont.Scale[ImagerFont.Find[aisCaptionFont], 9]]; Imager.SetXY[context, aisCaptionLoc]; Imager.ShowRope[context, caption]; }; Imager.SetPriorityImportant[context, TRUE]; IF NOT caption.IsEmpty THEN Imager.DoSave[context, Caption]; Imager.TranslateT[context, [pageWidth*0.5, pageHeight*0.5]]; Imager.ScaleT[context, scale]; Imager.TranslateT[context, [-(rect.x+rect.w*0.5), -(rect.y+rect.h*0.5)]]; IF fRef.raster.bitsPerPixel = 0 THEN Imager.SetSampledColor[context: context, pa: pa, m: NIL, colorOperator: ImagerColor.NewColorOperatorGrayLinear[0, maxSample, maxSample+1]] ELSE Imager.SetSampledColor[context: context, pa: pa, m: NIL, colorOperator: ImagerColor.NewColorOperatorGrayLinear[maxSample, 0, maxSample+1]]; Imager.MaskRectangle[context, rect]; }; IF beginPage[1, 1] THEN GOTO tooBad; ImagerInterpress.DeclarePixelArray[interpress, pa]; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0]; IF endPage[1, 1] THEN GOTO tooBad; AIS.CloseFile[fRef]; EXITS tooBad => failed ¬ TRUE; }; ColorAISToInterpress: PUBLIC PROC [inputRed, inputGreen, inputBlue: Rope.ROPE, interpress: ImagerInterpress.Ref, beginPage, endPage: ProgressProc, msg: IO.STREAM, pageWidth, pageHeight: REAL, caption: ROPE] RETURNS [failed: BOOL ¬ FALSE] ~ { pa: Imager.PixelArray; maxSample: CARDINAL; rect: Imager.Rectangle; scale: REAL; rgbArgs: ImagerColorES.RGBArgs ~ ImagerColorES.DefaultRGBArgs[]; Paint: PROC [context: Imager.Context] ~ { Caption: PROC ~ { Imager.ScaleT[context, inch/72]; Imager.SetFont[context, ImagerFont.Scale[ImagerFont.Find[aisCaptionFont], 9]]; Imager.SetXY[context, aisCaptionLoc]; Imager.ShowRope[context, caption]; }; Imager.SetPriorityImportant[context, TRUE]; IF NOT caption.IsEmpty THEN Imager.DoSave[context, Caption]; Imager.TranslateT[context, [pageWidth*0.5, pageHeight*0.5]]; Imager.ScaleT[context, scale]; Imager.TranslateT[context, [-(rect.x+rect.w*0.5), -(rect.y+rect.h*0.5)]]; rgbArgs.swhite ¬ maxSample; Imager.SetSampledColor[context: context, pa: pa, m: NIL, colorOperator: ImagerColorES.NewColorOperatorRGB[rgbArgs]]; Imager.MaskRectangle[context, rect]; }; pa ¬ ImagerPixelArray.Join3AIS[inputRed, inputGreen, inputBlue]; maxSample ¬ ImagerPixelArray.MaxSampleValue[pa, 0]; rect ¬ ImagerTransformation.TransformRectangle[pa.m, [0, 0, pa.sSize, pa.fSize]]; scale ¬ MIN[(pageWidth-2*aisMargin)/rect.w, (pageHeight-2*aisMargin)/rect.h]; IF beginPage[1, 1] THEN GOTO tooBad; ImagerInterpress.DeclarePixelArray[interpress, pa]; ImagerInterpress.DoPage[self: interpress, action: Paint, scale: 1.0]; IF endPage[1, 1] THEN GOTO tooBad; EXITS tooBad => failed ¬ TRUE; }; IPReadError: PUBLIC ERROR [class: INT, code: ATOM, explanation: Rope.ROPE] ~ CODE; IPReadLog: PROC [msg: IO.STREAM, class: INT, code: ATOM, explanation: ROPE] ~ { IF msg=NIL THEN { SELECT class FROM Interpress.classMasterError, Interpress.classAppearanceError => ERROR IPReadError[class, code, explanation]; Interpress.classMasterWarning, Interpress.classAppearanceWarning, Interpress.classComment => NULL; -- ignore those ENDCASE => ERROR IPReadError[class, code, explanation]; } ELSE { msg.PutRope[ SELECT class FROM Interpress.classMasterError => "Master Error: ", Interpress.classMasterWarning => "Master Warning: ", Interpress.classAppearanceError => "Appearance Error: ", Interpress.classAppearanceWarning => "Appearance Warning: ", Interpress.classComment => "Comment: ", ENDCASE => Rope.Cat["Class ", Convert.RopeFromInt[class], " Error: "] ]; msg.PutRope[explanation]; msg.PutRope[" . . . "]; }; }; InterpressToPress: PUBLIC PROC [inputName: Rope.ROPE, context: Imager.Context, beginPage, endPage: ProgressProc, msg: IO.STREAM] RETURNS [failed: BOOL ¬ FALSE] ~ { Log: Interpress.LogProc ~ { IPReadLog[msg, class, code, explanation] }; input: Interpress.Master ¬ Interpress.Open[FileNames.ResolveRelativePath[inputName], Log]; FOR i: INT IN [1..input.pages] DO Process.CheckForAbort[]; failed ¬ beginPage[i, input.pages]; IF failed THEN EXIT; Interpress.DoPage[master: input, page: i, context: context, log: Log]; Process.CheckForAbort[]; failed ¬ endPage[i, input.pages]; IF i # input.pages THEN ImagerPress.NewPage[context]; ENDLOOP; Interpress.Close[input]; }; InterpressToAIS: PUBLIC PROC [inputName: Rope.ROPE, outputBase: Rope.ROPE, msg: IO.STREAM, gray: BOOL, sPPI, fPPI: REAL, pageWidth, pageHeight: REAL] RETURNS [failed: BOOL ¬ FALSE] ~ { MaxSample: ImagerPixel.PixelProc ~ {RETURN [255]}; Log: Interpress.LogProc ~ { IPReadLog[msg, class, code, explanation] }; sSize: REAL = pageHeight/inch; fSize: REAL = pageWidth/inch; box: SF.Box = [min: [0, 0], max: [s: Real.Round[sPPI*sSize], f: Real.Round[fPPI*fSize]]]; context: Imager.Context; components: LIST OF ATOM = IF gray THEN LIST[$Intensity] ELSE LIST[$Red, $Green, $Blue]; pixelMap: ImagerPixel.PixelMap; input: Interpress.Master; pixelMap ¬ ImagerPixel.NewPixelMap[samplesPerPixel: (IF gray THEN 1 ELSE 3), box: box, maxSample: MaxSample]; context ¬ ImagerSmoothContext.Create[size: pixelMap.box.max, scanMode: Imager.defaultScanMode, initialScale: 1.0, cacheFonts: TRUE, surfaceUnitsPerPixel: 5]; ImagerSmoothContext.SetOutputBuffer[context, pixelMap, components]; Imager.SetColor[context, Imager.MakeGray[0]]; --set the master to white Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]]; Imager.SetColor[context, Imager.MakeGray[1]]; --set the master to white Imager.Scale2T[context, [x: fPPI/inch, y: sPPI/inch]]; input ¬ Interpress.Open[FileNames.ResolveRelativePath[inputName], Log]; IF msg#NIL THEN msg.PutF["Imaging page 1 ..."]; Interpress.DoPage[master: input, page: 1, context: context, log: Log]; IF gray THEN { name: ROPE ¬ Rope.Cat[outputBase, ".ais"]; ConvertRasterObject.AISFromSampleMap[name, pixelMap[0]]; IF msg#NIL THEN msg.PutF["%g ", IO.rope[name]]; } ELSE { red: ROPE ¬ Rope.Cat[outputBase, "-", "red", ".ais"]; green: ROPE ¬ Rope.Cat[outputBase, "-", "green", ".ais"]; blue: ROPE ¬ Rope.Cat[outputBase, "-", "blue", ".ais"]; ConvertRasterObject.AISFromSampleMap[red, pixelMap[0]]; ConvertRasterObject.AISFromSampleMap[green, pixelMap[1]]; ConvertRasterObject.AISFromSampleMap[blue, pixelMap[2]]; IF msg#NIL THEN msg.PutF["%g, %g, %g ", IO.rope[red], IO.rope[green], IO.rope[blue]]; }; Interpress.Close[input]; }; CH: PROC [char: CHAR] RETURNS [WORD] ~ INLINE {RETURN [ORD[char]]}; XC: PROC [set: [0..256), code: [0..256)] RETURNS [WORD] ~ {RETURN [set*256+code]}; C1: PROC [c: CHAR, set: [0..256), code: [0..256)] RETURNS [ImagerFontFilter.CharRangeMap] ~ { RETURN [[bc: CH[c], ec: CH[c], newbc: XC[set, code]]] }; classicModernEtAl: LIST OF ROPE ¬ LIST["Classic", "Modern"]; timesRomanEtAl: LIST OF LIST OF ROPE ¬ LIST[ LIST["TimesRoman", "Classic"], LIST["Helvetica", "Modern"], LIST["Gacha", "XeroxBook"], LIST["Tioga", "Classic"], LIST["Laurel", "Classic"]]; mrrEtAl: LIST OF ROPE ¬ LIST["-mrr", "-mir-italic", "-bir-bold-italic", "-brr-bold"]; alphaMap: ImagerFontFilter.CharacterCodeMap ~ LIST [ [bc: CH[' ], ec: CH['~], newbc: CH[' ]] ]; mathMap: ImagerFontFilter.CharacterCodeMap ¬ LIST [ C1['c, 0, 323B], C1['r, 0, 322B] ]; oisMap: ImagerFontFilter.CharacterCodeMap ¬ LIST [ [bc: CH['a], ec: CH['~], newbc: CH['a]], [bc: CH['.], ec: CH[']], newbc: CH['.]], [bc: CH['%], ec: CH[',], newbc: CH['%]], [bc: CH['-], ec: CH['-], newbc: XC[357B, 42B]], [bc: CH[' ], ec: CH['!], newbc: CH[' ]], [bc: CH['\"], ec: CH['\"], newbc: XC[0, 271B]], [bc: CH['#], ec: CH['#], newbc: CH['#]], [bc: CH['$], ec: CH['$], newbc: XC[0, 244B]], [bc: CH['^], ec: CH['^], newbc: XC[0, 255B]], [bc: CH['_], ec: CH['_], newbc: XC[0, 254B]], C1['\030, 357B, 45B], C1['\267, 357B, 146B], C1['\265, 41B, 172B], C1['\140, 0, 140B], C1[', 357B, 064B], C1[', 357B, 065B], ]; xc1Map: ImagerFontFilter.FontMap ¬ MakeXC1map[]; MakeXC1map: PROC RETURNS [f: ImagerFontFilter.FontMap] ~ { Enter: PROC [e: ImagerFontFilter.FontMapEntry] ~ {f ¬ CONS[e, f]}; FOR family: LIST OF ROPE ¬ classicModernEtAl, family.rest UNTIL family = NIL DO FOR face: LIST OF ROPE ¬ mrrEtAl, face.rest UNTIL face = NIL DO Enter[[ inputName: Rope.Cat["Xerox/Pressfonts/", family.first, face.first.Substr[0, 4]], output: LIST[[newName: Rope.Cat[xcFontBase, family.first, face.first.Substr[4]], charMap: oisMap]] ]]; ENDLOOP; ENDLOOP; FOR family: LIST OF LIST OF ROPE ¬ timesRomanEtAl, family.rest UNTIL family = NIL DO FOR face: LIST OF ROPE ¬ mrrEtAl, face.rest UNTIL face = NIL DO Enter[[ inputName: Rope.Cat["Xerox/Pressfonts/", family.first.first, face.first.Substr[0, 4]], output: LIST[[newName: Rope.Cat[xcFontBase, family.first.rest.first, face.first.Substr[4]], charMap: oisMap]], warn: TRUE ]]; ENDLOOP; ENDLOOP; Enter[[ inputName: "Xerox/Pressfonts/Logo-mrr", output: LIST[[newName: Rope.Cat[xcFontBase, "Logotypes-Xerox"], charMap: alphaMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mrr", output: LIST[[newName: Rope.Cat[xcFontBase, "Modern"], charMap: mathMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mir", output: LIST[[newName: Rope.Cat[xcFontBase, "Modern-italic"], charMap: mathMap]] ]]; }; PressToInterpressAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ {cmd.out.PutF["[%g", IO.int[pageNumber]]}; EndPage: ProgressProc ~ {cmd.out.PutRope["] "]}; version: ROPE = GetCmdToken[cmds]; verbose: ROPE = GetCmdToken[cmds]; header: ROPE = IF Rope.Size[version] = 3 AND Rope.Fetch[version, 1] = '. THEN Rope.Cat["Interpress/Xerox/", version, " "] ELSE NIL; output: ImagerInterpress.Ref ¬ ImagerInterpress.Create[outputName, header]; xc: BOOL ¬ Rope.Size[version] = 3 AND Rope.Fetch[version, 0] < '3; [] ¬ PressToInterpress[inputName, output, BeginPage, EndPage, cmd.out, xc, verbose.Equal["verbose", FALSE]]; ImagerInterpress.Close[output]; }; InterpressToCompressedIPAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ {cmd.out.PutF["[%g", IO.int[pageNumber]]}; EndPage: ProgressProc ~ {cmd.out.PutRope["] "]}; output: ImagerInterpress.Ref ~ ImagerInterpress.Create[outputName, "Interpress/Xerox/2.0 "]; [] ¬ InterpressToCompressedIP[inputName, output, BeginPage, EndPage, cmd.out, defaultPageWidth, defaultPageHeight]; ImagerInterpress.Close[output]; }; AISToInterpressAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ { IF cmd.commandLine # NIL THEN cmd.out.PutF["[%g", IO.int[pageNumber]]}; EndPage: ProgressProc ~ {IF cmd.commandLine # NIL THEN cmd.out.PutRope["] "]}; output: ImagerInterpress.Ref ¬ ImagerInterpress.Create[outputName, headerSampled]; [] ¬ AISToInterpress[inputName, output, BeginPage, EndPage, cmd.out, defaultPageWidth, defaultPageHeight, cmd.commandLine]; ImagerInterpress.Close[output]; }; ColorAISToInterpressCommand: PUBLIC Commander.CommandProc ~ { FileChoice: PROC [r: Rope.ROPE, a: ARRAY [0..3) OF Rope.ROPE] RETURNS [result: Rope.ROPE ¬ NIL] ~ { FOR i: NAT IN [0..3) DO IF a[i] # NIL THEN { name: ROPE ~ Rope.Cat[r, "-", a[i], ".ais"]; result ¬ FS.FileInfo[name ! FS.Error => {IF error.code = $unknownFile THEN CONTINUE}].fullFName; IF result# NIL THEN RETURN; }; ENDLOOP; }; GetColorNames: PROC [name: Rope.ROPE] RETURNS [ok: BOOL, red, grn, blu: Rope.ROPE] ~ { red ¬ FileChoice[name, ["red", "r", NIL]]; IF red = NIL THEN { ok ¬ FALSE; RETURN}; grn ¬ FileChoice[name, ["grn", "green", "g"]]; IF grn = NIL THEN { ok ¬ FALSE; RETURN}; blu ¬ FileChoice[name, ["blu", "blue", "b"]]; ok ¬ blu # NIL; }; BeginPage: ProgressProc ~ {IF NOT quiet THEN cmd.out.PutF["[%g", IO.int[pageNumber]]}; EndPage: ProgressProc ~ {IF NOT quiet THEN cmd.out.PutRope["] "]}; red, grn, blu: ROPE; interpress: ImagerInterpress.Ref; stream: IO.STREAM ¬ IO.RIS[cmd.commandLine]; firstToken: ROPE ¬ GetFileNameToken[stream]; quiet: BOOL ¬ Rope.Equal[firstToken, "-q", FALSE]; outputName: ROPE ¬ FileNames.ResolveRelativePath[IF quiet THEN GetFileNameToken[stream] ELSE firstToken]; secondTokenIndex: INT ¬ IO.GetIndex[stream]; gets: ROPE ¬ GetCmdToken[stream]; ok: BOOL ¬ FALSE; inputName: ROPE ¬ NIL; failed: BOOL; IF NOT gets.Equal["_"] THEN { inputName ¬ outputName; outputName ¬ NIL; stream.SetIndex[secondTokenIndex]; } ELSE {inputName ¬ FileNames.ResolveRelativePath[GetFileNameToken[stream]]}; IF inputName = NIL THEN RETURN[result: $Failure, msg: cmd.procData.doc]; [ok, red, grn, blu] ¬ GetColorNames[inputName ! FS.Error => { IF error.group = user THEN {result ¬ $Failure; msg ¬ error.explanation; GOTO Quit} }]; IF NOT ok THEN RETURN[result: $Failure, msg: "Could not find one or more of the input files\n"]; IF outputName = NIL THEN { outputName ¬ MakeOutputName[inputName, cmd.procData.doc]; }; cmd.out.PutF["Reading\n %g\n %g\n %g . . . ", IO.rope[red], IO.rope[grn], IO.rope[blu]]; interpress ¬ ImagerInterpress.Create[outputName, headerSampled]; IF quiet THEN cmd.commandLine ¬ NIL; failed ¬ ColorAISToInterpress[red, grn, blu, interpress, BeginPage, EndPage, cmd.out, defaultPageWidth, defaultPageHeight, cmd.commandLine]; ImagerInterpress.Close[interpress]; IF failed THEN RETURN[result: $Failure, msg: "Interpress generation failed"]; outputName ¬ FindFullName[outputName]; cmd.out.PutRope["\n "]; cmd.out.PutRope[outputName]; cmd.out.PutRope[" written.\n"]; EXITS Quit => NULL }; InterpressToPressAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ {cmd.out.PutF["[%g", IO.int[pageNumber]]}; EndPage: ProgressProc ~ {cmd.out.PutRope["] "]}; context: Imager.Context ~ ImagerPress.SimpleCreate[fileName: outputName, printerType: press]; [] ¬ InterpressToPress[inputName, context, BeginPage, EndPage, cmd.out]; ImagerPress.Close[context]; }; InterpressToAISAction: PUBLIC ActionProc = { sPixelsPerInch: REAL ¬ defaultAISPixelsPerInch; fPixelsPerInch: REAL ¬ defaultAISPixelsPerInch; sSize: REAL ¬ defaultPageHeight/inch; -- measured in inches fSize: REAL ¬ defaultPageWidth/inch; -- measured in inches gray: BOOL ¬ FALSE; UNTIL IO.EndOf[self: cmds] DO token: ROPE ~ GetCmdToken[cmds]; IF token=NIL THEN LOOP; SELECT TRUE FROM Rope.Equal[token, "gray", FALSE] => gray ¬ TRUE; Rope.Equal[token, "ppi:", FALSE] => sPixelsPerInch ¬ fPixelsPerInch ¬ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => Complain["\nIllegal value for ppi.\n"]]; Rope.Equal[token, "sppi:", FALSE] => sPixelsPerInch ¬ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => Complain["\nIllegal value for sppi.\n"]]; Rope.Equal[token, "fppi:", FALSE] => fPixelsPerInch ¬ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => Complain["\nIllegal value for fppi.\n"]]; Rope.Equal[token, "size:", FALSE] => { fSize ¬ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => Complain["\nIllegal value for size.\n"]]; sSize ¬ Convert.RealFromRope[r: GetCmdToken[cmds] ! Convert.Error => Complain["\nIllegal value for size.\n"]]; }; ENDCASE => Complain[Rope.Cat["\nUnrecognized token: ", token, "\n"]]; ENDLOOP; [] ¬ InterpressToAIS[inputName, outputName, cmd.out, gray, sPixelsPerInch, fPixelsPerInch, fSize*inch, sSize*inch]; }; FindFullName: PROC [inputName: ROPE] RETURNS [ROPE] ~ { fullFName: ROPE ¬ NIL; fullFName ¬ FS.FileInfo[inputName].fullFName; RETURN [fullFName] }; GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE ¬ NIL] = { CmdTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ OR char = '[ OR char = '] THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; rope ¬ stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token; }; GetFileNameToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE ¬ NIL] = { FileNameTokenBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = '_ THEN RETURN [break]; IF char = ' OR char = '\t OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; rope ¬ stream.GetTokenRope[FileNameTokenBreak ! IO.EndOfStream => CONTINUE].token; }; RealFromRope: PROC [rope: ROPE] RETURNS [real: REAL] = { oops: BOOL ¬ FALSE; real ¬ Convert.RealFromRope[rope ! Convert.Error => {oops ¬ TRUE; CONTINUE}]; IF oops THEN {oops ¬ FALSE; real ¬ Convert.IntFromRope[rope ! Convert.Error => {oops ¬ TRUE; CONTINUE}]}; IF oops THEN Complain[Rope.Concat["Number expected: ", rope]]; }; Complain: PUBLIC ERROR [complaint: ROPE] ~ CODE; ForceLower: PROC [old: CHAR] RETURNS [CHAR] ~ { RETURN [IF old IN ['A..'Z] THEN old+('a-'A) ELSE old] }; MakeOutputName: PROC [inputName: ROPE, doc: ROPE] RETURNS [ROPE] ~ { start: INT ¬ Rope.Index[s1: doc, s2: " to "]+4; end: INT ¬ Rope.SkipTo[s: doc, pos: start, skip: " \n\t"]; cp: FS.ComponentPositions; isAIS: BOOL ¬ Rope.Equal[Rope.Substr[doc, start, end-start], "ais", FALSE]; [inputName, cp] ¬ FS.ExpandName[inputName]; RETURN [Rope.Cat[ Rope.Translate[inputName, cp.base.start, cp.base.length, ForceLower], IF isAIS THEN NIL ELSE ".", IF isAIS THEN NIL ELSE Rope.Translate[doc, start, end-start, ForceLower] ]] }; Command: PUBLIC Commander.CommandProc ~ { refAction: REF ActionProc ~ NARROW[cmd.procData.clientData]; stream: IO.STREAM ¬ IO.RIS[cmd.commandLine]; firstToken: ROPE ¬ GetFileNameToken[stream]; quiet: BOOL ¬ Rope.Equal[firstToken, "-q", FALSE]; outputName: ROPE ¬ FileNames.ResolveRelativePath[IF quiet THEN GetFileNameToken[stream] ELSE firstToken]; secondTokenIndex: INT ¬ IO.GetIndex[stream]; gets: ROPE ¬ GetFileNameToken[stream]; inputName: ROPE ¬ NIL; IF NOT gets.Equal["_"] THEN { inputName ¬ outputName; outputName ¬ NIL; stream.SetIndex[secondTokenIndex]; } ELSE {inputName ¬ FileNames.ResolveRelativePath[GetFileNameToken[stream]]}; IF inputName = NIL THEN RETURN[result: $Failure, msg: cmd.procData.doc]; inputName ¬ FindFullName[inputName ! FS.Error => { IF error.group = user THEN {result ¬ $Failure; msg ¬ error.explanation; GOTO Quit} }]; IF outputName = NIL THEN { outputName ¬ MakeOutputName[inputName, cmd.procData.doc]; }; cmd.out.PutRope["Reading "]; cmd.out.PutRope[inputName]; cmd.out.PutRope[" . . . "]; IF quiet THEN cmd.commandLine ¬ NIL; refAction­[inputName, outputName, cmd, stream ! Complain => {result ¬ $Failure; msg ¬ complaint; GOTO Quit}; FS.Error => { IF error.group = user THEN {result ¬ $Failure; msg ¬ error.explanation; GOTO Quit} } ]; outputName ¬ FindFullName[outputName ! FS.Error => { outputName ¬ "Output file(s)"; CONTINUE}; ]; cmd.out.PutRope[outputName]; cmd.out.PutRope[" written.\n"]; EXITS Quit => NULL }; Bound: TYPE ~ RECORD [first, last: INT]; int: Bound ~ [INT.FIRST, INT.LAST]; nat: Bound ~ [NAT.FIRST, NAT.LAST]; card: Bound ~ [CARDINAL.FIRST, CARDINAL.LAST]; RealToNum: PROC [real: REAL, bounds: Bound ¬ int, name: ROPE ¬ NIL] RETURNS [number: INT ¬ 0] ~ { IF name=NIL THEN name ¬ "Value"; number ¬ Real.Round[real ! RuntimeError.UNCAUGHT => CONTINUE]; IF real#number THEN Complain[IO.PutFR[format: "%g (%g) should be integral.", v1: [rope [name]], v2: [real [real]]]]; IF number NOT IN [bounds.first .. bounds.last] THEN Complain[IO.PutFR[format: "Value (%g) should be in range [%g .. %g]", v1: [rope [name]], v2: [integer [bounds.first]], v3: [integer [bounds.last]]]]; }; xStar: ROPE ~ FS.ExpandName["*"].fullFName; regDir: ROPE ~ Rope.Substr[xStar, 0, Rope.Size[xStar]-1]; wDirList: LIST OF ROPE ¬ LIST[NIL, regDir]; FileContents: PROC [base, ext: ROPE] RETURNS [ROPE] ~ { FOR each: LIST OF ROPE ¬ wDirList, each.rest UNTIL each = NIL DO name: ROPE ~ FS.ExpandName[name: Rope.Cat[base, ext], wDir: each.first].fullFName; RETURN [RopeFile.Create[name: name, raw: FALSE ! FS.Error => {IF error.group = user THEN CONTINUE}]]; ENDLOOP; Complain[IO.PutFR[format: "Device type %g undefined.", v1: [rope [base]]]]; }; Require: PROC [stream: IO.STREAM, rope: ROPE, case: BOOLEAN ¬ FALSE] ~ { IF NOT Rope.Equal[s1: rope, s2: GetCmdToken[stream], case: case] THEN Complain[Rope.Cat["Expected \"", rope, "\"."]]; }; Commander.Register["PressToInterpress", Command, "Convert Press file to Interpress (output _ input [version])\n", NEW[ActionProc ¬ PressToInterpressAction]]; Commander.Register["InterpressToPress", Command, "Convert Interpress file to Press (output _ input)\n", NEW[ActionProc ¬ InterpressToPressAction]]; END.  CESConvertersCommand.mesa Copyright Σ 1984, 1985, 1986, 1990, 1992 by Xerox Corporation. All rights reserved. Michael Plass, November 2, 1990 1:00 pm PST Tim Diebert: February 18, 1986 10:36:06 am PST Pier, September 21, 1987 5:29:33 pm PDT Eric Nickell February 19, 1986 2:56:26 pm PST Doug Wyatt, July 22, 1986 6:28:45 pm PDT Maureen Stone, January 8, 1988 5:21:44 pm PST Jean-Marc Frailong January 20, 1988 12:18:56 pm PST Bloomenthal, April 8, 1988 4:29:45 pm PDT Beretta:PARC:Xerox (8*923-4484) August 31, 1989 4:39:01 pm PDT Types and constants Client interface to Interpress files Convert press file to IP file. Verbose=TRUE means log font substitutions. Print various feedbacks onto msg (don't print anything if msg is NIL). Supports any IP master version. pageWidth and pageHeight indicate page size in meters (IP conventions). The IP master is not closed on completion. Generate a compressed master. IP master should be version 2.0 (otherwise why compress it ?). Errors are printed on msg if non-NIL, else raise errors. pageWidth and pageHeight (in meters) should be given as there is no way of recovering them from the source IP master (????). Convert AIS file to IP master. Requires IP master to be at least version 3.1. pageWidth and pageHeight indicate page size in meters (IP conventions). The IP master is not closed on completion. Check for the 0 bit/pixel bitmaps here (Black on white) Convert color AIS file to IP master. Requires IP master to be at least version 3.1. pageWidth and pageHeight indicate page size in meters (IP conventions). The IP master is not closed on completion. Client interface from Interpress files Raised in all procs that read IP masters and have no message stream when the error is not trivial (# classMasterWarning, classAppearanceWarning, classComment) Log the error in clear if msg stream is present otherwise convert into an error. Convert IP file to press file described by an Imager context (obtained through ImagerPress.SimpleCreate). Errors are logged on msg if present, otherwise they are not caught. Return TRUE if anything went wrong. The press file is not terminated on exit, so that IP masters may be concatenated into a single press file. Convert IP master to color/gray AIS file. sPPI and fPPI denote respectively the number of points per inch in the slow & fast scan directions. pageWidth and pageHeight are in meters. Only the 1st page of the master is converted. The suffix .ais is appended to outputBase to form the final file name if gray=TRUE, otherwise the suffixes -red.ais, -green.ais, -blue.ais are appended to outputBase to form the final file names. XC Font translation This is what all this section is about... Command level Relying on doc, and having the install files register commands seems unsafe. Jules Not used anywhere (but not removed in case...) Currently disabled InterpressToJaMAction: ActionProc ~ { Log: Interpress.LogProc ~ { LogError[cmd.out, class, code, explanation] }; interpress: Interpress.Master ~ Interpress.Open[inputName, Log]; stream: IO.STREAM ~ FS.StreamOpen[outputName, $create]; context: Imager.Context ~ ImagerToJaM.Create[stream]; stream.PutRope["% Produced from "]; stream.PutRope[inputName]; stream.PutRope["\n"]; FOR i: INT IN [1..interpress.pages] DO Process.CheckForAbort[]; stream.PutF["%% Page %g\n", IO.int[i]]; Interpress.DoPage[master: interpress, page: i, context: context, log: Log]; ENDLOOP; ImagerToJaM.Close[context]; }; Commander.Register["AISToInterpress", Command, "Convert AIS file to Interpress (output _ input)\n", NEW[ActionProc _ AISToInterpressAction]]; Commander.Register["ColorAISToInterpress", ColorAISToInterpressCommand, "Convert Color AIS file to Interpress (output _ input)\n", NIL]; Commander.Register["InterpressToCompressedIP", Command, "Convert Interpress file to IP master of compressed page bitmaps (output _ input)\n", NEW[ActionProc _ InterpressToCompressedIPAction]]; Commander.Register["InterpressToAIS", Command, "Convert Interpress file to AIS (outputRoot _ input) {Gray} {ppi: }\n", NEW[ActionProc _ InterpressToAISAction]]; Κ#`–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ΟeœI™TK™+K™.K™'K™-K™(K™-K™3K™)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šœ ˜ Kšœ˜Kšœ ˜ Kšžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜—K˜KšΠlnœžœž˜#Kš žœžœ!žœαžœ:žœ4˜Kšžœ˜Kšœž œ ž˜K˜šžœžœžœ˜K˜—head™Kšœžœ Οc#˜8Kšœ žœ  5˜MKšœ žœ 7˜WKšœžœ  ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜K˜—š‘œžœžœ ˜MK˜\šžœžœžœž˜šžœžœžœž˜Kšœ%˜%Kšžœ˜—Kšžœ˜—Kšžœ*˜0Kšœ˜K˜—š‘œžœžœžœKžœžœžœžœ žœžœ˜ΠKšœ’™’Kš‘œD˜GKšœZ˜ZKšœžœO˜WKšœR˜RK•StartOfExpansionw[pixelMap: ImagerPixel.PixelMap, box: SF.Box, scanMode: ImagerTransformation.ScanMode, immutable: BOOL _ FALSE]šœΜžœ˜ΣK–Ζ[deviceSpaceSize: SF.Vec, scanMode: ImagerTransformation.ScanMode, surfaceUnitsPerInch: VEC, pixelUnits: BOOL _ FALSE, fontCacheName: ATOM _ NIL, fontTuner: ImagerDevice.FontTuner _ NIL]šœ±žœ8˜ξK–=[context: Imager.Context, bitmap: ImagerSample.SampleMap]šœK˜KK–?[context: Imager.Context, brick: ImagerBitmapContext.Brick]šœe˜ešžœžœž˜,Kšœžœžœ%žœ˜QKšžœžœ˜—šžœžœžœž˜!š‘ œžœ˜.Kšœ%žœ˜,K–>[context: Imager.Context, pa: ImagerPixelArray.PixelArray]šœ\˜\Kšœ˜—K˜K˜#Kšžœžœžœ˜Kšœ˜KšœL˜LK˜Kšœ>˜>K˜K˜!Kšžœžœžœ˜Kšžœ˜—šžœžœž˜,K–[interval: VM.Interval]šœžœžœ˜CKšžœžœ˜—Kšœ'˜'K˜K˜—š‘œžœžœžœKžœžœžœžœ žœžœ žœžœ˜άKš œžœ žœžœ[žœžœ ’œ™ΐKšœžœ,˜CK˜?Kšœ žœ*˜=K˜cKšœžœžœB˜SKšœžœžœ˜,š‘œžœ˜)š‘œžœ˜Kšœ ˜ KšœN˜NKšœ%˜%Kšœ"˜"Kšœ˜—Kšœ%žœ˜+Kšžœžœžœ!˜˜E—K˜—Kšœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—š‘œž œžœBžœžœžœ žœžœ˜£Kšœδ’œU™ΌKš‘œD˜GK˜Zšžœžœžœž˜!K˜K˜#Kšžœžœžœ˜KšœF˜FK˜K˜!Kšžœžœ˜5Kšžœ˜—Kšœ˜K˜K˜—š‘œž œžœžœžœžœžœžœžœžœ žœžœ˜ΈKšœžœžœΜΟfœ?žœ£œ£ œ£ œ9™§Kš‘ œžœ˜2Kš‘œD˜GKšœžœ˜Kšœžœ˜KšœžœR˜YKšœ˜Kšœ žœžœžœžœžœžœ žœžœ˜XK˜Kšœ˜K˜Kšœ5žœžœžœ%˜mKšœ~žœ˜KšœC˜CKšœ. ˜GK˜AKšœ. ˜GKšœ6˜6K˜GKšžœžœžœ ˜/KšœF˜Fšžœžœ˜Kšœžœ ˜*Kšœ8˜8Kšžœžœžœžœ ˜/K˜—šžœ˜Kšœžœ,˜5Kšœžœ.˜9Kšœžœ-˜7Kšœ7˜7Kšœ9˜9Kšœ8˜8Kš žœžœžœžœ žœžœ ˜UK˜—Kšœ˜K˜——™šžœžœžœžœžœžœžœžœ ˜CK˜—š žœžœ!žœžœžœ˜RK˜—šžœžœžœ!žœ$˜]Kšžœžœ žœ žœ ˜5Kšœ˜K˜—Kš œžœžœžœžœ˜<š œžœžœžœžœžœžœ˜,Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜šžœ˜K˜——š œ žœžœžœžœ9˜UK˜—šœ.žœ˜4Kšœžœ žœ žœ˜'Kšœ˜K˜—šœ-žœ˜3KšžœΟmœ ˜Kšžœ€œ ˜Kšœ˜K˜—šœ,žœ˜2Kšœžœ žœ žœ˜(Kšœžœ žœ žœ˜(Kšœžœ žœ žœ˜(Kšœžœ žœ žœ ˜/Kšœžœ žœ žœ˜(Kšœžœ žœžœ ˜/Kšœžœ žœ žœ˜(Kšœžœ žœ žœ ˜-Kšœžœ žœ žœ ˜-Kšœžœ žœ žœ ˜-Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšœ˜K˜—˜0K™)K˜—š‘ œžœžœ"˜:Kš‘œžœ+žœ˜Bš žœ žœžœžœ"žœ žœž˜Oš žœžœžœžœžœžœž˜?šœ˜KšœP˜PKšœžœV˜bKšœ˜—Kšžœ˜—Kšžœ˜—šžœ žœžœžœžœžœžœ žœž˜Tš žœžœžœžœžœžœž˜?šœ˜KšœV˜VKšœžœb˜nKšœž˜ Kšœ˜—Kšžœ˜—Kšžœ˜—šœ˜Kšœ'˜'KšœžœG˜SKšœ˜—šœ˜Kšœ'˜'Kšœžœ=˜IKšœ˜—šœ˜Kšœ'˜'KšœžœD˜PKšœ˜—Kšœ˜K˜——™ š‘œžœ˜.Kš‘ œ&žœ˜DKš‘œ)˜0Kšœ žœ˜"Kšœ žœ˜"Kš œžœžœžœžœ-žœžœ˜ƒK˜KKšœžœžœ˜BKšœdžœ˜lKšœ˜Kšœ˜K˜—š‘œžœ˜5Kš‘ œ&žœ˜DKš‘œ)˜0Kšœ\˜\K˜sKšœ˜Kšœ˜K˜—š‘œžœ˜,š‘ œ˜Kšžœžœžœžœ˜G—Kš‘œžœžœžœ˜NK˜RK˜{Kšœ˜Kšœ˜K˜—š‘œžœ˜=š ‘ œžœ žœžœžœžœ˜=Kšžœžœžœ˜%šžœžœžœž˜šžœžœžœ˜Kšœžœ"˜,Kš œ žœžœ žœžœžœ ˜`Kšžœ žœžœžœ˜Kšœ˜—Kšžœ˜—K˜—š Πbn œžœ žœžœžœžœ˜VKšœ$žœ˜*Kš žœžœžœžœžœ˜(K˜.Kš žœžœžœžœžœ˜(K˜-Kšœ žœ˜K˜—Kš ‘ œžœžœžœžœ˜VKš‘œžœžœžœ˜BKšœžœ˜Kšœ!˜!Kš œžœžœžœžœ˜,Kšœ žœ˜,Kšœžœ žœ˜2šœ žœ˜Kšœžœžœžœ ˜V—Kšœžœžœ˜,Kšœžœ˜!Kšœžœžœ˜Kšœ žœžœ˜Kšœžœ˜ šžœžœžœ˜K˜Kšœ žœ˜Kšœ"˜"Kšœ˜—KšžœG˜KKšžœ žœžœžœ*˜Hšœ0žœ ˜=Kšžœžœ.žœ˜RKšœ˜—KšžœžœžœžœK˜`šžœžœžœ˜K˜9Kšœ˜—Kšœ1žœ žœ žœ ˜[K˜@Kšžœžœžœ˜$K˜ŒKšœ#˜#Kšžœžœžœ8˜MK˜&Kšœ˜Kšœ˜Kšœ˜Kšžœ ž˜Kšœ˜K˜—š‘œžœ˜.Kš‘ œ&žœ˜DKš‘œ)˜0Kšœ]˜]K˜HKšœ˜Kšœ˜K˜—š‘œžœ˜,Kšœžœ˜/Kšœžœ˜/Kšœžœ ˜;Kšœžœ ˜:Kšœžœžœ˜–[self: STREAM]šžœžœž˜K–\[base: ROPE, start: INT _ 0, len: INT _ 2147483647, translator: Rope.TranslatorType]šœžœ˜ Kšžœžœžœžœ˜šžœžœž˜Kšœžœ žœ˜0K– [r: ROPE]šœžœŒ˜«K– [r: ROPE]šœžœ|˜œK– [r: ROPE]šœžœ|˜œ– [r: ROPE]šœžœ˜&K˜nK˜nK˜—Kšžœ?˜F—Kšžœ˜—K˜sKšœ˜K˜—š ‘ œžœ žœžœžœ˜7Kšœ žœžœ˜Kšœ žœ˜-Kšžœ ˜Kšœ˜K˜—– "cedar" styleš‘ œžœ žœžœžœžœžœ˜D– "cedar" styleš ‘ œžœžœžœžœ˜;Kš žœ žœ žœ žœžœ ˜;Kšžœ žœ žœ žœ žœ žœžœ˜VKšžœ ˜Kšœ˜—K– "cedar" stylešœ+žœžœ˜MKšœ˜K˜—– "cedar" styleš‘œžœ žœžœžœžœžœ˜I– "cedar" styleš ‘œžœžœžœžœ˜@Kšžœ žœžœ ˜!Kšžœ žœ žœ žœ žœ žœžœ˜VKšžœ ˜Kšœ˜—K– "cedar" stylešœ0žœžœ˜RKšœ˜K˜—– "cedar" styleš ‘ œžœžœžœžœ˜8K– "cedar" stylešœžœžœ˜K– "cedar" stylešœ<žœžœ˜MK– "cedar" styleš žœžœ žœ=žœžœ˜iK– "cedar" stylešžœžœ2˜>Kšœ˜K˜—š ‘œžœžœ žœžœ˜0K˜—š ‘ œžœžœžœžœ˜/Kš žœžœžœ žœ žœ˜5Kšœ˜K˜—š ‘œžœ žœžœžœžœ˜DKšœN ™TKšœžœ%˜/Kšœžœ2˜:Kšœžœ˜Kšœžœ9žœ˜KKšœžœ˜+šžœ ˜KšœE˜EKšžœžœžœžœ˜Kšžœžœžœžœ2˜HKšœ˜—Kšœ˜K˜—š‘œžœ˜)Kšœ žœžœ˜K–[format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šžœ žœ žœU˜tK–[format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]š žœžœžœžœ žœŠ˜ΙK˜K˜—Kšœžœžœ˜+Kšœžœ-˜9–"[name: ROPE, wDir: ROPE _ NIL]š œ žœžœžœžœžœ ˜+K˜—š ‘ œžœ žœžœžœ˜7š žœžœžœžœžœžœž˜@KšœžœžœC˜RKš žœ#žœžœ žœžœžœ˜eKšžœ˜—Kšœ žœ@˜KKšœ˜—š‘œžœ žœžœžœžœžœ˜HKšžœžœ;žœ0˜uK˜K˜——™š‘œ™%Kš‘œG™JKšœ@™@Kšœžœžœžœ!™7Kšœ5™5Kšœ#™#Kšœ™Kšœ™šžœžœžœž™&K™Kšœžœ ™'KšœK™KKšžœ™—Kšœ™Kšœ™K™—Kšœržœ(˜Kšœdžœ&™Kšœƒžœ™ˆKšœhžœ(˜“KšœŽžœ/™ΐKšœˆžœ&™±—Kšžœ˜K˜—…—dξ˜V