<<>> <> <> <> <> <> <<>> DIRECTORY Commander, CommandTool, Convert, FileNames, FS, Imager, ImagerColorFns, ImagerInterpress, ImagerTransformation, Interpress, IO, ProcessProps, Rope; InterpressComposeCommandImpl: CEDAR PROGRAM IMPORTS Commander, CommandTool, Convert, FileNames, FS, Imager, ImagerColorFns, ImagerInterpress, ImagerTransformation, Interpress, IO, ProcessProps, Rope ~ BEGIN ROPE: TYPE ~ Rope.ROPE; Transformation: TYPE ~ ImagerTransformation.Transformation; Master: TYPE ~ Interpress.Master; Input: TYPE ~ RECORD [name: ROPE _ NIL, xform: Transformation, master: Master]; InterpressCompose: PROC [output: ROPE, inputs: LIST OF Input] ~ { prevMsg: ROPE _ NIL; matchCount: INT _ 0; Log: Interpress.LogProc ~ { WITH ProcessProps.GetProp[$ErrOut] SELECT FROM errOut: IO.STREAM => { IF Rope.Equal[explanation, prevMsg] THEN {matchCount _ matchCount + 1} ELSE { IF matchCount > 0 THEN IO.PutF[errOut, " (and %g more)\n", IO.int[matchCount]]; IO.PutRope[errOut, explanation]; IF explanation # NIL THEN IO.PutChar[errOut, '\n]; prevMsg _ explanation; matchCount _ 0; }; }; ENDCASE => NULL; }; nPages: NAT _ 0; outRef: ImagerInterpress.Ref ~ ImagerInterpress.Create[output]; FOR l: LIST OF Input _ inputs, l.rest WHILE l # NIL DO m: Transformation _ l.first.xform; l.first.master _ Interpress.Open[l.first.name, NIL]; IF l.first.master.pages > nPages THEN nPages _ l.first.master.pages; ENDLOOP; FOR page: INT IN [1..nPages] DO WriteAction: PROC [context: Imager.Context] ~ { <> context.SetColor [ImagerColorFns.ColorFromCMYK [[0.0, 0.0, 0.0, 1.0]]]; FOR l: LIST OF Input _ inputs, l.rest WHILE l # NIL DO p: INT ~ ((page-1) MOD l.first.master.pages)+1; -- Cycle through master as needed <> Imager.ConcatT[context, l.first.xform]; Interpress.DoPage[l.first.master, p, context, NIL]; Imager.ConcatT[context, ImagerTransformation.Invert[l.first.xform]]; -- a crock! ENDLOOP }; ImagerInterpress.DoPage[outRef, WriteAction]; ENDLOOP; Log[-1, NIL, NIL]; ImagerInterpress.Close[outRef]; }; isItError: ERROR = CODE; InterpressComposeCommand: Commander.CommandProc ~ { ENABLE { isItError => GOTO BadSyntax; FS.Error => { msg _ error.explanation; GOTO Failure; }; Convert.Error => { msg _ "Conversion error"; GOTO Failure; }; }; IsIt: PROC [rope: ROPE, argsNeeded: INT] RETURNS [b: BOOL] ~ { IF argIndex >= args.argc THEN RETURN[FALSE]; b _ Rope.Equal[rope, args[argIndex], FALSE]; IF b AND args.argc <= argIndex+argsNeeded THEN ERROR isItError; }; SkipArgs: PROC [nSkip: INT] ~ {argIndex _ argIndex+nSkip}; Real: PROC [index: INT] RETURNS [r: REAL] ~ {r _ Convert.RealFromRope[args[index]]}; argIndex: INT _ 3; inputs: LIST OF Input; m: Transformation _ NIL; args: CommandTool.ArgumentVector ~ CommandTool.Parse[cmd]; IF args.argc < 3 OR NOT Rope.Equal["_", args[2]] THEN GOTO BadSyntax; WHILE argIndex < args.argc DO SELECT TRUE FROM IsIt["translate", 2] => { s: REAL _ 1.0; x: REAL _ Real[argIndex+1]; y: REAL _ Real[argIndex+2]; SkipArgs[3]; SELECT TRUE FROM IsIt["in", 0] => s _ Imager.metersPerInch; IsIt["cm", 0] => s _ 0.01; IsIt["mm", 0] => s _ 0.001; IsIt["pt", 0] => s _ Imager.metersPerPoint; ENDCASE; IF s # 1.0 THEN SkipArgs[1]; m^ _ ImagerTransformation.PreTranslate[m, [s*x, s*y]]^; }; IsIt["rotate", 1] => { angle: REAL _ Real[argIndex+1]; SkipArgs[2]; IF IsIt["radians", 1] THEN { angle _ 180.0*angle/3.1415926535; SkipArgs[1]; }; m^ _ ImagerTransformation.PreRotate[m, angle]^; }; IsIt["scale", 1] => { m^ _ ImagerTransformation.PreScale[m, Real[argIndex+1]]^; SkipArgs[2]; }; IsIt["scale2", 2] => { m^ _ ImagerTransformation.PreScale2[m, [Real[argIndex+1], Real[argIndex+2]]]^; SkipArgs[3]; }; ENDCASE => { m _ ImagerTransformation.Scale[1]; inputs _ CONS[[FileNames.ResolveRelativePath[args[argIndex]], m], inputs]; SkipArgs[1]; }; ENDLOOP; InterpressCompose[args[1], inputs]; EXITS BadSyntax => RETURN[$Failure, interpressComposeUsage]; Failure => result _ $Failure; }; interpressComposeUsage: ROPE ~ " InterpressCompose _ [xfrm1] ... [xfrmN] Combine input interpress masters, each with an optional transform. A transform is a combination of: translate [in | m | cm | mm | pt] | rotate [radians] | scale | scale2 ."; Commander.Register["InterpressCompose", InterpressComposeCommand, interpressComposeUsage]; Commander.Register["IPCompose", InterpressComposeCommand, interpressComposeUsage]; END.