InterpressBookletImpl.mesa
Copyright © 1987 by Xerox Corporation. All rights reserved.
Wes Irish, December 3, 1987 4:14:02 pm PST
InterpressBooklet creates a new Interpress master from an existing Interpress master. The input master is assumed to be a multiple-page Interpress master intended for 8-1/2 x 11 printing. When the resulting master is printed on a double sided 8-1/2 x 11 printer, and the pages folded in half, a "booklet" results. The pages of the resulting booklet will all be in the correct order with page one being the first or "cover" page.
The style CedarBooklet.style generates a print area appropriate for a booklet, no scaling is needed or done. If your document wasn't created with CedarBooklet.style then you may want InterpressBooklet to scale down the original so that if fits on the now 5.5 x 8.5 page, use the -f option for this purpose.
DIRECTORY
Commander USING [CommandProc, Handle, Register],
CommandTool USING [ArgumentVector, Parse, Failed],
Convert USING [RealFromRope],
FS USING [Error],
Imager USING [Context, DoSave, RotateT, ScaleT, TranslateT],
ImagerInterpress USING [Close, Create, DoPage, Ref ],
Interpress USING [DoPage, LogProc, Master, Open ],
IO USING [PutF, STREAM],
Rope USING [ ROPE, Fetch, Equal, Length, Substr ];
InterpressBookletImpl: CEDAR PROGRAM
IMPORTS Commander, CommandTool, Convert, FS, Imager, ImagerInterpress, Interpress, IO, Rope ~ {
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
paperWidth: REAL ← 0.01 * 2.54 * 8.5; -- meters
paperHight: REAL ← 0.01 * 2.54 * 11.0; -- meters
defaultScaleFactor: REAL = (paperHight*0.5)/paperWidth;
scaleFactor: REAL ← defaultScaleFactor;
scaleIt: BOOLFALSE;
input: ROPE;
output: ROPE;
Booklet: PROC [output, input: ROPE, logProc: Interpress.LogProc, ms: STREAM] ~ {
ref: ImagerInterpress.Ref ~ ImagerInterpress.Create[fileName: output];
master: Interpress.Master ~ Interpress.Open[fileName: input, log: logProc];
inPages: INT = master.pages;
outPages: INT = (inPages+3)/4;
lowPage: INT ← 1;
highPage: INT ← outPages * 4;
WriteSide1: PROC [context: Imager.Context] ~ {
LowPageAction: PROC ~ {
IF lowPage > inPages THEN RETURN;
Imager.TranslateT[context, [paperWidth, paperHight/2.0]];
IF scaleIt THEN Imager.ScaleT[context, scaleFactor];
Imager.RotateT[context, 90.0];
Interpress.DoPage[master: master, page: lowPage, context: context, log: logProc];
lowPage ← lowPage + 1;
};
HighPageAction: PROC ~ {
IF highPage > inPages THEN {highPage ← highPage - 1; RETURN};
Imager.TranslateT[context, [paperWidth, 0]];
IF scaleIt THEN Imager.ScaleT[context, scaleFactor];
Imager.RotateT[context, 90.0];
Interpress.DoPage[master: master, page: highPage, context: context, log: logProc];
highPage ← highPage - 1;
};
Imager.DoSave[context, LowPageAction];
Imager.DoSave[context, HighPageAction];
};
WriteSide2: PROC [context: Imager.Context] ~ {
LowPageAction: PROC ~ {
IF lowPage > inPages THEN RETURN;
Imager.TranslateT[context, [0, paperHight]];
IF scaleIt THEN Imager.ScaleT[context, scaleFactor];
Imager.RotateT[context, 270.0];
Interpress.DoPage[master: master, page: lowPage, context: context, log: logProc];
lowPage ← lowPage + 1;
};
HighPageAction: PROC ~ {
IF highPage > inPages THEN {highPage ← highPage - 1; RETURN};
Imager.TranslateT[context, [0, paperHight/2.0]];
IF scaleIt THEN Imager.ScaleT[context, scaleFactor];
Imager.RotateT[context, 270.0];
Interpress.DoPage[master: master, page: highPage, context: context, log: logProc];
highPage ← highPage - 1;
};
Imager.DoSave[context, LowPageAction];
Imager.DoSave[context, HighPageAction];
};
ms.PutF["Making booklet %g (%g/4 pages) from %g (%g input pages) ... ",
[rope[output]],
[integer[outPages*4]],
[rope[input]],
[integer[inPages]]];
WHILE lowPage < highPage DO
ms.PutF["[%g] [%g", [integer[(lowPage*2)-1]], [integer[lowPage*2]]];
ImagerInterpress.DoPage[self: ref, action: WriteSide1];
ms.PutF["] [%g] [%g", [integer[(lowPage*2)-1]], [integer[lowPage*2]]];
ImagerInterpress.DoPage[self: ref, action: WriteSide2];
ms.PutF["] "];
ENDLOOP;
ImagerInterpress.Close[self: ref];
ms.PutF["\n%g written.\n", [rope[output]]];
};
ProcessArgs: PROC [cmd: Commander.Handle, argv: CommandTool.ArgumentVector]
RETURNS [msg: ROPENIL] ~ {
i: INT ← 1;
arrowSpecified: BOOLFALSE;
input ← NIL;
output ← NIL;
scaleFactor ← defaultScaleFactor;
scaleIt ← FALSE;
WHILE i < argv.argc DO
len: INT ~ Rope.Length[argv[i]];
IF len = 0 THEN { msg ← "Null argument"; GOTO Bad };
IF Rope.Fetch[argv[i], 0] = '-
THEN {
IF len = 1 THEN { msg ← "Missing option"; GOTO Bad };
SELECT Rope.Fetch[argv[i], 1] FROM
'b => scaleIt ← FALSE; -- booklet style, no scaling
'f => scaleIt ← TRUE; -- fit a "standard" 8.5 x 11
's => { -- use an arbitrary scaleing factor
scaleIt ← TRUE;
scaleFactor ← Convert.RealFromRope[Rope.Substr[argv[i], 2]];
};
ENDCASE => { msg ← "Invalid option"; GOTO Bad };
}
ELSE {
SELECT TRUE FROM
Rope.Equal[argv[i], "←"] => {
IF input = NIL THEN { msg ← "No output file specified"; GOTO Bad };
arrowSpecified ← TRUE;
};
input = NIL => input ← argv[i];
(output = NIL) AND arrowSpecified => {
output ← input;
input ← argv[i];
};
ENDCASE => {
IF arrowSpecified
THEN msg ← "Too much in command line"
ELSE msg ← "Missing \"←\"";
GOTO Bad;
};
};
i ← i.SUCC;
ENDLOOP;
IF input = NIL OR output = NIL THEN { msg ← "File name missing"; GOTO Bad };
EXITS
Bad => NULL;
};
BookletLogProc: Interpress.LogProc ~ { -- doesn't do anything!
PROC [class: INT, code: ATOM, explanation: ROPE];
};
BookletCmd: Commander.CommandProc ~ {
ENABLE {
FS.Error => {
result ← $Failure;
msg ← error.explanation;
GOTO Failure;
};
};
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd
! CommandTool.Failed => { msg ← errorMsg; result ← $Failure; GOTO Failure }];
IF argv = NIL THEN RETURN;
msg ← ProcessArgs[cmd, argv];
IF msg # NIL THEN { result ← $Failure; RETURN };
Booklet[output, input, BookletLogProc, cmd.out];
EXITS
Failure => {};
};
doc: ROPE ← "Create a new IP master that will print as a booklet (8-1/2 x 11 paper, folded in half, in correct page order).";
Commander.Register["InterpressBooklet", BookletCmd, doc];
Commander.Register["IPBooklet", BookletCmd, doc];
}.