BookletLogProc: InterpressInterpreter.LogProc ~ {
cmd.err.PutRope["\n *** "];
cmd.err.PutRope[explanation];
cmd.err.PutRope[" *** "];
};
Booklet:
PROC [output, input:
ROPE, logProc: InterpressInterpreter.LogProc, ms:
STREAM] ~ {
fullFName: ROPE ~ FS.FileInfo[input].fullFName;
master: InterpressInterpreter.Master ~ InterpressInterpreter.Open[fileName: fullFName, log: logProc];
ref: ImagerInterpress.Ref ~ ImagerInterpress.Create[fileName: output];
inPages: INT = master.pages;
outPages: INT = (inPages+3)/4;
lowPage: INT ¬ 1;
highPage: INT ¬ outPages * 4;
DoPage:
PROC [context: Imager.Context, page:
INT] ~ {
Renumber:
PROC ~ {
font: ImagerFont.Font ~ Imager.FindFontScaled["Xerox/XC1-1-1/Modern", 9];
rope: ROPE ~ Convert.RopeFromInt[page];
Imager.ScaleT[context, 0.0254/72];
Imager.SetXY[context, [x: IF page MOD 2 = 0 THEN 36.0 ELSE 5.5*72-36-ImagerFont.RopeEscapement[font, rope].x, y: 8.5*72-36]];
Imager.SetFont[context, font];
Imager.ShowRope[context, rope];
};
IF renumber AND page > 1 THEN Imager.DoSave[context, Renumber];
IF scaleIt THEN Imager.ScaleT[context, scaleFactor];
IF up#0 THEN Imager.TranslateT[context, [0, up*0.5*0.0254]]; -- move up
InterpressInterpreter.DoPage[master: master, page: page, context: context, log: logProc];
};
WriteSide1:
PROC [context: Imager.Context] ~ {
LowPageAction:
PROC ~ {
IF lowPage > inPages THEN RETURN;
Imager.TranslateT[context, [paperWidth, paperHeight/2.0]];
Imager.RotateT[context, 90.0];
DoPage[context, lowPage];
lowPage ¬ lowPage + 1;
};
HighPageAction:
PROC ~ {
IF highPage > inPages THEN {highPage ¬ highPage - 1; RETURN};
Imager.TranslateT[context, [paperWidth, 0]];
Imager.RotateT[context, 90.0];
DoPage[context, highPage];
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, paperHeight]];
Imager.RotateT[context, 270.0];
DoPage[context, lowPage];
lowPage ¬ lowPage + 1;
};
HighPageAction:
PROC ~ {
IF highPage > inPages THEN {highPage ¬ highPage - 1; RETURN};
Imager.TranslateT[context, [0, paperHeight/2.0]];
Imager.RotateT[context, 270.0];
DoPage[context, highPage];
highPage ¬ highPage - 1;
};
Imager.DoSave[context, LowPageAction];
Imager.DoSave[context, HighPageAction];
};
ms.PutFL["Making booklet %g (%g/4 pages) from %g (%g input pages) ... ", LIST[
[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.PutRope["] "];
ENDLOOP;
ImagerInterpress.Close[self: ref];
ms.PutF1["\n%g written.\n", [rope[output]]];
};
ProcessArgs:
PROC [cmd: Commander.Handle, argv: CommanderOps.ArgumentVector]
RETURNS [msg:
ROPE ¬
NIL] ~ {
i: INT ¬ 1;
arrowSpecified: BOOL ¬ FALSE;
inputWidth: REAL ¬ 0.01 * 2.54 * 8.5; -- meters
inputHeight: REAL ¬ 0.01 * 2.54 * 11.0; -- meters
input ¬ NIL;
output ¬ NIL;
scaleIt ¬ FALSE;
scaleFactor ¬ 0.0;
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
'n => { renumber ¬ TRUE }; -- renumber
'u => { up ¬ up + 1 }; -- up a little
's => {
-- use an arbitrary scaling factor
scaleIt ¬ TRUE;
scaleFactor ¬ Convert.RealFromRope[Rope.Substr[argv[i], 2]];
};
'p =>
IF i+1 >= argv.argc
THEN
GOTO Bad
ELSE {
arg: ROPE ~ argv[i+1];
i ¬ i + 1;
SELECT
TRUE
FROM
Rope.Equal[arg, "usletter",
FALSE] => {
paperWidth ¬ 0.01 * 2.54 * 8.5; -- meters
paperHeight ¬ 0.01 * 2.54 * 11.0; -- meters
};
Rope.Equal[arg, "uslegal",
FALSE] => {
paperWidth ¬ 0.01 * 2.54 * 8.5; -- meters
paperHeight ¬ 0.01 * 2.54 * 14.0; -- meters
};
Rope.Equal[arg, "usledger",
FALSE] => {
paperWidth ¬ 0.01 * 2.54 * 11.0; -- meters
paperHeight ¬ 0.01 * 2.54 * 17.0; -- meters
};
Rope.Equal[arg, "a4",
FALSE] => {
paperWidth ¬ 0.210; -- meters
paperHeight ¬ 0.297; -- meters
};
ENDCASE => msg ¬ "known paper sizes are: usletter, uslegal, usledger, a4";
};
'i =>
IF i+1 >= argv.argc
THEN
GOTO Bad
ELSE {
arg: ROPE ~ argv[i+1];
i ¬ i + 1;
SELECT
TRUE
FROM
Rope.Equal[arg, "usletter",
FALSE] => {
inputWidth ¬ 0.01 * 2.54 * 8.5; -- meters
inputHeight ¬ 0.01 * 2.54 * 11.0; -- meters
};
Rope.Equal[arg, "uslegal",
FALSE] => {
inputWidth ¬ 0.01 * 2.54 * 8.5; -- meters
inputHeight ¬ 0.01 * 2.54 * 14.0; -- meters
};
Rope.Equal[arg, "usledger",
FALSE] => {
inputWidth ¬ 0.01 * 2.54 * 11.0; -- meters
inputHeight ¬ 0.01 * 2.54 * 17.0; -- meters
};
Rope.Equal[arg, "a4",
FALSE] => {
inputWidth ¬ 0.210; -- meters
inputHeight ¬ 0.297; -- meters
};
ENDCASE => msg ¬ "known paper sizes are: usletter, uslegal, usledger, a4";
};
ENDCASE => { msg ¬ "Invalid option"; GOTO Bad };
}
ELSE {
SELECT
TRUE
FROM
Rope.Equal[argv[i], "←"], 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 scaleFactor = 0.0 THEN scaleFactor ¬ MIN[(paperHeight*0.5)/inputWidth, paperWidth/inputHeight];
IF input = NIL OR output = NIL THEN { msg ¬ "File name missing"; GOTO Bad };
EXITS
Bad => { msg ¬ Rope.Cat[msg, ":\n", cmd.procData.doc]};
};