Guest User

Python script to drive PoDoFo to impose 2x2 for hardcover

a guest
May 4th, 2013
207
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import sys
  5. import re
  6. import os
  7. from pyPdf import PdfFileWriter, PdfFileReader
  8.  
  9. # Verbosity 0 means absolute silence
  10. # 1 means only error messages
  11. # 2 adds warnings as well
  12. # 3 adds information about what's going on
  13. # 4 adds useless chitchat
  14. # 5 debug
  15. verbose = 3
  16.  
  17. # Unit to PS points conversion
  18. mm = 2.834650
  19.  
  20. # pages per set: 8, 16, 24, 32 ...
  21. div = 16
  22.  
  23. # pages per fold
  24. fold = 8
  25.  
  26. # print full pane
  27. print_full_pane = True
  28.  
  29.  
  30. def usage():
  31.     print "Give files you want imposed as arguments."
  32.  
  33. class Page:
  34.     def __init__(self, height, width):
  35.         self.height = height
  36.         self.width = width
  37.  
  38.  
  39. class Margins:
  40.     def __init__(self, top = 0, bottom = 0, left = None, right = None,
  41.         inside = None, outside = None):
  42.         self.top = top
  43.         self.bottom = bottom
  44.         if inside or outside:
  45.             if inside:
  46.                 self.inside = inside
  47.             else:
  48.                 self.inside = 0
  49.             self.left = self.inside
  50.             if outside:
  51.                 self.outside = outside
  52.             else:
  53.                 self.outside = 0
  54.             self.right = self.outside
  55.             self.inoutside = True
  56.         else:
  57.             if left:
  58.                 self.left = left
  59.             else:
  60.                 self.left = 0
  61.             if right:
  62.                 self.right = right
  63.             else:
  64.                 self.right = 0
  65.             self.inoutside = False
  66.  
  67.  
  68. class PdfDoc:
  69.     filename = False
  70.     pages = 0
  71.  
  72.     def __init__(self, path):
  73.         self.path = path
  74.         self.dir, self.filename = os.path.split(path)
  75.         self.pdf = PdfFileReader(file(self.path))
  76.         self.info = self.pdf.getDocumentInfo()
  77.         self.pages = self.pdf.getNumPages()
  78.         self.mediabox = self.pdf.getPage(0).mediaBox
  79.         self.page = Page(
  80.             width = float(self.mediabox[2] - self.mediabox[0]),
  81.             height = float(self.mediabox[3] - self.mediabox[1]))
  82.         if verbose >= 3:
  83.             print('')
  84.             print('Document: %s (%.1f MB)' % (self.filename,
  85.                 os.path.getsize(self.path) / 1048576))
  86.             if self.info.has_key('/Title') and \
  87.                 self.info['/Title'] != '':
  88.                 print('Title: %s' % self.info['/Title'])
  89.             if self.info.has_key('/Author') and self.info['/Author'] != '':
  90.                 print('Author: %s' % self.info['/Author'])
  91.             if self.info.has_key('/CreationDate'):
  92.                 date = self.info['/CreationDate'][2:]
  93.             else:
  94.                 date = '00000000000000000000'
  95.             print('Created on %s-%s-%s %s:%s with %s %s' %
  96.                 (date[0:4], date[4:6], date[6:8], date[8:10], date[10:12],
  97.                 self.info['/Producer'], self.info['/Creator']))
  98.             print('Document dimensions: %.2f mm x %.2f mm' %
  99.                 (self.page.width / mm, self.page.height / mm))
  100.             print('')
  101.  
  102.  
  103. class Plan:
  104.     plate_margins = Margins()
  105.     pages = []
  106.    
  107.     def __init__(self, document):
  108.         self.document = document
  109.         self.page_margins = Margins()
  110.         self.plate_margins = Margins()
  111.    
  112.     def addPage(self, ref, dest, rot=0, left=False,  bottom=False, x=False, y=False):
  113.         if ref > self.document.pages:
  114.             return
  115.         if left and bottom and rot != 180:
  116.             x = self.x[left-1]
  117.             y = self.y[bottom-1]
  118.         elif left and bottom and rot == 180:
  119.             x = self.x180[left-1]
  120.             y = self.y180[bottom-1]
  121.         if rot == 180:
  122.             x += self.sheet.width
  123.             y += self.sheet.height
  124.         self.pages.append("%d; %d; %d; %f; %f;\n" % (ref, dest, rot, x, y))
  125.         #print ref, dest, rot, x, y
  126.  
  127.     def complete(self):
  128.         f = open('/tmp/plan.plan', 'w')
  129.         #print self.plate.width, self.plate.height
  130.         f.write('$PageWidth=%f\n$PageHeight=%f;\n\n' % (self.plate.width,
  131.             self.plate.height))
  132.         f.write(''.join(self.pages))
  133.         f.close()
  134.        
  135.         #os.system('podofoimpose "%s" "%s.out.pdf" /tmp/plan.plan' %
  136.         #    (self.document.path, self.document.path))
  137.         fin, fout = os.popen4('podofoimpose "%s" "%s.out.pdf" /tmp/plan.plan' %
  138.             (self.document.path, self.document.path))
  139.         result = fout.read()
  140.         if verbose >= 4:
  141.             print result
  142.        
  143.     def pageDimensions(self, sheet):
  144.         self.sheet = sheet
  145.    
  146.     def dimensions(self):
  147.         # Output page dimensions
  148.         # 2x2 nup
  149.         if print_full_pane:
  150.             self.plate = Page(
  151.                 width = 2 * self.sheet.width +
  152.                     self.plate_margins.left + self.plate_margins.right + \
  153.                     2 * (self.page_margins.left + self.page_margins.right),
  154.                 height = 2 * self.sheet.height +
  155.                     self.plate_margins.top + self.plate_margins.bottom + \
  156.                     2 * (self.page_margins.top + self.page_margins.bottom))
  157.            
  158.             # Output positions
  159.             if self.page_margins.inoutside:
  160.                 self.x = []
  161.                 self.x.append(self.plate_margins.left + self.page_margins.outside)
  162.                 self.x.append(self.plate_margins.left + 2 * self.page_margins.inside + \
  163.                     self.page_margins.outside + self.sheet.width)
  164.             else:
  165.                 self.x = []
  166.                 self.x.append(self.plate_margins.left + self.page_margins.left)
  167.                 self.x.append(self.plate_margins.left + 2 * self.page_margins.left + \
  168.                     self.page_margins.right + self.sheet.width)
  169.             self.y = []
  170.             self.y.append(self.plate_margins.bottom + self.page_margins.bottom)
  171.             self.y.append(self.plate_margins.bottom + 2 * self.page_margins.bottom + \
  172.                 self.page_margins.top + self.sheet.height)
  173.             if self.page_margins.inoutside:
  174.                 # Output positions for 180 deg rotated pages
  175.                 self.x180 = []
  176.                 self.x180.append(self.plate_margins.left + self.page_margins.outside)
  177.                 self.x180.append(self.plate_margins.left + 2 * self.page_margins.inside + \
  178.                     self.page_margins.outside + self.sheet.width)
  179.             else:
  180.                 self.x180 = []
  181.                 self.x180.append(self.plate_margins.left + self.page_margins.left)
  182.                 self.x180.append(self.plate_margins.left + 2 * self.page_margins.left + \
  183.                     self.page_margins.right + self.sheet.width)
  184.             self.y180 = []
  185.             self.y180.append(self.plate_margins.bottom + self.page_margins.bottom)
  186.             self.y180.append(self.plate_margins.bottom + self.page_margins.bottom + self.sheet.height + 2*self.page_margins.top)
  187.         else:
  188.             # we print half pane
  189.             if self.page_margins.inoutside:
  190.                 print 'jee'
  191.                 self.plate = Page(
  192.                     width = 2 * self.sheet.width +
  193.                         self.plate_margins.left + self.plate_margins.right + \
  194.                         2 * (self.page_margins.inside + self.page_margins.outside),
  195.                     height = 1 * self.sheet.height +
  196.                         self.plate_margins.top + self.plate_margins.bottom + \
  197.                         1 * (self.page_margins.top + self.page_margins.bottom))
  198.                
  199.                 # Output positions
  200.                 self.x = []
  201.                 self.x.append(self.plate_margins.left + self.page_margins.outside)
  202.                 self.x.append(self.plate_margins.left + 2 * self.page_margins.inside + \
  203.                     self.page_margins.outside + self.sheet.width)
  204.                 self.y = []
  205.                 self.y.append(self.plate_margins.bottom + self.page_margins.bottom)
  206.                 # Output positions for 180 deg rotated pages
  207.                 self.x180 = []
  208.                 self.x180.append(self.plate_margins.left + self.page_margins.outside)
  209.                 self.x180.append(self.plate_margins.left + 2 * self.page_margins.inside + \
  210.                     self.page_margins.outside + self.sheet.width)
  211.                 self.y180 = []
  212.                 self.y180.append(self.plate_margins.bottom + self.page_margins.top)
  213.             else:
  214.                 print 'buu'
  215.                 self.plate = Page(
  216.                     width = 2 * self.sheet.width +
  217.                         self.plate_margins.left + self.plate_margins.right + \
  218.                         2 * (self.page_margins.left + self.page_margins.right),
  219.                     height = 1 * self.sheet.height +
  220.                         self.plate_margins.top + self.plate_margins.bottom + \
  221.                         1 * (self.page_margins.top + self.page_margins.bottom))
  222.                
  223.                 # Output positions
  224.                 self.x = []
  225.                 self.x.append(self.plate_margins.left + self.page_margins.left)
  226.                 self.x.append(self.plate_margins.left + 2 * self.page_margins.left + \
  227.                     self.page_margins.right + self.sheet.width)
  228.                 self.y = []
  229.                 self.y.append(self.plate_margins.bottom + self.page_margins.bottom)
  230.  
  231.  
  232. class prepress:
  233.     documents = []
  234.  
  235.     def __init__(self):
  236.         # First we parse arguments
  237.         if len(sys.argv) != 2:
  238.             usage()
  239.             exit()
  240.         filename = sys.argv[1]
  241.        
  242.         document = PdfDoc(filename)
  243.        
  244.         plan = Plan(document)
  245.         plan.pageDimensions(document.page)
  246.         plan.plate_margins = Margins(
  247.             left   = 0*mm,
  248.             right  = 0*mm,
  249.             top    = 0*mm,
  250.             bottom = 0*mm)
  251.         # instead of left/right one could use inside or outside        
  252.         plan.page_margins = Margins(
  253.             inside   = 0*mm,
  254.             outside  = 3*mm,
  255.             top    = 3*mm,
  256.             bottom = 3*mm)
  257.         plan.dimensions()
  258.        
  259.         # Deciding of pages division to panes
  260.         remaining = document.pages % fold
  261.         if remaining != 0:
  262.             added_pages = fold - remaining
  263.         else:
  264.             added_pages = 0
  265.         total_pages = document.pages + added_pages
  266.         full_sequences = total_pages / div
  267.        
  268.         pages = []
  269.         for p in xrange(1, total_pages+1):
  270.             if p <= document.pages:
  271.                 pages.append(p)
  272.             else:
  273.                 pages.append(False)
  274.                
  275.         dest = 1
  276.         start = 0
  277.         for i in xrange(0, full_sequences):
  278.             subpages = self.foldable_brochure(pages[start:start+div])
  279.             start += div
  280.             if print_full_pane:
  281.                 self.four_per_page(plan, subpages, dest)
  282.                 dest += div/fold*2
  283.             else:
  284.                 self.four_as_two_per_page(plan, subpages, dest)
  285.                 dest += div/fold*4
  286.        
  287.         if start < total_pages:
  288.             subpages = self.foldable_brochure(pages[start:total_pages])
  289.             if print_full_pane:
  290.                 self.four_per_page(plan, subpages, dest)
  291.             else:
  292.                 self.four_as_two_per_page(plan, subpages, dest)
  293.         plan.complete()
  294.    
  295.     def four_per_page(self, plan, page_list, page):
  296.         for i in xrange(len(page_list)/4):
  297.             plan.addPage(ref=page_list[i*4+0], dest=page+i, rot=180, left=1,  bottom=2)
  298.             plan.addPage(ref=page_list[i*4+1], dest=page+i, rot=180, left=2,  bottom=2)
  299.             plan.addPage(ref=page_list[i*4+2], dest=page+i, rot=0, left=1,  bottom=1)
  300.             plan.addPage(ref=page_list[i*4+3], dest=page+i, rot=0, left=2,  bottom=1)
  301.  
  302.     def four_as_two_per_page(self, plan, page_list, page):
  303.         for i in xrange(len(page_list)/4):
  304.             plan.addPage(ref=page_list[i*4+0], dest=page+i*2, rot=180, left=1,  bottom=1)
  305.             plan.addPage(ref=page_list[i*4+1], dest=page+i*2, rot=180, left=2,  bottom=1)
  306.             plan.addPage(ref=page_list[i*4+2], dest=page+i*2+1, rot=0, left=1,  bottom=1)
  307.             plan.addPage(ref=page_list[i*4+3], dest=page+i*2+1, rot=0, left=2,  bottom=1)
  308.  
  309.     def foldable_brochure(self, page_list):
  310.         e = len(page_list)
  311.         sequence = (e) / 8
  312.  
  313.         page_list_fold = []
  314.         for i in xrange(sequence):
  315.             page_list_fold.append(page_list[e-i*4-4])
  316.             page_list_fold.append(page_list[i*4+3])
  317.             page_list_fold.append(page_list[e-i*4-1])
  318.             page_list_fold.append(page_list[i*4])
  319.             page_list_fold.append(page_list[i*4+2])
  320.             page_list_fold.append(page_list[e-i*4-3])
  321.             page_list_fold.append(page_list[i*4+1])
  322.             page_list_fold.append(page_list[e-i*4-2])
  323.         return page_list_fold
  324.  
  325. if __name__=="__main__":
  326.     d = prepress()
RAW Paste Data