1---lua 2---imposition plan : Generic Booklet -- US letter paper -- 8.5 x 11 3--- 4---It is said generic as it will try to determine 5---automatically how to fit the booklet onto US letter 6---paper sheets, scaling pages if necessary. 7---it is well suited for office documents for 8---which you do not care too much about resulting 9---imposition artefacts since it manages to save 10---paper! 11--- 12-- print("Booklet") 13-- We output a booklet on US letter paper -- 8.5 x 11 14 15-- Interface notes ..... 16---- Evidently PageCount, SourceWidth, and SourceHeight are 17---- passed to us from the C++ program when we are called. 18---- Evidently we are required to provide values for 19---- PageWidth, PageHeight, and Scale ... which are used by 20---- the C++ program after we return. Scale defaults to 1. 21---- 22---- Note that these Page-related names are unfortunate, 23---- because they do *not* correspond to the pages as defined 24---- by the source, or to the pages in the final booklet. 25---- Really PageHeight should be called SheetHeight and 26---- PageWidth should be called SheetWidth or something 27---- like that. 28---- 29---- Note that we calculate our offsets and margins in 30----_real_ units, not scaled units. That is significant 31---- PushRecord will scale its arguments, so we will need 32-----to descale the offsets in the call to PushRecord. 33 34-- Useful units, measured in local units (i.e. postscript points): 35inch = 72 36mm = inch / 25.4 37 38PageWidth = 8.5*inch 39PageHeight = 11*inch 40 41-- Turn on TopMode if you want to print the top side of each sheet 42-- Turn on BottomMode if you want to print the bottm side of each sheet 43-- Turn on TopMode and BottomMode if you want both, as for a duplex printer 44TopMode = 1 45BottomMode = 1 46-- Turn on BoStack if your non-duplex printer has the property 47-- that the first thing printed winds up at the bottom of the 48-- stack, face up. 49BoStack = 0 50 51print("PageCount",PageCount) 52 53-- Note that we need to distinguish 54---- the hw margins need to keep the printer happy 55---- the /added/ margins we need to apply here. 56-- Worst case is when the source 57-- material bleeds right to the edge of its bounding box. 58-- Conversely, if the source material has a lot of margin 59-- already built into it, we may not need any /extra/ margin 60-- at all, and we could set UsableHeight = PageHeight here. 61-- Similarly if Ydelta/2 is larger than the hwBottomMargin 62-- we shouldn't need to add any /add/ margin. 63 64hwTopMargin = 0.1*inch 65hwBottomMargin = 0.5*inch 66hwLeftMargin = 0.1*inch 67hwRightMargin = 0.1*inch 68 69srcMargin = 0 70addTopMargin = math.max(0, hwTopMargin - srcMargin) 71addBottomMargin = math.max(0, hwBottomMargin - srcMargin) 72addLeftMargin = math.max(0, hwLeftMargin - srcMargin) 73addRightMargin = math.max(0, hwRightMargin - srcMargin) 74 75-- When calculating wiggle room, assume paper will be used 76-- symmetrically. This is a nontrivial assumption, since 77-- e.g. we could use a paper cutter to chop off one edge 78-- and not the other ... but that would be beyond the 79-- scope of this analysis. Symmetry means that if we 80-- apply a margin to the recto page, we must apply the 81-- same margin to the verso page, even if the hardware 82-- would not require it. Hence the factors of 2 here: 83 84UsableHeight = PageHeight - 2*addTopMargin - 2*addBottomMargin 85UsableWidth = PageWidth - 2*addLeftMargin - 2*addRightMargin 86 87if(SourceWidth <= SourceHeight) 88then 89 Scale = math.min(UsableHeight / (2*SourceWidth), UsableWidth / SourceHeight) 90 rot = 90 91 Ywiggle = 0.5 * math.max(0, UsableHeight - 2*SourceWidth*Scale) 92 Xwiggle = math.max(0, UsableWidth - SourceHeight*Scale) 93 fudge = addTopMargin + 2*(addBottomMargin + Ywiggle) 94-- Apply a factor of /2 to Xwiggle here, 95-- because we want centering 96-- (not flush to right of sheet, i.e. bottom of page): 97-- Do not apply corresponding factor to Ywiggle, because 98-- we do want flush to top of sheet, i.e. right of page: 99 xof = addLeftMargin + SourceHeight*Scale + Xwiggle/2 100 yofRtop = SourceWidth*Scale + fudge 101 yofRbot = SourceWidth*Scale + fudge 102 yofVtop = addBottomMargin + Ywiggle 103 yofVbot = addBottomMargin + Ywiggle 104else 105 Scale = math.min(UsableHeight / (2*SourceHeight), UsableWidth / SourceWidth) 106 rot = 0 107 Ywiggle = 0.5 * math.max(0, UsableHeight - 2*SourceHeight*Scale) 108 Xwiggle = math.max(0, UsableWidth - SourceWidth*Scale) 109 fudge = addTopMargin + 2*(addBottomMargin + Ywiggle) 110 xof = addLeftMargin + Xwiggle/2 111 yofRtop = SourceHeight*Scale + fudge 112 yofRbot = SourceHeight*Scale + fudge 113 yofVtop = addBottomMargin + Ywiggle 114 yofVbot = addBottomMargin + Ywiggle 115end 116 117do 118 rest = PageCount % 4 119 totp = PageCount 120 if rest ~= 0 121 then 122 totp = totp + ( 4 - rest) 123 end 124-- "inc" counts input pages skipped as well as pages actually used: 125 inc = 0 126-- "outc" counts output pages: 127 outc = 0; 128 count = 0 129 imax = totp/4 130 middle = totp/2 131 while count < imax 132 do 133-- We assume that podofoimpose will discard invalid records 134-- such as those with source page greater than PageCount 135-- print(totp, inc, outc, rot, xof, yofRtop, yofVtop, yofRbot, yofVbot) 136-- Top of sheet: (8 1) ... (6 3) 137 if TopMode ~= 0 138 then 139-- We did all the interesting calculations in real units (above). 140-- We convert to nasty descaled units at the last moment: 141 PushRecord(totp - inc, outc + 1, rot, xof/Scale, yofVtop/Scale) 142 PushRecord(inc + 1, outc + 1, rot, xof/Scale, yofRtop/Scale) 143 outc = outc + 1 144 end 145-- Bottom of sheet: 146 if BottomMode ~= 0 147 then 148 if BoStack ~= 0 149 then 150-- Reversed bottom: (4 5) ... (2 7) 151 PushRecord(middle - inc, outc + 1, rot, xof/Scale, yofVbot/Scale) 152 PushRecord(middle + 1 + inc, outc + 1, rot, xof/Scale, yofRbot/Scale) 153 else 154-- Normal bottom: (2 7) ... (4 5) 155 PushRecord(inc + 2, outc + 1, rot, xof/Scale, yofVbot/Scale) 156 PushRecord(totp-(inc + 1), outc + 1, rot, xof/Scale, yofRbot/Scale) 157 end 158 159 outc = outc + 1 160 end 161 162 count = count + 1 163 inc = inc + 2 164 end 165end 166