agent-markdown-pdf 0.3.0__tar.gz → 0.4.0__tar.gz

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 (120) hide show
  1. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/PKG-INFO +89 -12
  2. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/README.md +88 -11
  3. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/PKG-INFO +89 -12
  4. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/SOURCES.txt +13 -4
  5. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/browser.py +21 -4
  6. agent_markdown_pdf-0.4.0/mdtopdf/core/diagram_diagnostics.py +37 -0
  7. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/doctor.py +2 -1
  8. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/inline.py +9 -1
  9. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/markdown.py +40 -5
  10. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/mermaid.py +5 -3
  11. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/mdtopdf_cli.py +2 -2
  12. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/skills/SKILL.md +23 -4
  13. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/themes/default.css +60 -19
  14. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/browser-render.js +0 -11
  15. agent_markdown_pdf-0.4.0/mdtopdf/vendor/diagram-render.js +120 -0
  16. agent_markdown_pdf-0.4.0/mdtopdf/vendor/page-layout.js +213 -0
  17. {agent_markdown_pdf-0.3.0/mdtopdf/vendor/mermaid → agent_markdown_pdf-0.4.0/mdtopdf/vendor/pele}/LICENSE +21 -2
  18. agent_markdown_pdf-0.4.0/mdtopdf/vendor/pele/NOTICE.md +11 -0
  19. agent_markdown_pdf-0.4.0/mdtopdf/vendor/pele/pele.global.js +147 -0
  20. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/pyproject.toml +6 -4
  21. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_core.py +10 -10
  22. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_decorations.py +49 -0
  23. agent_markdown_pdf-0.4.0/tests/test_diagram_diagnostics.py +164 -0
  24. agent_markdown_pdf-0.4.0/tests/test_diagram_layout.py +220 -0
  25. agent_markdown_pdf-0.4.0/tests/test_page_geometry.py +152 -0
  26. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_pdfium.py +26 -0
  27. agent_markdown_pdf-0.4.0/tests/test_pele.py +295 -0
  28. agent_markdown_pdf-0.4.0/tests/test_table_layout.py +170 -0
  29. agent_markdown_pdf-0.4.0/tests/test_theme_tokens.py +163 -0
  30. agent_markdown_pdf-0.3.0/mdtopdf/vendor/mermaid/NOTICE.md +0 -8
  31. agent_markdown_pdf-0.3.0/mdtopdf/vendor/mermaid/mermaid.min.js +0 -3405
  32. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/LICENSE +0 -0
  33. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/dependency_links.txt +0 -0
  34. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/entry_points.txt +0 -0
  35. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/requires.txt +0 -0
  36. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/agent_markdown_pdf.egg-info/top_level.txt +0 -0
  37. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/__init__.py +0 -0
  38. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/__main__.py +0 -0
  39. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/api.py +0 -0
  40. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/__init__.py +0 -0
  41. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/diagnostics.py +0 -0
  42. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/fonts.py +0 -0
  43. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/html.py +0 -0
  44. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/katex.py +0 -0
  45. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/obsidian.py +0 -0
  46. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/output.py +0 -0
  47. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/core/pdf.py +0 -0
  48. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/LICENSE +0 -0
  49. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/contrib/mhchem.min.js +0 -0
  50. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
  51. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
  52. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  53. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  54. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  55. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  56. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  57. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  58. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  59. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  60. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  61. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  62. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  63. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  64. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  65. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
  66. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.woff +0 -0
  67. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
  68. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  69. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  70. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  71. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
  72. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.woff +0 -0
  73. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
  74. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
  75. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.woff +0 -0
  76. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
  77. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  78. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  79. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  80. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
  81. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.woff +0 -0
  82. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
  83. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  84. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  85. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  86. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  87. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  88. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  89. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  90. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  91. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  92. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
  93. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.woff +0 -0
  94. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
  95. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
  96. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
  97. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  98. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
  99. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
  100. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  101. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
  102. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
  103. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  104. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
  105. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
  106. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  107. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  108. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  109. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  110. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/katex.min.css +0 -0
  111. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/mdtopdf/vendor/katex/dist/katex.min.js +0 -0
  112. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/setup.cfg +0 -0
  113. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_browser.py +0 -0
  114. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_browser_discovery.py +0 -0
  115. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_dependency_diagnostics.py +0 -0
  116. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_full_e2e.py +0 -0
  117. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_macos_fonts.py +0 -0
  118. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_math_alignment.py +0 -0
  119. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_reliability.py +0 -0
  120. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.0}/tests/test_stdin.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-markdown-pdf
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Agent-friendly Markdown-to-PDF CLI with HTML preview and JSON diagnostics
5
5
  Author: rainp
