ALT Linux Community general discussions
 help / color / mirror / Atom feed
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()

  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