DIRECTORY Commander, Convert, FileNames, FS, Imager, ImagerError, ImagerFontFilter, ImagerInterpress, ImagerPress, InterpressInterpreter, IO, PressConverters, Process, Rope, ShowPress; PressConvertersCommand: CEDAR PROGRAM IMPORTS Commander, Convert, FileNames, FS, Imager, ImagerError, ImagerFontFilter, ImagerInterpress, ImagerPress, InterpressInterpreter, IO, Process, Rope, ShowPress EXPORTS PressConverters ~ BEGIN ROPE: TYPE ~ Rope.ROPE; ActionProc: TYPE ~ PressConverters.ActionProc; ProgressProc: TYPE ~ PressConverters.ProgressProc; 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; }; 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 InterpressInterpreter.classMasterError, InterpressInterpreter.classAppearanceError => ERROR IPReadError[class, code, explanation]; InterpressInterpreter.classMasterWarning, InterpressInterpreter.classAppearanceWarning, InterpressInterpreter.classComment => NULL; -- ignore those ENDCASE => ERROR IPReadError[class, code, explanation]; } ELSE { msg.PutRope[ SELECT class FROM InterpressInterpreter.classMasterError => "Master Error: ", InterpressInterpreter.classMasterWarning => "Master Warning: ", InterpressInterpreter.classAppearanceError => "Appearance Error: ", InterpressInterpreter.classAppearanceWarning => "Appearance Warning: ", InterpressInterpreter.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: InterpressInterpreter.LogProc ~ { IPReadLog[msg, class, ImagerError.AtomFromErrorCode[code], explanation]; }; input: InterpressInterpreter.Master ¬ InterpressInterpreter.Open[FileNames.ResolveRelativePath[inputName], Log]; FOR i: INT IN [1..input.pages] DO Process.CheckForAbort[]; failed ¬ beginPage[i, input.pages]; IF failed THEN EXIT; InterpressInterpreter.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; InterpressInterpreter.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.Concat[xcFontBase, "Logotypes-Xerox"], charMap: alphaMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mrr", output: LIST[[newName: Rope.Concat[xcFontBase, "Modern"], charMap: mathMap]] ]]; Enter[[ inputName: "Xerox/Pressfonts/Math-mir", output: LIST[[newName: Rope.Concat[xcFontBase, "Modern-italic"], charMap: mathMap]] ]]; }; PressToInterpressAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ {cmd.out.PutF1["[%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]; }; InterpressToPressAction: PUBLIC ActionProc ~ { BeginPage: ProgressProc ~ {cmd.out.PutF1["[%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]; }; 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 }; 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. œ PressConvertersCommand.mesa Copyright Σ 1984, 1985, 1986, 1990, 1992 by Xerox Corporation. All rights reserved. Michael Plass, November 2, 1990 1:14 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, July 10, 1992 1:19 pm PDT Beretta:PARC:Xerox (8*923-4484) August 31, 1989 4:39:01 pm PDT Willie-s, July 22, 1992 12:35 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. 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. 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 Commands Κz•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ΟeœI™TK™+K™.K™'K™-K™(K™-K™3K™&K™>K™$—K˜KšΟk œ žœ_žœ,˜ΈK˜KšΠlnœžœž˜%Kšžœ žœ_žœ˜€Kšžœ˜Kšœž˜K˜šžœžœžœ˜K˜—head™Kšœ žœ˜.Kšœžœ ˜2K˜Kšœžœ Οc#˜8Kšœ žœ  5˜MKšœ žœ 7˜WKšœžœ  ˜˜E—K˜—Kšœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—š‘œž œžœBžœžœžœ žœžœ˜£Kšœδ’œU™Όš‘œ#˜&K˜HK˜—Kšœp˜pšžœžœžœž˜!K˜K˜#Kšžœžœžœ˜KšœQ˜QK˜K˜!Kšžœžœ˜5Kšžœ˜—Kšœ#˜#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šœžœJ˜VKšœ˜—šœ˜Kšœ'˜'Kšœžœ@˜LKšœ˜—šœ˜Kšœ'˜'KšœžœG˜SKšœ˜—Kšœ˜K˜——™ š‘œžœ˜.Kš‘ œ'žœ˜EKš‘œ)˜0Kšœ žœ˜"Kšœ žœ˜"Kš œžœžœžœžœ-žœžœ˜ƒK˜KKšœžœžœ˜BKšœdžœ˜lKšœ˜Kšœ˜K˜—š‘œžœ˜.Kš‘ œ'žœ˜EKš‘œ)˜0Kšœ]˜]K˜HKšœ˜Kšœ˜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šœ žœžœ˜