Initial commit

This commit is contained in:
Kenneth John Odle 2022-06-19 09:39:40 -04:00
commit 7438f7ae15
62 changed files with 20565 additions and 0 deletions

0
README.md Normal file
View File

BIN
book-g19ab6d77a_640.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
pdfbooklet.xcf Normal file

Binary file not shown.

BIN
pdfbooklet_3.1.2-3_all.deb Normal file

Binary file not shown.

View File

@ -0,0 +1,10 @@
Package: pdfbooklet
Version: 3.1.2-3
Architecture: all
Maintainer: Travis CI User <travis@travis-job-15a6ca42-09e1-42ff-b563-bc763a340a91>
Installed-Size: 5214
Depends: python3 (>= 3.4), python3-gi, python3-gi-cairo, python3-cairo, gir1.2-gtk-3.0, gir1.2-poppler-0.18
Section: alien
Priority: extra
Description: Make booklets from pdfs.
Converted by ken (https://git.kjodle.net)

View File

@ -0,0 +1,56 @@
ba56c5487eb08c12bb4a9b3e6a473ad5 postinst
52eff264dbe1c88e4cdae0e226a01f18 usr/bin/pdfbooklet
906b5b82769c2aa6670ad40ecde27913 usr/lib/python3/dist-packages/pdfbooklet-3.1.2-py3.5.egg-info
7c08f7a7b39e2ff0b9ec7ad59ab1b722 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__init__.py
bee924498685db3fa219dfc099933039 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/__init__.cpython-35.pyc
daec93ab0b71a886408c2271f569d69b usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/_version.cpython-35.pyc
399edd643a7ebe5705761d266f89a39e usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/filters.cpython-35.pyc
c341762928903c2ea146bab0a98222bc usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/generic.cpython-35.pyc
7bcd7e5070ea7cfb0b1a1fcbd2ba4a0c usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/merger.cpython-35.pyc
2ff2f3bbfe9960d891ee5297d99bc18f usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/pagerange.cpython-35.pyc
10eeae6883876bf6d1e494fb48480d78 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/pdf.cpython-35.pyc
60f85ad15bc9787fe4d9cd20dd9fcaab usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/utils.cpython-35.pyc
362b7ed03b0f0f02bb241cc3a5cab13e usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/__pycache__/xmp.cpython-35.pyc
7d0617c19300e959eced5ea961d7b603 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/_version.py
3d42cf9a67139de17946475432e93a34 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/filters.py
503d65931c283b5d3ccd52f88a365476 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/generic.py
38408394fbf7442d4ece6d17ff6433cf usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/merger.py
a74524899783ee4b56529d0287c3d5f6 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/pagerange.py
e6998315652813e37c44627569cd15b2 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/pdf.py
383614f6ba70f7d5cf9ed5496c201907 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/utils.py
e6379c525ae88b173e7b3a757e2c3063 usr/lib/python3/dist-packages/pdfbooklet/PyPDF2_G/xmp.py
d41d8cd98f00b204e9800998ecf8427e usr/lib/python3/dist-packages/pdfbooklet/__init__.py
3b3d4b3ad68d0b42baa9405ffab42e37 usr/lib/python3/dist-packages/pdfbooklet/__pycache__/__init__.cpython-35.pyc
a427643aa93316c1407cbfd1327d146e usr/lib/python3/dist-packages/pdfbooklet/__pycache__/elib_intl3.cpython-35.pyc
b2a93dc73d6f8e522c9ef5aa410846ed usr/lib/python3/dist-packages/pdfbooklet/__pycache__/files_chooser.cpython-35.pyc
856537a63a5a9fd96af18dece31c782e usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfbooklet.cpython-35.pyc
7bdc8cd69d4848eb87801f4cd1c6d53d usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfshuffler_g3.cpython-35.pyc
f65a8a722149a8f678c3ef49a48444b3 usr/lib/python3/dist-packages/pdfbooklet/__pycache__/pdfshuffler_iconview3.cpython-35.pyc
16d5f3a8ea1c233c81ef7b30127bc310 usr/lib/python3/dist-packages/pdfbooklet/elib_intl3.py
7262bce50b0bd5db96c298743f519b6f usr/lib/python3/dist-packages/pdfbooklet/files_chooser.py
4560e948c3a9c0ba561156c89222afe9 usr/lib/python3/dist-packages/pdfbooklet/pdfbooklet.py
85ff4690d95bcf0bc5dc88dc4518edee usr/lib/python3/dist-packages/pdfbooklet/pdfshuffler_g3.py
b18a190a171e1ae57118620f27773a26 usr/lib/python3/dist-packages/pdfbooklet/pdfshuffler_iconview3.py
f2a9808fe8ae4e932d6c471cf6326cb6 usr/share/applications/pdfbooklet.desktop
1e65a1a059a7ba375e144e57bafe0e03 usr/share/doc/pdfbooklet/changelog.Debian.gz
8c836ce2f8e3261dbabc7592a7cc9b6f usr/share/doc/pdfbooklet/copyright
5495e0fdf28e395bf3229069a7c5e1af usr/share/locale/fr/LC_MESSAGES/pdfbooklet.mo
b67b9bb1ea5b769203c3e73d9ecc4771 usr/share/locale/fr/LC_MESSAGES/pdfbooklet.po
97fc5e114afab69b2dda1d9ed27732d5 usr/share/locale/fr/LC_MESSAGES/pdfshuffler.mo
0bcfbf4a7a4e98c1dbd520fcc04ad342 usr/share/locale/fr/LC_MESSAGES/pdfshuffler.po
c3bc3ac07fa1d1c6f6c95e3e9d039908 usr/share/pdfbooklet/data/chooser_dialog.glade
84ff01d09458dc41a43edbc175896dd5 usr/share/pdfbooklet/data/nofile.pdf
f2a9808fe8ae4e932d6c471cf6326cb6 usr/share/pdfbooklet/data/pdfbooklet.desktop
7ba7a6336c65f32291fa2f4f1780dd44 usr/share/pdfbooklet/data/pdfbooklet.ico
ff8b8bd0473cff3b5f2e67f087674a95 usr/share/pdfbooklet/data/pdfbooklet.png
36aaf7de5c575a414bad40039dffbd5d usr/share/pdfbooklet/data/pdfbooklet.svg
7206b41ae6a12a3e60a66255f309d3a0 usr/share/pdfbooklet/data/pdfbooklet3.glade
22cc082abf6cc863fe0575fc574bac0f usr/share/pdfbooklet/data/pdfshuffler.ico
c101a33982b86a5e4deb7b49bd6a2252 usr/share/pdfbooklet/data/pdfshuffler64.ico
e08557a923bdc9dc3cb374ee36110a5d usr/share/pdfbooklet/data/pdfshuffler64.png
1d1da34644d20ead9325f6bbf6f2d9dd usr/share/pdfbooklet/data/pdfshuffler_g.glade
3242edc53175c4d9930b8f96529514c1 usr/share/pdfbooklet/documentation/Manuel_de_Pdf-Booklet.pdf
7c1c11d075a5ac583700a173ca40f589 usr/share/pdfbooklet/documentation/Note_for_Linux_users_3.0.6.html
09a1b8a9c361be1c84b5863d63344e3b usr/share/pdfbooklet/documentation/Pdf-Booklet_User's_Guide.pdf
36aaf7de5c575a414bad40039dffbd5d usr/share/pdfbooklet/icons/hicolor/scalable/pdfbooklet.svg
ff8b8bd0473cff3b5f2e67f087674a95 usr/share/pixmaps/pdfbooklet.png

View File

@ -0,0 +1 @@
chmod 777 ./usr/share/pdfbooklet/

View File

@ -0,0 +1,33 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
PdfBooklet 2.2.2 - GTK+ based utility for creating booklets
and other layouts from PDF documents.
<https://sourceforge.net/projects/pdfbooklet>
This file is part of PdfBooklet.
PdfBooklet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
try:
from pdfbooklet.pdfbooklet import main
main()
except ImportError as e:
print('Error: Could not import pdfbooklet')
print('Cause: %s' % e)

View File

@ -0,0 +1,10 @@
Metadata-Version: 1.0
Name: pdfbooklet
Version: 3.1.2
Summary: A simple application for creating booklets and other layouts from PDF files
Home-page: https://sourceforge.net/projects/pdfbooklet
Author: GAF Software
Author-email: Averell7 at sourceforge dot net
License: GNU GPL-3
Description: UNKNOWN
Platform: UNKNOWN

View File

@ -0,0 +1,5 @@
from .pdf import PdfFileReader, PdfFileWriter
from .merger import PdfFileMerger
from .pagerange import PageRange, parse_filename_page_ranges
from ._version import __version__
__all__ = ["pdf", "PdfFileMerger"]

View File

@ -0,0 +1 @@
__version__ = '1.25.1'

View File

@ -0,0 +1,362 @@
# vim: sw=4:expandtab:foldmethod=marker
#
# Copyright (c) 2006, Mathieu Fenniak
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
Implementation of stream filters for PDF.
"""
__author__ = "Mathieu Fenniak"
__author_email__ = "biziqe@mathieu.fenniak.net"
from .utils import PdfReadError, ord_, chr_
from sys import version_info
if version_info < ( 3, 0 ):
from cStringIO import StringIO
else:
from io import StringIO
import struct
try:
import zlib
def decompress(data):
return zlib.decompress(data)
def compress(data):
return zlib.compress(data)
except ImportError:
# Unable to import zlib. Attempt to use the System.IO.Compression
# library from the .NET framework. (IronPython only)
import System
from System import IO, Collections, Array
def _string_to_bytearr(buf):
retval = Array.CreateInstance(System.Byte, len(buf))
for i in range(len(buf)):
retval[i] = ord(buf[i])
return retval
def _bytearr_to_string(bytes):
retval = ""
for i in range(bytes.Length):
retval += chr(bytes[i])
return retval
def _read_bytes(stream):
ms = IO.MemoryStream()
buf = Array.CreateInstance(System.Byte, 2048)
while True:
bytes = stream.Read(buf, 0, buf.Length)
if bytes == 0:
break
else:
ms.Write(buf, 0, bytes)
retval = ms.ToArray()
ms.Close()
return retval
def decompress(data):
bytes = _string_to_bytearr(data)
ms = IO.MemoryStream()
ms.Write(bytes, 0, bytes.Length)
ms.Position = 0 # fseek 0
gz = IO.Compression.DeflateStream(ms, IO.Compression.CompressionMode.Decompress)
bytes = _read_bytes(gz)
retval = _bytearr_to_string(bytes)
gz.Close()
return retval
def compress(data):
bytes = _string_to_bytearr(data)
ms = IO.MemoryStream()
gz = IO.Compression.DeflateStream(ms, IO.Compression.CompressionMode.Compress, True)
gz.Write(bytes, 0, bytes.Length)
gz.Close()
ms.Position = 0 # fseek 0
bytes = ms.ToArray()
retval = _bytearr_to_string(bytes)
ms.Close()
return retval
class FlateDecode(object):
def decode(data, decodeParms):
data = decompress(data)
predictor = 1
if decodeParms:
try:
predictor = decodeParms.get("/Predictor", 1)
except AttributeError:
pass # usually an array with a null object was read
# predictor 1 == no predictor
if predictor != 1:
columns = decodeParms["/Columns"]
# PNG prediction:
if predictor >= 10 and predictor <= 15:
output = StringIO()
# PNG prediction can vary from row to row
rowlength = columns + 1
assert len(data) % rowlength == 0
prev_rowdata = (0,) * rowlength
for row in range(len(data) // rowlength):
rowdata = [ord_(x) for x in data[(row*rowlength):((row+1)*rowlength)]]
filterByte = rowdata[0]
if filterByte == 0:
pass
elif filterByte == 1:
for i in range(2, rowlength):
rowdata[i] = (rowdata[i] + rowdata[i-1]) % 256
elif filterByte == 2:
for i in range(1, rowlength):
rowdata[i] = (rowdata[i] + prev_rowdata[i]) % 256
else:
# unsupported PNG filter
raise PdfReadError("Unsupported PNG filter %r" % filterByte)
prev_rowdata = rowdata
output.write(''.join([chr(x) for x in rowdata[1:]]))
data = output.getvalue()
else:
# unsupported predictor
raise PdfReadError("Unsupported flatedecode predictor %r" % predictor)
return data
decode = staticmethod(decode)
def encode(data):
return compress(data)
encode = staticmethod(encode)
class ASCIIHexDecode(object):
def decode(data, decodeParms=None):
retval = ""
char = ""
x = 0
while True:
c = data[x]
if c == ">":
break
elif c.isspace():
x += 1
continue
char += c
if len(char) == 2:
retval += chr(int(char, base=16))
char = ""
x += 1
assert char == ""
return retval
decode = staticmethod(decode)
class LZWDecode(object):
"""Taken from:
http://www.java2s.com/Open-Source/Java-Document/PDF/PDF-Renderer/com/sun/pdfview/decode/LZWDecode.java.htm
"""
class decoder(object):
def __init__(self, data):
self.STOP=257
self.CLEARDICT=256
self.data=data
self.bytepos=0
self.bitpos=0
self.dict=[""]*4096
for i in range(256):
self.dict[i]=chr(i)
self.resetDict()
def resetDict(self):
self.dictlen=258
self.bitspercode=9
def nextCode(self):
fillbits=self.bitspercode
value=0
while fillbits>0 :
if self.bytepos >= len(self.data):
return -1
nextbits=ord(self.data[self.bytepos])
bitsfromhere=8-self.bitpos
if bitsfromhere>fillbits:
bitsfromhere=fillbits
value |= (((nextbits >> (8-self.bitpos-bitsfromhere)) &
(0xff >> (8-bitsfromhere))) <<
(fillbits-bitsfromhere))
fillbits -= bitsfromhere
self.bitpos += bitsfromhere
if self.bitpos >=8:
self.bitpos=0
self.bytepos = self.bytepos+1
return value
def decode(self):
""" algorithm derived from:
http://www.rasip.fer.hr/research/compress/algorithms/fund/lz/lzw.html
and the PDFReference
"""
cW = self.CLEARDICT;
baos=""
while True:
pW = cW;
cW = self.nextCode();
if cW == -1:
raise PdfReadError("Missed the stop code in LZWDecode!")
if cW == self.STOP:
break;
elif cW == self.CLEARDICT:
self.resetDict();
elif pW == self.CLEARDICT:
baos+=self.dict[cW]
else:
if cW < self.dictlen:
baos += self.dict[cW]
p=self.dict[pW]+self.dict[cW][0]
self.dict[self.dictlen]=p
self.dictlen+=1
else:
p=self.dict[pW]+self.dict[pW][0]
baos+=p
self.dict[self.dictlen] = p;
self.dictlen+=1
if (self.dictlen >= (1 << self.bitspercode) - 1 and
self.bitspercode < 12):
self.bitspercode+=1
return baos
@staticmethod
def decode(data,decodeParams=None):
return LZWDecode.decoder(data).decode()
class ASCII85Decode(object):
def decode(data, decodeParms=None):
if version_info < ( 3, 0 ):
retval = ""
group = []
x = 0
hitEod = False
# remove all whitespace from data
data = [y for y in data if not (y in ' \n\r\t')]
while not hitEod:
c = data[x]
if len(retval) == 0 and c == "<" and data[x+1] == "~":
x += 2
continue
#elif c.isspace():
# x += 1
# continue
elif c == 'z':
assert len(group) == 0
retval += '\x00\x00\x00\x00'
x += 1
continue
elif c == "~" and data[x+1] == ">":
if len(group) != 0:
# cannot have a final group of just 1 char
assert len(group) > 1
cnt = len(group) - 1
group += [ 85, 85, 85 ]
hitEod = cnt
else:
break
else:
c = ord(c) - 33
assert c >= 0 and c < 85
group += [ c ]
if len(group) >= 5:
b = group[0] * (85**4) + \
group[1] * (85**3) + \
group[2] * (85**2) + \
group[3] * 85 + \
group[4]
assert b < (2**32 - 1)
c4 = chr((b >> 0) % 256)
c3 = chr((b >> 8) % 256)
c2 = chr((b >> 16) % 256)
c1 = chr(b >> 24)
retval += (c1 + c2 + c3 + c4)
if hitEod:
retval = retval[:-4+hitEod]
group = []
x += 1
return retval
else:
if isinstance(data, str):
data = data.encode('ascii')
n = b = 0
out = bytearray()
for c in data:
if ord('!') <= c and c <= ord('u'):
n += 1
b = b*85+(c-33)
if n == 5:
out += struct.pack(b'>L',b)
n = b = 0
elif c == ord('z'):
assert n == 0
out += b'\0\0\0\0'
elif c == ord('~'):
if n:
for _ in range(5-n):
b = b*85+84
out += struct.pack(b'>L',b)[:n-1]
break
return bytes(out)
decode = staticmethod(decode)
def decodeStreamData(stream):
from .generic import NameObject
filters = stream.get("/Filter", ())
if len(filters) and not isinstance(filters[0], NameObject):
# we have a single filter instance
filters = (filters,)
data = stream._data
# If there is not data to decode we should not try to decode the data.
if data:
for filterType in filters:
if filterType == "/FlateDecode" or filterType == "/Fl":
data = FlateDecode.decode(data, stream.get("/DecodeParms"))
elif filterType == "/ASCIIHexDecode" or filterType == "/AHx":
data = ASCIIHexDecode.decode(data)
elif filterType == "/LZWDecode" or filterType == "/LZW":
data = LZWDecode.decode(data, stream.get("/DecodeParms"))
elif filterType == "/ASCII85Decode" or filterType == "/A85":
data = ASCII85Decode.decode(data)
elif filterType == "/Crypt":
decodeParams = stream.get("/DecodeParams", {})
if "/Name" not in decodeParams and "/Type" not in decodeParams:
pass
else:
raise NotImplementedError("/Crypt filter with /Name or /Type not supported yet")
else:
# unsupported filter
raise NotImplementedError("unsupported filter %s" % filterType)
return data

View File

@ -0,0 +1,553 @@
# vim: sw=4:expandtab:foldmethod=marker
#
# Copyright (c) 2006, Mathieu Fenniak
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from .generic import *
from .utils import isString, str_
from .pdf import PdfFileReader, PdfFileWriter
from .pagerange import PageRange
from sys import version_info
if version_info < ( 3, 0 ):
from cStringIO import StringIO
StreamIO = StringIO
else:
from io import BytesIO
from io import FileIO as file
StreamIO = BytesIO
class _MergedPage(object):
"""
_MergedPage is used internally by PdfFileMerger to collect necessary
information on each page that is being merged.
"""
def __init__(self, pagedata, src, id):
self.src = src
self.pagedata = pagedata
self.out_pagedata = None
self.id = id
class PdfFileMerger(object):
"""
Initializes a PdfFileMerger object. PdfFileMerger merges multiple PDFs
into a single PDF. It can concatenate, slice, insert, or any combination
of the above.
See the functions :meth:`merge()<merge>` (or :meth:`append()<append>`)
and :meth:`write()<write>` for usage information.
:param bool strict: Determines whether user should be warned of all
problems and also causes some correctable problems to be fatal.
Defaults to ``True``.
"""
def __init__(self, strict=True):
self.inputs = []
self.pages = []
self.output = PdfFileWriter()
self.bookmarks = []
self.named_dests = []
self.id_count = 0
self.strict = strict
def merge(self, position, fileobj, bookmark=None, pages=None, import_bookmarks=True):
"""
Merges the pages from the given file into the output file at the
specified page number.
:param int position: The *page number* to insert this file. File will
be inserted after the given number.
:param fileobj: A File Object or an object that supports the standard read
and seek methods similar to a File Object. Could also be a
string representing a path to a PDF file.
:param str bookmark: Optionally, you may specify a bookmark to be applied at
the beginning of the included file by supplying the text of the bookmark.
:param pages: can be a :ref:`Page Range <page-range>` or a ``(start, stop[, step])`` tuple
to merge only the specified range of pages from the source
document into the output document.
:param bool import_bookmarks: You may prevent the source document's bookmarks
from being imported by specifying this as ``False``.
"""
# This parameter is passed to self.inputs.append and means
# that the stream used was created in this method.
my_file = False
# If the fileobj parameter is a string, assume it is a path
# and create a file object at that location. If it is a file,
# copy the file's contents into a BytesIO (or StreamIO) stream object; if
# it is a PdfFileReader, copy that reader's stream into a
# BytesIO (or StreamIO) stream.
# If fileobj is none of the above types, it is not modified
decryption_key = None
if isString(fileobj):
fileobj = file(fileobj, 'rb')
my_file = True
elif isinstance(fileobj, file):
fileobj.seek(0)
filecontent = fileobj.read()
fileobj = StreamIO(filecontent)
my_file = True
elif isinstance(fileobj, PdfFileReader):
orig_tell = fileobj.stream.tell()
fileobj.stream.seek(0)
filecontent = StreamIO(fileobj.stream.read())
fileobj.stream.seek(orig_tell) # reset the stream to its original location
fileobj = filecontent
if hasattr(fileobj, '_decryption_key'):
decryption_key = fileobj._decryption_key
my_file = True
# Create a new PdfFileReader instance using the stream
# (either file or BytesIO or StringIO) created above
pdfr = PdfFileReader(fileobj, strict=self.strict)
if decryption_key is not None:
pdfr._decryption_key = decryption_key
# Find the range of pages to merge.
if pages == None:
pages = (0, pdfr.getNumPages())
elif isinstance(pages, PageRange):
pages = pages.indices(pdfr.getNumPages())
elif not isinstance(pages, tuple):
raise TypeError('"pages" must be a tuple of (start, stop[, step])')
srcpages = []
if bookmark:
bookmark = Bookmark(TextStringObject(bookmark), NumberObject(self.id_count), NameObject('/Fit'))
outline = []
if import_bookmarks:
outline = pdfr.getOutlines()
outline = self._trim_outline(pdfr, outline, pages)
if bookmark:
self.bookmarks += [bookmark, outline]
else:
self.bookmarks += outline
dests = pdfr.namedDestinations
dests = self._trim_dests(pdfr, dests, pages)
self.named_dests += dests
# Gather all the pages that are going to be merged
for i in range(*pages):
pg = pdfr.getPage(i)
id = self.id_count
self.id_count += 1
mp = _MergedPage(pg, pdfr, id)
srcpages.append(mp)
self._associate_dests_to_pages(srcpages)
self._associate_bookmarks_to_pages(srcpages)
# Slice to insert the pages at the specified position
self.pages[position:position] = srcpages
# Keep track of our input files so we can close them later
self.inputs.append((fileobj, pdfr, my_file))
def append(self, fileobj, bookmark=None, pages=None, import_bookmarks=True):
"""
Identical to the :meth:`merge()<merge>` method, but assumes you want to concatenate
all pages onto the end of the file instead of specifying a position.
:param fileobj: A File Object or an object that supports the standard read
and seek methods similar to a File Object. Could also be a
string representing a path to a PDF file.
:param str bookmark: Optionally, you may specify a bookmark to be applied at
the beginning of the included file by supplying the text of the bookmark.
:param pages: can be a :ref:`Page Range <page-range>` or a ``(start, stop[, step])`` tuple
to merge only the specified range of pages from the source
document into the output document.
:param bool import_bookmarks: You may prevent the source document's bookmarks
from being imported by specifying this as ``False``.
"""
self.merge(len(self.pages), fileobj, bookmark, pages, import_bookmarks)
def write(self, fileobj):
"""
Writes all data that has been merged to the given output file.
:param fileobj: Output file. Can be a filename or any kind of
file-like object.
"""
my_file = False
if isString(fileobj):
fileobj = file(fileobj, 'wb')
my_file = True
# Add pages to the PdfFileWriter
# The commented out line below was replaced with the two lines below it to allow PdfFileMerger to work with PyPdf 1.13
for page in self.pages:
self.output.addPage(page.pagedata)
page.out_pagedata = self.output.getReference(self.output._pages.getObject()["/Kids"][-1].getObject())
#idnum = self.output._objects.index(self.output._pages.getObject()["/Kids"][-1].getObject()) + 1
#page.out_pagedata = IndirectObject(idnum, 0, self.output)
# Once all pages are added, create bookmarks to point at those pages
self._write_dests()
self._write_bookmarks()
# Write the output to the file
self.output.write(fileobj)
if my_file:
fileobj.close()
def close(self):
"""
Shuts all file descriptors (input and output) and clears all memory
usage.
"""
self.pages = []
for fo, pdfr, mine in self.inputs:
if mine:
fo.close()
self.inputs = []
self.output = None
def addMetadata(self, infos):
"""
Add custom metadata to the output.
:param dict infos: a Python dictionary where each key is a field
and each value is your new metadata.
Example: ``{u'/Title': u'My title'}``
"""
self.output.addMetadata(infos)
def setPageLayout(self, layout):
"""
Set the page layout
:param str layout: The page layout to be used
Valid layouts are:
/NoLayout Layout explicitly not specified
/SinglePage Show one page at a time
/OneColumn Show one column at a time
/TwoColumnLeft Show pages in two columns, odd-numbered pages on the left
/TwoColumnRight Show pages in two columns, odd-numbered pages on the right
/TwoPageLeft Show two pages at a time, odd-numbered pages on the left
/TwoPageRight Show two pages at a time, odd-numbered pages on the right
"""
self.output.setPageLayout(layout)
def setPageMode(self, mode):
"""
Set the page mode.
:param str mode: The page mode to use.
Valid modes are:
/UseNone Do not show outlines or thumbnails panels
/UseOutlines Show outlines (aka bookmarks) panel
/UseThumbs Show page thumbnails panel
/FullScreen Fullscreen view
/UseOC Show Optional Content Group (OCG) panel
/UseAttachments Show attachments panel
"""
self.output.setPageMode(mode)
def _trim_dests(self, pdf, dests, pages):
"""
Removes any named destinations that are not a part of the specified
page set.
"""
new_dests = []
prev_header_added = True
for k, o in list(dests.items()):
for j in range(*pages):
if pdf.getPage(j).getObject() == o['/Page'].getObject():
o[NameObject('/Page')] = o['/Page'].getObject()
assert str_(k) == str_(o['/Title'])
new_dests.append(o)
break
return new_dests
def _trim_outline(self, pdf, outline, pages):
"""
Removes any outline/bookmark entries that are not a part of the
specified page set.
"""
new_outline = []
prev_header_added = True
for i, o in enumerate(outline):
if isinstance(o, list):
sub = self._trim_outline(pdf, o, pages)
if sub:
if not prev_header_added:
new_outline.append(outline[i-1])
new_outline.append(sub)
else:
prev_header_added = False
for j in range(*pages):
if pdf.getPage(j).getObject() == o['/Page'].getObject():
o[NameObject('/Page')] = o['/Page'].getObject()
new_outline.append(o)
prev_header_added = True
break
return new_outline
def _write_dests(self):
dests = self.named_dests
for v in dests:
pageno = None
pdf = None
if '/Page' in v:
for i, p in enumerate(self.pages):
if p.id == v['/Page']:
v[NameObject('/Page')] = p.out_pagedata
pageno = i
pdf = p.src
break
if pageno != None:
self.output.addNamedDestinationObject(v)
def _write_bookmarks(self, bookmarks=None, parent=None):
if bookmarks == None:
bookmarks = self.bookmarks
last_added = None
for b in bookmarks:
if isinstance(b, list):
self._write_bookmarks(b, last_added)
continue
pageno = None
pdf = None
if '/Page' in b:
for i, p in enumerate(self.pages):
if p.id == b['/Page']:
#b[NameObject('/Page')] = p.out_pagedata
args = [NumberObject(p.id), NameObject(b['/Type'])]
#nothing more to add
#if b['/Type'] == '/Fit' or b['/Type'] == '/FitB'
if b['/Type'] == '/FitH' or b['/Type'] == '/FitBH':
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Top']
elif b['/Type'] == '/FitV' or b['/Type'] == '/FitBV':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
del b['/Left']
elif b['/Type'] == '/XYZ':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
if '/Zoom' in b and not isinstance(b['/Zoom'], NullObject):
args.append(FloatObject(b['/Zoom']))
else:
args.append(FloatObject(0))
del b['/Top'], b['/Zoom'], b['/Left']
elif b['/Type'] == '/FitR':
if '/Left' in b and not isinstance(b['/Left'], NullObject):
args.append(FloatObject(b['/Left']))
else:
args.append(FloatObject(0))
if '/Bottom' in b and not isinstance(b['/Bottom'], NullObject):
args.append(FloatObject(b['/Bottom']))
else:
args.append(FloatObject(0))
if '/Right' in b and not isinstance(b['/Right'], NullObject):
args.append(FloatObject(b['/Right']))
else:
args.append(FloatObject(0))
if '/Top' in b and not isinstance(b['/Top'], NullObject):
args.append(FloatObject(b['/Top']))
else:
args.append(FloatObject(0))
del b['/Left'], b['/Right'], b['/Bottom'], b['/Top']
b[NameObject('/A')] = DictionaryObject({NameObject('/S'): NameObject('/GoTo'), NameObject('/D'): ArrayObject(args)})
pageno = i
pdf = p.src
break
if pageno != None:
del b['/Page'], b['/Type']
last_added = self.output.addBookmarkDict(b, parent)
def _associate_dests_to_pages(self, pages):
for nd in self.named_dests:
pageno = None
np = nd['/Page']
if isinstance(np, NumberObject):
continue
for p in pages:
if np.getObject() == p.pagedata.getObject():
pageno = p.id
if pageno != None:
nd[NameObject('/Page')] = NumberObject(pageno)
else:
raise ValueError("Unresolved named destination '%s'" % (nd['/Title'],))
def _associate_bookmarks_to_pages(self, pages, bookmarks=None):
if bookmarks == None:
bookmarks = self.bookmarks
for b in bookmarks:
if isinstance(b, list):
self._associate_bookmarks_to_pages(pages, b)
continue
pageno = None
bp = b['/Page']
if isinstance(bp, NumberObject):
continue
for p in pages:
if bp.getObject() == p.pagedata.getObject():
pageno = p.id
if pageno != None:
b[NameObject('/Page')] = NumberObject(pageno)
else:
raise ValueError("Unresolved bookmark '%s'" % (b['/Title'],))
def findBookmark(self, bookmark, root=None):
if root == None:
root = self.bookmarks
for i, b in enumerate(root):
if isinstance(b, list):
res = self.findBookmark(bookmark, b)
if res:
return [i] + res
elif b == bookmark or b['/Title'] == bookmark:
return [i]
return None
def addBookmark(self, title, pagenum, parent=None):
"""
Add a bookmark to this PDF file.
:param str title: Title to use for this bookmark.
:param int pagenum: Page number this bookmark will point to.
:param parent: A reference to a parent bookmark to create nested
bookmarks.
"""
if parent == None:
iloc = [len(self.bookmarks)-1]
elif isinstance(parent, list):
iloc = parent
else:
iloc = self.findBookmark(parent)
dest = Bookmark(TextStringObject(title), NumberObject(pagenum), NameObject('/FitH'), NumberObject(826))
if parent == None:
self.bookmarks.append(dest)
else:
bmparent = self.bookmarks
for i in iloc[:-1]:
bmparent = bmparent[i]
npos = iloc[-1]+1
if npos < len(bmparent) and isinstance(bmparent[npos], list):
bmparent[npos].append(dest)
else:
bmparent.insert(npos, [dest])
return dest
def addNamedDestination(self, title, pagenum):
"""
Add a destination to the output.
:param str title: Title to use
:param int pagenum: Page number this destination points at.
"""
dest = Destination(TextStringObject(title), NumberObject(pagenum), NameObject('/FitH'), NumberObject(826))
self.named_dests.append(dest)
class OutlinesObject(list):
def __init__(self, pdf, tree, parent=None):
list.__init__(self)
self.tree = tree
self.pdf = pdf
self.parent = parent
def remove(self, index):
obj = self[index]
del self[index]
self.tree.removeChild(obj)
def add(self, title, pagenum):
pageRef = self.pdf.getObject(self.pdf._pages)['/Kids'][pagenum]
action = DictionaryObject()
action.update({
NameObject('/D') : ArrayObject([pageRef, NameObject('/FitH'), NumberObject(826)]),
NameObject('/S') : NameObject('/GoTo')
})
actionRef = self.pdf._addObject(action)
bookmark = TreeObject()
bookmark.update({
NameObject('/A'): actionRef,
NameObject('/Title'): createStringObject(title),
})
self.pdf._addObject(bookmark)
self.tree.addChild(bookmark)
def removeAll(self):
for child in [x for x in self.tree.children()]:
self.tree.removeChild(child)
self.pop()

View File

@ -0,0 +1,152 @@
#!/usr/bin/env python
"""
Representation and utils for ranges of PDF file pages.
Copyright (c) 2014, Steve Witham <switham_github@mac-guyver.com>.
All rights reserved. This software is available under a BSD license;
see https://github.com/mstamy2/PyPDF2/blob/master/LICENSE
"""
import re
from .utils import isString
_INT_RE = r"(0|-?[1-9]\d*)" # A decimal int, don't allow "-0".
PAGE_RANGE_RE = "^({int}|({int}?(:{int}?(:{int}?)?)))$".format(int=_INT_RE)
# groups: 12 34 5 6 7 8
class ParseError(Exception):
pass
PAGE_RANGE_HELP = """Remember, page indices start with zero.
Page range expression examples:
: all pages. -1 last page.
22 just the 23rd page. :-1 all but the last page.
0:3 the first three pages. -2 second-to-last page.
:3 the first three pages. -2: last two pages.
5: from the sixth page onward. -3:-1 third & second to last.
The third, "stride" or "step" number is also recognized.
::2 0 2 4 ... to the end. 3:0:-1 3 2 1 but not 0.
1:10:2 1 3 5 7 9 2::-1 2 1 0.
::-1 all pages in reverse order.
"""
class PageRange(object):
"""
A slice-like representation of a range of page indices,
i.e. page numbers, only starting at zero.
The syntax is like what you would put between brackets [ ].
The slice is one of the few Python types that can't be subclassed,
but this class converts to and from slices, and allows similar use.
o PageRange(str) parses a string representing a page range.
o PageRange(slice) directly "imports" a slice.
o to_slice() gives the equivalent slice.
o str() and repr() allow printing.
o indices(n) is like slice.indices(n).
"""
def __init__(self, arg):
"""
Initialize with either a slice -- giving the equivalent page range,
or a PageRange object -- making a copy,
or a string like
"int", "[int]:[int]" or "[int]:[int]:[int]",
where the brackets indicate optional ints.
{page_range_help}
Note the difference between this notation and arguments to slice():
slice(3) means the first three pages;
PageRange("3") means the range of only the fourth page.
However PageRange(slice(3)) means the first three pages.
"""
if isinstance(arg, slice):
self._slice = arg
return
if isinstance(arg, PageRange):
self._slice = arg.to_slice()
return
m = isString(arg) and re.match(PAGE_RANGE_RE, arg)
if not m:
raise ParseError(arg)
elif m.group(2):
# Special case: just an int means a range of one page.
start = int(m.group(2))
stop = start + 1 if start != -1 else None
self._slice = slice(start, stop)
else:
self._slice = slice(*[int(g) if g else None
for g in m.group(4, 6, 8)])
# Just formatting this when there is __doc__ for __init__
if __init__.__doc__:
__init__.__doc__ = __init__.__doc__.format(page_range_help=PAGE_RANGE_HELP)
@staticmethod
def valid(input):
""" True if input is a valid initializer for a PageRange. """
return isinstance(input, slice) or \
isinstance(input, PageRange) or \
(isString(input)
and bool(re.match(PAGE_RANGE_RE, input)))
def to_slice(self):
""" Return the slice equivalent of this page range. """
return self._slice
def __str__(self):
""" A string like "1:2:3". """
s = self._slice
if s.step == None:
if s.start != None and s.stop == s.start + 1:
return str(s.start)
indices = s.start, s.stop
else:
indices = s.start, s.stop, s.step
return ':'.join("" if i == None else str(i) for i in indices)
def __repr__(self):
""" A string like "PageRange('1:2:3')". """
return "PageRange(" + repr(str(self)) + ")"
def indices(self, n):
"""
n is the length of the list of pages to choose from.
Returns arguments for range(). See help(slice.indices).
"""
return self._slice.indices(n)
PAGE_RANGE_ALL = PageRange(":") # The range of all pages.
def parse_filename_page_ranges(args):
"""
Given a list of filenames and page ranges, return a list of
(filename, page_range) pairs.
First arg must be a filename; other ags are filenames, page-range
expressions, slice objects, or PageRange objects.
A filename not followed by a page range indicates all pages of the file.
"""
pairs = []
pdf_filename = None
did_page_range = False
for arg in args + [None]:
if PageRange.valid(arg):
if not pdf_filename:
raise ValueError("The first argument must be a filename, " \
"not a page range.")
pairs.append( (pdf_filename, PageRange(arg)) )
did_page_range = True
else:
# New filename or end of list--do all of the previous file?
if pdf_filename and not did_page_range:
pairs.append( (pdf_filename, PAGE_RANGE_ALL) )
pdf_filename = arg
did_page_range = False
return pairs

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,295 @@
# Copyright (c) 2006, Mathieu Fenniak
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
Utility functions for PDF library.
"""
__author__ = "Mathieu Fenniak"
__author_email__ = "biziqe@mathieu.fenniak.net"
import sys
try:
import __builtin__ as builtins
except ImportError: # Py3
import builtins
xrange_fn = getattr(builtins, "xrange", range)
_basestring = getattr(builtins, "basestring", str)
bytes_type = type(bytes()) # Works the same in Python 2.X and 3.X
string_type = getattr(builtins, "unicode", str)
int_types = (int, long) if sys.version_info[0] < 3 else (int,)
# Make basic type tests more consistent
def isString(s):
"""Test if arg is a string. Compatible with Python 2 and 3."""
return isinstance(s, _basestring)
def isInt(n):
"""Test if arg is an int. Compatible with Python 2 and 3."""
return isinstance(n, int_types)
def isBytes(b):
"""Test if arg is a bytes instance. Compatible with Python 2 and 3."""
return isinstance(b, bytes_type)
#custom implementation of warnings.formatwarning
def formatWarning(message, category, filename, lineno, line=None):
file = filename.replace("/", "\\").rsplit("\\", 1)[1] # find the file name
return "%s: %s [%s:%s]\n" % (category.__name__, message, file, lineno)
def readUntilWhitespace(stream, maxchars=None):
"""
Reads non-whitespace characters and returns them.
Stops upon encountering whitespace or when maxchars is reached.
"""
txt = b_("")
while True:
tok = stream.read(1)
if tok.isspace() or not tok:
break
txt += tok
if len(txt) == maxchars:
break
return txt
def readNonWhitespace(stream):
"""
Finds and reads the next non-whitespace character (ignores whitespace).
"""
tok = WHITESPACES[0]
while tok in WHITESPACES:
tok = stream.read(1)
return tok
def skipOverWhitespace(stream):
"""
Similar to readNonWhitespace, but returns a Boolean if more than
one whitespace character was read.
"""
tok = WHITESPACES[0]
cnt = 0;
while tok in WHITESPACES:
tok = stream.read(1)
cnt+=1
return (cnt > 1)
def skipOverComment(stream):
tok = stream.read(1)
stream.seek(-1, 1)
if tok == b_('%'):
while tok not in (b_('\n'), b_('\r')):
tok = stream.read(1)
def readUntilRegex(stream, regex, ignore_eof=False):
"""
Reads until the regular expression pattern matched (ignore the match)
Raise PdfStreamError on premature end-of-file.
:param bool ignore_eof: If true, ignore end-of-line and return immediately
"""
name = b_('')
while True:
tok = stream.read(16)
if not tok:
# stream has truncated prematurely
if ignore_eof == True:
return name
else:
raise PdfStreamError("Stream has ended unexpectedly")
m = regex.search(tok)
if m is not None:
name += tok[:m.start()]
stream.seek(m.start()-len(tok), 1)
break
name += tok
return name
class ConvertFunctionsToVirtualList(object):
def __init__(self, lengthFunction, getFunction):
self.lengthFunction = lengthFunction
self.getFunction = getFunction
def __len__(self):
return self.lengthFunction()
def __getitem__(self, index):
if isinstance(index, slice):
indices = xrange_fn(*index.indices(len(self)))
cls = type(self)
return cls(indices.__len__, lambda idx: self[indices[idx]])
if not isInt(index):
raise TypeError("sequence indices must be integers")
len_self = len(self)
if index < 0:
# support negative indexes
index = len_self + index
if index < 0 or index >= len_self:
raise IndexError("sequence index out of range")
return self.getFunction(index)
def RC4_encrypt(key, plaintext):
S = [i for i in range(256)]
j = 0
for i in range(256):
j = (j + S[i] + ord_(key[i % len(key)])) % 256
S[i], S[j] = S[j], S[i]
i, j = 0, 0
retval = b_("")
for x in range(len(plaintext)):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = S[(S[i] + S[j]) % 256]
retval += b_(chr(ord_(plaintext[x]) ^ t))
return retval
def matrixMultiply(a, b):
return [[sum([float(i)*float(j)
for i, j in zip(row, col)]
) for col in zip(*b)]
for row in a]
def markLocation(stream):
"""Creates text file showing current location in context."""
# Mainly for debugging
RADIUS = 5000
stream.seek(-RADIUS, 1)
outputDoc = open('PyPDF2_pdfLocation.txt', 'w')
outputDoc.write(stream.read(RADIUS))
outputDoc.write('HERE')
outputDoc.write(stream.read(RADIUS))
outputDoc.close()
stream.seek(-RADIUS, 1)
class PyPdfError(Exception):
pass
class PdfReadError(PyPdfError):
pass
class PageSizeNotDefinedError(PyPdfError):
pass
class PdfReadWarning(UserWarning):
pass
class PdfStreamError(PdfReadError):
pass
if sys.version_info[0] < 3:
def b_(s):
return s
else:
B_CACHE = {}
def b_(s):
bc = B_CACHE
if s in bc:
return bc[s]
if type(s) == bytes:
return s
else:
r = s.encode('latin-1')
if len(s) < 2:
bc[s] = r
return r
def u_(s):
if sys.version_info[0] < 3:
return unicode(s, 'unicode_escape')
else:
return s
def str_(b):
if sys.version_info[0] < 3:
return b
else:
if type(b) == bytes:
return b.decode('latin-1')
else:
return b
def ord_(b):
if sys.version_info[0] < 3 or type(b) == str:
return ord(b)
else:
return b
def chr_(c):
if sys.version_info[0] < 3:
return c
else:
return chr(c)
def barray(b):
if sys.version_info[0] < 3:
return b
else:
return bytearray(b)
def hexencode(b):
if sys.version_info[0] < 3:
return b.encode('hex')
else:
import codecs
coder = codecs.getencoder('hex_codec')
return coder(b)[0]
def hexStr(num):
return hex(num).replace('L', '')
WHITESPACES = [b_(x) for x in [' ', '\n', '\r', '\t', '\x00']]

View File

@ -0,0 +1,358 @@
import re
import datetime
import decimal
from .generic import PdfObject
from xml.dom import getDOMImplementation
from xml.dom.minidom import parseString
from .utils import u_
RDF_NAMESPACE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
DC_NAMESPACE = "http://purl.org/dc/elements/1.1/"
XMP_NAMESPACE = "http://ns.adobe.com/xap/1.0/"
PDF_NAMESPACE = "http://ns.adobe.com/pdf/1.3/"
XMPMM_NAMESPACE = "http://ns.adobe.com/xap/1.0/mm/"
# What is the PDFX namespace, you might ask? I might ask that too. It's
# a completely undocumented namespace used to place "custom metadata"
# properties, which are arbitrary metadata properties with no semantic or
# documented meaning. Elements in the namespace are key/value-style storage,
# where the element name is the key and the content is the value. The keys
# are transformed into valid XML identifiers by substituting an invalid
# identifier character with \u2182 followed by the unicode hex ID of the
# original character. A key like "my car" is therefore "my\u21820020car".
#
# \u2182, in case you're wondering, is the unicode character
# \u{ROMAN NUMERAL TEN THOUSAND}, a straightforward and obvious choice for
# escaping characters.
#
# Intentional users of the pdfx namespace should be shot on sight. A
# custom data schema and sensical XML elements could be used instead, as is
# suggested by Adobe's own documentation on XMP (under "Extensibility of
# Schemas").
#
# Information presented here on the /pdfx/ schema is a result of limited
# reverse engineering, and does not constitute a full specification.
PDFX_NAMESPACE = "http://ns.adobe.com/pdfx/1.3/"
iso8601 = re.compile("""
(?P<year>[0-9]{4})
(-
(?P<month>[0-9]{2})
(-
(?P<day>[0-9]+)
(T
(?P<hour>[0-9]{2}):
(?P<minute>[0-9]{2})
(:(?P<second>[0-9]{2}(.[0-9]+)?))?
(?P<tzd>Z|[-+][0-9]{2}:[0-9]{2})
)?
)?
)?
""", re.VERBOSE)
class XmpInformation(PdfObject):
"""
An object that represents Adobe XMP metadata.
Usually accessed by :meth:`getXmpMetadata()<PyPDF2.PdfFileReader.getXmpMetadata>`
"""
def __init__(self, stream):
self.stream = stream
docRoot = parseString(self.stream.getData())
self.rdfRoot = docRoot.getElementsByTagNameNS(RDF_NAMESPACE, "RDF")[0]
self.cache = {}
def writeToStream(self, stream, encryption_key):
self.stream.writeToStream(stream, encryption_key)
def getElement(self, aboutUri, namespace, name):
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
attr = desc.getAttributeNodeNS(namespace, name)
if attr != None:
yield attr
for element in desc.getElementsByTagNameNS(namespace, name):
yield element
def getNodesInNamespace(self, aboutUri, namespace):
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == aboutUri:
for i in range(desc.attributes.length):
attr = desc.attributes.item(i)
if attr.namespaceURI == namespace:
yield attr
for child in desc.childNodes:
if child.namespaceURI == namespace:
yield child
def _getText(self, element):
text = ""
for child in element.childNodes:
if child.nodeType == child.TEXT_NODE:
text += child.data
return text
def _converter_string(value):
return value
def _converter_date(value):
m = iso8601.match(value)
year = int(m.group("year"))
month = int(m.group("month") or "1")
day = int(m.group("day") or "1")
hour = int(m.group("hour") or "0")
minute = int(m.group("minute") or "0")
second = decimal.Decimal(m.group("second") or "0")
seconds = second.to_integral(decimal.ROUND_FLOOR)
milliseconds = (second - seconds) * 1000000
tzd = m.group("tzd") or "Z"
dt = datetime.datetime(year, month, day, hour, minute, seconds, milliseconds)
if tzd != "Z":
tzd_hours, tzd_minutes = [int(x) for x in tzd.split(":")]
tzd_hours *= -1
if tzd_hours < 0:
tzd_minutes *= -1
dt = dt + datetime.timedelta(hours=tzd_hours, minutes=tzd_minutes)
return dt
_test_converter_date = staticmethod(_converter_date)
def _getter_bag(namespace, name, converter):
def get(self):
cached = self.cache.get(namespace, {}).get(name)
if cached:
return cached
retval = []
for element in self.getElement("", namespace, name):
bags = element.getElementsByTagNameNS(RDF_NAMESPACE, "Bag")
if len(bags):
for bag in bags:
for item in bag.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
value = self._getText(item)
value = converter(value)
retval.append(value)
ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = retval
return retval
return get
def _getter_seq(namespace, name, converter):
def get(self):
cached = self.cache.get(namespace, {}).get(name)
if cached:
return cached
retval = []
for element in self.getElement("", namespace, name):
seqs = element.getElementsByTagNameNS(RDF_NAMESPACE, "Seq")
if len(seqs):
for seq in seqs:
for item in seq.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
value = self._getText(item)
value = converter(value)
retval.append(value)
else:
value = converter(self._getText(element))
retval.append(value)
ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = retval
return retval
return get
def _getter_langalt(namespace, name, converter):
def get(self):
cached = self.cache.get(namespace, {}).get(name)
if cached:
return cached
retval = {}
for element in self.getElement("", namespace, name):
alts = element.getElementsByTagNameNS(RDF_NAMESPACE, "Alt")
if len(alts):
for alt in alts:
for item in alt.getElementsByTagNameNS(RDF_NAMESPACE, "li"):
value = self._getText(item)
value = converter(value)
retval[item.getAttribute("xml:lang")] = value
else:
retval["x-default"] = converter(self._getText(element))
ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = retval
return retval
return get
def _getter_single(namespace, name, converter):
def get(self):
cached = self.cache.get(namespace, {}).get(name)
if cached:
return cached
value = None
for element in self.getElement("", namespace, name):
if element.nodeType == element.ATTRIBUTE_NODE:
value = element.nodeValue
else:
value = self._getText(element)
break
if value != None:
value = converter(value)
ns_cache = self.cache.setdefault(namespace, {})
ns_cache[name] = value
return value
return get
dc_contributor = property(_getter_bag(DC_NAMESPACE, "contributor", _converter_string))
"""
Contributors to the resource (other than the authors). An unsorted
array of names.
"""
dc_coverage = property(_getter_single(DC_NAMESPACE, "coverage", _converter_string))
"""
Text describing the extent or scope of the resource.
"""
dc_creator = property(_getter_seq(DC_NAMESPACE, "creator", _converter_string))
"""
A sorted array of names of the authors of the resource, listed in order
of precedence.
"""
dc_date = property(_getter_seq(DC_NAMESPACE, "date", _converter_date))
"""
A sorted array of dates (datetime.datetime instances) of signifigance to
the resource. The dates and times are in UTC.
"""
dc_description = property(_getter_langalt(DC_NAMESPACE, "description", _converter_string))
"""
A language-keyed dictionary of textual descriptions of the content of the
resource.
"""
dc_format = property(_getter_single(DC_NAMESPACE, "format", _converter_string))
"""
The mime-type of the resource.
"""
dc_identifier = property(_getter_single(DC_NAMESPACE, "identifier", _converter_string))
"""
Unique identifier of the resource.
"""
dc_language = property(_getter_bag(DC_NAMESPACE, "language", _converter_string))
"""
An unordered array specifying the languages used in the resource.
"""
dc_publisher = property(_getter_bag(DC_NAMESPACE, "publisher", _converter_string))
"""
An unordered array of publisher names.
"""
dc_relation = property(_getter_bag(DC_NAMESPACE, "relation", _converter_string))
"""
An unordered array of text descriptions of relationships to other
documents.
"""
dc_rights = property(_getter_langalt(DC_NAMESPACE, "rights", _converter_string))
"""
A language-keyed dictionary of textual descriptions of the rights the
user has to this resource.
"""
dc_source = property(_getter_single(DC_NAMESPACE, "source", _converter_string))
"""
Unique identifier of the work from which this resource was derived.
"""
dc_subject = property(_getter_bag(DC_NAMESPACE, "subject", _converter_string))
"""
An unordered array of descriptive phrases or keywrods that specify the
topic of the content of the resource.
"""
dc_title = property(_getter_langalt(DC_NAMESPACE, "title", _converter_string))
"""
A language-keyed dictionary of the title of the resource.
"""
dc_type = property(_getter_bag(DC_NAMESPACE, "type", _converter_string))
"""
An unordered array of textual descriptions of the document type.
"""
pdf_keywords = property(_getter_single(PDF_NAMESPACE, "Keywords", _converter_string))
"""
An unformatted text string representing document keywords.
"""
pdf_pdfversion = property(_getter_single(PDF_NAMESPACE, "PDFVersion", _converter_string))
"""
The PDF file version, for example 1.0, 1.3.
"""
pdf_producer = property(_getter_single(PDF_NAMESPACE, "Producer", _converter_string))
"""
The name of the tool that created the PDF document.
"""
xmp_createDate = property(_getter_single(XMP_NAMESPACE, "CreateDate", _converter_date))
"""
The date and time the resource was originally created. The date and
time are returned as a UTC datetime.datetime object.
"""
xmp_modifyDate = property(_getter_single(XMP_NAMESPACE, "ModifyDate", _converter_date))
"""
The date and time the resource was last modified. The date and time
are returned as a UTC datetime.datetime object.
"""
xmp_metadataDate = property(_getter_single(XMP_NAMESPACE, "MetadataDate", _converter_date))
"""
The date and time that any metadata for this resource was last
changed. The date and time are returned as a UTC datetime.datetime
object.
"""
xmp_creatorTool = property(_getter_single(XMP_NAMESPACE, "CreatorTool", _converter_string))
"""
The name of the first known tool used to create the resource.
"""
xmpmm_documentId = property(_getter_single(XMPMM_NAMESPACE, "DocumentID", _converter_string))
"""
The common identifier for all versions and renditions of this resource.
"""
xmpmm_instanceId = property(_getter_single(XMPMM_NAMESPACE, "InstanceID", _converter_string))
"""
An identifier for a specific incarnation of a document, updated each
time a file is saved.
"""
def custom_properties(self):
if not hasattr(self, "_custom_properties"):
self._custom_properties = {}
for node in self.getNodesInNamespace("", PDFX_NAMESPACE):
key = node.localName
while True:
# see documentation about PDFX_NAMESPACE earlier in file
idx = key.find(u_("\u2182"))
if idx == -1:
break
key = key[:idx] + chr(int(key[idx+1:idx+5], base=16)) + key[idx+5:]
if node.nodeType == node.ATTRIBUTE_NODE:
value = node.nodeValue
else:
value = self._getText(node)
self._custom_properties[key] = value
return self._custom_properties
custom_properties = property(custom_properties)
"""
Retrieves custom metadata properties defined in the undocumented pdfx
metadata schema.
:return: a dictionary of key/value items for custom metadata properties.
:rtype: dict
"""

View File

@ -0,0 +1,527 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import unicode_literals
#
# Copyright <20> 2007-2010 Dieter Verfaillie <dieterv@optionexplicit.be>
#
# This file is part of elib.intl.
#
# elib.intl is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# elib.intl is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with elib.intl. If not, see <http://www.gnu.org/licenses/>.
# Update by Dysmas : added the option to explicitly define the language :
# parameter "code" in the function : install , line 453
'''
The elib.intl module provides enhanced internationalization (I18N) services for
your Python modules and applications.
elib.intl wraps Python's :func:`gettext` functionality and adds the following on
Microsoft Windows systems:
- automatic detection of the current screen language (not necessarily the same
as the installation language) provided by MUI packs,
- makes sure internationalized C libraries which internally invoke gettext() or
dcgettext() can properly locate their message catalogs. This fixes a known
limitation in gettext's Windows support when using eg. gtk.builder or gtk.glade.
See http://www.gnu.org/software/gettext/FAQ.html#windows_setenv for more
information.
The elib.intl module defines the following functions:
'''
__all__ = ['install', 'install_module']
__version__ = '0.0.3'
__docformat__ = 'restructuredtext'
import os
import sys
import locale
import gettext
from logging import getLogger
logger = getLogger('elib.intl')
def _isofromlcid(lcid):
'''
:param lcid: Microsoft Windows LCID
:returns: the ISO 639-1 language code for a given lcid. If there is no
ISO 639-1 language code assigned to the language specified by lcid,
the ISO 639-2 language code is returned. If the language specified
by lcid is unknown in the ISO 639-x database, None is returned.
More information can be found on the following websites:
- List of ISO 639-1 and ISO 639-2 language codes: http://www.loc.gov/standards/iso639-2/
- List of known lcid's: http://www.microsoft.com/globaldev/reference/lcid-all.mspx
- List of known MUI packs: http://www.microsoft.com/globaldev/reference/win2k/setup/Langid.mspx
'''
mapping = {1078: 'af', #Afrikaans - South Africa
1052: 'sq', #Albanian - Albania
1118: 'am', #Amharic - Ethiopia
1025: 'ar', #Arabic - Saudi Arabia
5121: 'ar', #Arabic - Algeria
15361: 'ar', #Arabic - Bahrain
3073: 'ar', #Arabic - Egypt
2049: 'ar', #Arabic - Iraq
11265: 'ar', #Arabic - Jordan
13313: 'ar', #Arabic - Kuwait
12289: 'ar', #Arabic - Lebanon
4097: 'ar', #Arabic - Libya
6145: 'ar', #Arabic - Morocco
8193: 'ar', #Arabic - Oman
16385: 'ar', #Arabic - Qatar
10241: 'ar', #Arabic - Syria
7169: 'ar', #Arabic - Tunisia
14337: 'ar', #Arabic - U.A.E.
9217: 'ar', #Arabic - Yemen
1067: 'hy', #Armenian - Armenia
1101: 'as', #Assamese
2092: 'az', #Azeri (Cyrillic)
1068: 'az', #Azeri (Latin)
1069: 'eu', #Basque
1059: 'be', #Belarusian
1093: 'bn', #Bengali (India)
2117: 'bn', #Bengali (Bangladesh)
5146: 'bs', #Bosnian (Bosnia/Herzegovina)
1026: 'bg', #Bulgarian
1109: 'my', #Burmese
1027: 'ca', #Catalan
1116: 'chr', #Cherokee - United States
2052: 'zh', #Chinese - People's Republic of China
4100: 'zh', #Chinese - Singapore
1028: 'zh', #Chinese - Taiwan
3076: 'zh', #Chinese - Hong Kong SAR
5124: 'zh', #Chinese - Macao SAR
1050: 'hr', #Croatian
4122: 'hr', #Croatian (Bosnia/Herzegovina)
1029: 'cs', #Czech
1030: 'da', #Danish
1125: 'dv', #Divehi
1043: 'nl', #Dutch - Netherlands
2067: 'nl', #Dutch - Belgium
1126: 'bin', #Edo
1033: 'en', #English - United States
2057: 'en', #English - United Kingdom
3081: 'en', #English - Australia
10249: 'en', #English - Belize
4105: 'en', #English - Canada
9225: 'en', #English - Caribbean
15369: 'en', #English - Hong Kong SAR
16393: 'en', #English - India
14345: 'en', #English - Indonesia
6153: 'en', #English - Ireland
8201: 'en', #English - Jamaica
17417: 'en', #English - Malaysia
5129: 'en', #English - New Zealand
13321: 'en', #English - Philippines
18441: 'en', #English - Singapore
7177: 'en', #English - South Africa
11273: 'en', #English - Trinidad
12297: 'en', #English - Zimbabwe
1061: 'et', #Estonian
1080: 'fo', #Faroese
1065: None, #TODO: Farsi
1124: 'fil', #Filipino
1035: 'fi', #Finnish
1036: 'fr', #French - France
2060: 'fr', #French - Belgium
11276: 'fr', #French - Cameroon
3084: 'fr', #French - Canada
9228: 'fr', #French - Democratic Rep. of Congo
12300: 'fr', #French - Cote d'Ivoire
15372: 'fr', #French - Haiti
5132: 'fr', #French - Luxembourg
13324: 'fr', #French - Mali
6156: 'fr', #French - Monaco
14348: 'fr', #French - Morocco
58380: 'fr', #French - North Africa
8204: 'fr', #French - Reunion
10252: 'fr', #French - Senegal
4108: 'fr', #French - Switzerland
7180: 'fr', #French - West Indies
1122: 'fy', #Frisian - Netherlands
1127: None, #TODO: Fulfulde - Nigeria
1071: 'mk', #FYRO Macedonian
2108: 'ga', #Gaelic (Ireland)
1084: 'gd', #Gaelic (Scotland)
1110: 'gl', #Galician
1079: 'ka', #Georgian
1031: 'de', #German - Germany
3079: 'de', #German - Austria
5127: 'de', #German - Liechtenstein
4103: 'de', #German - Luxembourg
2055: 'de', #German - Switzerland
1032: 'el', #Greek
1140: 'gn', #Guarani - Paraguay
1095: 'gu', #Gujarati
1128: 'ha', #Hausa - Nigeria
1141: 'haw', #Hawaiian - United States
1037: 'he', #Hebrew
1081: 'hi', #Hindi
1038: 'hu', #Hungarian
1129: None, #TODO: Ibibio - Nigeria
1039: 'is', #Icelandic
1136: 'ig', #Igbo - Nigeria
1057: 'id', #Indonesian
1117: 'iu', #Inuktitut
1040: 'it', #Italian - Italy
2064: 'it', #Italian - Switzerland
1041: 'ja', #Japanese
1099: 'kn', #Kannada
1137: 'kr', #Kanuri - Nigeria
2144: 'ks', #Kashmiri
1120: 'ks', #Kashmiri (Arabic)
1087: 'kk', #Kazakh
1107: 'km', #Khmer
1111: 'kok', #Konkani
1042: 'ko', #Korean
1088: 'ky', #Kyrgyz (Cyrillic)
1108: 'lo', #Lao
1142: 'la', #Latin
1062: 'lv', #Latvian
1063: 'lt', #Lithuanian
1086: 'ms', #Malay - Malaysia
2110: 'ms', #Malay - Brunei Darussalam
1100: 'ml', #Malayalam
1082: 'mt', #Maltese
1112: 'mni', #Manipuri
1153: 'mi', #Maori - New Zealand
1102: 'mr', #Marathi
1104: 'mn', #Mongolian (Cyrillic)
2128: 'mn', #Mongolian (Mongolian)
1121: 'ne', #Nepali
2145: 'ne', #Nepali - India
1044: 'no', #Norwegian (Bokm??l)
2068: 'no', #Norwegian (Nynorsk)
1096: 'or', #Oriya
1138: 'om', #Oromo
1145: 'pap', #Papiamentu
1123: 'ps', #Pashto
1045: 'pl', #Polish
1046: 'pt', #Portuguese - Brazil
2070: 'pt', #Portuguese - Portugal
1094: 'pa', #Punjabi
2118: 'pa', #Punjabi (Pakistan)
1131: 'qu', #Quecha - Bolivia
2155: 'qu', #Quecha - Ecuador
3179: 'qu', #Quecha - Peru
1047: 'rm', #Rhaeto-Romanic
1048: 'ro', #Romanian
2072: 'ro', #Romanian - Moldava
1049: 'ru', #Russian
2073: 'ru', #Russian - Moldava
1083: 'se', #Sami (Lappish)
1103: 'sa', #Sanskrit
1132: 'nso', #Sepedi
3098: 'sr', #Serbian (Cyrillic)
2074: 'sr', #Serbian (Latin)
1113: 'sd', #Sindhi - India
2137: 'sd', #Sindhi - Pakistan
1115: 'si', #Sinhalese - Sri Lanka
1051: 'sk', #Slovak
1060: 'sl', #Slovenian
1143: 'so', #Somali
1070: 'wen', #Sorbian
3082: 'es', #Spanish - Spain (Modern Sort)
1034: 'es', #Spanish - Spain (Traditional Sort)
11274: 'es', #Spanish - Argentina
16394: 'es', #Spanish - Bolivia
13322: 'es', #Spanish - Chile
9226: 'es', #Spanish - Colombia
5130: 'es', #Spanish - Costa Rica
7178: 'es', #Spanish - Dominican Republic
12298: 'es', #Spanish - Ecuador
17418: 'es', #Spanish - El Salvador
4106: 'es', #Spanish - Guatemala
18442: 'es', #Spanish - Honduras
58378: 'es', #Spanish - Latin America
2058: 'es', #Spanish - Mexico
19466: 'es', #Spanish - Nicaragua
6154: 'es', #Spanish - Panama
15370: 'es', #Spanish - Paraguay
10250: 'es', #Spanish - Peru
20490: 'es', #Spanish - Puerto Rico
21514: 'es', #Spanish - United States
14346: 'es', #Spanish - Uruguay
8202: 'es', #Spanish - Venezuela
1072: None, #TODO: Sutu
1089: 'sw', #Swahili
1053: 'sv', #Swedish
2077: 'sv', #Swedish - Finland
1114: 'syr', #Syriac
1064: 'tg', #Tajik
1119: None, #TODO: Tamazight (Arabic)
2143: None, #TODO: Tamazight (Latin)
1097: 'ta', #Tamil
1092: 'tt', #Tatar
1098: 'te', #Telugu
1054: 'th', #Thai
2129: 'bo', #Tibetan - Bhutan
1105: 'bo', #Tibetan - People's Republic of China
2163: 'ti', #Tigrigna - Eritrea
1139: 'ti', #Tigrigna - Ethiopia
1073: 'ts', #Tsonga
1074: 'tn', #Tswana
1055: 'tr', #Turkish
1090: 'tk', #Turkmen
1152: 'ug', #Uighur - China
1058: 'uk', #Ukrainian
1056: 'ur', #Urdu
2080: 'ur', #Urdu - India
2115: 'uz', #Uzbek (Cyrillic)
1091: 'uz', #Uzbek (Latin)
1075: 've', #Venda
1066: 'vi', #Vietnamese
1106: 'cy', #Welsh
1076: 'xh', #Xhosa
1144: 'ii', #Yi
1085: 'yi', #Yiddish
1130: 'yo', #Yoruba
1077: 'zu'} #Zulu
return mapping[lcid]
def _getscreenlanguage():
global language_code
'''
:returns: the ISO 639-x language code for this session.
If the LANGUAGE environment variable is set, it's value overrides the
screen language detection. Otherwise the screen language is determined by
the currently selected Microsoft Windows MUI language pack or the Microsoft
Windows installation language.
Works on Microsoft Windows 2000 and up.
'''
if sys.platform == 'win32' or sys.platform == 'nt':
# Start with nothing
lang = None
# Check the LANGUAGE environment variable
lang = os.getenv('LANGUAGE')
if language_code != "" :
lang = language_code
if lang is None:
# Start with nothing
lcid = None
try:
from ctypes import windll
lcid = windll.kernel32.GetUserDefaultUILanguage()
except:
logger.debug('Failed to get current screen language with \'GetUserDefaultUILanguage\'')
finally:
if lcid is None:
lang = 'C'
else:
lang = _isofromlcid(lcid)
logger.debug('Windows screen language is \'%s\' (lcid %s)' % (lang, lcid))
return lang
def _putenv(name, value):
'''
:param name: environment variable name
:param value: environment variable value
This function ensures that changes to an environment variable are applied
to each copy of the environment variables used by a process. Starting from
Python 2.4, os.environ changes only apply to the copy Python keeps (os.environ)
and are no longer automatically applied to the other copies for the process.
On Microsoft Windows, each process has multiple copies of the environment
variables, one managed by the OS and one managed by the C library. We also
need to take care of the fact that the C library used by Python is not
necessarily the same as the C library used by pygtk and friends. This because
the latest releases of pygtk and friends are built with mingw32 and are thus
linked against msvcrt.dll. The official gtk+ binaries have always been built
in this way.
'''
if sys.platform == 'win32' or sys.platform == 'nt':
from ctypes import windll
from ctypes import cdll
from ctypes.util import find_msvcrt
# Update Python's copy of the environment variables
os.environ[name] = value
# Update the copy maintained by Windows (so SysInternals Process Explorer sees it)
try:
result = windll.kernel32.SetEnvironmentVariableW(name, value)
if result == 0: raise Warning
except Exception:
logger.debug('Failed to set environment variable \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % name)
else:
logger.debug('Set environment variable \'%s\' to \'%s\' (\'kernel32.SetEnvironmentVariableW\')' % (name, value))
# Update the copy maintained by msvcrt (used by gtk+ runtime)
try:
result = cdll.msvcrt._putenv('%s=%s' % (name, value))
if result !=0: raise Warning
except Exception:
logger.debug('Failed to set environment variable \'%s\' (\'msvcrt._putenv\')' % name)
else:
logger.debug('Set environment variable \'%s\' to \'%s\' (\'msvcrt._putenv\')' % (name, value))
# Update the copy maintained by whatever c runtime is used by Python
try:
msvcrt = find_msvcrt()
msvcrtname = str(msvcrt).split('.')[0] if '.' in msvcrt else str(msvcrt)
result = cdll.LoadLibrary(msvcrt)._putenv('%s=%s' % (name, value))
if result != 0: raise Warning
except Exception:
logger.debug('Failed to set environment variable \'%s\' (\'%s._putenv\')' % (name, msvcrtname))
else:
logger.debug('Set environment variable \'%s\' to \'%s\' (\'%s._putenv\')' % (name, value, msvcrtname))
def _dugettext(domain, message):
'''
:param domain: translation domain
:param message: message to translate
:returns: the translated message
Unicode version of :func:`gettext.dgettext`.
'''
try:
t = gettext.translation(domain, gettext._localedirs.get(domain, None),
codeset=gettext._localecodesets.get(domain))
except IOError:
return message
else:
return t.ugettext(message)
def _install(domain, localedir, asglobal=False):
'''
:param domain: translation domain
:param localedir: locale directory
:param asglobal: if True, installs the function _() in Python<EFBFBD>s builtin namespace. Default is False
Private function doing all the work for the :func:`elib.intl.install` and
:func:`elib.intl.install_module` functions.
'''
# prep locale system
if asglobal:
locale.setlocale(locale.LC_ALL, '')
# on windows systems, set the LANGUAGE environment variable
if sys.platform == 'win32' or sys.platform == 'nt':
_putenv('LANGUAGE', _getscreenlanguage())
#print "=========2>", os.getenv('LANGUAGE')
#print ("=========2>",_getscreenlanguage())
# The locale module on Max OS X lacks bindtextdomain so we specifically
# test on linux2 here. See commit 4ae8b26fd569382ab66a9e844daa0e01de409ceb
if sys.platform == 'linux2':
locale.bindtextdomain(domain, localedir)
locale.bind_textdomain_codeset(domain, 'UTF-8')
locale.textdomain(domain)
# initialize Python's gettext interface
gettext.bindtextdomain(domain, localedir)
gettext.bind_textdomain_codeset(domain, 'UTF-8')
if asglobal:
gettext.textdomain(domain)
# on windows systems, initialize libintl
domain = domain.encode("cp1252")
localedir = localedir.encode("cp1252")
if sys.platform == 'win32' or sys.platform == 'nt':
from ctypes import cdll
libintl = cdll.LoadLibrary("libintl-8.dll")
libintl.bindtextdomain(domain, localedir)
libintl.bind_textdomain_codeset(domain, 'UTF-8')
if asglobal:
libintl.textdomain(domain)
del libintl
def install(domain, localedir, code = ""):
'''
:param domain: translation domain
:param localedir: locale directory
:param code: Language code required. Default means autodetect.
Installs the function _() in Python<EFBFBD>s builtin namespace, based on
domain and localedir. Codeset is always UTF-8.
As seen below, you usually mark the strings in your application that are
candidates for translation, by wrapping them in a call to the _() function,
like this:
.. sourcecode:: python
import elib.intl
elib.intl.install('myapplication', '/path/to/usr/share/locale')
print _('This string will be translated.')
Note that this is only one way, albeit the most convenient way,
to make the _() function available to your application. Because it affects
the entire application globally, and specifically Python<EFBFBD>s built-in
namespace, localized modules should never install _(). Instead, you should
use :func:`elib.intl.install_module` to make _() available to your module.
'''
global language_code
language_code = code
_install(domain, localedir, True)
gettext.install(domain, localedir)
def install_module(domain, localedir):
'''
:param domain: translation domain
:param localedir: locale directory
:returns: an anonymous function object, based on domain and localedir.
Codeset is always UTF-8.
You may find this function usefull when writing localized modules.
Use this code to make _() available to your module:
.. sourcecode:: python
import elib.intl
_ = elib.intl.install_module('mymodule', '/path/to/usr/share/locale')
print _('This string will be translated.')
When writing a package, you can usually do this in the package's __init__.py
file and import the _() function from the package namespace as needed.
'''
_install(domain, localedir, False)
return lambda message: _dugettext(domain, message)
def main() :
language = ""
if sys.platform == 'win32' or sys.platform == 'nt':
install("pdfbooklet", "share/locale", language)
print (_getscreenlanguage())
else :
install("pdfbooklet", "/usr/share/locale", language)
print (_("There is no selection"))
if __name__ == '__main__' :
main()

View File

@ -0,0 +1,183 @@
#!/usr/bin/python
# coding: utf-8 -*-
# version 3.0.3
import os, sys
from gi.repository import Gtk, Gio
from pdfbooklet.PyPDF2_G import PdfFileReader
def alert(message, type = 0) :
dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING,
Gtk.ButtonsType.CLOSE , message)
dialog.run()
dialog.destroy()
class Chooser:
def __init__(self,
inputFiles_a = None,
share_path_u = "",
mru_dir = ""):
self.inputFiles_a = inputFiles_a
self.chooser1 = Gtk.Builder()
self.chooser1.add_from_file(os.path.join(share_path_u, 'data/chooser_dialog.glade'))
self.chooser1.connect_signals(self)
self.chooser = self.chooser1.get_object("filechooserdialog1")
# treeview
self.treeview1 = self.chooser1.get_object("treeview1")
# create a TreeStore with one string column to use as the model
#self.treestore = self.treeview1.get_model()
self.treestore = Gtk.ListStore(str,int)
self.cell = Gtk.CellRendererText()
# set the model for TreeView
self.treeview1.set_model(self.treestore)
self.tvcolumn = Gtk.TreeViewColumn(_('Filename'))
self.treeview1.append_column(self.tvcolumn)
# add the cell to the tvcolumn and allow it to expand
self.tvcolumn.pack_start(self.cell, True)
# set the cell "text" attribute to column 0 - retrieve text
# from that column in treestore
self.tvcolumn.add_attribute(self.cell, 'text', 0)
## self.tvcolumn = Gtk.TreeViewColumn(_('Pages'))
## self.treeview1.append_column(self.tvcolumn)
## self.tvcolumn.pack_start(self.cell, True)
## self.tvcolumn.add_attribute(self.cell, 'text', 1)
# Allow drag and drop reordering of rows
self.treeview1.set_reorderable(True)
# load files in parameter list
for key in self.inputFiles_a :
self.treestore.append([self.inputFiles_a[key], 0])
old_dir = ""
old_name = ""
chooser = self.chooser1.get_object("filechooserdialog1")
chooser.set_current_folder(mru_dir)
chooser.set_select_multiple(True)
filter_all = Gtk.FileFilter()
filter_all.set_name(_('All files'))
filter_all.add_pattern('*')
chooser.add_filter(filter_all)
filter_pdf = Gtk.FileFilter()
filter_pdf.set_name(_('PDF files'))
filter_pdf.add_mime_type('application/pdf')
filter_pdf.add_pattern('*.pdf')
chooser.add_filter(filter_pdf)
chooser.set_filter(filter_pdf)
response = chooser.run()
def chooserClose(self, widget) :
self.chooser.destroy()
def chooserOK(self, widget) :
self.treestore.clear()
self.genFilesArray()
self.chooser.destroy()
def pdf_remove(self, widget) :
selection = self.treeview1.get_selection()
#sel = selection.get_selected_rows()
model, iter0 = selection.get_selected()
model.remove(iter0)
def pdf_up(self, widget) :
selection = self.treeview1.get_selection()
model, iter0 = selection.get_selected()
string = model.get_string_from_iter(iter0)
newpos = int(string) - 1
if newpos < 0 : newpos = 0
newpos = model.get_iter_from_string(str(newpos))
model.move_before(iter0, newpos)
def pdf_down(self, widget) :
selection = self.treeview1.get_selection()
model, iter0 = selection.get_selected()
model.move_after(iter0, model.iter_next(iter0))
# clears the list and open a file
def pdf_open(self,widget) :
self.treestore.clear()
self.add_file("")
def add_file(self, widget):
for filename in self.chooser.get_filenames():
if os.path.isfile(filename):
# FIXME
## f = Gio.File(filename)
## f_info = f.query_info('standard::content-type')
## mime_type = f_info.get_content_type()
mime_type = ".pdf"
if mime_type == 'application/pdf' or mime_type == '.pdf':
self.loadPdfFile(filename)
else :
print(_('File type not supported!'))
else:
print(_('File %s does not exist') % filename)
def loadPdfFile(self,filename) :
pdfFile = PdfFileReader(open(filename, "rb"))
numpages = pdfFile.getNumPages()
self.treestore.append([filename, numpages])
# regenerate the array of files (easier to use than the treestore)
def genFilesArray(self, dummy = "") :
inputFiles_a = {}
selectedFiles1 = self.chooser.get_filenames()
# eliminate directories
selectedFiles = []
for file_u in selectedFiles1 :
if os.path.isdir(file_u) :
alert(_("You have chosen a directory, it is not supported"))
else :
# FIXME
## f = gio.File(filename)
## f_info = f.query_info('standard::content-type')
## mime_type = f_info.get_content_type()
## if mime_type == 'application/pdf' or mime_type == '.pdf':
## self.loadPdfFile(filename)
## else :
## print(_('File type not supported!'))
selectedFiles.append(file_u)
if len(selectedFiles) == 0 :
print(_('Closed, no files selected'))
return
size_i = len(self.treestore)
if size_i == 0 : # nothing in the list
for i in range(len(selectedFiles)) :
inputFiles_a[i + 1] = selectedFiles[i]
else : # use the list
for i in range(size_i) :
iter0 = self.treestore.get_iter(i)
filename_s = self.treestore.get_value(iter0,0)
inputFiles_a[i + 1] = filename_s
self.inputFiles_a = inputFiles_a

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
PdfShuffler 0.6.0 - GTK+ based utility for splitting, rearrangement and
modification of PDF documents.
Copyright (C) 2008-2012 Konstantinos Poulios
<https://sourceforge.net/projects/pdfshuffler>
This file is part of PdfShuffler.
PdfShuffler is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
from gi.repository import Gtk, GObject
from gi.repository import cairo
from math import pi as M_PI
class CellRendererImage(Gtk.CellRenderer):
__gproperties__ = {
"image": (GObject.TYPE_PYOBJECT, "Image", "Image",
GObject.PARAM_READWRITE),
"width": (GObject.TYPE_FLOAT, "Width", "Width",
0., 1.e4, 0., GObject.PARAM_READWRITE),
"height": (GObject.TYPE_FLOAT, "Height", "Height",
0., 1.e4, 0., GObject.PARAM_READWRITE),
"rotation": (GObject.TYPE_INT, "Rotation", "Rotation",
0, 360, 0, GObject.PARAM_READWRITE),
"scale": (GObject.TYPE_FLOAT, "Scale", "Scale",
0.01, 100., 1., GObject.PARAM_READWRITE),
"resample": (GObject.TYPE_FLOAT,
"Resample", "Resample Coefficient",
1., 100., 1., GObject.PARAM_READWRITE),
"cropL": (GObject.TYPE_FLOAT, "CropL", "CropL",
0., 1., 0., GObject.PARAM_READWRITE),
"cropR": (GObject.TYPE_FLOAT, "CropR", "CropR",
0., 1., 0., GObject.PARAM_READWRITE),
"cropT": (GObject.TYPE_FLOAT, "CropT", "CropT",
0., 1., 0., GObject.PARAM_READWRITE),
"cropB": (GObject.TYPE_FLOAT, "CropB", "CropB",
0., 1., 0., GObject.PARAM_READWRITE),
}
def __init__(self):
## self.__GObject_init__() Original code modified in the line below
Gtk.CellRendererText.__init__(self)
GObject.GObject.__init__(self)
self.th1 = 2. # border thickness
self.th2 = 3. # shadow thickness
def get_geometry(self):
rotation = int(self.rotation) % 360
rotation = ((rotation) / 90) * 90
if not self.image:
w0 = w1 = self.width / self.resample
h0 = h1 = self.height / self.resample
else:
w0 = self.image.get_width()
h0 = self.image.get_height()
if rotation == 90 or rotation == 270:
w1, h1 = h0, w0
else:
w1, h1 = w0, h0
x = self.cropL * w1
y = self.cropT * h1
scale = self.resample * self.scale
w2 = int(scale * (1. - self.cropL - self.cropR) * w1)
h2 = int(scale * (1. - self.cropT - self.cropB) * h1)
return w0,h0,w1,h1,w2,h2,rotation
def do_set_property(self, pspec, value):
setattr(self, pspec.name, value)
def do_get_property(self, pspec):
return getattr(self, pspec.name)
def do_render(self, window, widget, cell_area, \
expose_area, flags):
if not self.image:
return
w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
th = int(2*self.th1+self.th2)
w = w2 + th
h = h2 + th
x = cell_area.x
y = cell_area.y
if cell_area and w > 0 and h > 0:
x += self.get_property('xalign') * \
(cell_area.width - w - self.get_property('xpad'))
y += self.get_property('yalign') * \
(cell_area.height - h - self.get_property('ypad'))
cr = window # cr = window.cairo_create()
cr.translate(x,y)
x = self.cropL * w1
y = self.cropT * h1
#shadow
cr.set_source_rgb(0.5, 0.5, 1)
cr.rectangle(th, th, w2, h2)
cr.fill()
#border
cr.set_source_rgb(0, 0, 0)
cr.rectangle(0, 0, w2+2*self.th1, h2+2*self.th1)
cr.fill()
#image
cr.set_source_rgb(1, 1, 1)
cr.rectangle(self.th1, self.th1, w2, h2)
cr.fill_preserve()
cr.clip()
cr.translate(self.th1,self.th1)
scale = self.resample * self.scale
cr.scale(scale, scale)
cr.translate(-x,-y)
if rotation > 0:
cr.translate(w1/2,h1/2)
cr.rotate(rotation * M_PI / 180)
cr.translate(-w0/2,-h0/2)
cr.set_source_surface(self.image)
cr.paint()
def do_get_size(self, widget, cell_area=None):
x = y = 0
w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
th = int(2*self.th1+self.th2)
w = w2 + th
h = h2 + th
if cell_area and w > 0 and h > 0:
x = self.get_property('xalign') * \
(cell_area.width - w - self.get_property('xpad'))
y = self.get_property('yalign') * \
(cell_area.height - h - self.get_property('ypad'))
w += 2 * self.get_property('xpad')
h += 2 * self.get_property('ypad')
return int(x), int(y), w, h

View File

@ -0,0 +1,10 @@
[Desktop Entry]
Version=2.0
Name=PDF-Booklet
Comment=PDF Merging, Rearranging, Splitting, Rotating and Cropping
Type=Application
Exec=pdfbooklet
Icon=pdfbooklet
Categories=Office;
Terminal=false
StartupNotify=false

View File

@ -0,0 +1,8 @@
This package was debianized by the alien program by converting
a binary .tgz package on Fri, 05 Jul 2019 11:09:47 +0000
Copyright: unknown
Information from the binary package:
-rw-rw-r-- 1 travis travis 5324800 Jul 5 11:09 ./pdfbooklet-3.1.2-all_64_corr.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
msgid ""
msgstr ""
"Project-Id-Version: PDF-Shuffler 0.5\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-08-18 08:12+0200\n"
"PO-Revision-Date: 2015-08-18 08:26+0100\n"
"Last-Translator: DP <daniel.pot@wanadoo.fr>\n"
"Language-Team: Emmanuel <emmanuel@simple-linux.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: french\n"
"X-Poedit-Country: FRANCE\n"
#: ..\..\..\pdfshuffler_g.py:127
msgid "Can't load icon. Application is not installed correctly."
msgstr "Impossible de charger l'icône. L'application n'est pas installée correctement."
#: ..\..\..\pdfshuffler_g.py:318
msgid "No document"
msgstr "Pas de document"
#: ..\..\..\pdfshuffler_g.py:320
msgid "Several documents"
msgstr "Plusieurs documents"
#: ..\..\..\pdfshuffler_g.py:336
#, python-format
msgid "Rendering thumbnails... [%(i1)s/%(i2)s]"
msgstr "Rendu miniatures... [%(i1)s/%(i2)s]"
#: ..\..\..\pdfshuffler_g.py:453
msgid "page"
msgstr "page"
#: ..\..\..\pdfshuffler_g.py:479
msgid "Export ..."
msgstr "Exporter ..."
#: ..\..\..\pdfshuffler_g.py:488
#: ..\..\..\pdfshuffler_g.py:610
msgid "PDF files"
msgstr "Fichier PDF"
#: ..\..\..\pdfshuffler_g.py:494
#: ..\..\..\pdfshuffler_g.py:605
msgid "All files"
msgstr "Tous les fichiers"
#: ..\..\..\pdfshuffler_g.py:538
#, python-format
msgid ""
"File %s is encrypted.\n"
"Support for encrypted files has not been implemented yet.\n"
"File export failed."
msgstr ""
"Le fichier %s est crypté.\n"
"Le support pour ce type de fichier n'a pas encore été implémenté.\n"
"L'exportation du fichier a échoué"
#: ..\..\..\pdfshuffler_g.py:594
msgid "Import..."
msgstr "Importer ..."
#: ..\..\..\pdfshuffler_g.py:630
msgid "OpenDocument not supported yet!"
msgstr "OpenDocument n'est pas encore supporté !"
#: ..\..\..\pdfshuffler_g.py:632
msgid "Image file not supported yet!"
msgstr "Le format image n'est pas encore supporté !"
#: ..\..\..\pdfshuffler_g.py:634
msgid "File type not supported!"
msgstr "Type de ficher pas encore supporté !"
#: ..\..\..\pdfshuffler_g.py:636
#, python-format
msgid "File %s does not exist"
msgstr "Le fichier %s n'existe pas"
#: ..\..\..\pdfshuffler_g.py:638
msgid "Closed, no files selected"
msgstr "Fermé, aucun fichier sélectionné"
#: ..\..\..\pdfshuffler_g.py:1030
msgid "Left"
msgstr "Gauche"
#: ..\..\..\pdfshuffler_g.py:1030
msgid "Right"
msgstr "Droite"
#: ..\..\..\pdfshuffler_g.py:1031
msgid "Top"
msgstr "Dessus"
#: ..\..\..\pdfshuffler_g.py:1031
msgid "Bottom"
msgstr "Bas"
#: ..\..\..\pdfshuffler_g.py:1049
msgid "Crop Selected Pages"
msgstr "Couper la(les) page(s) sélectionné(es)"
#: ..\..\..\pdfshuffler_g.py:1057
msgid "Crop Margins"
msgstr "Couper les marges"
#: ..\..\..\pdfshuffler_g.py:1064
#, python-format
msgid "% of width"
msgstr " \\%de la largeur"
#: ..\..\..\pdfshuffler_g.py:1064
#, python-format
msgid "% of height"
msgstr " \\%de la hauteur"
#: ..\..\..\pdfshuffler_g.py:1102
msgid "Dialog closed"
msgstr "Fenêtre de dialogue fermée"
#: ..\..\..\pdfshuffler_g.py:1116
#, python-format
msgid "%s is a tool for rearranging and modifying PDF files. Developed using GTK+ and Python"
msgstr "%s est un outil destiné à réarranger et modifier les pages de fichiers PDF. Développé avec GTK+ et Python"
#: ..\..\..\data\pdfshuffler_g.glade:83
#: ..\..\..\data\pdfshuffler_g.glade:370
msgid "Rotate _Right"
msgstr "Tourner à droite"
#: ..\..\..\data\pdfshuffler_g.glade:95
#: ..\..\..\data\pdfshuffler_g.glade:358
msgid "Rotate _Left"
msgstr "Tourner à gauche"
#: ..\..\..\data\pdfshuffler_g.glade:107
msgid "C_rop"
msgstr "_Couper les mages"
#: ..\..\..\data\pdfshuffler_g.glade:130
msgid "Add _Blank Page Before"
msgstr "Ajouter une page_ blanche avant"
#: ..\..\..\data\pdfshuffler_g.glade:190
msgid "Add Blank Page _After"
msgstr "_Ajouter une page blanche après"
#: ..\..\..\data\pdfshuffler_g.glade:281
msgid "_File"
msgstr "_Fichier"
#: ..\..\..\data\pdfshuffler_g.glade:289
msgid "_Open"
msgstr "_Ouvrir"
#: ..\..\..\data\pdfshuffler_g.glade:301
msgid "_Save"
msgstr "_Enregistrer"
#: ..\..\..\data\pdfshuffler_g.glade:313
msgid "Save _As..."
msgstr "Enregistrer _sous..."
#: ..\..\..\data\pdfshuffler_g.glade:331
msgid "_Quit"
msgstr "_Quitter"
#: ..\..\..\data\pdfshuffler_g.glade:350
msgid "_Edit"
msgstr "É_diter"
#: ..\..\..\data\pdfshuffler_g.glade:382
msgid "Add blank page _before"
msgstr "Ajouter une page _blanche avant"
#: ..\..\..\data\pdfshuffler_g.glade:439
msgid "Add blank page _after"
msgstr "Ajouter une page blanche _après"
#: ..\..\..\data\pdfshuffler_g.glade:502
msgid "_Delete"
msgstr "_Effacer"
#: ..\..\..\data\pdfshuffler_g.glade:514
msgid "_Crop"
msgstr "_Recouper"
#: ..\..\..\data\pdfshuffler_g.glade:533
msgid "_View"
msgstr "_Voir"
#: ..\..\..\data\pdfshuffler_g.glade:541
msgid "Zoom _in"
msgstr "_Zoom avant"
#: ..\..\..\data\pdfshuffler_g.glade:553
msgid "Zoom _out"
msgstr "Zoom _arrière"
#: ..\..\..\data\pdfshuffler_g.glade:572
msgid "_Help"
msgstr "_Aide"
#: ..\..\..\data\pdfshuffler_g.glade:580
msgid "_About"
msgstr "A propos"
#: ..\..\..\data\pdfshuffler_g.glade:617
msgid "Open"
msgstr "Ouvrir"
#: ..\..\..\data\pdfshuffler_g.glade:632
msgid "Save"
msgstr "Enregistrer"
#: ..\..\..\data\pdfshuffler_g.glade:647
msgid "Save as"
msgstr "Enregistrer sous..."
#: ..\..\..\data\pdfshuffler_g.glade:672
msgid "Zoom in"
msgstr "Agrandir"
#: ..\..\..\data\pdfshuffler_g.glade:687
msgid "Zoom out"
msgstr "Réduire"
#: ..\..\..\data\pdfshuffler_g.glade:712
msgid "Rotate left"
msgstr "Tourner à gauche"
#: ..\..\..\data\pdfshuffler_g.glade:727
msgid "Rotate right"
msgstr "Tourner à droite"
#: ..\..\..\data\pdfshuffler_g.glade:742
msgid "Crop"
msgstr "Couper les marges"
#: ..\..\..\data\pdfshuffler_g.glade:757
msgid "Delete"
msgstr "Effacer"
#~ msgid "Error writing file: %s"
#~ msgstr "Une erreur s'est produite pendant l'écriture du fichier : %s"
#~ msgid "File %s is encrypted."
#~ msgstr "Le fichier %s est codé."
#~ msgid "File export failed."
#~ msgstr "Exportation des fichiers échouée."
#~ msgid "exporting to:"
#~ msgstr "exporter en :"
#~ msgid "Import pdf"
#~ msgstr "Importer PDF"
#~ msgid "Export pdf"
#~ msgstr "Exporter PDF"
#~ msgid "Rotate Page(s) Clockwise"
#~ msgstr "Rotation de la(les) page(s) en sens horaire"
#~ msgid "Rotate Page(s) Counterclockwise"
#~ msgstr "Rotation de la(les) page(s) en sens anti-horaire"
#~ msgid "Crop Page(s)"
#~ msgstr "Couper la(les) page(s)"
#~ msgid ""
#~ "PDF-Shuffler is a simple pyGTK utility which lets you merge, split and "
#~ "rearrange PDF documents. You can also rotate and crop individual pages of "
#~ "a pdf document."
#~ msgstr ""
#~ "PDF-Shuffler est un simple outil pyGTK qui vous permet de réunir, couper "
#~ "et réarrangez des documents PDF. Vous pouvez aussi pivoter et couper des "
#~ "pages individuelles d'un document pdf."

View File

@ -0,0 +1,299 @@
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkFileChooserDialog" id="filechooserdialog1">
<property name="width_request">800</property>
<property name="height_request">600</property>
<property name="border_width">5</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">normal</property>
<property name="skip_taskbar_hint">True</property>
<property name="select_multiple">True</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="spacing">7</property>
<property name="layout_style">end</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Open Selected File(s)</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image1</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="chooserOK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="chooserClose"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame6">
<property name="height_request">150</property>
<property name="visible">True</property>
<property name="label_xalign">0</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">2</property>
<property name="reorderable">True</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<property name="enable_grid_lines">horizontal</property>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox10">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="button14">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="pdf_up"/>
<child>
<object class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="stock">gtk-go-up</property>
<property name="icon-size">2</property>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button15">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="pdf_down"/>
<child>
<object class="GtkImage" id="image9">
<property name="visible">True</property>
<property name="stock">gtk-go-down</property>
<property name="icon-size">2</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton" id="button20">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="pdf_open"/>
<child>
<object class="GtkImage" id="image13">
<property name="visible">True</property>
<property name="stock">gtk-new</property>
<property name="icon-size">2</property>
</object>
</child>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button19">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="add_file"/>
<child>
<object class="GtkImage" id="image12">
<property name="visible">True</property>
<property name="stock">gtk-add</property>
<property name="icon-size">2</property>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button13">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="pdf_remove"/>
<child>
<object class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="stock">gtk-remove</property>
<property name="icon-size">2</property>
</object>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Input files&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button21">
<property name="label" translatable="yes">Open File(s) in List</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">image2</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="genFilesArray"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="chooserClose"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="2">button21</action-widget>
<action-widget response="0">button2</action-widget>
</action-widgets>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
</object>
</interface>

View File

@ -0,0 +1,10 @@
[Desktop Entry]
Version=2.0
Name=PDF-Booklet
Comment=PDF Merging, Rearranging, Splitting, Rotating and Cropping
Type=Application
Exec=pdfbooklet
Icon=pdfbooklet
Categories=Office;
Terminal=false
StartupNotify=false

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.48.2 r9819"
version="1.0"
sodipodi:docname="pdfbooklet.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet.png"
inkscape:export-xdpi="14.4"
inkscape:export-ydpi="14.4">
<defs
id="defs4">
<linearGradient
id="linearGradient4751">
<stop
style="stop-color:#ff0000;stop-opacity:1;"
offset="0"
id="stop4753" />
<stop
id="stop4763"
offset="0.91071427"
style="stop-color:#7f007f;stop-opacity:1;" />
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="1"
id="stop4755" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4743">
<stop
style="stop-color:#4d4d4d;stop-opacity:1;"
offset="0"
id="stop4745" />
<stop
style="stop-color:#4d4d4d;stop-opacity:0;"
offset="1"
id="stop4747" />
</linearGradient>
<linearGradient
id="linearGradient4735">
<stop
style="stop-color:#d6e3e3;stop-opacity:1;"
offset="0"
id="stop4737" />
<stop
style="stop-color:#00ffff;stop-opacity:1;"
offset="1"
id="stop4739" />
</linearGradient>
<linearGradient
id="linearGradient4727">
<stop
style="stop-color:#3758ff;stop-opacity:1;"
offset="0"
id="stop4729" />
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="1"
id="stop4731" />
</linearGradient>
<linearGradient
id="linearGradient4717">
<stop
style="stop-color:#ffb2ff;stop-opacity:1;"
offset="0"
id="stop4719" />
<stop
id="stop4725"
offset="1"
style="stop-color:#ff00ff;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4707">
<stop
style="stop-color:#ffda42;stop-opacity:1;"
offset="0"
id="stop4709" />
<stop
id="stop4715"
offset="1"
style="stop-color:#ff0000;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4691">
<stop
id="stop4705"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop4703"
offset="1"
style="stop-color:#04ff00;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2390"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4691"
id="linearGradient4699"
x1="15.185715"
y1="119.40044"
x2="201.11098"
y2="119.40044"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4707"
id="linearGradient4713"
x1="0.881223"
y1="109.5406"
x2="170.03773"
y2="109.5406"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4717"
id="linearGradient4723"
x1="22.021743"
y1="99.182249"
x2="153.85376"
y2="99.182249"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4727"
id="linearGradient4733"
x1="12.858827"
y1="101.05511"
x2="125.1628"
y2="101.05511"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.7613146,-17.953527)"
spreadMethod="pad" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4735"
id="radialGradient4741"
cx="189.2718"
cy="133.60805"
fx="189.2718"
fy="133.60805"
r="111.12802"
gradientTransform="matrix(1,0,0,0.8186404,-57.578695,84.012848)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4743"
id="radialGradient4749"
cx="139.74099"
cy="255.0762"
fx="139.74099"
fy="255.0762"
r="130.42264"
gradientTransform="matrix(1.5440848,0,0,0.1951499,-0.6671924,127.80153)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4751"
id="radialGradient4767"
cx="215.10474"
cy="177.57961"
fx="215.10474"
fy="177.57961"
r="202.15565"
gradientTransform="matrix(1,0,0,0.1297218,0,154.54365)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="118.615"
inkscape:cy="120.88252"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1000"
inkscape:window-height="723"
inkscape:window-x="91"
inkscape:window-y="25"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#808080;stroke:#4d4d4d;stroke-width:1.55596292;stroke-miterlimit:4;stroke-dasharray:none"
d="M 3.6961424,132.18198 C 2.0734071,137.17299 5.3215966,138.82427 9.4737962,140.08403 L 21.878827,143.73734 L 21.93547,145.18199 C 22.063721,148.21357 24.603735,150.44398 27.628159,150.19475 L 37.852434,149.34554 L 144.85256,187.55164 C 147.74004,188.84041 151.03082,185.53512 152.32956,182.00055 L 162.59651,158.04802 L 237.92198,209.66552 C 240.3826,211.47359 243.99965,211.10563 246.05061,208.8435 L 299.26781,121.18769 C 301.31878,118.92557 300.99161,115.63206 298.53099,113.82398"
id="rect3192"
sodipodi:nodetypes="ccccccccccccc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<rect
style="fill:url(#linearGradient4733);fill-opacity:1.0;stroke:#000000;stroke-width:2.17599440000000000;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2398"
width="110.12798"
height="127.43299"
x="14.708143"
y="19.385107"
ry="5.4777718"
transform="matrix(0.996623,-8.2113516e-2,4.2261543e-2,0.9991066,0,0)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
style="fill:url(#linearGradient4723);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
d="M 48.822926,13.984228 L 146.97785,15.809809 C 150.02702,15.966042 152.60863,18.546516 152.7662,21.595637 L 140.04042,143.15846 C 140.19798,146.20757 137.87007,148.5365 134.82089,148.38027 L 28.897664,142.02316 C 25.848474,141.86694 23.266872,139.28646 23.109307,136.23734 L 43.603394,19.206039 C 43.445829,16.156918 45.773736,13.827994 48.822926,13.984228 z"
id="rect3173"
sodipodi:nodetypes="ccccccccc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
sodipodi:nodetypes="ccccccczc"
id="path3176"
d="M 77.468573,15.926305 L 163.16182,40.40946 C 166.211,40.565688 168.79261,43.146168 168.95017,46.195288 L 123.20908,161.93187 C 123.36663,164.98099 121.03874,167.30992 117.98955,167.15368 L 8.1821682,134.90221 C 4.0299791,133.64299 0.7711377,132.00367 2.3938114,127.01247 L 71.439841,21.148117 C 73.107769,18.590777 74.419383,15.770071 77.468573,15.926305 z"
style="fill:url(#linearGradient4713);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
style="fill:url(#linearGradient4699);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
d="M 101.42086,20.215059 L 194.23507,47.530409 C 197.28424,47.686637 199.86585,50.267117 200.02342,53.316237 L 151.04551,176.82113 C 149.74652,180.35577 146.44758,183.65573 143.56023,182.36662 L 21.453033,138.78637 C 17.627627,137.3569 14.949799,134.46878 16.959396,131.05846 L 92.479018,25.275031 C 94.253024,22.790104 94.892122,19.654227 101.42086,20.215059 z"
id="path3178"
sodipodi:nodetypes="ccccccczc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
sodipodi:nodetypes="ccccccccc"
id="path3180"
d="m 22.998972,167.35118 72.936413,-61.88033 c 2.05122,-2.26151 5.683065,-2.62641 8.143185,-0.81816 l 135.57057,81.6271 c 2.46012,1.80827 2.78931,5.08465 0.73808,7.34616 l -53.20188,87.6828 c -2.05121,2.26152 -5.68306,2.62641 -8.14318,0.81815 L 23.737057,174.69734 c -2.460114,-1.80826 -2.789302,-5.08463 -0.738085,-7.34616 z"
style="fill:url(#radialGradient4741);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:27.77963257px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="-20.606281"
y="149.67995"
id="text3205"
transform="matrix(0.7546661,-0.656109,0.8129658,0.6182944,0,0)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
sodipodi:role="line"
id="tspan3207"
x="-20.606281"
y="149.67995"
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
<text
transform="matrix(-0.5491289,0.833383,-0.8542178,-0.5246662,0,0)"
id="text3229"
y="-282.16574"
x="-57.589748"
style="font-size:27.77963066px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
y="-282.16574"
x="-57.589748"
id="tspan3231"
sodipodi:role="line"
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
<text
xml:space="preserve"
style="font-size:65.77364348999999777px;font-style:normal;font-weight:normal;fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;stroke-miterlimit:4;stroke-dasharray:none"
x="7.2658076"
y="202.10019"
id="text3233"
transform="scale(0.6989506,1.4307163)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
sodipodi:role="line"
id="tspan3235"
x="7.2658076"
y="202.10019"
style="fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-miterlimit:4;stroke-dasharray:none">PDF-Shuffler</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,968 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">-24</property>
<property name="upper">5</property>
<property name="value">-14</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
<property name="page_size">10</property>
</object>
<object class="GtkDialog" id="dialog1">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="type_hint">normal</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">5</property>
<property name="n_columns">3</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkEntry" id="Left">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Right">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Top">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="Bottom">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
<action-widget response="0">button2</action-widget>
</action-widgets>
</object>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-redo</property>
</object>
<object class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-zoom-in</property>
</object>
<object class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-zoom-out</property>
</object>
<object class="GtkImage" id="image12">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-leave-fullscreen</property>
</object>
<object class="GtkImage" id="image13">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-undo</property>
</object>
<object class="GtkImage" id="image14">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-redo</property>
</object>
<object class="GtkImage" id="image15">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-new</property>
</object>
<object class="GtkImage" id="image16">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-new</property>
</object>
<object class="GtkImage" id="image17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-about</property>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-undo</property>
</object>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-leave-fullscreen</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-new</property>
</object>
<object class="GtkMenu" id="contextmenu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menu1_RR">
<property name="label" translatable="yes">Rotate _Right</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image1</property>
<property name="use_stock">False</property>
<signal name="activate" handler="rotate_page_right" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menu1_RL">
<property name="label" translatable="yes">Rotate _Left</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image2</property>
<property name="use_stock">False</property>
<signal name="activate" handler="rotate_page_left" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menu1_crop">
<property name="label" translatable="yes">C_rop</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image3</property>
<property name="use_stock">False</property>
<signal name="activate" handler="crop_page_dialog" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menu1_del">
<property name="label">gtk-clear</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="clear_selected" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menu1_BB">
<property name="label" translatable="yes">Add _Blank Page Before</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image4</property>
<property name="use_stock">False</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="before_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_1</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="before_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_2</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="before_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_3</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="before_4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_4</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Add Blank Page _After</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="after_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_1</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="after_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_2</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="after_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_3</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="after_4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_4</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-open</property>
</object>
<object class="GtkImage" id="image6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-save</property>
</object>
<object class="GtkImage" id="image7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-save-as</property>
</object>
<object class="GtkImage" id="image8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-quit</property>
</object>
<object class="GtkImage" id="image9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-delete</property>
</object>
<object class="GtkWindow" id="main_window">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuBar" id="menubar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="menuitem_file">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_File</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu_file">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_import">
<property name="label" translatable="yes">_Open</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image5</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_action_add_doc_activate" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_save">
<property name="label" translatable="yes">_Save</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image6</property>
<property name="use_stock">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_save_as">
<property name="label" translatable="yes">Save _As...</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image7</property>
<property name="use_stock">False</property>
<signal name="activate" handler="choose_export_pdf_name" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem_file">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_quit">
<property name="label" translatable="yes">_Quit</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image8</property>
<property name="use_stock">False</property>
<signal name="activate" handler="close_application" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_edit">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Edit</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu_edit">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_rotate_left">
<property name="label" translatable="yes">Rotate _Left</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image13</property>
<property name="use_stock">False</property>
<signal name="activate" handler="rotate_page_left" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_rotate_right">
<property name="label" translatable="yes">Rotate _Right</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image14</property>
<property name="use_stock">False</property>
<signal name="activate" handler="rotate_page_right" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_add_before">
<property name="label" translatable="yes">Add blank page _before</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image15</property>
<property name="use_stock">False</property>
<child type="submenu">
<object class="GtkMenu" id="menu3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="beforemenu_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_1</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="beforemenu_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_2</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="beforemenu_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_3</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="beforemenu_4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_4</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_add_after">
<property name="label" translatable="yes">Add blank page _after</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image16</property>
<property name="use_stock">False</property>
<child type="submenu">
<object class="GtkMenu" id="menu4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="aftermenu_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_1</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="aftermenu_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_2</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="aftermenu_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_3</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="aftermenu_4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_4</property>
<property name="use_underline">True</property>
<signal name="activate" handler="add_blank_page" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_delete">
<property name="label" translatable="yes">_Delete</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image9</property>
<property name="use_stock">False</property>
<signal name="activate" handler="clear_selected" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="menuitem2_crop">
<property name="label" translatable="yes">_Crop</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image12</property>
<property name="use_stock">False</property>
<signal name="activate" handler="crop_page_dialog" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_view">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_View</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu_view">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_zoomin">
<property name="label" translatable="yes">Zoom _in</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image10</property>
<property name="use_stock">False</property>
<signal name="activate" handler="zoom_in" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_zoomout">
<property name="label" translatable="yes">Zoom _out</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image11</property>
<property name="use_stock">False</property>
<signal name="activate" handler="zoom_out" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_help">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Help</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu_help">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="imagemenuitem_about">
<property name="label" translatable="yes">_About</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="image">image17</property>
<property name="use_stock">False</property>
<signal name="activate" handler="about_dialog" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToolbar" id="toolbar1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="toolbar_style">icons</property>
<property name="show_arrow">False</property>
<property name="icon_size">4</property>
<child>
<object class="GtkToolButton" id="toolbutton1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Open</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-open</property>
<signal name="clicked" handler="on_action_add_doc_activate" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Save</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-save</property>
<signal name="clicked" handler="choose_export_pdf_name" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Save as</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-save-as</property>
<signal name="clicked" handler="choose_export_pdf_name" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem" id="toolbutton4">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Zoom in</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-zoom-in</property>
<signal name="clicked" handler="zoom_in" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Zoom out</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-zoom-out</property>
<signal name="clicked" handler="zoom_out" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkSeparatorToolItem" id="toolbutton7">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Rotate left</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-undo</property>
<signal name="clicked" handler="rotate_page_left" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Rotate right</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-redo</property>
<signal name="clicked" handler="rotate_page_right" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Crop</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-leave-fullscreen</property>
<signal name="clicked" handler="crop_page_dialog" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolbutton11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Delete</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-delete</property>
<signal name="clicked" handler="clear_selected" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkHScale" id="hscale1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="adjustment">adjustment1</property>
<property name="lower_stepper_sensitivity">on</property>
<property name="upper_stepper_sensitivity">off</property>
<property name="restrict_to_fill_level">False</property>
<property name="fill_level">5</property>
<property name="digits">2</property>
<property name="draw_value">False</property>
<property name="value_pos">right</property>
<signal name="change-value" handler="zoom_bar" swapped="no"/>
<signal name="move-slider" handler="zoom_bar" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkProgressBar" id="progressbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,97 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Atlantis Word Processor 2.0.5.1, http://www.AtlantisWordProcessor.com"><title>Important Note for Linux users</title>
<style>p{margin-top:0pt;margin-bottom:0pt;font-family:Arial;font-size:11pt;color:black}</style></head><body bgcolor="#ffffca">
<p style="margin-top: 12pt; margin-bottom: 3pt;"><span style="font-size: 14pt; color: blue;"><b>Important Note for Linux users</b></span></p>
<p style="font-weight: bold; color: rgb(204, 0, 0);">You will find the
last version of Linux installers in the beta directory. <br>
</p>
<p style="font-weight: bold; color: rgb(204, 0, 0);">pdfbooklet_3.0.6_all.deb hs been tested and seems OK. <br>
</p>
<p style="font-weight: bold; color: rgb(204, 0, 0);">The .rpm installer has not been tested. <br>
</p>
<p style="font-weight: bold; color: rgb(204, 0, 0);">For the tar.gz files, see the dependencies below. <br>
<br>
</p>
<p><br>
</p>
<p>PdfBooklet is developed originally in Windows and for Windows.
Nevertheless it works perfectly on Linux, we have made the code
compatible. It runs in Python 2.7 or 3.4.</p>
<p><br>
</p>
<p><b>1) Installation</b></p>
<p>You sould normally use the <span style="font-weight: bold;">.deb file</span> which should work out of the box.<br>
The <span style="font-weight: bold;">.rpm</span> file is not yet tested, and the dependencies are not properly set. <br>
</p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span> <br>
</p><span style="color: rgb(0, 0, 0);"></span>
<p>In case these installers do not work for you, we are providing other solutions.&nbsp; </p>
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>a) Install from source</b></p>
<p style="margin-left: 40px;">Decompress the file : <i>Install by unzipping linux.zip </i>in a directory where you have full write rights. Run pdfbooklet.py with the following command :</p>
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p style="margin-left: 40px;"><span style="font-family: Courier New;">python pdfbooklet.py</span></p>
<p style="margin-left: 40px;">or<span style="font-family: Courier New;"> </span></p>
<p style="margin-left: 40px;"><span style="font-family: Courier New;">python3 pdfbooklet.py</span></p>
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p style="margin-left: 40px;">If you have the dependencies satisfied, the program should run. If
not, either install the missing packages, if you know how to do that,
or use the second solution :</p>
<p style="margin-left: 40px;"><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>b) Install the pyinstaller bundle</b></p>
<p style="margin-left: 40px;">To solve the dependencies problem, we have built a bundle with
pyinstaller, which contains everything needed : Python3, Gtk3, Poppler.
</p>
<p style="margin-left: 40px;">Unzip the big file : pdfbooklet 3.x.x pyinstaller.zip, in a directory where you have write rights. </p>
<p style="margin-left: 40px;">Run the file : pdfbooklet</p>
<p style="margin-top: 12pt; margin-bottom: 3pt; margin-left: 40px;"><b>c) Install from tarball</b></p>
<p style="margin-left: 40px;">We offer also the tarballs in 32 and 64 bits if you know how to install them. </p>
<p style="margin-top: 12pt; margin-bottom: 3pt;"><span style="font-size: 12pt; color: rgb(0, 0, 0);"><b><i>2) Known problems<br>
</i></b></span></p>
<ol>
<li style="font-family: monospace;">
<p>Dependencies problems : see below the modules which must be installed. Otherwise consider using the pyinstaller bundle. </p>
</li>
<li>
<p>pdfbooklet needs read/write rights in the forder where
pdfbooklet.cfg is located and the installer does not always provides
this. <span style="font-size: 12pt; color: rgb(0, 0, 0);"><b><i><br>
</i></b></span></p>
</li>
</ol>
<p style="margin-top: 9pt; margin-bottom: 3pt;"><span style="font-size: 12pt;"><b><i>Technical information </i></b></span></p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The needed dependencies for python3 are :<br>
&nbsp;python-gi<br>
&nbsp;python-gi-cairo<br>
</p>
<p>&nbsp;python3-gi<br>
<span style="color: rgb(0, 0, 0);">&nbsp;python3-cairo</span><br>
</p>
<p>&nbsp;python3-gi-cairo</p>
<p>&nbsp;gir1.2-gtk-3.0</p>
<p>&nbsp;gir1.2-poppler-0.18<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; They are installed with the following commande line :<br>
</p>
<p>&nbsp;- sudo apt-get install&nbsp; python-gi&nbsp; python-gi-cairo python3-gi <span style="color: rgb(0, 0, 0);">python3-cairo&nbsp; </span>python3-gi-cairo&nbsp; gir1.2-gtk-3.0&nbsp; gir1.2-poppler-0.18 </p>
<p><br>
</p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p>For python 2.7 :</p>
<p>- sudo apt-get install&nbsp; python-gobject-cairo</p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
<p><span style="color: rgb(0, 0, 0);">&nbsp;</span></p>
</body></html>

