From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.0 From: Gleb Kulikov To: ALT Linux Community general discussions Date: Tue, 04 Nov 2014 10:51:12 +0600 Message-ID: <2172782.jqFalHygcR@h77.localdomain> Organization: ASD IAO SB RAS X-Face: *.tnb'M; )dxikq9#+>Umx+%XczFejqg":45mV?$Iu(Hi)qEytW^u??1Ccr{dYOHV??-ifK3_Ug.ORuWI\@"+7)?#.o,[ v~M9 User-Agent: KMail/4.14.2 (Linux/3.14.22-std-def-alt1; KDE/4.14.2; x86_64; ; ) In-Reply-To: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart1499855.TQST2jErm9" Content-Transfer-Encoding: 7Bit Subject: Re: [Comm] =?utf-8?b?0JrQsNC6INGA0LDQt9GA0LXQt9Cw0YLRjCDQutC90LjQs9GD?= =?utf-8?b?INC00LvRjyDQv9GA0L7RiNC40LLQutC4?= X-BeenThere: community@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Community general discussions List-Id: ALT Linux Community general discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Nov 2014 04:51:21 -0000 Archived-At: List-Archive: List-Post: This is a multi-part message in MIME format. --nextPart1499855.TQST2jErm9 Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8" 0JIg0L/QuNGB0YzQvNC1INC+0YIg0J/QvtC90LXQtNC10LvRjNC90LjQuiAwMyDQvdC+0Y/QsdGA 0Y8gMjAxNCAyMDoyOTo0MyDQv9C+0LvRjNC30L7QstCw0YLQtdC70YwgRXVnaW5lIEtvc2Vua28g CtC90LDQv9C40YHQsNC7OgoKPiDQktC+0L/RgNC+0YE6INC60LDQuiDQvtCx0LXRgdC/0LXRh9C4 0YLRjCDRgtCw0LrRg9GOINCy0LXRgNGB0YLQutGDINGC0LXQutGB0YLQsD8KCtCSINCw0YLRgtCw 0YfQtSDQv9C+0L/Rg9C70Y/RgNC90YvQuSDRgdC60YDQuNC/0YIsINC/0YDQvtC00LXQu9GL0LLQ sNGO0YnQuNC5INGN0YLRgyDQvtC/0LXRgNCw0YbQuNGOINC90LDQtCDQv9GA0L7QuNC30LLQvtC7 0YzQvdGL0LzQuCBwZGYgCtGE0LDQudC70LDQvNC4IChOQiE6INGC0YDQtdCx0YPQtdGCIHBkZmxh dGV4ICsgcGRmaW5mbyDQuCDQvdC1INGC0LXRgNC/0LjRgiwgINC10YHQu9C4INC40LzQtdC90LAg 0YTQsNC50LvQvtCyINC90LAgCtGA0YPRgdGB0LrQvtC8INC40LvQuCDRgdC+0LTQtdGA0LbQsNGC INGB0L/QtdGG0YHQuNC80LLQvtC70YsgW9GN0YLQviwg0YHQutC+0YDQtdC1LCDQv9GA0LXRgtC1 0L3Qt9C40Lgg0LogcGRmbGF0ZXhdKS4KCgoKLS0gCiAgICAgINCh0LDQu9GO0YIsIC9HTGViCgpV SU46IDE1MzQxOTIwCmphYmJlcjovL2dsZWJAYXNkLmlhby5ydQpzaXA6Ly8yMzg3MjQ1QHNpcG5l dC5ydQkJCSh0ZWxlcGhvbnkpCnNreXBlOi8vZ2xlYl9rdWxpa292LnRvbXNrCQkodGVsZXBob255 KQoK --nextPart1499855.TQST2jErm9 Content-Disposition: attachment; filename="pdfbook" Content-Transfer-Encoding: 7Bit Content-Type: text/x-python; charset="UTF-8"; name="pdfbook" #! /usr/bin/python # pdfbook.c Rearrange pages in a PDF file into signatures. # # Author Tigran Aivazian (original C version) # Olivier Aubert (python version) # # Copyright: GPLv2 # # Based on the algorithm from psutils/psbook.c, which was # written by Angus J. C. Duggan 1991-1995. # # For example, to convert a file gnt.pdf into a book with # signature 32, we can use: # # $ pdfbook -s32 gnt.pdf gnt-book.pdf # FIXME: implement max signature size # FIXME: try to set the "duplex on short sides" option import sys import os import shutil import re import tempfile from optparse import OptionParser def check_program(p): for d in os.getenv('PATH').split(':'): if os.path.exists(os.path.join(d, p)): return True return False def check_dependencies(): ret=True if not check_program('pdflatex'): print "pdflatex is not installed. Please install it." ret=False if not check_program('pdfinfo'): print "pdfinfo is not installed. Please install the xpdf-utils package." ret=False return ret def swap_pairs(array, len): """Swap pages for right-to-left typesetting """ for i in range(0, len, 2): array[i], array[i+1] = array[i+1], array[i] def get_number_of_pages(fname): """Return the number of pages in the PDF file. """ npages=0 regexp=re.compile("Pages:\s+(\d+)") f=os.popen("pdfinfo '%s'" % fname) for l in f: m=regexp.search(l) if m: npages=m.group(1) break return int(npages) def shuffled_pages(npages, options): """Generated the list of page numbers for booklet printing. """ signature=options.signature if signature == 0: maxpage = npages + (4 - npages % 4) % 4 signature = maxpage else: maxpage = npages + (signature - npages % signature) % signature actualpg = [ 0 ] * maxpage for i in range(0, maxpage): actual = i - i % signature if i % 4 in (0, 3): actual += signature - 1 - (i % signature) / 2 else: actual += (i % signature) / 2 if actual < npages: actualpg[i] = actual + 1 if options.rtol: swap_pairs(actualpg, maxpage) return actualpg def generate_book(inputfile, outputfile, options): """Convert input to output, using options. """ npages = get_number_of_pages(inputfile) if npages < 1: print "invalid number of pages (%d)" % npages check_dependencies() return if options.debug: print "Processing %d pages" % npages actualpg = shuffled_pages(npages, options) def printable(n): if n: if not options.quiet: print "[%d]" % n, return str(n) else: if not options.quiet: print "[*]", return "{}" compile_dir=tempfile.mkdtemp() if options.debug: print "Generating files in directory ", compile_dir (outbase, ext) = os.path.splitext(os.path.basename(outputfile)) outtex=".".join( (outbase, 'tex') ) outpdf=".".join( (outbase, 'pdf') ) fullouttex=os.path.join( compile_dir, outtex ) fulloutpdf=os.path.join( compile_dir, outpdf ) # LaTeX generation fout = open(fullouttex, "w") fout.write("""\\documentclass[12pt,a4paper,openany]{book} \\usepackage{pdfpages} \\begin{document} \\includepdf[nup=1x2,landscape,pages={%s}]{%s} \\end{document} """ % (",".join( [ printable(n) for n in actualpg ] ), inputfile )) fout.close() if not options.quiet: print "\nGenerating %s now, please wait..." % outputfile cmdline = "pdflatex -output-directory '%s' '%s'" % ( compile_dir, fullouttex ) if not options.debug: cmdline += "> /dev/null 2>&1 < /dev/null" else: print "Executing ", cmdline ret=os.system(cmdline) if ret: print "Failed to generate %s" % outputfile check_dependencies() return if os.path.exists(fulloutpdf): shutil.move( fulloutpdf, outputfile ) else: print "Cannot find %s in %s" % (outpdf, compile_dir) return 1 if options.debug < 2: # Cleanup shutil.rmtree(compile_dir) return 0 def main(): """Option parsing. """ parser=OptionParser(usage="""Rearrange pages in a PDF file into signatures. %prog [options] input_file.pdf [output_file.pdf]""") parser.add_option("-s", "--signature", dest="signature", action="store", type="int", default=0, metavar="SIGNATURE", help="Signature of the booklet. It must be positive and divisible by 4.") parser.add_option("-r", "--right-to-left", dest="rtol", action="store_true", help="Do right-to-left typesetting", default=False) parser.add_option("-q", "--quiet", dest="quiet", action="store_true", help="Be quiet", default=False) parser.add_option("-d", "--debug", dest="debug", action="store", help="Debug level (1: display messages, 2: keep intermediary files", default=0) (options, args) = parser.parse_args() try: inputfile=args[0] except IndexError: print "input file must be specified" parser.print_help() return if not os.path.exists(inputfile): print "Cannot read input file", inputfile return (inputbase, ext) = os.path.splitext(inputfile) if ext != '.pdf': print "Input file %s should end with .pdf" % inputfile return try: outputfile=args[1] except IndexError: outbase = os.path.basename(inputbase) outputfile=outbase+"-book"+ext if options.signature: if options.signature < 0 or options.signature % 4: parser.print_help() return if options.debug: print "Input file :", inputfile print "Output file :", outputfile print "Signature :", options.signature return generate_book(inputfile, outputfile, options) if __name__ == '__main__': main() --nextPart1499855.TQST2jErm9--