Skip to content

Commit

Permalink
Merge branch 'stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
brechtm committed Aug 19, 2016
2 parents ff22768 + 6c4f329 commit 3478f0b
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 69 deletions.
7 changes: 6 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ Release History
Release 0.3.0.dev
~~~~~~~~~~~~~~~~~

Release 0.2.1.dev
Release 0.2.2.dev
~~~~~~~~~~~~~~~~~

Release 0.2.1 (2016-08-18)
~~~~~~~~~~~~~~~~~~~~~~~~~~

New Features:

* optionally limit the width of large images and make use of this to simulate
the Sphinx LaTeX builder behavior (#46)
* reStructuredText/Sphinx: support for images with hyperlinks (#49)
* record the styled page numbers in the PDF as page labels (#41)
* unsupported Python versions: prevent installation where possible (sdist)
or exit on import (wheel)
* support Python 3.6
Expand All @@ -22,6 +26,7 @@ Bugfixes:
option can actually be used
* Fix #47: ClassNotFound exception in Literal_Block.lexer_getter()
* Fix #45: Images that don't fit are still placed on the page
* don't warn about duplicate style matches that resolve to the same style


Release 0.2.0 (2016-08-10)
Expand Down
2 changes: 1 addition & 1 deletion doc/_build/html
Submodule html updated 65 files
+1 −1 .buildinfo
+0 −0 .nojekyll
+ _downloads/demo.pdf
+ _downloads/rinohtype.pdf
+343 −179 _sources/advanced.txt
+25 −10 _sources/api/flowable.txt
+6 −1 _sources/api/index.txt
+5 −14 _sources/api/paragraph.txt
+12 −0 _sources/api/structure.txt
+25 −0 _sources/api/style.txt
+61 −0 _sources/api/template.txt
+22 −0 _sources/article.txt
+17 −0 _sources/book.txt
+22 −20 _sources/index.txt
+7 −7 _sources/install.txt
+43 −47 _sources/intro.txt
+0 −31 _sources/invoice.txt
+242 −117 _sources/quickstart.txt
+7 −0 _sources/rinoh.txt
+72 −0 _sources/sphinx.txt
+14 −0 _sources/templates.txt
+0 −585 _static/alabaster.css
+10 −5 _static/basic.css
+2 −0 _static/css/badge_only.css
+5 −0 _static/css/theme.css
+26 −2 _static/doctools.js
+ _static/fonts/Inconsolata-Bold.ttf
+ _static/fonts/Inconsolata-Regular.ttf
+ _static/fonts/Lato-Bold.ttf
+ _static/fonts/Lato-Regular.ttf
+ _static/fonts/RobotoSlab-Bold.ttf
+ _static/fonts/RobotoSlab-Regular.ttf
+ _static/fonts/fontawesome-webfont.eot
+520 −0 _static/fonts/fontawesome-webfont.svg
+ _static/fonts/fontawesome-webfont.ttf
+ _static/fonts/fontawesome-webfont.woff
+4 −0 _static/js/modernizr.min.js
+153 −0 _static/js/theme.js
+2 −0 _static/pygments.css
+40 −11 _static/searchtools.js
+2 −2 _static/websupport.js
+562 −318 advanced.html
+538 −0 api/flowable.html
+0 −256 api/flowables.html
+219 −88 api/index.html
+273 −186 api/paragraph.html
+257 −0 api/structure.html
+310 −0 api/style.html
+421 −0 api/template.html
+304 −0 article.html
+378 −0 book.html
+276 −88 changelog.html
+659 −126 genindex.html
+222 −106 index.html
+204 −98 install.html
+237 −141 intro.html
+0 −117 invoice.html
+ objects.inv
+209 −67 py-modindex.html
+481 −455 quickstart.html
+268 −0 rinoh.html
+189 −76 search.html
+1 −1 searchindex.js
+291 −0 sphinx.html
+222 −0 templates.html
23 changes: 20 additions & 3 deletions src/rinoh/backend/pdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import math

from io import StringIO, BytesIO
from io import BytesIO
from contextlib import contextmanager

from . import cos
Expand Down Expand Up @@ -107,20 +107,37 @@ def _create_outline_level(self, sections_tree, parent, top_level):
parent['Count'] = cos.Integer(count if top_level else - count)

def write(self, file):
for page in self.pages:
from ... import number
page_number_formats = {number.NUMBER: cos.DECIMAL_ARABIC,
number.CHARACTER_LC: cos.LOWERCASE_LETTERS,
number.CHARACTER_UC: cos.UPPERCASE_LETTERS,
number.ROMAN_LC: cos.LOWERCASE_ROMAN,
number.ROMAN_UC: cos.UPPERCASE_ROMAN}

page_labels = self.cos_document.catalog['PageLabels']['Nums']
last_number_format = None
for index, page in enumerate(self.pages):
contents = cos.Stream(filter=FlateDecode())
contents.write(page.canvas.getvalue())
page.cos_page['Contents'] = contents
if page.number_format != last_number_format:
pdf_number_format = page_number_formats[page.number_format]
page_labels.append(cos.Integer(index))
page_labels.append(cos.PageLabel(pdf_number_format,
start=page.number))
last_number_format = page.number_format
self.cos_document.write(file)


class Page(object):
def __init__(self, backend_document, width, height):
def __init__(self, backend_document, width, height, number, number_format):
self.backend_document = backend_document
cos_pages = backend_document.cos_document.catalog['Pages']
self.cos_page = cos_pages.new_page(float(width), float(height))
self.width = width
self.height = height
self.number = number
self.number_format = number_format
self.canvas = PageCanvas(self)
self.backend_document.pages.append(self)

Expand Down
22 changes: 22 additions & 0 deletions src/rinoh/backend/pdf/cos.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ class Document(dict):

def __init__(self, creator):
self.catalog = Catalog()
self.catalog['PageLabels'] = Dictionary(indirect=True)
self.catalog['PageLabels']['Nums'] = Array()
self.info = Dictionary(indirect=True)
self.timestamp = time.time()
self.set_info('Creator', creator)
Expand Down Expand Up @@ -605,6 +607,26 @@ def __init__(self, parent, width, height):
Real(width), Real(height)])


DECIMAL_ARABIC = Name('D')
UPPERCASE_ROMAN = Name('R')
LOWERCASE_ROMAN = Name('r')
UPPERCASE_LETTERS = Name('A')
LOWERCASE_LETTERS = Name('a')


class PageLabel(Dictionary):
type = 'PageLabel'

def __init__(self, numbering_style=None, label_prefix=None, start=None):
super().__init__(indirect=False)
if numbering_style:
self['S'] = numbering_style
if label_prefix is not None:
self['P'] = String(label_prefix)
if start is not None:
self['St'] = Integer(start)


class Outlines(Dictionary):
type = 'Outlines'

Expand Down
3 changes: 2 additions & 1 deletion src/rinoh/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ def __init__(self, document_part, paper, orientation=PORTRAIT):
document = self.document_part.document
backend_document = document.backend_document
self.backend_page = document.backend.Page(backend_document,
width, height)
width, height, self.number,
self.number_format)
self.section = None # will point to the last section on this page
self.overflowed_chains = []
self._current_section = {}
Expand Down
12 changes: 9 additions & 3 deletions src/rinoh/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,9 +653,15 @@ def find_matches(self, styled, container):
def find_style(self, styled, container):
matches = sorted(self.find_matches(styled, container),
key=attrgetter('specificity'), reverse=True)
if len(set(match.specificity for match in matches)) < len(matches):
styled.warn('Multiple selectors match with the same specificity. '
'See the style log for details.', container)
if len(matches) > 1:
last_match = matches[0]
for match in matches[1:]:
if (match.specificity == last_match.specificity
and match.style_name != last_match.style_name):
styled.warn('Multiple selectors match with the same '
'specificity. See the style log for details.',
container)
last_match = match
for match in matches:
try:
return self[match.style_name]
Expand Down
68 changes: 10 additions & 58 deletions tests_regression/helpers/pdf_linkchecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,38 @@
# https://gist.github.com/tiarno/dea01f70a54cac52f6a6

