Skip to content

Commit b3247e8

Browse files
authored
ENH: Add papersizes (#800)
1 parent d1be80d commit b3247e8

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

PyPDF2/__init__.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
from ._version import __version__
2-
from .merger import PdfFileMerger
3-
from .pagerange import PageRange, parse_filename_page_ranges
4-
from .pdf import PdfFileReader, PdfFileWriter
1+
from PyPDF2._version import __version__
2+
from PyPDF2.merger import PdfFileMerger
3+
from PyPDF2.pagerange import PageRange, parse_filename_page_ranges
4+
from PyPDF2.papersizes import PaperSize
5+
from PyPDF2.pdf import PdfFileReader, PdfFileWriter
6+
from PyPDF2 import pdf
57

68
__all__ = [
79
"__version__",
810
"PageRange",
11+
"PaperSize",
912
"parse_filename_page_ranges",
1013
"pdf",
1114
"PdfFileMerger",

PyPDF2/papersizes.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Helper to get paper sizes."""
2+
3+
from collections import namedtuple
4+
5+
Dimensions = namedtuple("Dimensions", ["width", "height"])
6+
7+
8+
class PaperSize(object):
9+
"""(width, height) of the paper in portrait mode in pixels at 72 ppi."""
10+
11+
# Notes how to calculate it:
12+
# 1. Get the size of the paper in mm
13+
# 2. Convert it to inches (25.4 millimeters are equal to 1 inches)
14+
# 3. Convert it to pixels ad 72dpi (1 inch is equal to 72 pixels)
15+
16+
# All Din-A paper sizes follow this pattern:
17+
# 2xA(n-1) = A(n)
18+
# So the height of the next bigger one is the width of the smaller one
19+
# The ratio is always approximately the ratio 1:2**0.5
20+
# Additionally, A0 is defined to have an area of 1 m**2
21+
# Be aware of rounding issues!
22+
A0 = Dimensions(2384, 3370) # 841mm x 1189mm
23+
A1 = Dimensions(1684, 2384)
24+
A2 = Dimensions(1191, 1684)
25+
A3 = Dimensions(842, 1191)
26+
A4 = Dimensions(
27+
595, 842
28+
) # Printer paper, documents - this is by far the most common
29+
A5 = Dimensions(420, 595) # Paperback books
30+
A6 = Dimensions(298, 420) # Post cards
31+
A7 = Dimensions(210, 298)
32+
A8 = Dimensions(147, 210)
33+
34+
# Envelopes
35+
C4 = Dimensions(649, 918)
36+
37+
38+
_din_a = [
39+
PaperSize.A0,
40+
PaperSize.A1,
41+
PaperSize.A2,
42+
PaperSize.A3,
43+
PaperSize.A4,
44+
PaperSize.A5,
45+
PaperSize.A6,
46+
PaperSize.A7,
47+
PaperSize.A8,
48+
]

Tests/test_papersizes.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from PyPDF2 import papersizes
2+
import pytest
3+
4+
5+
def test_din_a0():
6+
dim = papersizes.PaperSize.A0
7+
area_square_pixels = float(dim.width) * dim.height
8+
9+
# 72 pixels is 1 inch
10+
area_square_inch = area_square_pixels / 72**2
11+
12+
# 25.4 millimeter is equal to 1 inches
13+
area_square_mm = area_square_inch * (25.4)**2
14+
assert abs(area_square_mm - 999949) < 100
15+
conversion_factor = 72 / 25.4
16+
assert (dim.width - 841 * conversion_factor) < 1
17+
assert (dim.width - 1189 * conversion_factor) < 1
18+
19+
20+
21+
@pytest.mark.parametrize("dimensions", papersizes._din_a)
22+
def test_din_a_ratio(dimensions):
23+
assert abs(dimensions.height - dimensions.width * 2**0.5) <= 2.5
24+
25+
26+
@pytest.mark.parametrize(
27+
"dimensions_a, dimensions_b", list(zip(papersizes._din_a, papersizes._din_a[1:]))
28+
)
29+
def test_din_a_doubling(dimensions_a, dimensions_b):
30+
assert abs(dimensions_a.height - 2 * dimensions_b.width) <= 4

0 commit comments

Comments
 (0)