DIRECTORY Atom, ViewerClasses, TiogaMenuOps, Convert, Commander, FS, Imager, ImagerInterpress, Interpress, IO, Rope, TiogaAccess; InterpressToTiogaArtworkImpl: CEDAR PROGRAM IMPORTS TiogaMenuOps, Convert, Commander, FS, Imager, ImagerInterpress, Interpress, IO, Rope, TiogaAccess ~ BEGIN ROPE: TYPE ~ Rope.ROPE; ActionProc: TYPE ~ PROC [data: ParsedCommand, cmd: Commander.Handle]; Log: Interpress.LogProc ~ { cmd: Commander.Handle ~ NARROW[master.logData]; msg: IO.STREAM ~ cmd.out; msg.PutRope[ SELECT class FROM masterError => "Master Error: ", masterWarning => "Master Warning: ", appearanceError => "Appearance Error: ", appearanceWarning => "Appearance Warning: ", comment => "Comment: ", ENDCASE => NIL ]; msg.PutRope[explanation]; msg.PutRope[" . . . "]; }; Error: ERROR [rope: ROPE] ~ CODE; GetIPFragment: PROC [data: ParsedCommand, cmd: Commander.Handle] RETURNS [ROPE] ~ { inputMaster: Interpress.OpenMaster ~ Interpress.Open[data.inputName, Log, cmd]; ros: IO.STREAM ~ IO.ROS[]; outputMaster: ImagerInterpress.Ref ~ ImagerInterpress.CreateFromStream[ros, "Interpress/Xerox/3.0 "]; action: PROC [context: Imager.Context] ~ { IF data.scale # 1.0 THEN Imager.ScaleT[context, data.scale]; IF data.clip THEN Imager.ClipRectangle[context, [0, -data.depth, data.width, data.height+data.depth]]; Imager.TranslateT[context, [-data.leftMargin, data.topMargin-data.pageHeight+data.height]]; Interpress.DoPage[master: inputMaster, context: context, page: data.page]; }; IF data.page NOT IN [1..inputMaster.pages] THEN Error["Page number out of range"]; ImagerInterpress.DoPage[outputMaster, action, 1.0]; ImagerInterpress.Finish[outputMaster]; RETURN [IO.RopeFromROS[ros]]; }; vanillaTC: TiogaAccess.TiogaChar ~ [ charSet: 0, char: '\n, looks: ALL[FALSE], format: $default, comment: FALSE, endOfNode: FALSE, deltaLevel: 0, propList: NIL ]; InterpressToTiogaArtworkAction: PROC [data: ParsedCommand, cmd: Commander.Handle] ~ { ipFragment: ROPE ~ GetIPFragment[data, cmd]; writer: TiogaAccess.Writer _ TiogaAccess.Create[]; tc: TiogaAccess.TiogaChar _ [ charSet: 0, char: '\n, looks: ALL[FALSE], format: $default, comment: TRUE, endOfNode: FALSE, deltaLevel: 1, propList: NIL ]; PutRope: PROC [rope: ROPE] ~ { action: Rope.ActionType ~ {tc.char _ c; TiogaAccess.Put[writer, tc]}; [] _ Rope.Map[base: rope, action: action]; }; PutLooksRope: PROC [rope: ROPE, look1, look2: CHAR _ '\000] ~ { save: TiogaAccess.Looks ~ tc.looks; IF look1 # '\000 THEN tc.looks[look1] _ TRUE; IF look2 # '\000 THEN tc.looks[look2] _ TRUE; PutRope[rope]; tc.looks _ save; }; PutRopeProp: PROC [key: ATOM, val: ROPE] ~ { tc.propList _ CONS[NEW[Atom.DottedPairNode _ [key: key, val: val]], tc.propList]; }; sepNeeded: BOOL _ FALSE; Sp: PROC ~ {PutRope[" "]; sepNeeded _ FALSE}; Comma: PROC ~ {IF sepNeeded THEN PutRope[", "]; sepNeeded _ FALSE}; Putmm: PROC [meters: REAL] ~ { PutLooksRope[Convert.RopeFromReal[meters*1000], 'f]; PutLooksRope["mm", 's, 'o]; sepNeeded _ TRUE; }; PutKey: PROC [rope: ROPE] ~ { Comma[]; PutLooksRope[rope, 'o]; PutLooksRope[": ", 'o]; sepNeeded _ TRUE; }; PutKeyMeters: PROC [name: ROPE, meters, defaultMeters: REAL] ~ { IF meters#defaultMeters THEN {PutKey[name]; Putmm[meters]}; }; tc.endOfNode _ TRUE; PutRope["\n"]; tc.endOfNode _ FALSE; PutLooksRope["Interpress Artwork", 'n]; PutRope[": "]; PutRope[data.inputName]; Sp[]; PutKeyMeters["pageHeight", data.pageHeight, default.pageHeight]; PutKeyMeters["pageWidth", data.pageWidth, default.pageWidth]; PutKeyMeters["topMargin", data.topMargin, default.topMargin]; PutKeyMeters["height", data.height, default.height]; PutKeyMeters["depth", data.depth, default.depth]; PutKeyMeters["width", data.width, default.width]; PutKeyMeters["topSpace", data.topSpace, default.topSpace]; PutKeyMeters["bottomSpace", data.bottomSpace, default.bottomSpace]; IF data.page#default.page THEN {PutKey["page"]; PutLooksRope[Convert.RopeFromInt[data.page], 'f]}; IF data.scale#default.scale THEN {PutKey["scale"]; PutLooksRope[Convert.RopeFromReal[data.scale], 'f]}; IF data.clip THEN {PutKey["clip"]; PutLooksRope["TRUE", 'o, 's]}; PutRopeProp[$Postfix, Rope.Cat[ Convert.RopeFromReal[(data.height+data.topSpace)*1000*data.scale], " mm topLeading ", Convert.RopeFromReal[(data.height+data.topSpace)*1000*data.scale], " mm topIndent " ].Cat[ Convert.RopeFromReal[(data.depth+data.bottomSpace)*1000*data.scale], " mm bottomLeading ", Convert.RopeFromReal[data.width*1000*data.scale], " mm lineLength " ]]; PutRopeProp[$Bounds, Rope.Cat[ Convert.RopeFromReal[-data.depth*1000*data.scale], " mm ymin ", Convert.RopeFromReal[data.width*1000*data.scale], " mm xmax " ].Cat[ Convert.RopeFromReal[data.height*1000*data.scale], " mm ymax " ]]; PutRopeProp[$Artwork, "Interpress"]; PutRopeProp[$Interpress, ipFragment]; tc.endOfNode _ TRUE; tc.deltaLevel _ 1; tc.char _ '\n; TiogaAccess.Put[writer, tc]; tc _ vanillaTC; PutRope[" Insert caption here "]; tc.endOfNode _ TRUE; tc.char _ '\n; tc.format _ $caption; TiogaAccess.Put[writer, tc]; IF data.outputName # NIL THEN { TiogaAccess.WriteFile[writer, data.outputName]; } ELSE { wdstar: ROPE ~ FS.ExpandName["*"].fullFName; wd: ROPE ~ wdstar.Substr[0, wdstar.Size-1]; viewer: ViewerClasses.Viewer _ TiogaMenuOps.Open[wd]; TiogaAccess.WriteViewer[writer, viewer]; }; }; FindFullName: PROC [inputName: ROPE] RETURNS [ROPE] ~ { fullFName: ROPE _ NIL; fullFName _ FS.FileInfo[inputName].fullFName; RETURN [fullFName] }; CmdTokenBreak: 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]; }; GetCmdToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE] = { rope _ NIL; rope _ stream.GetTokenRope[CmdTokenBreak ! IO.EndOfStream => CONTINUE].token; }; NameBreak: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = ': OR char = '= OR char = '~ THEN RETURN [break]; IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetName: PROC [stream: IO.STREAM] RETURNS [name: ROPE] ~ { name _ NIL; name _ IO.GetTokenRope[stream, NameBreak ! IO.EndOfStream => CONTINUE].token; }; ParseError: ERROR [msg: ROPE, index: INT] ~ CODE; RaiseParseError: PROC [stream: IO.STREAM, msg: ROPE] ~ { ERROR ParseError[msg, stream.GetIndex]; }; GetMeters: PROC [stream: IO.STREAM] RETURNS [REAL] = { r: REAL _ IO.GetReal[stream]; unit: ROPE _ GetName[stream]; multipler: REAL _ SELECT TRUE FROM unit.Equal["in"] => 0.0254, unit.Equal["pt"] => 0.0254/72.27, unit.Equal["cm"] => 0.01, unit.Equal["mm"] => 0.001, unit.Equal["bp"] => 0.0254/72.0, ENDCASE => 0.0; IF multipler = 0.0 THEN RaiseParseError[stream, "Unknown unit: "]; RETURN [r*multipler]; }; ParsedCommand: TYPE ~ REF ParsedCommandRep; ParsedCommandRep: TYPE ~ RECORD [ outputName, inputName: ROPE _ NIL, page: INT _ 1, pageHeight, pageWidth, topMargin, leftMargin, height, depth, width, topSpace, bottomSpace: REAL _ 0.0, scale: REAL _ 1.0, clip: BOOL _ FALSE ]; Parse: PROC [stream: IO.STREAM] RETURNS [data: ParsedCommand] ~ { outputName: ROPE _ GetCmdToken[stream]; secondTokenIndex: INT _ stream.GetIndex; gets: ROPE _ GetCmdToken[stream]; inputName: ROPE _ NIL; IF NOT gets.Equal["_"] THEN { inputName _ outputName; outputName _ NIL; stream.SetIndex[secondTokenIndex]; } ELSE {inputName _ GetCmdToken[stream]}; IF inputName = NIL THEN RaiseParseError[stream, docRope]; inputName _ FindFullName[inputName]; data _ NEW[ParsedCommandRep _ default]; data.outputName _ outputName; data.inputName _ inputName; DO keyword: ROPE _ GetName[stream]; colon: ROPE _ GetName[stream]; c: CHAR _ '\000; IF keyword = NIL THEN EXIT; IF colon.Size = 1 AND ((c_colon.Fetch[0])=': OR c='= OR c = '~) THEN NULL ELSE RaiseParseError[stream, "Colon expected after keyword: "]; SELECT TRUE FROM keyword.Equal["Page", FALSE] => data.page _ IO.GetInt[stream]; keyword.Equal["PageHeight", FALSE] => data.pageHeight _ GetMeters[stream]; keyword.Equal["PageWidth", FALSE] => data.pageWidth _ GetMeters[stream]; keyword.Equal["TopMargin", FALSE] => data.topMargin _ GetMeters[stream]; keyword.Equal["LeftMargin", FALSE] => data.leftMargin _ GetMeters[stream]; keyword.Equal["Height", FALSE] => data.height _ GetMeters[stream]; keyword.Equal["Depth", FALSE] => data.depth _ GetMeters[stream]; keyword.Equal["Width", FALSE] => data.width _ GetMeters[stream]; keyword.Equal["Scale", FALSE] => data.scale _ IO.GetReal[stream]; keyword.Equal["Clip", FALSE] => data.clip _ IO.GetBool[stream]; ENDCASE => RaiseParseError[stream, "Unknown keyword parameter: "]; ENDLOOP; }; Command: Commander.CommandProc ~ { stream: IO.STREAM _ IO.RIS[cmd.commandLine]; refAction: REF ActionProc ~ NARROW[cmd.procData.clientData]; data: ParsedCommand; data _ Parse[stream ! ParseError => { start: INT _ MAX[index-10, 0]; cmd.out.PutRope[msg]; IF start > 0 THEN cmd.out.PutRope["..."]; cmd.out.PutRope[cmd.commandLine.Substr[start, index-start]]; IF index > 1 THEN cmd.out.PutRope["..."]; cmd.out.PutRope["\n"]; GOTO Quit }; FS.Error => { cmd.out.PutRope[error.explanation]; cmd.out.PutRope["\n"]; GOTO Quit }; ]; IF data.height*data.scale > maxSafeHeight THEN { cmd.out.PutRope["Warning: height is too large for proper refresh\n"]; }; IF data.depth*data.scale > maxSafeDepth THEN { cmd.out.PutRope["Warning: depth is too large for proper refresh\n"]; }; cmd.out.PutRope["Reading "]; cmd.out.PutRope[data.inputName]; cmd.out.PutRope[" . . . "]; refAction^[data, cmd ! Error => { cmd.out.PutRope[rope]; cmd.out.PutRope["\n"]; GOTO Quit }]; IF data.outputName # NIL THEN { data.outputName _ FindFullName[data.outputName]; cmd.out.PutRope[data.outputName]; cmd.out.PutRope[" written.\n"]; } ELSE cmd.out.PutRope[" ok.\n"]; EXITS Quit => {} }; inch: REAL ~ 0.0254; bp: REAL _ inch/72.0; maxSafeHeight: REAL _ 512*bp; maxSafeDepth: REAL _ 128*bp; default: ParsedCommandRep _ [ page: 1, topMargin: 1*inch, pageHeight: 11*inch, pageWidth: 8.5*inch, leftMargin: 1*inch, height: 9*inch, depth: 0*inch, width: 6.5*inch, topSpace: 4*bp, bottomSpace: 8*bp, scale: 1.0, clip: FALSE ]; docRope: ROPE ~ "[ _] page: 1, topMargin: 1 in, leftMargin: 1 in, height: 9 in, depth: 0 in, width: 6.5 in, scale: 1, topSpace: 4 bp, bottomSpace: 8 bp, clip: FALSE"; Commander.Register["InterpressToTiogaArtwork", Command, Rope.Cat["Convert Interpress file to Tioga\n ", docRope, "\n"], NEW[ActionProc _ InterpressToTiogaArtworkAction]]; END. œInterpressToTiogaArtworkImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Michael Plass, September 6, 1985 6:00:32 pm PDT Κ Ε˜codešœ!™!Kšœ Οmœ7™BK™/—K˜JšΟk œ8žœ(žœ˜K˜KšΠlnœžœž˜+Kšžœ#žœ(žœ˜iKšœž˜K˜šžœžœžœ˜K˜—šœ žœžœ.˜EK˜—šΟnœ˜Kšœžœ˜/Kšœžœžœ ˜šœ ˜ šžœž˜Kšœ ˜ Kšœ$˜$Kšœ(˜(Kšœ,˜,Kšœ˜Kšžœž˜—K˜—Kšœ˜Kšœ˜Kšœ˜K˜—šœžœžœžœ˜!K˜—š  œžœ.žœžœ˜SKšœO˜OKš œžœžœžœžœ˜Kšœe˜ešœžœ˜*Kšžœžœ$˜˜>K˜—Kšœ$˜$Kšœ%˜%Kšœžœ˜K˜Kšœ˜Kšœ˜K˜Kšœ#˜#Kšœžœ˜Kšœ˜K˜Kšœ˜šžœžœžœ˜Kšœ/˜/Kšœ˜—šžœ˜Kšœžœžœ˜,Kšœžœ#˜+Kšœ5˜5Kšœ(˜(Kšœ˜—Kšœ˜K˜—š   œžœ žœžœžœ˜7Kšœ žœžœ˜Kšœ žœ˜-Kšžœ ˜Kšœ˜K˜—– "cedar" styleš   œžœžœžœžœ˜;Kšžœ žœžœ ˜!Kšžœ žœ žœ žœ žœ žœžœ˜VKšžœ ˜Kšœ˜K˜—– "cedar" styleš   œžœ žœžœžœžœ˜>K– "cedar" stylešœžœ˜ K– "cedar" stylešœ+žœžœ˜MKšœ˜K˜—– "cedar" styleš   œžœžœžœžœ˜7Jš žœ žœ žœ žœžœ ˜;Jšžœ žœ žœ žœ žœ žœžœ˜UJšžœ ˜Jšœ˜—J– "cedar" style˜š  œžœ žœžœžœžœ˜:Jšœžœ˜ Jšœžœ"žœžœ˜MJ˜J˜—K– "cedar" styleš œ žœžœ žœžœ˜1– "cedar" styleš  œžœ žœžœžœ˜8Kšžœ"˜'Kšœ˜K˜—– "cedar" styleš   œžœ žœžœžœžœ˜6Jšœžœžœ˜Jšœžœ˜šœ žœžœžœž˜"Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšœ ˜ Jšžœ˜—Jšžœžœ+˜BJšžœ˜Jšœ˜J˜—J– "cedar" stylešœžœžœ˜+– "cedar" stylešœžœžœ˜!J– "cedar" stylešœžœžœ˜"J– "cedar" stylešœžœ˜J– "cedar" stylešœ[žœ˜fJ– "cedar" stylešœžœ˜J– "cedar" stylešœžœž˜J– "cedar" stylešœ˜J– "cedar" style˜—š  œžœ žœžœžœ˜AKšœ žœ˜'Kšœžœ˜(Kšœžœ˜!Kšœ žœžœ˜šžœžœžœ˜Kšœ˜Kšœ žœ˜Kšœ"˜"Kšœ˜—Kšžœ#˜'Kšžœ žœžœ"˜9Kšœ$˜$Jšœžœ˜'Jšœ˜Jšœ˜šž˜Jšœ žœ˜ Jšœžœ˜Jšœžœ ˜Jšžœ žœžœžœ˜Jš žœžœžœžœ žœž˜IJšžœ;˜?šžœžœž˜Jšœžœžœ˜>Jšœžœ)˜JJšœžœ(˜HJšœžœ(˜HJšœžœ)˜JJšœžœ%˜BJšœžœ$˜@Jšœžœ$˜@Jšœžœžœ˜AJšœžœžœ˜?Jšžœ;˜B—Jšžœ˜—Kšœ˜K˜—š œ˜"Kš œžœžœžœžœ˜,Kšœ žœžœ˜