IPtoPSCmdImpl.mesa
Copyright Ó 1987, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, August 2, 1993 10:41 am PDT
Jules Bloomenthal June 8, 1993 2:37 pm PDT
Willie-s, June 1, 1992 10:33 am PDT
Command Level Procedures for Interpress to PostScript
DIRECTORY Atom, Commander, CommanderOps, Convert, FS, Imager, ImagerBox, ImagerError, ImagerMaskCapture, ImagerTransformation, InterpressInterpreter, IPtoPS, IO, IPMaster, Process, Rope, SF;
IPtoPSCmdImpl: CEDAR PROGRAM
IMPORTS Atom, Commander, CommanderOps, Convert, FS, Imager, ImagerBox, ImagerError, ImagerMaskCapture, ImagerTransformation, InterpressInterpreter, IPtoPS, IO, IPMaster, Process, Rope
~ BEGIN
ROPE:  TYPE ~ Rope.ROPE;
Master: TYPE ~ InterpressInterpreter.Master;
LogError: PROC [out: IO.STREAM, class: INT, code: ATOM, explanation: ROPE] ~ {
IO.PutRope[out, 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: "]
];
IO.PutRope[out, explanation];
IO.PutRope[out, " . . . "];
};
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 ¬ IO.GetTokenRope[stream, CmdTokenBreak ! IO.EndOfStream => CONTINUE].token;
};
GetToken: PROC [stream: IO.STREAM] RETURNS [rope: ROPE ¬ NIL] ~ {
TokenBreak: 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 ¬ IO.GetTokenRope[stream, TokenBreak ! IO.EndOfStream => CONTINUE].token;
};
Encapsulate: PROC [ip: Master] RETURNS [ROPE] ~ {
Op: PROC [context: Imager.Context] ~ {
Imager.SetColor[context, Imager.black];
Imager.SetStrokeEnd[context, square];
Imager.SetStrokeWidth[context, 0.0];
Imager.SetAmplifySpace[context, 1.0];
InterpressInterpreter.DoPage[ip, 1, context, NIL];
};
m: Imager.Transformation ¬ ImagerTransformation.Scale[150.0/0.0254]; -- ~150 pixels/inch
n: Imager.Transformation ¬ ImagerTransformation.PostScale[m, 0.0254]; -- back to inches
b: SF.Box ¬ ImagerMaskCapture.CaptureBounds[Op, m ! ImagerMaskCapture.Cant =>RESUME];
r: ImagerBox.Rectangle ¬ ImagerTransformation.InverseTransformRectangle[
n, ImagerBox.RectangleFromBox[[b.min.s, b.min.f, b.max.s, b.max.f]]];
RETURN[IO.PutFLR["%%BoundingBox: %g %g %g %g",
LIST[IO.real[72.0*r.x], IO.real[72.0*r.y], IO.real[72.0*(r.x+r.w)], IO.real[72.0*(r.y+r.h)]]] ];
Should be <xleft> <y1ower> <xright> <yupper>, in points, Postscript origin at lower left.
};
Command: Commander.CommandProc ~ {
ENABLE IPMaster.Error => {msg ¬ error.explanation; GOTO Bad};
Log: InterpressInterpreter.LogProc ~ {
LogError[cmd.out, class, ImagerError.AtomFromErrorCode[code], explanation];
};
Translate: PROC RETURNS [warns: ROPE ¬ NIL] ~ {
ENABLE IPtoPS.Warn => {warns ¬ Rope.Cat[warns, "\n\t", reason]; RESUME};
nBad: INTEGER ¬ 0;
user: ROPE ¬ NARROW[CommanderOps.GetProp[NIL, $USER]];
debugStream: IO.STREAM ¬ IF debug THEN cmd.out ELSE NIL;
comment: ROPE ¬ IF encapsulate THEN Encapsulate[ip] ELSE NIL;
c: Imager.Context ~ IPtoPS.Create[out, ip.pages, user, comment, compact, debugStream];
FOR i: INT IN [1..ip.pages] DO
Page: PROC ~ {
Imager.ScaleT[c, 72.0/0.0254];
InterpressInterpreter.DoPage[master: ip, page: i, context: c, log: Log];
};
Process.CheckForAbort[];
IO.PutF1[cmd.out, "[%g", IO.int[i]];
IO.PutF1[out, "%%%%page %g\n", IO.int[i]];
Imager.DoSave[c, Page];
IO.PutF1[out, "%% end page %g\n", IO.int[i]];
IO.PutRope[out, "showpage\n"];
IO.PutRope[cmd.out, "] "];
ENDLOOP;
IO.PutF1[out, "\n%%%%Trailer\n%%%%Pages: %g\n", IO.int[ip.pages]];
warns ¬ Rope.Concat[warns, SELECT (nBad ¬ IPtoPS.NInvalidChars[c]) FROM
1 => "\n\t1 invalid char (replaced with a space)",
> 1 => IO.PutFR1["\n\t%g invalid chars (replaced with spaces)", IO.int[nBad]],
ENDCASE => NIL];
IPtoPS.Close[c];
};
ip: Master;
out: IO.STREAM;
warnings, input, output: ROPE ¬ NIL;
compact, debug, encapsulate: BOOL ¬ FALSE;
argv: CommanderOps.ArgumentVector ¬ CommanderOps.Parse[cmd];
Atom.PutProp[$IPtoPSDebug, $Out, cmd.out];
FOR i: INTEGER IN [1..argv.argc) DO
SELECT TRUE FROM
Rope.Equal[argv[i], "-compact"] => compact ¬ TRUE;
Rope.Equal[argv[i], "-debug"] => debug ¬ TRUE;
Rope.Equal[argv[i], "-encapsulate"] => encapsulate ¬ TRUE;
Rope.Equal[argv[i], "←"] =>
IF i IN (1..argv.argc-1)
THEN {
output ¬ argv[i-1];
input ¬ argv[i+1];
}
ELSE RETURN[$Failure, doc];
ENDCASE => input ¬ argv[i]
ENDLOOP;
IF Rope.IsEmpty[input] THEN RETURN[$Failure, doc];
input ¬ FS.FileInfo[input ! FS.Error => {msg ¬ error.explanation; GOTO Bad}].fullFName;
IF Rope.IsEmpty[output] THEN {
cp: FS.ComponentPositions;
[input, cp] ¬ FS.ExpandName[input];
output ¬ Rope.Cat[Rope.Substr[input, cp.base.start, cp.base.length], ".", "ps"];
};
ip ¬ InterpressInterpreter.Open[input, Log];
IF encapsulate AND ip.pages > 1 THEN RETURN[
$Failure, IO.PutFR1["%g pages (encapsulated PS must be one page)", IO.int[ip.pages]]];
out ¬ FS.StreamOpen[output, create];
IO.PutF1[cmd.out, "Reading %g . . . ", IO.rope[input]];
warnings ¬ Translate[ !
IPMaster.Error => {msg ¬ error.explanation; GOTO Bad};
FS.Error => {msg ¬ error.explanation; GOTO Bad}
];
output ¬ FS.FileInfo[output ! FS.Error => {output ¬ "Output file(s)"; CONTINUE}].fullFName;
IF warnings # NIL THEN IO.PutF1[cmd.out, "\nWarnings:%g\n", IO.rope[warnings]];
IO.PutF1[cmd.out, "%g written.\n", IO.rope[output]];
EXITS Bad => RETURN[$Failure, IF Rope.IsEmpty[msg] THEN doc ELSE Rope.Concat["\n", msg]];
};
doc: ROPE ~ "
convert Interpress file to PostScript file; usage:
IPtoPS (InterpressToPostscript) [<output> ← ] <input> [-<option>]
the -encapsulate option will produce encapsulated PostScript
the -compact option will produce a more compact PostScript\n";
Commander.Register["InterpressToPostscript", Command, doc];
Commander.Register["IPtoPS", Command, doc];
END.