Anonymous avatar Anonymous committed 33264ea

Three new options:
1. Force specific output paper format
2. Replicate each page to fill one output page with copies of one input page
3. Keep original page ratio

Comments (0)

Files changed (2)

                        RD first Right then Down (default),
                        UL first Up then Left, etc. (all combinations allowed).
   -o --output FILE   Set output path (incl. some patterns).
+  -f --outformat FORMAT  Force output format to be FORMAT
+  -k --keepPageRatio Keep page ratio when scaling
+  -m --multiply      Multiply each page to fill a whole page in the output file
 
 EXAMPLES:
-  %(prog)s -n 2 file.pdf       # 2 pages per sheet
-  %(prog)s -n 8 file.pdf       # 8 pages per sheet
-  %(prog)s -n 8 -l LD file.pdf # 8 pages per sheet, first left then down
+  %(prog)s -n 2 file.pdf          # 2 pages per sheet
+  %(prog)s -n 8 file.pdf          # 8 pages per sheet
+  %(prog)s -n 8 -l LD file.pdf    # 8 pages per sheet, first left then down
+  %(prog)s -n 8 -f a4 file.pdf    # 8 pages per sheet on an A4 output format
+      # (useful to bring a bunch of smaller formats to one A4 sized page)
+  %(prog)s -n 8 -f a4 -m file.pdf # 8 pages per sheet on an A4 output format
+      # but with 8 copies of page 1 on the first output page, etc.
+  
+  
 
 COPYLEFT:
   see http://www.gnu.org/copyleft/gpl.html
     "Main for command-line usage."
 
     try:
-        longOpts = "help version layout= output=".split()
-        opts, args = getopt.getopt(sys.argv[1:], "hvn:l:o:V", longOpts)
+        longOpts = "help version layout= output= outformat= multiply keepPageRatio".split()
+        opts, args = getopt.getopt(sys.argv[1:], "hvn:l:o:Vf:mk", longOpts)
     except getopt.GetoptError:
         print "ERROR"
         _showUsage()
     numPagePerSheet = 4
     outputPat = None
     verbose = False
+    outputFormat = None
+    multiplyPages = False
+    keepPageRatio = False
     for key, val in opts:
         if key in ("-h", "--help"):
             _showUsage()
             outputPat = val
         elif key in ("-l", "--layout"):
             layoutDesc = val
+        elif key in ("-f", "--outformat"):
+            outputFormat = val
+        elif key in ("-m", "--multiply"):
+            multiplyPages = True
+        elif key in ("-k", "--keepPageRatio"):
+            keepPageRatio = True
 
     # determine paths of input files
     paths = [a for a in args if os.path.exists(a)]
-
-    for path in paths:
-        generateNup(path, numPagePerSheet,
-            outPathPatternOrFile=outputPat, dirs=layoutDesc, verbose=verbose)
-
-
-if __name__ == '__main__':
+    
+    for path in paths:    
+        generateNup(path, numPagePerSheet, 
+            outPathPatternOrFile=outputPat, dirs=layoutDesc, verbose=verbose, outputFormat=outputFormat, multiplyPages=multiplyPages, keepPageRatio=keepPageRatio)
+    
+    
+if __name__ == '__main__':    
     _main()
 """
 _mtA4Pdf = zlib.decompress(base64.decodestring(_mtA4PdfZip64))
 
+# Some basic paper dimensions calculated using reportlab
+dimensions = {'a0': (2381.102362204724, 3367.55905511811),
+              'a1': (1683.779527559055, 2381.102362204724),
+              'a2': (1190.551181102362, 1683.779527559055),
+              'a3': (841.8897637795275, 1190.551181102362),
+              'a4': (595.275590551181, 841.8897637795275),
+              'a5': (420.94488188976374, 595.275590551181),
+              'a6': (297.6377952755905, 420.94488188976374),
+              'a7': (210.47244094488187, 297.6377952755905),
+              'a8': (148.81889763779526, 210.47244094488187),
+              'a9': (105.23622047244093, 148.81889763779526),
+              'a10': (74.40944881889763, 105.23622047244093),
+              'elevenseventeen': (792.0, 1224.0),
+              'legal': (612.0, 1008.0),
+              'letter': (612.0, 792.0)}
+
+def getDimensions(outputFormat):
+  if not outputFormat.lower() in dimensions:
+    raise LookupError("Unknown format: '%s'" % outputFormat)
+  return dimensions[outputFormat.lower()]
 
 def isSquare(n):
     "Is this a square number?"
     return isSquare(n * 2)
 
 
-def calcScalingFactors(w, h, wp, hp):
+def calcScalingFactors(w, h, wp, hp, keepPageRatio=False):
     wp, hp = map(float, (wp, hp))
 
     if w == None:
         xscale = w / wp
         yscale = h / hp
 
-    return xscale, yscale
+    if keepPageRatio:
+      scale = min(xscale, yscale)
+      return scale, scale
+    else:
+      return xscale, yscale
+
 
 
 def calcRects(pageSize, numTiles, dirs="RD"):
     return False
 
 
-def generateNup(inPathOrFile, n, outPathPatternOrFile=None, dirs="RD",
-        verbose=False):
+def generateNup(inPathOrFile, n, outPathPatternOrFile=None, dirs="RD", verbose=False, outputFormat=None, multiplyPages=False, keepPageRatio=False):
     """Generate a N-up document version.
 
     If outPathPatternOrFile is None, the output will be written
     docReader = PdfFileReader(inFile)
     numPages = docReader.getNumPages()
     oldPageSize = docReader.getPage(0).mediaBox.upperRight
+    outputPageSize = oldPageSize
+    # force specific output format?
+    if outputFormat:
+      outputPageSize = getDimensions(outputFormat)
+      # Landscape? Then switch dimensions
+      if docReader.getPage(0).mediaBox.upperRight[0] > docReader.getPage(0).mediaBox.upperRight[1]:
+        outputPageSize = outputPageSize[1], outputPageSize[0]
 
     # create empty output document buffer
     if isSquare(n):
-        newPageSize = oldPageSize
+        newPageSize = outputPageSize
     elif isHalfSquare(n):
-        newPageSize = oldPageSize[1], oldPageSize[0]
+        newPageSize = outputPageSize[1], outputPageSize[0]
     np = numPages / n + numPages % n
     buf = exP1multiN(_mtA4Pdf, newPageSize, np)
 
     # combine
     ops = []
     newPageNum = -1
-    for i in range(numPages):
+    pagesToRender = numPages
+    if multiplyPages:
+      pagesToRender = numPages * n
+    for i in range(pagesToRender):
         if i % n == 0:
             newPageNum += 1
         op = (inPathOrFile, i, (0, 0, None, None), i / n, rects[i % n])
         ops.append(op)
 
-    srcr = srcReader = PdfFileReader(inFile)
-    srcPages = [srcr.getPage(i) for i in range(srcr.getNumPages())]
+    srcPages = [docReader.getPage(i/n if multiplyPages else i) for i in range(pagesToRender)]
 
     if type(oppof) in types.StringTypes:
         outFile = open(outPath, "rb")
             pageWidth, pageHeight = page2.mediaBox.upperRight
             destX, destY, destWidth, destHeight = destRect
             xScale, yScale = calcScalingFactors(
-                destWidth, destHeight, pageWidth, pageHeight)
+                destWidth, destHeight, pageWidth, pageHeight, keepPageRatio)
 
             newResources = DO()
             rename = {}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.