agent-markdown-pdf 0.3.0__tar.gz → 0.4.1__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.1}/PKG-INFO +90 -12
  2. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/README.md +89 -11
  3. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/PKG-INFO +90 -12
  4. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/SOURCES.txt +13 -4
  5. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/browser.py +21 -4
  6. agent_markdown_pdf-0.4.1/mdtopdf/core/diagram_diagnostics.py +37 -0
  7. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/doctor.py +2 -1
  8. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/inline.py +9 -1
  9. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/markdown.py +40 -5
  10. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/mermaid.py +5 -3
  11. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/mdtopdf_cli.py +2 -2
  12. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/skills/SKILL.md +23 -4
  13. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/themes/default.css +60 -19
  14. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/browser-render.js +0 -11
  15. agent_markdown_pdf-0.4.1/mdtopdf/vendor/diagram-render.js +120 -0
  16. agent_markdown_pdf-0.4.1/mdtopdf/vendor/page-layout.js +213 -0
  17. {agent_markdown_pdf-0.3.0/mdtopdf/vendor/mermaid → agent_markdown_pdf-0.4.1/mdtopdf/vendor/pele}/LICENSE +21 -2
  18. agent_markdown_pdf-0.4.1/mdtopdf/vendor/pele/NOTICE.md +11 -0
  19. agent_markdown_pdf-0.4.1/mdtopdf/vendor/pele/pele.global.js +147 -0
  20. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/pyproject.toml +6 -4
  21. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_core.py +10 -10
  22. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_decorations.py +49 -0
  23. agent_markdown_pdf-0.4.1/tests/test_diagram_diagnostics.py +164 -0
  24. agent_markdown_pdf-0.4.1/tests/test_diagram_layout.py +220 -0
  25. agent_markdown_pdf-0.4.1/tests/test_page_geometry.py +152 -0
  26. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_pdfium.py +26 -0
  27. agent_markdown_pdf-0.4.1/tests/test_pele.py +295 -0
  28. agent_markdown_pdf-0.4.1/tests/test_table_layout.py +170 -0
  29. agent_markdown_pdf-0.4.1/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.1}/LICENSE +0 -0
  33. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/dependency_links.txt +0 -0
  34. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/entry_points.txt +0 -0
  35. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/requires.txt +0 -0
  36. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/agent_markdown_pdf.egg-info/top_level.txt +0 -0
  37. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/__init__.py +0 -0
  38. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/__main__.py +0 -0
  39. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/api.py +0 -0
  40. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/__init__.py +0 -0
  41. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/diagnostics.py +0 -0
  42. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/fonts.py +0 -0
  43. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/html.py +0 -0
  44. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/katex.py +0 -0
  45. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/obsidian.py +0 -0
  46. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/output.py +0 -0
  47. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/core/pdf.py +0 -0
  48. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/LICENSE +0 -0
  49. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/contrib/mhchem.min.js +0 -0
  50. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
  51. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
  52. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  53. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  54. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  55. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  56. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  57. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  58. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  59. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  60. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  61. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  62. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  63. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  64. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  65. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
  66. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.woff +0 -0
  67. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
  68. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  69. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  70. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  71. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
  72. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.woff +0 -0
  73. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
  74. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
  75. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.woff +0 -0
  76. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
  77. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  78. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  79. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  80. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
  81. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.woff +0 -0
  82. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
  83. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  84. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  85. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  86. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  87. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  88. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  89. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  90. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  91. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  92. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
  93. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.woff +0 -0
  94. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
  95. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
  96. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
  97. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  98. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
  99. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
  100. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  101. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
  102. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
  103. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  104. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
  105. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
  106. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  107. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  108. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  109. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  110. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/katex.min.css +0 -0
  111. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/mdtopdf/vendor/katex/dist/katex.min.js +0 -0
  112. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/setup.cfg +0 -0
  113. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_browser.py +0 -0
  114. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_browser_discovery.py +0 -0
  115. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_dependency_diagnostics.py +0 -0
  116. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_full_e2e.py +0 -0
  117. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_macos_fonts.py +0 -0
  118. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_math_alignment.py +0 -0
  119. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/tests/test_reliability.py +0 -0
  120. {agent_markdown_pdf-0.3.0 → agent_markdown_pdf-0.4.1}/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.1
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.1"
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 restored light-blue theme in 0.4.1, with Pele diagrams
222
+ and Chromium PDF rendering.
222
223
 
223
224
  | Page 1 | Page 2 |
224
225
  | --- | --- |
@@ -234,10 +235,84 @@ 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 light-blue palette and Latin-first font stack, with pale blue
257
+ nodes, dark text, and blue-gray connectors. Version 0.4.1 restores this palette
258
+ after the lavender default in 0.4.0.
259
+
260
+ To customize the document and diagram palette, pass a CSS file with `--css`:
261
+
262
+ ```css
263
+ :root {
264
+ --mdtopdf-accent: #0f6ea7;
265
+ --mdtopdf-surface: #f5f9fd;
266
+ }
267
+ .mermaid-diagram {
268
+ --pele-border: #9bb2c8;
269
+ }
270
+ ```
271
+
272
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
273
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
274
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
275
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
276
+ Local `--pele-*` overrides still customize diagrams independently.
277
+
278
+ Diagram layout uses the configured `@page` size and margins, including named
279
+ pages. Before pagination, it conservatively uses the smallest available width
280
+ and height across matching first/left/right page styles. The source diagram
281
+ direction is preserved. This supports common print CSS; inspect the final PDF
282
+ when using more complex page rules.
283
+
284
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
285
+ result includes a `diagram_text_too_small` warning with the diagram index and
286
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
287
+ diagrams. To adjust the warning threshold, use
288
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
289
+ This changes the check, not the font size. `--strict` rejects the warning and
290
+ preserves an existing output.
291
+
292
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
293
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
294
+ source excerpt. When the location can be established, `diagram_line`,
295
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
296
+ `source_start_line` identifies the code block's first content line.
297
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
298
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
299
+
300
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
301
+ `themeVariables` settings do not set its colors; use the CSS variables above.
302
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
303
+ existing diagrams in HTML and the final PDF. See Pele's
304
+ [compatibility guide](https://pele.run/compatibility) and
305
+ [theme variables](https://pele.run/theming).
306
+
307
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
308
+ including quoted names, fail to parse in this version.
309
+
310
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
311
+
312
+ ```shell
313
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
314
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
315
+ ```
241
316
 
242
317
  ### Upgrading from 0.2.x
243
318
 
@@ -253,7 +328,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
253
328
  | Feature | Notes |
254
329
  | --- | --- |
255
330
  | 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. |
331
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
257
332
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
258
333
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
259
334
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -371,7 +446,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
371
446
  `mdtopdf` supports:
372
447
 
373
448
  - CommonMark
374
- - Tables
449
+ - Tables with content-based column widths and wrapping for long words and URLs
375
450
  - Strikethrough
376
451
  - Task lists
377
452
  - Footnotes
@@ -384,7 +459,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
384
459
  - Obsidian-style callouts such as `> [!note] Title`
385
460
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
386
461
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
387
- - Mermaid diagrams through bundled Mermaid in Chromium
462
+ - Mermaid code blocks through bundled Pele in Chromium
388
463
 
389
464
  Raw HTML is disabled by default except for the safe subset above. For trusted
390
465
  local Markdown, pass `--unsafe-html`.
@@ -484,8 +559,11 @@ python -m twine check dist/*
484
559
 
485
560
  ## License
486
561
 
487
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
488
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
562
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
563
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
564
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
565
+ Pele's bundled version, source, and asset hash are recorded in
566
+ `mdtopdf/vendor/pele/NOTICE.md`.
489
567
 
490
568
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
491
569
  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.1"
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 restored light-blue theme in 0.4.1, with Pele diagrams
179
+ and Chromium PDF rendering.
179
180
 
180
181
  | Page 1 | Page 2 |
181
182
  | --- | --- |
@@ -191,10 +192,84 @@ 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 light-blue palette and Latin-first font stack, with pale blue
214
+ nodes, dark text, and blue-gray connectors. Version 0.4.1 restores this palette
215
+ after the lavender default in 0.4.0.
216
+
217
+ To customize the document and diagram palette, pass a CSS file with `--css`:
218
+
219
+ ```css
220
+ :root {
221
+ --mdtopdf-accent: #0f6ea7;
222
+ --mdtopdf-surface: #f5f9fd;
223
+ }
224
+ .mermaid-diagram {
225
+ --pele-border: #9bb2c8;
226
+ }
227
+ ```
228
+
229
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
230
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
231
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
232
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
233
+ Local `--pele-*` overrides still customize diagrams independently.
234
+
235
+ Diagram layout uses the configured `@page` size and margins, including named
236
+ pages. Before pagination, it conservatively uses the smallest available width
237
+ and height across matching first/left/right page styles. The source diagram
238
+ direction is preserved. This supports common print CSS; inspect the final PDF
239
+ when using more complex page rules.
240
+
241
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
242
+ result includes a `diagram_text_too_small` warning with the diagram index and
243
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
244
+ diagrams. To adjust the warning threshold, use
245
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
246
+ This changes the check, not the font size. `--strict` rejects the warning and
247
+ preserves an existing output.
248
+
249
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
250
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
251
+ source excerpt. When the location can be established, `diagram_line`,
252
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
253
+ `source_start_line` identifies the code block's first content line.
254
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
255
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
256
+
257
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
258
+ `themeVariables` settings do not set its colors; use the CSS variables above.
259
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
260
+ existing diagrams in HTML and the final PDF. See Pele's
261
+ [compatibility guide](https://pele.run/compatibility) and
262
+ [theme variables](https://pele.run/theming).
263
+
264
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
265
+ including quoted names, fail to parse in this version.
266
+
267
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
268
+
269
+ ```shell
270
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
271
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
272
+ ```
198
273
 
199
274
  ### Upgrading from 0.2.x
200
275
 
@@ -210,7 +285,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
210
285
  | Feature | Notes |
211
286
  | --- | --- |
212
287
  | 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. |
288
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
214
289
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
215
290
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
216
291
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -328,7 +403,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
328
403
  `mdtopdf` supports:
329
404
 
330
405
  - CommonMark
331
- - Tables
406
+ - Tables with content-based column widths and wrapping for long words and URLs
332
407
  - Strikethrough
333
408
  - Task lists
334
409
  - Footnotes
@@ -341,7 +416,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
341
416
  - Obsidian-style callouts such as `> [!note] Title`
342
417
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
343
418
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
344
- - Mermaid diagrams through bundled Mermaid in Chromium
419
+ - Mermaid code blocks through bundled Pele in Chromium
345
420
 
346
421
  Raw HTML is disabled by default except for the safe subset above. For trusted
347
422
  local Markdown, pass `--unsafe-html`.
@@ -441,8 +516,11 @@ python -m twine check dist/*
441
516
 
442
517
  ## License
443
518
 
444
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
445
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
519
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
520
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
521
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
522
+ Pele's bundled version, source, and asset hash are recorded in
523
+ `mdtopdf/vendor/pele/NOTICE.md`.
446
524
 
447
525
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
448
526
  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.1
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.1"
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 restored light-blue theme in 0.4.1, with Pele diagrams
222
+ and Chromium PDF rendering.
222
223
 
223
224
  | Page 1 | Page 2 |
224
225
  | --- | --- |
@@ -234,10 +235,84 @@ 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 light-blue palette and Latin-first font stack, with pale blue
257
+ nodes, dark text, and blue-gray connectors. Version 0.4.1 restores this palette
258
+ after the lavender default in 0.4.0.
259
+
260
+ To customize the document and diagram palette, pass a CSS file with `--css`:
261
+
262
+ ```css
263
+ :root {
264
+ --mdtopdf-accent: #0f6ea7;
265
+ --mdtopdf-surface: #f5f9fd;
266
+ }
267
+ .mermaid-diagram {
268
+ --pele-border: #9bb2c8;
269
+ }
270
+ ```
271
+
272
+ Shared palette variables are `--mdtopdf-background`, `--mdtopdf-text`,
273
+ `--mdtopdf-heading`, `--mdtopdf-accent`, `--mdtopdf-muted`, `--mdtopdf-surface`,
274
+ `--mdtopdf-surface-alt`, `--mdtopdf-border`, and `--mdtopdf-critical`.
275
+ Heading levels 2–6 also have `--mdtopdf-heading-2` through `--mdtopdf-heading-6`.
276
+ Local `--pele-*` overrides still customize diagrams independently.
277
+
278
+ Diagram layout uses the configured `@page` size and margins, including named
279
+ pages. Before pagination, it conservatively uses the smallest available width
280
+ and height across matching first/left/right page styles. The source diagram
281
+ direction is preserved. This supports common print CSS; inspect the final PDF
282
+ when using more complex page rules.
283
+
284
+ If fitting a diagram makes its text smaller than approximately **8pt**, the
285
+ result includes a `diagram_text_too_small` warning with the diagram index and
286
+ estimated printed font size. Prefer a wider page, larger labels, or smaller
287
+ diagrams. To adjust the warning threshold, use
288
+ `.mermaid-diagram { --mdtopdf-diagram-min-font-size: 9pt; }` in your CSS.
289
+ This changes the check, not the font size. `--strict` rejects the warning and
290
+ preserves an existing output.
291
+
292
+ Diagram failures return `error_code: "diagram_render_failed"`, an actionable
293
+ `hint`, and `error_details` with Pele's code, the 1-based diagram index, and a
294
+ source excerpt. When the location can be established, `diagram_line`,
295
+ `diagram_column`, and `source_line` refer to the original diagram and Markdown;
296
+ `source_start_line` identifies the code block's first content line.
297
+ Pele's own `renderer_line` / `renderer_column` are kept separately because its
298
+ preprocessing can shift locations. Unknown locations are omitted, not guessed.
299
+
300
+ Pele has its own layout, so diagram geometry can change. Mermaid `theme` and
301
+ `themeVariables` settings do not set its colors; use the CSS variables above.
302
+ Arbitrary HTML labels and external Mermaid plugins are unsupported. Review
303
+ existing diagrams in HTML and the final PDF. See Pele's
304
+ [compatibility guide](https://pele.run/compatibility) and
305
+ [theme variables](https://pele.run/theming).
306
+
307
+ The bundled Pele **1.8.0** requires ASCII Sankey node names. Chinese node names,
308
+ including quoted names, fail to parse in this version.
309
+
310
+ Use `examples/pele-compatibility.md` with its companion CSS to review diagram output:
311
+
312
+ ```shell
313
+ mdtopdf html examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.html --overwrite
314
+ mdtopdf convert examples/pele-compatibility.md --css examples/pele-compatibility.css -o pele-compatibility.pdf --overwrite
315
+ ```
241
316
 
242
317
  ### Upgrading from 0.2.x
243
318
 
@@ -253,7 +328,7 @@ the old backend. See the [release notes](https://github.com/ABClize/mdtopdf/blob
253
328
  | Feature | Notes |
254
329
  | --- | --- |
255
330
  | 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. |
331
+ | Environment checks | `doctor --json` checks Python imports, the browser executable, bundled KaTeX/Pele assets, and recommended fonts. |
257
332
  | Local rendering | Markdown, CSS, math, Mermaid SVG generation, and PDF export stay on the machine. |
258
333
  | HTML preview | Generate standalone HTML before PDF export for fast visual inspection. |
259
334
  | Obsidian compatibility | Wikilinks, aliases, frontmatter hiding, comments, highlights, and typed callouts. |
@@ -371,7 +446,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
371
446
  `mdtopdf` supports:
372
447
 
373
448
  - CommonMark
374
- - Tables
449
+ - Tables with content-based column widths and wrapping for long words and URLs
375
450
  - Strikethrough
376
451
  - Task lists
377
452
  - Footnotes
@@ -384,7 +459,7 @@ markdown_file_to_pdf("report.md", output_path="report.pdf", overwrite=True)
384
459
  - Obsidian-style callouts such as `> [!note] Title`
385
460
  - Safe inline HTML tags such as `<br>`, `<kbd>`, `<mark>`, `<sup>`, and `<sub>`
386
461
  - TeX math through `$inline$`, `$$block$$`, and common `amsmath` environments
387
- - Mermaid diagrams through bundled Mermaid in Chromium
462
+ - Mermaid code blocks through bundled Pele in Chromium
388
463
 
389
464
  Raw HTML is disabled by default except for the safe subset above. For trusted
390
465
  local Markdown, pass `--unsafe-html`.
@@ -484,8 +559,11 @@ python -m twine check dist/*
484
559
 
485
560
  ## License
486
561
 
487
- MIT. Bundled KaTeX and Mermaid assets include their MIT licenses at
488
- `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/mermaid/LICENSE`.
562
+ MIT. Bundled KaTeX and Pele assets include their MIT licenses at
563
+ `mdtopdf/vendor/katex/LICENSE` and `mdtopdf/vendor/pele/LICENSE`.
564
+ `mdtopdf/vendor/pele/LICENSE` also includes the Lucide ISC license.
565
+ Pele's bundled version, source, and asset hash are recorded in
566
+ `mdtopdf/vendor/pele/NOTICE.md`.
489
567
 
490
568
  `mdtopdf` does not bundle CJK body fonts, emoji fonts, or proprietary system
491
569
  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