View File

@ -0,0 +1,333 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="300"
height="300"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.48.2 r9819"
version="1.0"
sodipodi:docname="pdfbooklet.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet.png"
inkscape:export-xdpi="14.4"
inkscape:export-ydpi="14.4">
<defs
id="defs4">
<linearGradient
id="linearGradient4751">
<stop
style="stop-color:#ff0000;stop-opacity:1;"
offset="0"
id="stop4753" />
<stop
id="stop4763"
offset="0.91071427"
style="stop-color:#7f007f;stop-opacity:1;" />
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="1"
id="stop4755" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4743">
<stop
style="stop-color:#4d4d4d;stop-opacity:1;"
offset="0"
id="stop4745" />
<stop
style="stop-color:#4d4d4d;stop-opacity:0;"
offset="1"
id="stop4747" />
</linearGradient>
<linearGradient
id="linearGradient4735">
<stop
style="stop-color:#d6e3e3;stop-opacity:1;"
offset="0"
id="stop4737" />
<stop
style="stop-color:#00ffff;stop-opacity:1;"
offset="1"
id="stop4739" />
</linearGradient>
<linearGradient
id="linearGradient4727">
<stop
style="stop-color:#3758ff;stop-opacity:1;"
offset="0"
id="stop4729" />
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="1"
id="stop4731" />
</linearGradient>
<linearGradient
id="linearGradient4717">
<stop
style="stop-color:#ffb2ff;stop-opacity:1;"
offset="0"
id="stop4719" />
<stop
id="stop4725"
offset="1"
style="stop-color:#ff00ff;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4707">
<stop
style="stop-color:#ffda42;stop-opacity:1;"
offset="0"
id="stop4709" />
<stop
id="stop4715"
offset="1"
style="stop-color:#ff0000;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4691">
<stop
id="stop4705"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop4703"
offset="1"
style="stop-color:#04ff00;stop-opacity:1;" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective2390"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 526.18109 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4691"
id="linearGradient4699"
x1="15.185715"
y1="119.40044"
x2="201.11098"
y2="119.40044"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4707"
id="linearGradient4713"
x1="0.881223"
y1="109.5406"
x2="170.03773"
y2="109.5406"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4717"
id="linearGradient4723"
x1="22.021743"
y1="99.182249"
x2="153.85376"
y2="99.182249"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0,-18)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4727"
id="linearGradient4733"
x1="12.858827"
y1="101.05511"
x2="125.1628"
y2="101.05511"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.7613146,-17.953527)"
spreadMethod="pad" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4735"
id="radialGradient4741"
cx="189.2718"
cy="133.60805"
fx="189.2718"
fy="133.60805"
r="111.12802"
gradientTransform="matrix(1,0,0,0.8186404,-57.578695,84.012848)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4743"
id="radialGradient4749"
cx="139.74099"
cy="255.0762"
fx="139.74099"
fy="255.0762"
r="130.42264"
gradientTransform="matrix(1.5440848,0,0,0.1951499,-0.6671924,127.80153)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4751"
id="radialGradient4767"
cx="215.10474"
cy="177.57961"
fx="215.10474"
fy="177.57961"
r="202.15565"
gradientTransform="matrix(1,0,0,0.1297218,0,154.54365)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98994949"
inkscape:cx="118.615"
inkscape:cy="120.88252"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1000"
inkscape:window-height="723"
inkscape:window-x="91"
inkscape:window-y="25"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#808080;stroke:#4d4d4d;stroke-width:1.55596292;stroke-miterlimit:4;stroke-dasharray:none"
d="M 3.6961424,132.18198 C 2.0734071,137.17299 5.3215966,138.82427 9.4737962,140.08403 L 21.878827,143.73734 L 21.93547,145.18199 C 22.063721,148.21357 24.603735,150.44398 27.628159,150.19475 L 37.852434,149.34554 L 144.85256,187.55164 C 147.74004,188.84041 151.03082,185.53512 152.32956,182.00055 L 162.59651,158.04802 L 237.92198,209.66552 C 240.3826,211.47359 243.99965,211.10563 246.05061,208.8435 L 299.26781,121.18769 C 301.31878,118.92557 300.99161,115.63206 298.53099,113.82398"
id="rect3192"
sodipodi:nodetypes="ccccccccccccc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<rect
style="fill:url(#linearGradient4733);fill-opacity:1.0;stroke:#000000;stroke-width:2.17599440000000000;stroke-miterlimit:4;stroke-dasharray:none"
id="rect2398"
width="110.12798"
height="127.43299"
x="14.708143"
y="19.385107"
ry="5.4777718"
transform="matrix(0.996623,-8.2113516e-2,4.2261543e-2,0.9991066,0,0)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
style="fill:url(#linearGradient4723);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
d="M 48.822926,13.984228 L 146.97785,15.809809 C 150.02702,15.966042 152.60863,18.546516 152.7662,21.595637 L 140.04042,143.15846 C 140.19798,146.20757 137.87007,148.5365 134.82089,148.38027 L 28.897664,142.02316 C 25.848474,141.86694 23.266872,139.28646 23.109307,136.23734 L 43.603394,19.206039 C 43.445829,16.156918 45.773736,13.827994 48.822926,13.984228 z"
id="rect3173"
sodipodi:nodetypes="ccccccccc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
sodipodi:nodetypes="ccccccczc"
id="path3176"
d="M 77.468573,15.926305 L 163.16182,40.40946 C 166.211,40.565688 168.79261,43.146168 168.95017,46.195288 L 123.20908,161.93187 C 123.36663,164.98099 121.03874,167.30992 117.98955,167.15368 L 8.1821682,134.90221 C 4.0299791,133.64299 0.7711377,132.00367 2.3938114,127.01247 L 71.439841,21.148117 C 73.107769,18.590777 74.419383,15.770071 77.468573,15.926305 z"
style="fill:url(#linearGradient4713);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
style="fill:url(#linearGradient4699);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
d="M 101.42086,20.215059 L 194.23507,47.530409 C 197.28424,47.686637 199.86585,50.267117 200.02342,53.316237 L 151.04551,176.82113 C 149.74652,180.35577 146.44758,183.65573 143.56023,182.36662 L 21.453033,138.78637 C 17.627627,137.3569 14.949799,134.46878 16.959396,131.05846 L 92.479018,25.275031 C 94.253024,22.790104 94.892122,19.654227 101.42086,20.215059 z"
id="path3178"
sodipodi:nodetypes="ccccccczc"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861" />
<path
sodipodi:nodetypes="ccccccccc"
id="path3180"
d="m 22.998972,167.35118 72.936413,-61.88033 c 2.05122,-2.26151 5.683065,-2.62641 8.143185,-0.81816 l 135.57057,81.6271 c 2.46012,1.80827 2.78931,5.08465 0.73808,7.34616 l -53.20188,87.6828 c -2.05121,2.26152 -5.68306,2.62641 -8.14318,0.81815 L 23.737057,174.69734 c -2.460114,-1.80826 -2.789302,-5.08463 -0.738085,-7.34616 z"
style="fill:url(#radialGradient4741);fill-opacity:1;stroke:#000000;stroke-width:2.17512703;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:27.77963257px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="-20.606281"
y="149.67995"
id="text3205"
transform="matrix(0.7546661,-0.656109,0.8129658,0.6182944,0,0)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
sodipodi:role="line"
id="tspan3207"
x="-20.606281"
y="149.67995"
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
<text
transform="matrix(-0.5491289,0.833383,-0.8542178,-0.5246662,0,0)"
id="text3229"
y="-282.16574"
x="-57.589748"
style="font-size:27.77963066px;font-style:normal;font-weight:normal;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
y="-282.16574"
x="-57.589748"
id="tspan3231"
sodipodi:role="line"
style="font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">PDF</tspan></text>
<text
xml:space="preserve"
style="font-size:65.77364348999999777px;font-style:normal;font-weight:normal;fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans;stroke-miterlimit:4;stroke-dasharray:none"
x="7.2658076"
y="202.10019"
id="text3233"
transform="scale(0.6989506,1.4307163)"
inkscape:export-filename="/home/kostas/Desktop/pdfbooklet16.png"
inkscape:export-xdpi="5.0848861"
inkscape:export-ydpi="5.0848861"><tspan
sodipodi:role="line"
id="tspan3235"
x="7.2658076"
y="202.10019"
style="fill:url(#radialGradient4767);fill-opacity:1;stroke:#000000;stroke-width:2.34399998;stroke-miterlimit:4;stroke-dasharray:none">PDF-Shuffler</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB