docvortex 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. docvortex/__init__.py +21 -0
  2. docvortex/analyzers/__init__.py +3 -0
  3. docvortex/analyzers/native/__init__.py +37 -0
  4. docvortex/analyzers/native/_shared/__init__.py +3 -0
  5. docvortex/analyzers/native/_shared/hyperlink.py +16 -0
  6. docvortex/analyzers/native/_shared/image.py +8 -0
  7. docvortex/analyzers/native/_shared/markup/__init__.py +47 -0
  8. docvortex/analyzers/native/_shared/markup/anchors.py +30 -0
  9. docvortex/analyzers/native/_shared/markup/formula.py +37 -0
  10. docvortex/analyzers/native/_shared/markup/projector.py +57 -0
  11. docvortex/analyzers/native/_shared/markup/styles.py +19 -0
  12. docvortex/analyzers/native/_shared/mathml.py +17 -0
  13. docvortex/analyzers/native/_shared/names.py +7 -0
  14. docvortex/analyzers/native/_shared/xycut.py +414 -0
  15. docvortex/analyzers/native/contracts.py +44 -0
  16. docvortex/analyzers/native/csv.py +351 -0
  17. docvortex/analyzers/native/epub/__init__.py +18 -0
  18. docvortex/analyzers/native/epub/constants.py +45 -0
  19. docvortex/analyzers/native/epub/converter.py +80 -0
  20. docvortex/analyzers/native/epub/errors.py +20 -0
  21. docvortex/analyzers/native/epub/metadata.py +31 -0
  22. docvortex/analyzers/native/epub/package.py +649 -0
  23. docvortex/analyzers/native/epub/xhtml.py +306 -0
  24. docvortex/analyzers/native/html/__init__.py +6 -0
  25. docvortex/analyzers/native/html/anchors.py +271 -0
  26. docvortex/analyzers/native/html/constants.py +25 -0
  27. docvortex/analyzers/native/html/contracts.py +7 -0
  28. docvortex/analyzers/native/html/converter.py +117 -0
  29. docvortex/analyzers/native/html/document.py +389 -0
  30. docvortex/analyzers/native/html/errors.py +12 -0
  31. docvortex/analyzers/native/html/resources.py +365 -0
  32. docvortex/analyzers/native/html/selector.py +421 -0
  33. docvortex/analyzers/native/models.py +209 -0
  34. docvortex/analyzers/native/ofd/__init__.py +14 -0
  35. docvortex/analyzers/native/ofd/constants.py +59 -0
  36. docvortex/analyzers/native/ofd/converter.py +31 -0
  37. docvortex/analyzers/native/ofd/errors.py +16 -0
  38. docvortex/analyzers/native/ofd/geometry.py +215 -0
  39. docvortex/analyzers/native/ofd/images.py +124 -0
  40. docvortex/analyzers/native/ofd/metadata.py +53 -0
  41. docvortex/analyzers/native/ofd/models.py +170 -0
  42. docvortex/analyzers/native/ofd/package.py +346 -0
  43. docvortex/analyzers/native/ofd/path.py +201 -0
  44. docvortex/analyzers/native/ofd/reading_order.py +293 -0
  45. docvortex/analyzers/native/ofd/resources.py +122 -0
  46. docvortex/analyzers/native/ofd/scene.py +347 -0
  47. docvortex/analyzers/native/ofd/table.py +240 -0
  48. docvortex/analyzers/native/ofd/text.py +521 -0
  49. docvortex/analyzers/native/office/__init__.py +3 -0
  50. docvortex/analyzers/native/office/doc/__init__.py +3 -0
  51. docvortex/analyzers/native/office/doc/bookmarks.py +81 -0
  52. docvortex/analyzers/native/office/doc/doc_converter.py +573 -0
  53. docvortex/analyzers/native/office/doc/fib.py +261 -0
  54. docvortex/analyzers/native/office/doc/fields.py +101 -0
  55. docvortex/analyzers/native/office/doc/formatting.py +171 -0
  56. docvortex/analyzers/native/office/doc/images.py +162 -0
  57. docvortex/analyzers/native/office/doc/lists.py +356 -0
  58. docvortex/analyzers/native/office/doc/models.py +164 -0
  59. docvortex/analyzers/native/office/doc/parser.py +851 -0
  60. docvortex/analyzers/native/office/doc/pieces.py +256 -0
  61. docvortex/analyzers/native/office/doc/records.py +40 -0
  62. docvortex/analyzers/native/office/doc/sprm.py +269 -0
  63. docvortex/analyzers/native/office/doc/styles.py +215 -0
  64. docvortex/analyzers/native/office/docx/__init__.py +3 -0
  65. docvortex/analyzers/native/office/docx/context.py +71 -0
  66. docvortex/analyzers/native/office/docx/docx_converter.py +614 -0
  67. docvortex/analyzers/native/office/docx/equationxml.py +119 -0
  68. docvortex/analyzers/native/office/docx/fields.py +816 -0
  69. docvortex/analyzers/native/office/docx/formatting_types.py +23 -0
  70. docvortex/analyzers/native/office/docx/main.py +50 -0
  71. docvortex/analyzers/native/office/docx/numbering.py +491 -0
  72. docvortex/analyzers/native/office/docx/office_xml.py +57 -0
  73. docvortex/analyzers/native/office/docx/package_normalizer.py +248 -0
  74. docvortex/analyzers/native/office/docx/resources.py +526 -0
  75. docvortex/analyzers/native/office/docx/styles.py +693 -0
  76. docvortex/analyzers/native/office/docx/tables.py +515 -0
  77. docvortex/analyzers/native/office/equation/__init__.py +3 -0
  78. docvortex/analyzers/native/office/equation/image.py +470 -0
  79. docvortex/analyzers/native/office/equation/latex_dict.py +324 -0
  80. docvortex/analyzers/native/office/equation/mtef.py +885 -0
  81. docvortex/analyzers/native/office/equation/mtef_v5.py +941 -0
  82. docvortex/analyzers/native/office/equation/omml.py +561 -0
  83. docvortex/analyzers/native/office/equation/ooxml.py +62 -0
  84. docvortex/analyzers/native/office/errors.py +33 -0
  85. docvortex/analyzers/native/office/image.py +307 -0
  86. docvortex/analyzers/native/office/legacy/__init__.py +3 -0
  87. docvortex/analyzers/native/office/legacy/binary.py +43 -0
  88. docvortex/analyzers/native/office/legacy/officeart.py +362 -0
  89. docvortex/analyzers/native/office/legacy/ole.py +110 -0
  90. docvortex/analyzers/native/office/limits.py +12 -0
  91. docvortex/analyzers/native/office/odf/__init__.py +3 -0
  92. docvortex/analyzers/native/office/odf/chart.py +76 -0
  93. docvortex/analyzers/native/office/odf/constants.py +70 -0
  94. docvortex/analyzers/native/office/odf/converters.py +403 -0
  95. docvortex/analyzers/native/office/odf/errors.py +18 -0
  96. docvortex/analyzers/native/office/odf/metadata.py +91 -0
  97. docvortex/analyzers/native/office/odf/models.py +176 -0
  98. docvortex/analyzers/native/office/odf/package.py +270 -0
  99. docvortex/analyzers/native/office/odf/styles.py +329 -0
  100. docvortex/analyzers/native/office/odf/table.py +469 -0
  101. docvortex/analyzers/native/office/odf/text.py +1002 -0
  102. docvortex/analyzers/native/office/ooxml_chart.py +1016 -0
  103. docvortex/analyzers/native/office/opc.py +38 -0
  104. docvortex/analyzers/native/office/ppt/__init__.py +3 -0
  105. docvortex/analyzers/native/office/ppt/models.py +118 -0
  106. docvortex/analyzers/native/office/ppt/parser.py +1895 -0
  107. docvortex/analyzers/native/office/ppt/ppt_converter.py +292 -0
  108. docvortex/analyzers/native/office/ppt/records.py +131 -0
  109. docvortex/analyzers/native/office/ppt/style_text.py +247 -0
  110. docvortex/analyzers/native/office/pptx/__init__.py +3 -0
  111. docvortex/analyzers/native/office/pptx/context.py +113 -0
  112. docvortex/analyzers/native/office/pptx/lists.py +558 -0
  113. docvortex/analyzers/native/office/pptx/main.py +20 -0
  114. docvortex/analyzers/native/office/pptx/package_normalizer.py +321 -0
  115. docvortex/analyzers/native/office/pptx/pptx_converter.py +323 -0
  116. docvortex/analyzers/native/office/pptx/resources.py +329 -0
  117. docvortex/analyzers/native/office/pptx/shapes.py +393 -0
  118. docvortex/analyzers/native/office/pptx/text_styles.py +625 -0
  119. docvortex/analyzers/native/office/pptx/titles.py +178 -0
  120. docvortex/analyzers/native/office/rich_text.py +420 -0
  121. docvortex/analyzers/native/office/rtf/__init__.py +3 -0
  122. docvortex/analyzers/native/office/rtf/converter.py +708 -0
  123. docvortex/analyzers/native/office/rtf/lexer.py +213 -0
  124. docvortex/analyzers/native/office/rtf/math.py +339 -0
  125. docvortex/analyzers/native/office/rtf/models.py +185 -0
  126. docvortex/analyzers/native/office/rtf/parser.py +1553 -0
  127. docvortex/analyzers/native/office/spreadsheet/__init__.py +3 -0
  128. docvortex/analyzers/native/office/spreadsheet/html.py +81 -0
  129. docvortex/analyzers/native/office/spreadsheet/models.py +79 -0
  130. docvortex/analyzers/native/office/spreadsheet/projector.py +928 -0
  131. docvortex/analyzers/native/office/streams.py +18 -0
  132. docvortex/analyzers/native/office/xls/__init__.py +3 -0
  133. docvortex/analyzers/native/office/xls/chart.py +132 -0
  134. docvortex/analyzers/native/office/xls/embedded_chart.py +299 -0
  135. docvortex/analyzers/native/office/xls/models.py +109 -0
  136. docvortex/analyzers/native/office/xls/number_format.py +521 -0
  137. docvortex/analyzers/native/office/xls/parser.py +1145 -0
  138. docvortex/analyzers/native/office/xls/records.py +201 -0
  139. docvortex/analyzers/native/office/xls/strings.py +205 -0
  140. docvortex/analyzers/native/office/xls/xls_converter.py +354 -0
  141. docvortex/analyzers/native/office/xlsx/__init__.py +3 -0
  142. docvortex/analyzers/native/office/xlsx/main.py +20 -0
  143. docvortex/analyzers/native/office/xlsx/ooxml_ole.py +522 -0
  144. docvortex/analyzers/native/office/xlsx/package_normalizer.py +310 -0
  145. docvortex/analyzers/native/office/xlsx/xlsx_converter.py +716 -0
  146. docvortex/analyzers/native/pdf/__init__.py +3 -0
  147. docvortex/analyzers/native/pdf/auxiliary_text.py +1671 -0
  148. docvortex/analyzers/native/pdf/char_geometry.py +1662 -0
  149. docvortex/analyzers/native/pdf/code_blocks.py +535 -0
  150. docvortex/analyzers/native/pdf/formulas.py +1985 -0
  151. docvortex/analyzers/native/pdf/geometry.py +281 -0
  152. docvortex/analyzers/native/pdf/graphics.py +1501 -0
  153. docvortex/analyzers/native/pdf/index_blocks.py +268 -0
  154. docvortex/analyzers/native/pdf/inline/__init__.py +3 -0
  155. docvortex/analyzers/native/pdf/inline/common.py +112 -0
  156. docvortex/analyzers/native/pdf/inline/detection.py +590 -0
  157. docvortex/analyzers/native/pdf/inline/matching.py +1185 -0
  158. docvortex/analyzers/native/pdf/inline/materialize.py +457 -0
  159. docvortex/analyzers/native/pdf/inline/scripts.py +975 -0
  160. docvortex/analyzers/native/pdf/inline/types.py +385 -0
  161. docvortex/analyzers/native/pdf/line_layout.py +1106 -0
  162. docvortex/analyzers/native/pdf/line_merging.py +1223 -0
  163. docvortex/analyzers/native/pdf/models.py +246 -0
  164. docvortex/analyzers/native/pdf/native_text.py +1004 -0
  165. docvortex/analyzers/native/pdf/pipeline.py +1390 -0
  166. docvortex/analyzers/native/pdf/script_geometry.py +636 -0
  167. docvortex/analyzers/native/pdf/shared.py +30 -0
  168. docvortex/analyzers/native/pdf/spatial_text.py +383 -0
  169. docvortex/analyzers/native/pdf/table_annotations.py +446 -0
  170. docvortex/analyzers/native/pdf/table_constants.py +48 -0
  171. docvortex/analyzers/native/pdf/table_detection.py +227 -0
  172. docvortex/analyzers/native/pdf/table_filled_grid.py +218 -0
  173. docvortex/analyzers/native/pdf/table_geometry.py +40 -0
  174. docvortex/analyzers/native/pdf/table_materialization.py +444 -0
  175. docvortex/analyzers/native/pdf/table_recovery/__init__.py +15 -0
  176. docvortex/analyzers/native/pdf/table_recovery/candidate.py +356 -0
  177. docvortex/analyzers/native/pdf/table_recovery/contracts.py +154 -0
  178. docvortex/analyzers/native/pdf/table_recovery/engine.py +609 -0
  179. docvortex/analyzers/native/pdf/table_recovery/geometry.py +164 -0
  180. docvortex/analyzers/native/pdf/table_recovery/sparse_common.py +85 -0
  181. docvortex/analyzers/native/pdf/table_recovery/sparse_hybrid.py +804 -0
  182. docvortex/analyzers/native/pdf/table_recovery/sparse_multiline.py +1122 -0
  183. docvortex/analyzers/native/pdf/table_recovery/text.py +414 -0
  184. docvortex/analyzers/native/pdf/table_recovery/text_grid.py +618 -0
  185. docvortex/analyzers/native/pdf/table_recovery/vector.py +1931 -0
  186. docvortex/analyzers/native/pdf/table_rows.py +34 -0
  187. docvortex/analyzers/native/pdf/table_rules.py +1129 -0
  188. docvortex/analyzers/native/pdf/table_text_styles.py +283 -0
  189. docvortex/analyzers/native/pdf/tables.py +147 -0
  190. docvortex/analyzers/native/pdf/text_assembly/__init__.py +3 -0
  191. docvortex/analyzers/native/pdf/text_assembly/annotations.py +581 -0
  192. docvortex/analyzers/native/pdf/text_assembly/assembly.py +292 -0
  193. docvortex/analyzers/native/pdf/text_assembly/common.py +477 -0
  194. docvortex/analyzers/native/pdf/text_assembly/footnotes.py +394 -0
  195. docvortex/analyzers/native/pdf/text_assembly/merging.py +1274 -0
  196. docvortex/analyzers/native/pdf/text_assembly/rows.py +692 -0
  197. docvortex/analyzers/native/pdf/text_blocks.py +82 -0
  198. docvortex/analyzers/native/pdf/text_styles.py +55 -0
  199. docvortex/analyzers/native/pdf/title_analysis/__init__.py +3 -0
  200. docvortex/analyzers/native/pdf/title_analysis/body_profile.py +215 -0
  201. docvortex/analyzers/native/pdf/title_analysis/common.py +117 -0
  202. docvortex/analyzers/native/pdf/title_analysis/document_profile.py +164 -0
  203. docvortex/analyzers/native/pdf/title_analysis/lane_titles.py +758 -0
  204. docvortex/analyzers/native/pdf/title_analysis/page_titles.py +1024 -0
  205. docvortex/analyzers/native/pdf/title_analysis/prototype.py +194 -0
  206. docvortex/analyzers/native/pdf/title_analysis/structural.py +1081 -0
  207. docvortex/analyzers/native/pdf/titles.py +75 -0
  208. docvortex/analyzers/native/pdf/typography.py +19 -0
  209. docvortex/analyzers/native/pdf/visual_annotations.py +1262 -0
  210. docvortex/api.py +180 -0
  211. docvortex/assets/__init__.py +5 -0
  212. docvortex/assets/store.py +51 -0
  213. docvortex/cli.py +54 -0
  214. docvortex/codecs/__init__.py +3 -0
  215. docvortex/codecs/html/__init__.py +22 -0
  216. docvortex/codecs/html/contracts.py +236 -0
  217. docvortex/codecs/html/materializer.py +331 -0
  218. docvortex/codecs/html/parser.py +763 -0
  219. docvortex/codecs/html/resources.py +34 -0
  220. docvortex/codecs/json.py +17 -0
  221. docvortex/content/__init__.py +5 -0
  222. docvortex/content/inline.py +248 -0
  223. docvortex/content/markup/__init__.py +44 -0
  224. docvortex/content/markup/anchors.py +188 -0
  225. docvortex/content/markup/formula.py +280 -0
  226. docvortex/content/markup/projector.py +1237 -0
  227. docvortex/content/markup/styles.py +327 -0
  228. docvortex/content/mathml.py +167 -0
  229. docvortex/content/normalization.py +188 -0
  230. docvortex/content/spans.py +183 -0
  231. docvortex/content/table/__init__.py +18 -0
  232. docvortex/content/table/blocks.py +152 -0
  233. docvortex/content/table/content.py +425 -0
  234. docvortex/content/table/document.py +104 -0
  235. docvortex/content/table/html.py +399 -0
  236. docvortex/content/table/models.py +76 -0
  237. docvortex/content/table/rules.py +42 -0
  238. docvortex/content/table/structure.py +221 -0
  239. docvortex/content/tree.py +5 -0
  240. docvortex/document/__init__.py +3 -0
  241. docvortex/document/contracts.py +22 -0
  242. docvortex/document/detection.py +389 -0
  243. docvortex/document/filetypes.py +175 -0
  244. docvortex/document/page_range.py +167 -0
  245. docvortex/document/pdf/__init__.py +19 -0
  246. docvortex/document/pdf/classify.py +1138 -0
  247. docvortex/document/pdf/constants.py +132 -0
  248. docvortex/document/pdf/diagnostics.py +350 -0
  249. docvortex/document/pdf/document.py +582 -0
  250. docvortex/document/pdf/font_runtime.py +335 -0
  251. docvortex/document/pdf/geometry.py +31 -0
  252. docvortex/document/pdf/images.py +654 -0
  253. docvortex/document/pdf/native_annotations.py +367 -0
  254. docvortex/document/pdf/native_contracts.py +169 -0
  255. docvortex/document/pdf/native_coordinates.py +216 -0
  256. docvortex/document/pdf/native_lifecycle.py +16 -0
  257. docvortex/document/pdf/native_objects.py +902 -0
  258. docvortex/document/pdf/native_text_geometry.py +315 -0
  259. docvortex/document/pdf/pdfium.py +325 -0
  260. docvortex/document/pdf/raster.py +46 -0
  261. docvortex/document/pdf/text/__init__.py +62 -0
  262. docvortex/document/pdf/text/contracts.py +211 -0
  263. docvortex/document/pdf/text/extract.py +165 -0
  264. docvortex/document/pdf/text/geometry.py +16 -0
  265. docvortex/document/pdf/text/groups.py +162 -0
  266. docvortex/document/pdf/visual_geometry.py +201 -0
  267. docvortex/document/pdf/visuals.py +343 -0
  268. docvortex/document/source.py +92 -0
  269. docvortex/errors.py +21 -0
  270. docvortex/export/__init__.py +3 -0
  271. docvortex/export/bundle.py +98 -0
  272. docvortex/export/files.py +66 -0
  273. docvortex/export/middle.py +208 -0
  274. docvortex/foundation/__init__.py +3 -0
  275. docvortex/foundation/geometry.py +125 -0
  276. docvortex/foundation/hyperlink.py +65 -0
  277. docvortex/foundation/image.py +48 -0
  278. docvortex/foundation/image_encoding.py +30 -0
  279. docvortex/foundation/image_payload.py +280 -0
  280. docvortex/foundation/language.py +92 -0
  281. docvortex/foundation/platform.py +38 -0
  282. docvortex/foundation/text.py +153 -0
  283. docvortex/foundation/type_identity.py +20 -0
  284. docvortex/foundation/xml_names.py +20 -0
  285. docvortex/options.py +30 -0
  286. docvortex/postprocess/__init__.py +3 -0
  287. docvortex/postprocess/content.py +53 -0
  288. docvortex/postprocess/document.py +19 -0
  289. docvortex/postprocess/lists.py +236 -0
  290. docvortex/postprocess/page_blocks.py +214 -0
  291. docvortex/postprocess/pages.py +95 -0
  292. docvortex/postprocess/paragraphs.py +580 -0
  293. docvortex/postprocess/visual.py +715 -0
  294. docvortex/render/__init__.py +48 -0
  295. docvortex/render/_internal/__init__.py +3 -0
  296. docvortex/render/_internal/common/__init__.py +3 -0
  297. docvortex/render/_internal/common/context.py +43 -0
  298. docvortex/render/_internal/common/html_table.py +178 -0
  299. docvortex/render/_internal/common/index.py +33 -0
  300. docvortex/render/_internal/common/list_items.py +158 -0
  301. docvortex/render/_internal/common/planner.py +140 -0
  302. docvortex/render/_internal/docx/__init__.py +3 -0
  303. docvortex/render/_internal/docx/assets.py +202 -0
  304. docvortex/render/_internal/docx/inline.py +434 -0
  305. docvortex/render/_internal/docx/math.py +220 -0
  306. docvortex/render/_internal/docx/renderer.py +905 -0
  307. docvortex/render/_internal/docx/styles.py +195 -0
  308. docvortex/render/_internal/docx/table.py +442 -0
  309. docvortex/render/_internal/epub/__init__.py +5 -0
  310. docvortex/render/_internal/epub/assets.py +173 -0
  311. docvortex/render/_internal/epub/package.py +249 -0
  312. docvortex/render/_internal/epub/renderer.py +1156 -0
  313. docvortex/render/_internal/html/__init__.py +3 -0
  314. docvortex/render/_internal/html/inline.py +346 -0
  315. docvortex/render/_internal/html/renderer.py +1041 -0
  316. docvortex/render/_internal/html/sanitizer.py +478 -0
  317. docvortex/render/_internal/html/table.py +121 -0
  318. docvortex/render/_internal/latex/__init__.py +1 -0
  319. docvortex/render/_internal/latex/assets.py +85 -0
  320. docvortex/render/_internal/latex/inline.py +145 -0
  321. docvortex/render/_internal/latex/renderer.py +506 -0
  322. docvortex/render/_internal/latex/table.py +347 -0
  323. docvortex/render/_internal/markdown/__init__.py +3 -0
  324. docvortex/render/_internal/markdown/assets.py +78 -0
  325. docvortex/render/_internal/markdown/blocks.py +635 -0
  326. docvortex/render/_internal/markdown/escaping.py +51 -0
  327. docvortex/render/_internal/markdown/inline.py +260 -0
  328. docvortex/render/_internal/markdown/renderer.py +93 -0
  329. docvortex/render/_internal/markdown/table.py +281 -0
  330. docvortex/render/_internal/pdf/__init__.py +3 -0
  331. docvortex/render/_internal/pdf/assets.py +197 -0
  332. docvortex/render/_internal/pdf/formula.py +417 -0
  333. docvortex/render/_internal/pdf/inline.py +343 -0
  334. docvortex/render/_internal/pdf/renderer.py +734 -0
  335. docvortex/render/_internal/pdf/styles.py +206 -0
  336. docvortex/render/_internal/pdf/table.py +272 -0
  337. docvortex/render/_internal/structured_content/__init__.py +3 -0
  338. docvortex/render/_internal/structured_content/renderer.py +193 -0
  339. docvortex/render/api.py +199 -0
  340. docvortex/render/contracts.py +205 -0
  341. docvortex/render/docx.py +38 -0
  342. docvortex/render/epub.py +35 -0
  343. docvortex/render/fragments.py +70 -0
  344. docvortex/render/html.py +29 -0
  345. docvortex/render/latex.py +24 -0
  346. docvortex/render/markdown.py +50 -0
  347. docvortex/render/pdf.py +25 -0
  348. docvortex/render/structured_content.py +23 -0
  349. docvortex/resources/epub/docvortex.css +91 -0
  350. docvortex/resources/fasttext-langdetect/lid.176.ftz +0 -0
  351. docvortex/resources/fonts/DroidSansFallbackFull.ttf +0 -0
  352. docvortex/resources/fonts/NOTICE +190 -0
  353. docvortex/resources/fonts/manifest.json +9 -0
  354. docvortex/resources/html/docvortex.css +601 -0
  355. docvortex/resources/html/docvortex.min.css +1 -0
  356. docvortex/result.py +91 -0
  357. docvortex/schema.py +1141 -0
  358. docvortex/version.py +3 -0
  359. docvortex-0.2.1.dist-info/METADATA +193 -0
  360. docvortex-0.2.1.dist-info/RECORD +364 -0
  361. docvortex-0.2.1.dist-info/WHEEL +5 -0
  362. docvortex-0.2.1.dist-info/entry_points.txt +2 -0
  363. docvortex-0.2.1.dist-info/licenses/LICENSE.md +21 -0
  364. docvortex-0.2.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,199 @@