import sys
import urllib

from PyPDF2 import PdfFileReader
from rinoh.backend.pdf import PDFReader

import requests


def check_ftp(url):
try:
response = urllib.urlopen(url)
except IOError as e:
result, reason = False, e
else:
if response.read():
result, reason = True, 'okay'
else:
result, reason = False, 'Empty Page'
return result, reason


def check_url(url, auth=None):
headers = {'User-Agent': 'Mozilla/5.0', 'Accept': '*/*'}
if url.startswith('ftp://'):
result, reason = check_ftp(url)
else:
try:
response = requests.get(url, timeout=6, auth=auth, headers=headers)
except (requests.ConnectionError,
requests.HTTPError,
requests.Timeout,
requests.exceptions.MissingSchema,
requests.exceptions.InvalidSchema) as e:
result, reason = False, e
else:
if response.text:
result, reason = response.status_code, response.reason
else:
result, reason = False, 'Empty Page'

return result, reason


def check_pdf(pdf):
links = list()
urls = list()
badurls = list()

for page in pdf.pages:
obj = page.getObject()
for annot in [x.getObject() for x in obj.get('/Annots', [])]:
if '/A' in annot:
dst = annot['/A'].get('/D')
url = annot['/A'].get('/URI')
if dst:
links.append(dst)
elif url:
continue
urls.append(url)
result, reason = check_url(url)
if not result:
badurls.append({'url':url, 'reason': '%r' % reason})
elif '/Dest' in annot:
links.append(annot['/Dest'])
for page in pdf.catalog['Pages']['Kids']:
obj = page.object
for annot in [x.object for x in obj.get('Annots', [])]:
if 'A' in annot and 'D' in annot['A']:
links.append(str(annot['A']['D']))
elif 'Dest' in annot:
links.append(str(annot['Dest']))


anchors = pdf.namedDestinations.keys()
anchors = [str(key) for key in pdf.catalog['Names']['Dests']['Names'][::2]]
superfluous_anchors = [x for x in anchors if x not in links]
badlinks = [x for x in links if x not in anchors]
return anchors, links, superfluous_anchors, badlinks, urls, badurls


def check_pdf_links(filename):
pdf = PdfFileReader(filename)
pdf = PDFReader(filename)
return check_pdf(pdf)


if __name__ == '__main__':
fname = sys.argv[1]
print('Checking %s' % fname)
pdf = PdfFileReader(fname)
(anchors, links, superfluous_anchors,
badlinks, urls, badurls) = check_pdf_links(fname)
print('urls: ', ', '.join(urls))
Expand Down
2 changes: 0 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ commands =
deps =
{[testenv]deps}
pytest-assume
requests
PyPDF2
commands =
./run_tests.sh {posargs} tests_regression

Expand Down

0 comments on commit 3478f0b

Please sign in to comment.