|
3 | 3 | import typing |
4 | 4 | import pathlib |
5 | 5 |
|
6 | | - |
7 | | -from markdown_it import MarkdownIt |
8 | 6 | 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 | +) |
9 | 11 |
|
10 | 12 |
|
11 | 13 | class Section: |
@@ -94,16 +96,57 @@ def add_section(self, section: Section, user_css: typing.Optional[str] = None) - |
94 | 96 |
|
95 | 97 | return html |
96 | 98 |
|
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.""" |
99 | 101 | self.writer.close() |
100 | 102 | self.out_file.seek(0) |
101 | 103 | doc = fitz.Story.add_pdf_links(self.out_file, self.hrefs) |
102 | 104 | doc.set_metadata(self.meta) |
103 | 105 | if self.toc_level > 0: |
104 | 106 | 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() |
105 | 113 | if self.optimize: |
106 | 114 | doc.ez_save(file_name) |
107 | 115 | else: |
108 | 116 | doc.save(file_name) |
109 | 117 | 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() |
0 commit comments