<<>> <> <> <> <> <> <> <> <> <> <> <> 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['©, 0, 323B], C1['®, 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]]; <> <}\n", NEW[ActionProc _ InterpressToAISAction]];>> END.