Skip to content

Commit 178972a

Browse files
authored
Allow to save result to file-like object. (#66)
1 parent 2645735 commit 178972a

4 files changed

Lines changed: 81 additions & 4 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ Save to file.
109109
pdf.save("guide.pdf")
110110
```
111111

112+
Or save to file-like object.
113+
114+
```python
115+
import io
116+
117+
out = io.BytesIO()
118+
pdf.save_bytes(out)
119+
assert out.getbuffer().nbytes > 0
120+
```
121+
112122
![Pdf](img/with_toc.png)
113123

114124
## Settings and options

README_ru.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ pdf.meta["author"] = "Виталий Богомолов"
103103
pdf.save("guide.pdf")
104104
```
105105

106+
Либо сохраняем в буфер памяти.
107+
108+
```python
109+
import io
110+
111+
out = io.BytesIO()
112+
pdf.save_bytes(out)
113+
assert out.getbuffer().nbytes > 0
114+
```
115+
106116
![Pdf](img/with_toc.png)
107117

108118
## Настройки и опции

markdown_pdf/__init__.py

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import typing
44
import pathlib
55

6-
7-
from markdown_it import MarkdownIt
86
import fitz
7+
from markdown_it import MarkdownIt
8+
from pymupdf import (
9+
_as_pdf_document, mupdf, JM_embedded_clean, JM_ensure_identity, JM_new_output_fileptr, ASSERT_PDF,
10+
)
911

1012

1113
class Section:
@@ -94,16 +96,57 @@ def add_section(self, section: Section, user_css: typing.Optional[str] = None) -
9496

9597
return html
9698

97-
def save(self, file_name: typing.Union[str, pathlib.Path]) -> None:
98-
"""Save pdf to file."""
99+
def _make_doc(self):
100+
"""Return fitz doc object."""
99101
self.writer.close()
100102
self.out_file.seek(0)
101103
doc = fitz.Story.add_pdf_links(self.out_file, self.hrefs)
102104
doc.set_metadata(self.meta)
103105
if self.toc_level > 0:
104106
doc.set_toc(self.toc)
107+
108+
return doc
109+
110+
def save(self, file_name: typing.Union[str, pathlib.Path]) -> None:
111+
"""Save pdf to file."""
112+
doc = self._make_doc()
105113
if self.optimize:
106114
doc.ez_save(file_name)
107115
else:
108116
doc.save(file_name)
109117
doc.close()
118+
119+
def save_bytes(self, bytesio: io.BytesIO) -> None:
120+
"""Save pdf to file-like object."""
121+
doc = self._make_doc()
122+
123+
pdf = _as_pdf_document(doc)
124+
opts = mupdf.PdfWriteOptions()
125+
126+
opts.do_incremental = 0
127+
opts.do_ascii = 0
128+
opts.do_compress = 0
129+
opts.do_compress_images = 0
130+
opts.do_compress_fonts = 0
131+
opts.do_decompress = 0
132+
opts.do_garbage = 0
133+
opts.do_pretty = 0
134+
opts.do_linear = 0
135+
opts.do_clean = 0
136+
opts.do_sanitize = 0
137+
opts.dont_regenerate_id = 0
138+
opts.do_appearance = 0
139+
opts.do_encrypt = 1
140+
opts.permissions = 4095
141+
opts.do_preserve_metadata = 1
142+
opts.do_use_objstms = 0
143+
opts.compression_effort = 0
144+
145+
ASSERT_PDF(pdf)
146+
pdf.m_internal.resynth_required = 0
147+
JM_embedded_clean(pdf)
148+
JM_ensure_identity(pdf)
149+
150+
out = JM_new_output_fileptr(bytesio)
151+
mupdf.pdf_write_document(pdf, out, opts)
152+
out.fz_close_output()

tests/test/test_converter.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
make test T=test_converter.py
44
"""
5+
import io
56
from . import TestBase
67

78
TABLE_TEXT = """# Section with Table
@@ -80,3 +81,16 @@ def test_hrefs(self):
8081
Section(open(self.fixture("hrefs.md"), "rt", encoding='utf-8').read())
8182
)
8283
pdf.save(self.build("hrefs.pdf"))
84+
85+
def test_bytes(self):
86+
"""Save pdf as bytes IO."""
87+
from markdown_pdf import Section, MarkdownPdf
88+
out = io.BytesIO()
89+
90+
pdf = MarkdownPdf(toc_level=2)
91+
pdf.add_section(Section("# Title Bytes\n", toc=False))
92+
pdf.add_section(Section("# Bytes1\n\nbody\n"))
93+
pdf.save_bytes(out)
94+
assert out.getbuffer().nbytes > 0
95+
with open(self.build("as_bytes.pdf"), "wb") as i:
96+
i.write(out.getvalue())

0 commit comments

Comments
 (0)