From: Gleb Kulikov <glebus@asd.iao.ru>
To: ALT Linux Community general discussions <community@lists.altlinux.org>
Subject: Re: [Comm] Как разрезать книгу для прошивки
Date: Tue, 04 Nov 2014 10:51:12 +0600
Message-ID: <2172782.jqFalHygcR@h77.localdomain> (raw)
In-Reply-To: <CAB_XSX08NOo3dqcb0mJV_0pi=a-vnL5h1RYCK9PoYm3kpxA+6w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 744 bytes --]
В письме от Понедельник 03 ноября 2014 20:29:43 пользователь Eugine Kosenko
написал:
> Вопрос: как обеспечить такую верстку текста?
В аттаче популярный скрипт, проделывающий эту операцию над произвольными pdf
файлами (NB!: требует pdflatex + pdfinfo и не терпит, если имена файлов на
русском или содержат спецсимволы [это, скорее, претензии к pdflatex]).
--
Салют, /GLeb
UIN: 15341920
jabber://gleb@asd.iao.ru
sip://2387245@sipnet.ru (telephony)
skype://gleb_kulikov.tomsk (telephony)
[-- Attachment #2: pdfbook --]
[-- Type: text/x-python, Size: 5713 bytes --]
#! /usr/bin/python
# pdfbook.c Rearrange pages in a PDF file into signatures.
#
# Author Tigran Aivazian <tigran at aivazian.fsnet.co.uk> (original C version)
# Olivier Aubert <olivier.aubert at liris.cnrs.fr> (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()
next prev parent reply other threads:[~2014-11-04 4:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-03 18:29 Eugine Kosenko
2014-11-03 20:14 ` Denis G. Samsonenko
2014-11-04 4:51 ` Gleb Kulikov [this message]
2014-11-04 9:54 ` Victor
2014-11-04 13:23 ` Sergey
2014-11-06 14:38 ` Eugine Kosenko
2014-11-07 7:34 ` Sergey
2014-11-06 14:32 ` Eugine Kosenko
2014-11-13 4:24 ` Gleb Kulikov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2172782.jqFalHygcR@h77.localdomain \
--to=glebus@asd.iao.ru \
--cc=community@lists.altlinux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
ALT Linux Community general discussions
This inbox may be cloned and mirrored by anyone:
git clone --mirror http://lore.altlinux.org/community/0 community/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 community community/ http://lore.altlinux.org/community \
mandrake-russian@linuxteam.iplabs.ru community@lists.altlinux.org community@lists.altlinux.ru community@lists.altlinux.com
public-inbox-index community
Example config snippet for mirrors.
Newsgroup available over NNTP:
nntp://lore.altlinux.org/org.altlinux.lists.community
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git