1
+ """严格 MiddleJson 多格式渲染的统一公共入口。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal, overload
6
+
7
+ from ..schema import MiddleJson
8
+
9
+ from .contracts import (
10
+ DocxRenderOptions,
11
+ EpubRenderOptions,
12
+ HtmlRenderOptions,
13
+ LatexRenderOptions,
14
+ MarkdownRenderOptions,
15
+ PdfRenderOptions,
16
+ RenderFormat,
17
+ RenderOptions,
18
+ RenderOutput,
19
+ StructuredContentRenderOptions,
20
+ )
21
+ from .docx import render_docx
22
+ from .epub import render_epub
23
+ from .html import render_html
24
+ from .latex import render_latex
25
+ from .markdown import render_markdown
26
+ from .pdf import render_pdf
27
+ from .structured_content import render_structured_content
28
+
29
+
30
+ @overload
31
+ def render(
32
+ middle_json: MiddleJson,
33
+ output_format: Literal[RenderFormat.MARKDOWN],
34
+ *,
35
+ options: MarkdownRenderOptions | None = None,
36
+ ) -> str:
37
+ """声明 Markdown 目标对应的字符串返回类型。"""
38
+ ...
39
+
40
+
41
+ @overload
42
+ def render(
43
+ middle_json: MiddleJson,
44
+ output_format: Literal[RenderFormat.HTML],
45
+ *,
46
+ options: HtmlRenderOptions | None = None,
47
+ ) -> str:
48
+ """声明 HTML 目标对应的字符串返回类型。"""
49
+ ...
50
+
51
+
52
+ @overload
53
+ def render(
54
+ middle_json: MiddleJson,
55
+ output_format: Literal[RenderFormat.LATEX],
56
+ *,
57
+ options: LatexRenderOptions | None = None,
58
+ ) -> str:
59
+ """声明 LaTeX 目标对应的字符串返回类型。"""
60
+ ...
61
+
62
+
63
+ @overload
64
+ def render(
65
+ middle_json: MiddleJson,
66
+ output_format: Literal[RenderFormat.DOCX],
67
+ *,
68
+ options: DocxRenderOptions | None = None,
69
+ ) -> bytes:
70
+ """声明 DOCX 目标对应的字节返回类型。"""
71
+ ...
72
+
73
+
74
+ @overload
75
+ def render(
76
+ middle_json: MiddleJson,
77
+ output_format: Literal[RenderFormat.EPUB],
78
+ *,
79
+ options: EpubRenderOptions | None = None,
80
+ ) -> bytes:
81
+ """声明 EPUB 目标对应的字节返回类型。"""
82
+ ...
83
+
84
+
85
+ @overload
86
+ def render(
87
+ middle_json: MiddleJson,
88
+ output_format: Literal[RenderFormat.PDF],
89
+ *,
90
+ options: PdfRenderOptions | None = None,
91
+ ) -> bytes:
92
+ """声明 PDF 目标对应的字节返回类型。"""
93
+ ...
94
+
95
+
96
+ @overload
97
+ def render(
98
+ middle_json: MiddleJson,
99
+ output_format: Literal[RenderFormat.STRUCTURED_CONTENT],
100
+ *,
101
+ options: StructuredContentRenderOptions | None = None,
102
+ ) -> dict[str, Any]:
103
+ """声明 Structured Content 目标对应的字典返回类型。"""
104
+ ...
105
+
106
+
107
+ def render(
108
+ middle_json: MiddleJson,
109
+ output_format: RenderFormat,
110
+ *,
111
+ options: RenderOptions | None = None,
112
+ ) -> RenderOutput:
113
+ """按严格目标格式和对应选项把 MiddleJson 渲染为原生结果。"""
114
+ if not isinstance(middle_json, MiddleJson):
115
+ raise TypeError("render expects a MiddleJson instance")
116
+ if not isinstance(output_format, RenderFormat):
117
+ raise TypeError("output_format must be a RenderFormat value")
118
+
119
+ if output_format is RenderFormat.MARKDOWN:
120
+ resolved_options = options if options is not None else MarkdownRenderOptions()
121
+ if not isinstance(resolved_options, MarkdownRenderOptions):
122
+ raise TypeError("MARKDOWN output requires MarkdownRenderOptions")
123
+ return render_markdown(
124
+ middle_json,
125
+ latex_delimiters=resolved_options.latex_delimiters,
126
+ mode=resolved_options.mode,
127
+ asset_base_url=resolved_options.asset_base_url,
128
+ image_renderer=resolved_options.image_renderer,
129
+ )
130
+
131
+ if output_format is RenderFormat.HTML:
132
+ resolved_options = options if options is not None else HtmlRenderOptions()
133
+ if not isinstance(resolved_options, HtmlRenderOptions):
134
+ raise TypeError("HTML output requires HtmlRenderOptions")
135
+ return render_html(
136
+ middle_json,
137
+ mode=resolved_options.mode,
138
+ asset_base_url=resolved_options.asset_base_url,
139
+ standalone=resolved_options.standalone,
140
+ document_title=resolved_options.document_title,
141
+ )
142
+
143
+ if output_format is RenderFormat.LATEX:
144
+ resolved_options = options if options is not None else LatexRenderOptions()
145
+ if not isinstance(resolved_options, LatexRenderOptions):
146
+ raise TypeError("LATEX output requires LatexRenderOptions")
147
+ return render_latex(
148
+ middle_json,
149
+ asset_base_path=resolved_options.asset_base_path,
150
+ document_title=resolved_options.document_title,
151
+ )
152
+
153
+ if output_format is RenderFormat.DOCX:
154
+ resolved_options = options if options is not None else DocxRenderOptions()
155
+ if not isinstance(resolved_options, DocxRenderOptions):
156
+ raise TypeError("DOCX output requires DocxRenderOptions")
157
+ return render_docx(
158
+ middle_json,
159
+ asset_resolver=resolved_options.asset_resolver,
160
+ )
161
+
162
+ if output_format is RenderFormat.EPUB:
163
+ resolved_options = options if options is not None else EpubRenderOptions()
164
+ if not isinstance(resolved_options, EpubRenderOptions):
165
+ raise TypeError("EPUB output requires EpubRenderOptions")
166
+ return render_epub(
167
+ middle_json,
168
+ title=resolved_options.title,
169
+ authors=resolved_options.authors,
170
+ language=resolved_options.language,
171
+ identifier=resolved_options.identifier,
172
+ modified_at=resolved_options.modified_at,
173
+ asset_resolver=resolved_options.asset_resolver,
174
+ )
175
+
176
+ if output_format is RenderFormat.PDF:
177
+ resolved_options = options if options is not None else PdfRenderOptions()
178
+ if not isinstance(resolved_options, PdfRenderOptions):
179
+ raise TypeError("PDF output requires PdfRenderOptions")
180
+ return render_pdf(
181
+ middle_json,
182
+ asset_resolver=resolved_options.asset_resolver,
183
+ document_title=resolved_options.document_title,
184
+ )
185
+
186
+ if output_format is RenderFormat.STRUCTURED_CONTENT:
187
+ resolved_options = options if options is not None else StructuredContentRenderOptions()
188
+ if not isinstance(resolved_options, StructuredContentRenderOptions):
189
+ raise TypeError("STRUCTURED_CONTENT output requires StructuredContentRenderOptions")
190
+ return render_structured_content(
191
+ middle_json,
192
+ latex_delimiters=resolved_options.latex_delimiters,
193
+ asset_base_url=resolved_options.asset_base_url,
194
+ )
195
+
196
+ raise ValueError(f"Unsupported RenderFormat: {output_format}")
197
+
198
+
199
+ __all__ = ["render"]
@@ -0,0 +1,205 @@
1
+ """MiddleJson 多格式 renderer 共用的公共类型与调用选项。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime
7
+ from enum import Enum
8
+ import re
9
+ from typing import Any, Callable, TypeAlias
10
+
11
+ from ..schema import BlockBase
12
+ from ..options import LatexDelimitersConfig
13
+
14
+
15
+ class RenderFormat(str, Enum):
16
+ """统一渲染入口支持的目标格式。"""
17
+
18
+ MARKDOWN = "markdown"
19
+ HTML = "html"
20
+ LATEX = "latex"
21
+ DOCX = "docx"
22
+ EPUB = "epub"
23
+ STRUCTURED_CONTENT = "structured_content"
24
+ PDF = "pdf"
25
+
26
+
27
+ class RenderMode(str, Enum):
28
+ """Markdown 与 HTML renderer 共用的默认合并视图与完整分页视图。"""
29
+
30
+ DEFAULT = "default"
31
+ FULL = "full"
32
+
33
+
34
+ AssetResolver: TypeAlias = Callable[[str], bytes]
35
+ ImageRenderer: TypeAlias = Callable[[BlockBase], str]
36
+
37
+
38
+ def _validate_mode(mode: object) -> None:
39
+ """校验 Markdown 与 HTML renderer 的公共模式参数。"""
40
+ if not isinstance(mode, RenderMode):
41
+ raise TypeError("mode must be a RenderMode value")
42
+
43
+
44
+ def _validate_asset_base_url(asset_base_url: object) -> None:
45
+ """校验用于拼接相对图片路径的资源根地址。"""
46
+ if not isinstance(asset_base_url, str):
47
+ raise TypeError("asset_base_url must be a string")
48
+
49
+
50
+ @dataclass(frozen=True, slots=True)
51
+ class MarkdownRenderOptions:
52
+ """Markdown renderer 的统一入口选项。"""
53
+
54
+ latex_delimiters: LatexDelimitersConfig | None = None
55
+
56
+ mode: RenderMode = RenderMode.DEFAULT
57
+ asset_base_url: str = ""
58
+ image_renderer: ImageRenderer | None = None
59
+
60
+ def __post_init__(self) -> None:
61
+ """在构造时拒绝不符合严格公共契约的选项值。"""
62
+ _validate_mode(self.mode)
63
+ _validate_asset_base_url(self.asset_base_url)
64
+ if self.image_renderer is not None and not callable(self.image_renderer):
65
+ raise TypeError("image_renderer must be callable or None")
66
+
67
+
68
+ @dataclass(frozen=True, slots=True)
69
+ class HtmlRenderOptions:
70
+ """HTML renderer 的统一入口选项。"""
71
+
72
+ mode: RenderMode = RenderMode.DEFAULT
73
+ asset_base_url: str = ""
74
+ standalone: bool = True
75
+ document_title: str | None = None
76
+
77
+ def __post_init__(self) -> None:
78
+ """在构造时校验 HTML 文档形态与标题选项。"""
79
+ _validate_mode(self.mode)
80
+ _validate_asset_base_url(self.asset_base_url)
81
+ if not isinstance(self.standalone, bool):
82
+ raise TypeError("standalone must be a bool")
83
+ if self.document_title is not None and not isinstance(self.document_title, str):
84
+ raise TypeError("document_title must be a string or None")
85
+
86
+
87
+ @dataclass(frozen=True, slots=True)
88
+ class LatexRenderOptions:
89
+ """LaTeX renderer 的统一入口选项。"""
90
+
91
+ asset_base_path: str = ""
92
+ document_title: str | None = None
93
+
94
+ def __post_init__(self) -> None:
95
+ """在构造时校验 LaTeX 素材路径前缀与文档标题。"""
96
+ if not isinstance(self.asset_base_path, str):
97
+ raise TypeError("asset_base_path must be a string")
98
+ if self.document_title is not None and not isinstance(self.document_title, str):
99
+ raise TypeError("document_title must be a string or None")
100
+
101
+
102
+ @dataclass(frozen=True, slots=True)
103
+ class DocxRenderOptions:
104
+ """DOCX renderer 的统一入口选项。"""
105
+
106
+ asset_resolver: AssetResolver | None = None
107
+
108
+ def __post_init__(self) -> None:
109
+ """在构造时校验可选素材解析器。"""
110
+ if self.asset_resolver is not None and not callable(self.asset_resolver):
111
+ raise TypeError("asset_resolver must be callable or None")
112
+
113
+
114
+ _EPUB_LANGUAGE_RE = re.compile(r"(?:[A-Za-z]{2,8}|und)(?:-[A-Za-z0-9]{1,8})*\Z", re.IGNORECASE)
115
+
116
+
117
+ @dataclass(frozen=True, slots=True)
118
+ class EpubRenderOptions:
119
+ """EPUB 3.3 renderer 的统一入口选项。"""
120
+
121
+ title: str | None = None
122
+ authors: tuple[str, ...] = ()
123
+ language: str = "und"
124
+ identifier: str | None = None
125
+ modified_at: datetime | None = None
126
+ asset_resolver: AssetResolver | None = None
127
+
128
+ def __post_init__(self) -> None:
129
+ """在构造时校验 EPUB 元数据、时间与素材解析器。"""
130
+ if self.title is not None and (not isinstance(self.title, str) or not self.title.strip()):
131
+ raise TypeError("title must be a non-empty string or None")
132
+ if not isinstance(self.authors, tuple) or any(
133
+ not isinstance(author, str) or not author.strip() for author in self.authors
134
+ ):
135
+ raise TypeError("authors must be a tuple of non-empty strings")
136
+ if not isinstance(self.language, str) or _EPUB_LANGUAGE_RE.fullmatch(self.language.strip()) is None:
137
+ raise ValueError("language must be a supported BCP 47 language tag")
138
+ if self.identifier is not None and (not isinstance(self.identifier, str) or not self.identifier.strip()):
139
+ raise TypeError("identifier must be a non-empty string or None")
140
+ if self.modified_at is not None:
141
+ if not isinstance(self.modified_at, datetime):
142
+ raise TypeError("modified_at must be a datetime or None")
143
+ if self.modified_at.utcoffset() is None:
144
+ raise ValueError("modified_at must be timezone-aware")
145
+ if self.modified_at.year < 1000:
146
+ raise ValueError("modified_at year must use four digits")
147
+ if self.asset_resolver is not None and not callable(self.asset_resolver):
148
+ raise TypeError("asset_resolver must be callable or None")
149
+
150
+
151
+ @dataclass(frozen=True, slots=True)
152
+ class PdfRenderOptions:
153
+ """PDF renderer 的统一入口选项。"""
154
+
155
+ asset_resolver: AssetResolver | None = None
156
+ document_title: str | None = None
157
+
158
+ def __post_init__(self) -> None:
159
+ """在构造时校验素材解析器与文档标题。"""
160
+ if self.asset_resolver is not None and not callable(self.asset_resolver):
161
+ raise TypeError("asset_resolver must be callable or None")
162
+ if self.document_title is not None and not isinstance(self.document_title, str):
163
+ raise TypeError("document_title must be a string or None")
164
+
165
+
166
+ @dataclass(frozen=True, slots=True)
167
+ class StructuredContentRenderOptions:
168
+ """树形 Markdown Structured Content renderer 的统一入口选项。"""
169
+
170
+ latex_delimiters: LatexDelimitersConfig | None = None
171
+
172
+ asset_base_url: str = ""
173
+
174
+ def __post_init__(self) -> None:
175
+ """在构造时校验图片资源根地址。"""
176
+ _validate_asset_base_url(self.asset_base_url)
177
+
178
+
179
+ RenderOptions: TypeAlias = (
180
+ MarkdownRenderOptions
181
+ | HtmlRenderOptions
182
+ | LatexRenderOptions
183
+ | DocxRenderOptions
184
+ | EpubRenderOptions
185
+ | PdfRenderOptions
186
+ | StructuredContentRenderOptions
187
+ )
188
+ RenderOutput: TypeAlias = str | bytes | dict[str, Any]
189
+
190
+
191
+ __all__ = [
192
+ "AssetResolver",
193
+ "DocxRenderOptions",
194
+ "EpubRenderOptions",
195
+ "HtmlRenderOptions",
196
+ "ImageRenderer",
197
+ "LatexRenderOptions",
198
+ "MarkdownRenderOptions",
199
+ "PdfRenderOptions",
200
+ "RenderFormat",
201
+ "RenderMode",
202
+ "RenderOptions",
203
+ "RenderOutput",
204
+ "StructuredContentRenderOptions",
205
+ ]
@@ -0,0 +1,38 @@
1
+ """严格 MiddleJson 到 DOCX 的轻量公共门面与稳定异常。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..schema import MiddleJson
6
+ from .contracts import AssetResolver
7
+
8
+
9
+ class DocxRenderError(RuntimeError):
10
+ """表示 renderer 无法在不丢失必需内容的前提下生成 DOCX。"""
11
+
12
+ def __init__(
13
+ self,
14
+ message: str,
15
+ *,
16
+ page_idx: int,
17
+ block_index: int | None,
18
+ block_type: str,
19
+ ) -> None:
20
+ """保存错误消息及稳定的 page/block 定位字段。"""
21
+ self.page_idx = page_idx
22
+ self.block_index = block_index
23
+ self.block_type = block_type
24
+ super().__init__(f"{message} (page_idx={page_idx}, block_index={block_index}, block_type={block_type})")
25
+
26
+
27
+ def render_docx(
28
+ middle_json: MiddleJson,
29
+ *,
30
+ asset_resolver: AssetResolver | None = None,
31
+ ) -> bytes:
32
+ """惰性加载 DOCX 实现并渲染严格 MiddleJson。"""
33
+ from ._internal.docx.renderer import render_docx as _render_docx
34
+
35
+ return _render_docx(middle_json, asset_resolver=asset_resolver)
36
+
37
+
38
+ __all__ = ["DocxRenderError", "render_docx"]
@@ -0,0 +1,35 @@
1
+ """严格 MiddleJson 到 EPUB 3.3 的轻量公共门面。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+
7
+ from ..schema import MiddleJson
8
+ from .contracts import AssetResolver
9
+
10
+
11
+ def render_epub(
12
+ middle_json: MiddleJson,
13
+ *,
14
+ title: str | None = None,
15
+ authors: tuple[str, ...] = (),
16
+ language: str = "und",
17
+ identifier: str | None = None,
18
+ modified_at: datetime | None = None,
19
+ asset_resolver: AssetResolver | None = None,
20
+ ) -> bytes:
21
+ """惰性加载 EPUB 实现并返回完整 EPUB 3.3 容器字节。"""
22
+ from ._internal.epub.renderer import render_epub as _render_epub
23
+
24
+ return _render_epub(
25
+ middle_json,
26
+ title=title,
27
+ authors=authors,
28
+ language=language,
29
+ identifier=identifier,
30
+ modified_at=modified_at,
31
+ asset_resolver=asset_resolver,
32
+ )
33
+
34
+
35
+ __all__ = ["render_epub"]
@@ -0,0 +1,70 @@
1
+ """公开共享渲染片段操作,供宿主组合专用输出而不依赖私有模块。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..options import LatexDelimitersConfig
6
+ from ..schema import ImagePayloadBlock, InlineSpan
7
+ from ._internal.common.list_items import ListItem, ListItemKind, OrderedListStyle
8
+
9
+
10
+ def render_inline_content(content: list[InlineSpan], delimiters: LatexDelimitersConfig) -> str:
11
+ """将行内语义编码为 Markdown,沿用共享的样式与公式规则。"""
12
+ from ._internal.markdown.inline import render_inline_content as render_value
13
+
14
+ return render_value(content, delimiters)
15
+
16
+
17
+ def render_internal_link(label: str, anchor: str) -> str:
18
+ """构造与共享 Markdown renderer 一致的内部链接。"""
19
+ from ._internal.markdown.inline import render_internal_link as render_value
20
+
21
+ return render_value(label, anchor)
22
+
23
+
24
+ def resolve_image_source(block: ImagePayloadBlock, asset_base_url: str = "") -> str | None:
25
+ """按既有素材优先级解析图片引用,不写出文件。"""
26
+ from ._internal.markdown.assets import resolve_image_source as resolve_value
27
+
28
+ return resolve_value(block, asset_base_url)
29
+
30
+
31
+ def normalize_image_source(source: str) -> str:
32
+ """规范化素材路径,保持共享渲染器的 URL 与路径处理行为。"""
33
+ from ._internal.markdown.assets import normalize_image_source as normalize_value
34
+
35
+ return normalize_value(source)
36
+
37
+
38
+ def format_embedded_html(markup: str, *, asset_base_url: str, delimiters: LatexDelimitersConfig) -> str:
39
+ """复用嵌入 HTML 的图片地址和公式分隔符处理。"""
40
+ from ._internal.markdown.table import format_embedded_html as format_value
41
+
42
+ return format_value(markup, asset_base_url=asset_base_url, delimiters=delimiters)
43
+
44
+
45
+ def strip_index_page_tail(content: list[InlineSpan]) -> list[InlineSpan]:
46
+ """剥离目录尾部页码,保持行内样式和链接语义。"""
47
+ from ._internal.common.index import strip_index_page_tail as strip_value
48
+
49
+ return strip_value(content)
50
+
51
+
52
+ def parse_list_item_marker(content: list[InlineSpan]) -> ListItem:
53
+ """解析列表标记并返回共享的不可变条目描述。"""
54
+ from ._internal.common.list_items import parse_list_item_marker as parse_value
55
+
56
+ return parse_value(content)
57
+
58
+
59
+ __all__ = [
60
+ "ListItem",
61
+ "ListItemKind",
62
+ "OrderedListStyle",
63
+ "render_inline_content",
64
+ "render_internal_link",
65
+ "resolve_image_source",
66
+ "normalize_image_source",
67
+ "format_embedded_html",
68
+ "strip_index_page_tail",
69
+ "parse_list_item_marker",
70
+ ]
@@ -0,0 +1,29 @@
1
+ """严格 MiddleJson 到 HTML 的轻量公共门面。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..schema import MiddleJson
6
+ from .contracts import RenderMode
7
+
8
+
9
+ def render_html(
10
+ middle_json: MiddleJson,
11
+ *,
12
+ mode: RenderMode = RenderMode.DEFAULT,
13
+ asset_base_url: str = "",
14
+ standalone: bool = True,
15
+ document_title: str | None = None,
16
+ ) -> str:
17
+ """惰性加载 HTML 实现并渲染严格 MiddleJson。"""
18
+ from ._internal.html.renderer import render_html as _render_html
19
+
20
+ return _render_html(
21
+ middle_json,
22
+ mode=mode,
23
+ asset_base_url=asset_base_url,
24
+ standalone=standalone,
25
+ document_title=document_title,
26
+ )
27
+
28
+
29
+ __all__ = ["render_html"]
@@ -0,0 +1,24 @@
1
+ """严格 MiddleJson 到 TeX Live LaTeX 源码的轻量公共门面。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..schema import MiddleJson
6
+
7
+
8
+ def render_latex(
9
+ middle_json: MiddleJson,
10
+ *,
11
+ asset_base_path: str = "",
12
+ document_title: str | None = None,
13
+ ) -> str:
14
+ """惰性加载 LaTeX 实现并返回完整 UTF-8 文档源码。"""
15
+ from ._internal.latex.renderer import render_latex as _render_latex
16
+
17
+ return _render_latex(
18
+ middle_json,
19
+ asset_base_path=asset_base_path,
20
+ document_title=document_title,
21
+ )
22
+
23
+
24
+ __all__ = ["render_latex"]
@@ -0,0 +1,50 @@
1
+ """严格 MiddleJson 到 Markdown 的轻量公共门面。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..options import LatexDelimitersConfig
6
+ from ..schema import MiddleJson, PageBlock
7
+ from .contracts import ImageRenderer, RenderMode
8
+
9
+
10
+ def render_markdown(
11
+ middle_json: MiddleJson,
12
+ *,
13
+ mode: RenderMode = RenderMode.DEFAULT,
14
+ asset_base_url: str = "",
15
+ image_renderer: ImageRenderer | None = None,
16
+ latex_delimiters: LatexDelimitersConfig | None = None,
17
+ ) -> str:
18
+ """惰性加载 Markdown 实现并渲染严格 MiddleJson。"""
19
+ from ._internal.markdown.renderer import render_markdown as _render_markdown
20
+
21
+ return _render_markdown(
22
+ middle_json,
23
+ latex_delimiters=latex_delimiters,
24
+ mode=mode,
25
+ asset_base_url=asset_base_url,
26
+ image_renderer=image_renderer,
27
+ )
28
+
29
+
30
+ def render_single_block(
31
+ block: PageBlock,
32
+ *,
33
+ delimiters: LatexDelimitersConfig,
34
+ asset_base_url: str,
35
+ image_renderer: ImageRenderer | None = None,
36
+ ) -> str:
37
+ """为文档库等局部读取调用方渲染单个顶层块,不执行文档级合并。"""
38
+ from ._internal.markdown.blocks import render_single_block as render_block
39
+
40
+ return render_block(block, delimiters=delimiters, asset_base_url=asset_base_url, image_renderer=image_renderer)
41
+
42
+
43
+ def build_markdown_image(source: str, alt: str = "") -> str:
44
+ """通过公开接口构造转义后的图片引用,避免调用方依赖 renderer 私有文件。"""
45
+ from ._internal.markdown.assets import build_markdown_image as build_image
46
+
47
+ return build_image(source, alt)
48
+
49
+
50
+ __all__ = ["render_markdown", "render_single_block", "build_markdown_image"]
@@ -0,0 +1,25 @@
1
+ """严格 MiddleJson 到 PDF bytes 的轻量公共门面。"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..schema import MiddleJson
6
+ from .contracts import AssetResolver
7
+
8
+
9
+ def render_pdf(
10
+ middle_json: MiddleJson,
11
+ *,
12
+ asset_resolver: AssetResolver | None = None,
13
+ document_title: str | None = None,
14
+ ) -> bytes:
15
+ """惰性加载 PDF 实现并渲染严格 MiddleJson。"""
16
+ from ._internal.pdf.renderer import render_pdf as _render_pdf
17
+
18
+ return _render_pdf(
19
+ middle_json,
20
+ asset_resolver=asset_resolver,
21
+ document_title=document_title,
22
+ )
23
+
24
+
25
+ __all__ = ["render_pdf"]