6
6
  License-Expression: MIT
@@ -87,7 +87,7 @@ command-line interface where the style can be defined up front.
87
87
  Install from PyPI in your Python environment:
88
88
 
89
89
  ```shell
90
- python -m pip install "agent-markdown-pdf>=0.3.0"
90
+ python -m pip install "agent-markdown-pdf>=0.4.0"
91
91
  ```
92
92
 
93
93
  The PyPI distribution is `agent-markdown-pdf`; it installs the `mdtopdf` command.
@@ -218,7 +218,8 @@ bundled renderer makes the basic doctor check fail.
218
218
  The gallery below is rendered from the final PDF produced by
219
219
  `examples/visual-test-en.md`. It shows the actual pages an agent can hand back
220
220
  to a user: headings, callouts, tables, code, math, images, Mermaid, and
221
- pagination.
221
+ pagination. The images show the 0.4.0 renderer, with Pele diagrams
222
+ and Chromium PDF rendering.
222
223
 
223
224
  | Page 1 | Page 2 |
224
225
  | --- | --- |
@@ -234,10 +235,83 @@ pagination.
234
235
  Markdown -> markdown-it-py HTML -> theme/custom CSS -> Chromium PDF
235
236
  ```
236
237
 
237
- One Chromium session renders bundled KaTeX and Mermaid, waits for fonts and
238
- images, and prints the PDF. No separate Mermaid CLI, Node.js installation,
239
- WeasyPrint, or MSYS2 setup is needed. Browser installation is an explicit setup
240
- step; conversion never downloads a browser.
238
+ One Chromium session renders formulas with bundled KaTeX and Mermaid code blocks
239
+ with bundled Pele, waits for fonts and images, and prints the PDF. No separate
240
+ Mermaid CLI, Node.js installation, WeasyPrint, or MSYS2 setup is needed. Browser
241
+ installation is an explicit setup step; conversion never downloads a browser.
242
+
243
+ ### Mermaid diagrams with Pele
244
+
245
+ Keep using `mermaid` or `mmd` fenced code blocks:
246
+
247
+ ````markdown
248
+ ```mermaid
249
+ flowchart LR
250
+ A[Draft] --> B[Review] --> C[PDF]
251
+ ```
252
+ ````
253
+
254
+ Pele produces SVG for HTML preview and PDF. Diagram label formulas written as
255
+ `$$...$$` use the bundled KaTeX renderer. The default SVG theme matches the
256
+ document's soft lavender palette and Latin-first font stack, with pale purple
257
+ nodes, dark text, and gray-purple connectors.
258
+
259
+ To customize the document and diagram palette, pass a CSS file with `--css`:
260
+
261
+ ```css
262
+ :root {
263
+ --mdtopdf-accent: #7352a6;
264
+ --mdtopdf-surface: #f3effa;
265
+ }
266
+ .mermaid-diagram {
267
+ --pele-border: #b5a2cf;
268
+ }
269
+ ```
270
+
271
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
272
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
273
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
274
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
275
+ Local `--pele-*` overrides still customize diagrams independently.
276
+
277
+ Diagram layout uses the configured `@page` size and margins, including named
278
+ pages. Before pagination, it conservatively uses the smallest available width
279
+ and height across matching first/left/right page styles. The source diagram
280
+ direction is preserved. This supports common print CSS; inspect the final PDF
281
+ when using more complex page rules.
282
+
283
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
284
+ result includes a `diagram_text_too_small` warning with the diagram index and
285
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
286
+ diagrams. To adjust the warning threshold, use
287
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
288
+ This changes the check, not the font size. `--strict` rejects the warning and
289
+ preserves an existing output.
290
+
291
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
292
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
293
+ source excerpt. When the location can be established, `diagram_line`,
294
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
295
+ `source_start_line` identifies the code block's first content line.
296
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
297
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
298
+
299
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
300
+ `themeVariables` settings do not set its colors; use the CSS variables above.
301
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
302
+ existing diagrams in HTML and the final PDF. See Pele's
303
+ [compatibility guide](https://pele.run/compatibility) and
304
+ [theme variables](https://pele.run/theming).
305
+
306
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
307
+ including quoted names, fail to parse in this version.
308
+
309
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
310
+
311
+ ```shell
312
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
313
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
314
+ ```
241
315
 
242
316
  ### Upgrading from 0.2.x
243
317
 
@@ -253,7 +327,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
253
327
  | Feature | Notes |
254
328
  | --- | --- |
255
329
  | JSON output | `--json` is available for conversion, HTML preview, doctor, and theme listing. |
256
- | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Mermaid assets, and recommended fonts. |
330
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
257
331
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
258
332
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
259
333
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -371,7 +445,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
371
445
  `mdtopdf` supports:
372
446
 
373
447
  - CommonMark
374
- - Tables
448
+ - Tables with content-based column widths and wrapping for long words and URLs
375
449
  - Strikethrough
376
450
  - Task lists
377
451
  - Footnotes
@@ -384,7 +458,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
384
458
  - Obsidian-style callouts such as `> [!note] Title`
385
459
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
386
460
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
387
- - Mermaid diagrams through bundled Mermaid in Chromium
461
+ - Mermaid code blocks through bundled Pele in Chromium
388
462
 
389
463
  Raw HTML is disabled by default except for the safe subset above. For trusted
390
464
  local Markdown, pass `--unsafe-html`.
@@ -484,8 +558,11 @@ python -m twine check dist/*
484
558
 
485
559
  ## License
486
560
 
487
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
488
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
561
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
562
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
563
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
564
+ Pele's bundled version, source, and asset hash are recorded in
565
+ `mdtopdf/vendor/pele/NOTICE.md`.
489
566
 
490
567
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
491
568
  fonts. The default theme references local system fonts such as Segoe UI,
@@ -44,7 +44,7 @@ command-line interface where the style can be defined up front.
44
44
  Install from PyPI in your Python environment:
45
45
 
46
46
  ```shell
