Skip to content

Commit ec96d91

Browse files
vb64jcharman
andauthored
Custom paper sizes (#74)
* Implement custom paper sizes (#73) * fix operand * paper_size as tuple * mm to py constant * fix doc * Move paper size code to Section class * cosmetic * add tests --------- Co-authored-by: Jake Charman <jake@jakecharman.co.uk>
1 parent 514e37f commit ec96d91

4 files changed

Lines changed: 37 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ The `Section` class can set the following attributes.
131131

132132
- toc: whether to include the headers `<h1>` - `<h6>` of this section in the TOC. Default is True.
133133
- root: the name of the root directory from which the image file paths starts in markdown. Default ".".
134-
- paper_size: name of paper size, [as described here](https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size). Default "A4".
134+
- paper_size: either the name of a paper size, [as described here](https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size), or a list/tuple containing the width and height in mm. Default "A4".
135135
- borders: size of borders. Default (36, 36, -36, -36).
136136

137137
The following document properties are available for assignment (dictionary `MarkdownPdf.meta`) with the default values indicated.

README_ru.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ assert out.getbuffer().nbytes > 0
124124

125125
- toc: нужно ли включать заголовки `<h1>` - `<h6>` этой секции в TOC. По умолчанию True.
126126
- root: имя корневого каталога, от которого начинаются пути файлов картинок в markdown. По умолчанию ".".
127-
- paper_size: название размера бумаги, [как описано здесь](https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size). По умолчанию "A4".
127+
- paper_size: название размера бумаги, [как описано здесь](https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size), или list/tuple содержащий ширину и высоту в мм. По умолчанию "A4".
128128
- borders: размер полей. По умолчанию (36, 36, -36, -36).
129129

130130
Для присвоения доступны следующие свойства документа (словарь `MarkdownPdf.meta`) с указанными значениями по умолчанию.

markdown_pdf/__init__.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import fitz
77
from markdown_it import MarkdownIt
88
from pymupdf import (
9-
_as_pdf_document, mupdf, JM_embedded_clean, JM_ensure_identity, JM_new_output_fileptr, ASSERT_PDF,
9+
_as_pdf_document, mupdf, JM_embedded_clean, JM_ensure_identity, JM_new_output_fileptr, ASSERT_PDF, Rect,
1010
)
1111

12+
MM_2_PT = 2.835
13+
1214

1315
class Section:
1416
"""Markdown section."""
@@ -18,15 +20,25 @@ def __init__(
1820
text: str,
1921
toc: bool = True,
2022
root: str = ".",
21-
paper_size: str = "A4",
23+
paper_size: str or list or tuple = "A4",
2224
borders: typing.Tuple[int, int, int, int] = (36, 36, -36, -36)
2325
):
2426
"""Create md section with given properties."""
2527
self.text = text
2628
self.toc = toc
2729
self.root = root
28-
# https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size
30+
2931
self.paper_size = paper_size
32+
if isinstance(paper_size, str):
33+
# https://pymupdf.readthedocs.io/en/latest/functions.html#paper_size
34+
self.rect = fitz.paper_rect(paper_size)
35+
elif isinstance(paper_size, (list, tuple)):
36+
# Other paper sizes are in pt, so need to times mm by 2.835.
37+
width, height = paper_size
38+
self.rect = Rect(0.0, 0.0, (width * MM_2_PT), (height * MM_2_PT))
39+
else:
40+
raise TypeError("paper_size must be 'str', 'tuple' or 'list'")
41+
3042
self.borders = borders
3143

3244

@@ -81,14 +93,13 @@ def _recorder(elpos):
8193

8294
def add_section(self, section: Section, user_css: typing.Optional[str] = None) -> str:
8395
"""Add markdown section to pdf."""
84-
rect = fitz.paper_rect(section.paper_size)
85-
where = rect + section.borders
96+
where = section.rect + section.borders
8697
html = self.m_d.render(section.text)
8798
story = fitz.Story(html=html, archive=section.root, user_css=user_css)
8899
more = 1
89100
while more: # loop outputting the story
90101
self.page_num += 1
91-
device = self.writer.begin_page(rect)
102+
device = self.writer.begin_page(section.rect)
92103
more, _ = story.place(where) # layout into allowed rectangle
93104
story.element_positions(self._recorder, {"toc": section.toc, "pdfile": self})
94105
story.draw(device)

tests/test/test_converter.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
make test T=test_converter.py
44
"""
55
import io
6+
import pytest
7+
68
from . import TestBase
79

810
TABLE_TEXT = """# Section with Table
@@ -94,3 +96,19 @@ def test_bytes(self):
9496
assert out.getbuffer().nbytes > 0
9597
with open(self.build("as_bytes.pdf"), "wb") as i:
9698
i.write(out.getvalue())
99+
100+
def test_paper_size(self):
101+
"""Check paper_size arg for Section class."""
102+
from markdown_pdf import Section
103+
104+
section = Section("Title") # default paper size 'A4'
105+
assert section.rect.height == 842.0
106+
assert section.rect.width == 595.0
107+
108+
section = Section("Title", paper_size=(5, 10)) # 5x10 mm
109+
assert section.rect.height == 28.35
110+
assert section.rect.width == 14.175
111+
112+
with pytest.raises(TypeError) as err:
113+
Section("Title", paper_size=111)
114+
assert 'paper_size must be' in str(err.value)

0 commit comments

Comments
 (0)