47
- python -m pip install "agent-markdown-pdf>=0.3.0"
47
+ python -m pip install "agent-markdown-pdf>=0.4.0"
48
48
  ```
49
49
 
50
50
  The PyPI distribution is `agent-markdown-pdf`; it installs the `mdtopdf` command.
@@ -175,7 +175,8 @@ bundled renderer makes the basic doctor check fail.
175
175
  The gallery below is rendered from the final PDF produced by
176
176
  `examples/visual-test-en.md`. It shows the actual pages an agent can hand back
177
177
  to a user: headings, callouts, tables, code, math, images, Mermaid, and
178
- pagination.
178
+ pagination. The images show the 0.4.0 renderer, with Pele diagrams
179
+ and Chromium PDF rendering.
179
180
 
180
181
  | Page 1 | Page 2 |
181
182
  | --- | --- |
@@ -191,10 +192,83 @@ pagination.
191
192
  Markdown -> markdown-it-py HTML -> theme/custom CSS -> Chromium PDF
192
193
  ```
193
194
 
194
- One Chromium session renders bundled KaTeX and Mermaid, waits for fonts and
195
- images, and prints the PDF. No separate Mermaid CLI, Node.js installation,
196
- WeasyPrint, or MSYS2 setup is needed. Browser installation is an explicit setup
197
- step; conversion never downloads a browser.
195
+ One Chromium session renders formulas with bundled KaTeX and Mermaid code blocks
196
+ with bundled Pele, waits for fonts and images, and prints the PDF. No separate
197
+ Mermaid CLI, Node.js installation, WeasyPrint, or MSYS2 setup is needed. Browser
198
+ installation is an explicit setup step; conversion never downloads a browser.
199
+
200
+ ### Mermaid diagrams with Pele
201
+
202
+ Keep using `mermaid` or `mmd` fenced code blocks:
203
+
204
+ ````markdown
205
+ ```mermaid
206
+ flowchart LR
207
+ A[Draft] --> B[Review] --> C[PDF]
208
+ ```
209
+ ````
210
+
211
+ Pele produces SVG for HTML preview and PDF. Diagram label formulas written as
212
+ `$$...$$` use the bundled KaTeX renderer. The default SVG theme matches the
213
+ document's soft lavender palette and Latin-first font stack, with pale purple
214
+ nodes, dark text, and gray-purple connectors.
215
+
216
+ To customize the document and diagram palette, pass a CSS file with `--css`:
217
+
218
+ ```css
219
+ :root {
220
+ --mdtopdf-accent: #7352a6;
221
+ --mdtopdf-surface: #f3effa;
222
+ }
223
+ .mermaid-diagram {
224
+ --pele-border: #b5a2cf;
225
+ }
226
+ ```
227
+
228
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
229
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
230
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
231
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
232
+ Local `--pele-*` overrides still customize diagrams independently.
233
+
234
+ Diagram layout uses the configured `@page` size and margins, including named
235
+ pages. Before pagination, it conservatively uses the smallest available width
236
+ and height across matching first/left/right page styles. The source diagram
237
+ direction is preserved. This supports common print CSS; inspect the final PDF
238
+ when using more complex page rules.
239
+
240
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
241
+ result includes a `diagram_text_too_small` warning with the diagram index and
242
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
243
+ diagrams. To adjust the warning threshold, use
244
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
245
+ This changes the check, not the font size. `--strict` rejects the warning and
246
+ preserves an existing output.
247
+
248
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
249
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
250
+ source excerpt. When the location can be established, `diagram_line`,
251
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
252
+ `source_start_line` identifies the code block's first content line.
253
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
254
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
255
+
256
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
257
+ `themeVariables` settings do not set its colors; use the CSS variables above.
258
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
259
+ existing diagrams in HTML and the final PDF. See Pele's
260
+ [compatibility guide](https://pele.run/compatibility) and
261
+ [theme variables](https://pele.run/theming).
262
+
263
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
264
+ including quoted names, fail to parse in this version.
265
+
266
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
267
+
268
+ ```shell
269
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
270
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
271
+ ```
198
272
 
199
273
  ### Upgrading from 0.2.x
200
274
 
@@ -210,7 +284,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
210
284
  | Feature | Notes |
211
285
  | --- | --- |
212
286
  | JSON output | `--json` is available for conversion, HTML preview, doctor, and theme listing. |
213
- | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Mermaid assets, and recommended fonts. |
287
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
214
288
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
215
289
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
216
290
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -328,7 +402,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
328
402
  `mdtopdf` supports:
329
403
 
330
404
  - CommonMark
331
- - Tables
405
+ - Tables with content-based column widths and wrapping for long words and URLs
332
406
  - Strikethrough
333
407
  - Task lists
334
408
  - Footnotes
@@ -341,7 +415,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
341
415
  - Obsidian-style callouts such as `> [!note] Title`
342
416
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
343
417
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
344
- - Mermaid diagrams through bundled Mermaid in Chromium
418
+ - Mermaid code blocks through bundled Pele in Chromium
345
419
 
346
420
  Raw HTML is disabled by default except for the safe subset above. For trusted
347
421
  local Markdown, pass `--unsafe-html`.
@@ -441,8 +515,11 @@ python -m twine check dist/*
441
515
 
442
516
  ## License
443
517
 
444
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
445
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
518
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
519
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
520
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
521
+ Pele's bundled version, source, and asset hash are recorded in
522
+ `mdtopdf/vendor/pele/NOTICE.md`.
446
523
 
447
524
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
448
525
  fonts. The default theme references local system fonts such as Segoe UI,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-markdown-pdf
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Agent-friendly Markdown-to-PDF CLI with HTML preview and JSON diagnostics
5
5
  Author: rainp
6
6
  License-Expression: MIT
@@ -87,7 +87,7 @@ command-line interface where the style can be defined up front.
87
87
  Install from PyPI in your Python environment:
88
88
 
89
89
  ```shell
90
- python -m pip install "agent-markdown-pdf>=0.3.0"
90
+ python -m pip install "agent-markdown-pdf>=0.4.0"
91
91
  ```
92
92
 
93
93
  The PyPI distribution is `agent-markdown-pdf`; it installs the `mdtopdf` command.
@@ -218,7 +218,8 @@ bundled renderer makes the basic doctor check fail.
218
218
  The gallery below is rendered from the final PDF produced by
219
219
  `examples/visual-test-en.md`. It shows the actual pages an agent can hand back
220
220
  to a user: headings, callouts, tables, code, math, images, Mermaid, and
221
- pagination.
221
+ pagination. The images show the 0.4.0 renderer, with Pele diagrams
222
+ and Chromium PDF rendering.
222
223
 
223
224
  | Page 1 | Page 2 |
224
225
  | --- | --- |
@@ -234,10 +235,83 @@ pagination.
234
235
  Markdown -> markdown-it-py HTML -> theme/custom CSS -> Chromium PDF
235
236
  ```
236
237
 
237
- One Chromium session renders bundled KaTeX and Mermaid, waits for fonts and
238
- images, and prints the PDF. No separate Mermaid CLI, Node.js installation,
239
- WeasyPrint, or MSYS2 setup is needed. Browser installation is an explicit setup
240
- step; conversion never downloads a browser.
238
+ One Chromium session renders formulas with bundled KaTeX and Mermaid code blocks
239
+ with bundled Pele, waits for fonts and images, and prints the PDF. No separate
240
+ Mermaid CLI, Node.js installation, WeasyPrint, or MSYS2 setup is needed. Browser
241
+ installation is an explicit setup step; conversion never downloads a browser.
242
+
243
+ ### Mermaid diagrams with Pele
244
+
245
+ Keep using `mermaid` or `mmd` fenced code blocks:
246
+
247
+ ````markdown
248
+ ```mermaid
249
+ flowchart LR
250
+ A[Draft] --> B[Review] --> C[PDF]
251
+ ```
252
+ ````
253
+
254
+ Pele produces SVG for HTML preview and PDF. Diagram label formulas written as
255
+ `$$...$$` use the bundled KaTeX renderer. The default SVG theme matches the
256
+ document's soft lavender palette and Latin-first font stack, with pale purple
257
+ nodes, dark text, and gray-purple connectors.
258
+
259
+ To customize the document and diagram palette, pass a CSS file with `--css`:
260
+
261
+ ```css
262
+ :root {
263
+ --mdtopdf-accent: #7352a6;
264
+ --mdtopdf-surface: #f3effa;
265
+ }
266
+ .mermaid-diagram {
267
+ --pele-border: #b5a2cf;
268
+ }
269
+ ```
270
+
271
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
272
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
273
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
274
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
275
+ Local `--pele-*` overrides still customize diagrams independently.
276
+
277
+ Diagram layout uses the configured `@page` size and margins, including named
278
+ pages. Before pagination, it conservatively uses the smallest available width
279
+ and height across matching first/left/right page styles. The source diagram
280
+ direction is preserved. This supports common print CSS; inspect the final PDF
281
+ when using more complex page rules.
282
+
283
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
284
+ result includes a `diagram_text_too_small` warning with the diagram index and
285
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
286
+ diagrams. To adjust the warning threshold, use
287
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
288
+ This changes the check, not the font size. `--strict` rejects the warning and
289
+ preserves an existing output.
290
+
291
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
292
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
293
+ source excerpt. When the location can be established, `diagram_line`,
294
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
295
+ `source_start_line` identifies the code block's first content line.
296
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
297
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
298
+
299
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
300
+ `themeVariables` settings do not set its colors; use the CSS variables above.
301
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
302
+ existing diagrams in HTML and the final PDF. See Pele's
303
+ [compatibility guide](https://pele.run/compatibility) and
304
+ [theme variables](https://pele.run/theming).
305
+
306
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
307
+ including quoted names, fail to parse in this version.
308
+
309
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
310
+
311
+ ```shell
312
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
313
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
314
+ ```
241
315
 
242
316
  ### Upgrading from 0.2.x
243
317
 
@@ -253,7 +327,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
253
327
  | Feature | Notes |
254
328
  | --- | --- |
255
329
  | JSON output | `--json` is available for conversion, HTML preview, doctor, and theme listing. |
256
- | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Mermaid assets, and recommended fonts. |
330
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
257
331
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
258
332
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
259
333
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -371,7 +445,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
371
445
  `mdtopdf` supports:
372
446
 
373
447
  - CommonMark
374
- - Tables
448
+ - Tables with content-based column widths and wrapping for long words and URLs
375
449
  - Strikethrough
376
450
  - Task lists
377
451
  - Footnotes
@@ -384,7 +458,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
384
458
  - Obsidian-style callouts such as `> [!note] Title`
385
459
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
386
460
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
387
- - Mermaid diagrams through bundled Mermaid in Chromium
461
+ - Mermaid code blocks through bundled Pele in Chromium
388
462
 
389
463
  Raw HTML is disabled by default except for the safe subset above. For trusted
390
464
  local Markdown, pass `--unsafe-html`.
@@ -484,8 +558,11 @@ python -m twine check dist/*
484
558
 
485
559
  ## License
486
560
 
487
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
488
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
561
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
562
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
563
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
564
+ Pele's bundled version, source, and asset hash are recorded in
565
+ `mdtopdf/vendor/pele/NOTICE.md`.
489
566
 
490
567
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
491
568
  fonts. The default theme references local system fonts such as Segoe UI,
@@ -14,6 +14,7 @@ mdtopdf/mdtopdf_cli.py
14
14
  mdtopdf/core/__init__.py
15
15
  mdtopdf/core/browser.py
16
16
  mdtopdf/core/diagnostics.py
17
+ mdtopdf/core/diagram_diagnostics.py
17
18
  mdtopdf/core/doctor.py
18
19
  mdtopdf/core/fonts.py
19
20
  mdtopdf/core/html.py
@@ -27,6 +28,8 @@ mdtopdf/core/pdf.py
27
28
  mdtopdf/skills/SKILL.md
28
29
  mdtopdf/themes/default.css
29
30
  mdtopdf/vendor/browser-render.js
31
+ mdtopdf/vendor/diagram-render.js
32
+ mdtopdf/vendor/page-layout.js
30
33
  mdtopdf/vendor/katex/LICENSE
31
34
  mdtopdf/vendor/katex/dist/katex.min.css
32
35
  mdtopdf/vendor/katex/dist/katex.min.js
@@ -91,17 +94,23 @@ mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.woff2
91
94
  mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.ttf
92
95
  mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff
93
96
  mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff2
94
- mdtopdf/vendor/mermaid/LICENSE
95
- mdtopdf/vendor/mermaid/NOTICE.md
96
- mdtopdf/vendor/mermaid/mermaid.min.js
97
+ mdtopdf/vendor/pele/LICENSE
98
+ mdtopdf/vendor/pele/NOTICE.md
99
+ mdtopdf/vendor/pele/pele.global.js
97
100
  tests/test_browser.py
98
101
  tests/test_browser_discovery.py
99
102
  tests/test_core.py
100
103
  tests/test_decorations.py
101
104
  tests/test_dependency_diagnostics.py
105
+ tests/test_diagram_diagnostics.py
106
+ tests/test_diagram_layout.py
102
107
  tests/test_full_e2e.py
103
108
  tests/test_macos_fonts.py
104
109
  tests/test_math_alignment.py
110
+ tests/test_page_geometry.py
105
111
  tests/test_pdfium.py
112
+ tests/test_pele.py
106
113
  tests/test_reliability.py
107
- tests/test_stdin.py
114
+ tests/test_stdin.py
115
+ tests/test_table_layout.py
116
+ tests/test_theme_tokens.py
@@ -7,12 +7,15 @@ from dataclasses import dataclass
7
7
  from html import escape
8
8
  from importlib import resources
9
9
  import os
10
+ import math
10
11
  import platform
11
12
  import secrets
12
13
  from pathlib import Path
13
14
  import tempfile
14
15
  from urllib.parse import urlparse
15
16
 
17
+ from mdtopdf.core.diagram_diagnostics import DiagramRenderError, raise_diagram_error
18
+
16
19
 
17
20
  BROWSER_ENV = "MDTOPDF_BROWSER_EXECUTABLE"
18
21
  INSTALL_HINT = "Run python -m playwright install chromium --no-shell during environment setup."
@@ -149,7 +152,7 @@ def render_document(html, *, base_url=None, output_path=None, timeout=90):
149
152
  return await asyncio.wait_for(_render(html, base_url=base_url, output_path=output_path), timeout)
150
153
  try:
151
154
  return _execute(run)
152
- except BrowserRenderError:
155
+ except (BrowserRenderError, DiagramRenderError):
153
156
  raise
154
157
  except Exception as exc:
155
158
  raise _failure(exc) from exc
@@ -217,13 +220,27 @@ async def _render(html, *, base_url, output_path):
217
220
  await page.emulate_media(media="print")
218
221
  await page.goto(source.as_uri(), wait_until="load")
219
222
  package = resources.files("mdtopdf")
220
- if await page.locator("[data-mdtopdf-math]").count():
223
+ has_diagrams = await page.locator("[data-mdtopdf-mermaid]").count()
224
+ layouts = []
225
+ if has_diagrams:
226
+ layout_script = package.joinpath("vendor/page-layout.js").read_text(encoding="utf-8")
227
+ area = await page.evaluate(layout_script)
228
+ await page.set_viewport_size({"width": math.ceil(area["width"]), "height": math.ceil(area["height"])})
229
+ layouts = await page.evaluate(layout_script, {"action": "prepare"})
230
+ if has_diagrams or await page.locator("[data-mdtopdf-math]").count():
221
231
  for name in ("katex.min.js", "contrib/mhchem.min.js"):
222
232
  await _load_script(page, package.joinpath("vendor/katex/dist", name), nonce)
223
- if await page.locator("[data-mdtopdf-mermaid]").count():
224
- await _load_script(page, package.joinpath("vendor/mermaid/mermaid.min.js"), nonce)
233
+ if has_diagrams:
234
+ from mdtopdf.core.mermaid import MERMAID_ASSET
235
+ await _load_script(page, package.joinpath(MERMAID_ASSET), nonce)
225
236
  diagnostics = await page.evaluate(package.joinpath("vendor/browser-render.js").read_text(encoding="utf-8"))
226
237
  warnings.extend(diagnostics)
238
+ if has_diagrams:
239
+ diagrams = await page.evaluate(package.joinpath("vendor/diagram-render.js").read_text(encoding="utf-8"), layouts)
240
+ if diagrams["error"]:
241
+ raise_diagram_error(diagrams["error"])
242
+ warnings.extend(diagrams["warnings"])
243
+ warnings.extend(await page.evaluate(layout_script, {"action": "check", "layouts": layouts}))
227
244
  await page.evaluate("async () => { await document.fonts.ready; await Promise.all([...document.images].map(i => i.decode().catch(() => null))); }")
228
245
  missing = await page.locator("img").evaluate_all("images => images.filter(i => !i.naturalWidth).map(i => i.currentSrc || i.src)")
229
246
  for url in missing:
@@ -0,0 +1,37 @@
1
+ """Actionable diagram failures, separate from browser environment failures."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class DiagramRenderError(RuntimeError):
7
+ """A diagram could not be parsed or rendered by the bundled renderer."""
8
+
9
+ error_code = "diagram_render_failed"
10
+
11
+ def __init__(self, details: dict):
12
+ self.error_details = dict(details)
13
+ index = details.get("diagram_index", 1)
14
+ location = f"Diagram {index}"
15
+ if details.get("source_line"):
16
+ location += f" at Markdown line {details['source_line']}"
17
+ elif details.get("diagram_line"):
18
+ location += f" at diagram line {details['diagram_line']}"
19
+ elif details.get("source_start_line"):
20
+ location += f" starting at Markdown line {details['source_start_line']}"
21
+ message = details.get("message") or "Pele could not render this diagram."
22
+ super().__init__(f"{location}: {message}")
23
+ action = {
24
+ "limit": "Simplify the diagram or split it into smaller code blocks.",
25
+ "unsupported-diagram": "Use a diagram type and header supported by Pele.",
26
+ "syntax": "Correct the reported diagram syntax.",
27
+ "semantic": "Correct the conflicting or unresolved diagram declarations.",
28
+ }.get(details.get("code"), "Check the diagram's syntax and Pele compatibility.")
29
+ self.hint = (
30
+ f"Check the Mermaid/mmd code block for diagram {index}. {action} "
31
+ "See error_details for its location and source excerpt."
32
+ )
33
+
34
+
35
+ def raise_diagram_error(details: dict) -> None:
36
+ """Raise a browser-serialized diagram failure without losing its metadata."""
37
+ raise DiagramRenderError(details)
@@ -13,6 +13,7 @@ from pathlib import Path
13
13
 
14
14
  from mdtopdf.core.browser import BROWSER_ENV, inspect_browser
15
15
  from mdtopdf.core.fonts import inspect_recommended_font_groups
16
+ from mdtopdf.core.mermaid import MERMAID_ASSET
16
17
 
17
18
 
18
19
  def run_doctor(*, render_check=False):
@@ -31,7 +32,7 @@ def run_doctor(*, render_check=False):
31
32
  "recommendations": [],
32
33
  }
33
34
  root = resources.files("mdtopdf")
34
- for name, path in (("mermaid", "vendor/mermaid/mermaid.min.js"), ("katex", "vendor/katex/dist/katex.min.js")):
35
+ for name, path in (("mermaid", MERMAID_ASSET), ("katex", "vendor/katex/dist/katex.min.js")):
35
36
  exists = root.joinpath(path).is_file()
36
37
  result["tools"][name] = {"ok": exists, "backend": "bundled-javascript", "optional": False,
37
38
  "requires_network": False, "error": None if exists else "Bundled asset is missing."}
@@ -10,11 +10,17 @@ from markdown_it import MarkdownIt
10
10
  FENCE_RE = re.compile(r"^(?P<indent> {0,3})(?P<fence>`{3,}|~{3,})")
11
11
 
12
12
 
13
- def protect_code_blocks(markdown_text: str) -> tuple[str, dict[str, str]]:
13
+ def protect_code_blocks(
14
+ markdown_text: str, *, source_lines: dict[str, int] | None = None,
15
+ ) -> tuple[str, dict[str, str]]:
14
16
  """Shield CommonMark code blocks, including blocks inside containers.
15
17
 
16
18
  Restore the source before final parsing, not after HTML rendering: code must
17
19
  still be escaped by the Markdown renderer and highlighted normally.
20
+
21
+ If supplied, ``source_lines`` records each placeholder's zero-based original
22
+ line. Consumers can retain source locations even when preprocessing removes
23
+ frontmatter or comments before restoring the blocks.
18
24
  """
19
25
  lines = markdown_text.splitlines(keepends=True)
20
26
  replacements: dict[str, str] = {}
@@ -30,6 +36,8 @@ def protect_code_blocks(markdown_text: str) -> tuple[str, dict[str, str]]:
30
36
  newline = "\r\n" if original.endswith("\r\n") else "\n" if original.endswith("\n") else ""
31
37
  marker = f"```{prefix}X{start}END\n```{newline}"
32
38
  replacements[marker] = original
39
+ if source_lines is not None:
40
+ source_lines[marker] = start
33
41
  lines[start:end] = [marker]
34
42
  return "".join(lines), replacements
35
43