pdfmd-cli 3.25.20__tar.gz → 3.28.49__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 (223) hide show
  1. {pdfmd_cli-3.25.20/pdfmd_cli.egg-info → pdfmd_cli-3.28.49}/PKG-INFO +621 -61
  2. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/README.md +618 -59
  3. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd.py +6281 -706
  4. pdfmd_cli-3.28.49/pdfmd_check/__init__.py +15 -0
  5. pdfmd_cli-3.28.49/pdfmd_check/lint.py +581 -0
  6. pdfmd_cli-3.28.49/pdfmd_chem/__init__.py +2 -0
  7. pdfmd_cli-3.28.49/pdfmd_chem/__main__.py +12 -0
  8. pdfmd_cli-3.28.49/pdfmd_chem/batch.py +129 -0
  9. pdfmd_cli-3.28.49/pdfmd_chem/render.py +315 -0
  10. pdfmd_cli-3.28.49/pdfmd_chem/siunitx.py +701 -0
  11. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49/pdfmd_cli.egg-info}/PKG-INFO +621 -61
  12. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_cli.egg-info/SOURCES.txt +93 -0
  13. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_cli.egg-info/entry_points.txt +1 -0
  14. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_cli.egg-info/top_level.txt +7 -0
  15. pdfmd_cli-3.28.49/pdfmd_css/__init__.py +230 -0
  16. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_direct/__init__.py +3 -3
  17. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_direct/html.py +13 -5
  18. pdfmd_cli-3.28.49/pdfmd_flat/__init__.py +81 -0
  19. pdfmd_cli-3.28.49/pdfmd_flat/asciify.py +315 -0
  20. pdfmd_cli-3.28.49/pdfmd_flat/keep.py +176 -0
  21. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_help/__init__.py +47 -13
  22. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_images/remote.py +24 -1
  23. pdfmd_cli-3.28.49/pdfmd_labels/__init__.py +24 -0
  24. pdfmd_cli-3.28.49/pdfmd_labels/replay.py +73 -0
  25. pdfmd_cli-3.28.49/pdfmd_labels/scan.py +239 -0
  26. pdfmd_cli-3.28.49/pdfmd_lua/ascii.lua +135 -0
  27. pdfmd_cli-3.28.49/pdfmd_lua/chem.lua +79 -0
  28. pdfmd_cli-3.28.49/pdfmd_lua/chem_client.lua +156 -0
  29. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/csv_table.lua +153 -31
  30. pdfmd_cli-3.28.49/pdfmd_lua/diagram.lua +246 -0
  31. pdfmd_cli-3.28.49/pdfmd_lua/flat.lua +547 -0
  32. pdfmd_cli-3.28.49/pdfmd_lua/graphviz.cjs +59 -0
  33. pdfmd_cli-3.28.49/pdfmd_lua/katex.cjs +33 -0
  34. pdfmd_cli-3.28.49/pdfmd_lua/mathjax.cjs +54 -0
  35. pdfmd_cli-3.28.49/pdfmd_lua/pagebreak.lua +159 -0
  36. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/pdf_images.lua +10 -4
  37. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/raw.lua +156 -16
  38. pdfmd_cli-3.28.49/pdfmd_lua/select.lua +92 -0
  39. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/table_width.lua +15 -0
  40. pdfmd_cli-3.28.49/pdfmd_lua/title_meta.lua +59 -0
  41. pdfmd_cli-3.28.49/pdfmd_lua/typst.lua +100 -0
  42. pdfmd_cli-3.28.49/pdfmd_lua/weasyprint.lua +272 -0
  43. pdfmd_cli-3.28.49/pdfmd_mhchem/LICENSE +201 -0
  44. pdfmd_cli-3.28.49/pdfmd_mhchem/__init__.py +6 -0
  45. pdfmd_cli-3.28.49/pdfmd_mhchem/parser.py +1207 -0
  46. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/__init__.py +2 -1
  47. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/odt.py +13 -0
  48. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/office.lua +315 -381
  49. pdfmd_cli-3.28.49/pdfmd_office/properties.py +100 -0
  50. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_raw/__init__.py +6 -4
  51. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_setup/__init__.py +17 -6
  52. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_setup/fancy.py +90 -16
  53. pdfmd_cli-3.28.49/pdfmd_setup/inventory.py +244 -0
  54. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_setup/plain.py +39 -10
  55. pdfmd_cli-3.28.49/pdfmd_setup/registry.py +442 -0
  56. pdfmd_cli-3.28.49/pdfmd_templates/__init__.py +119 -0
  57. pdfmd_cli-3.28.49/pdfmd_templates/data/article/__name__.md +40 -0
  58. pdfmd_cli-3.28.49/pdfmd_templates/data/article/description.txt +1 -0
  59. pdfmd_cli-3.28.49/pdfmd_templates/data/article/next.txt +1 -0
  60. pdfmd_cli-3.28.49/pdfmd_templates/data/article/refs.bib +6 -0
  61. pdfmd_cli-3.28.49/pdfmd_templates/data/book/__name__.md +8 -0
  62. pdfmd_cli-3.28.49/pdfmd_templates/data/book/description.txt +1 -0
  63. pdfmd_cli-3.28.49/pdfmd_templates/data/book/next.txt +1 -0
  64. pdfmd_cli-3.28.49/pdfmd_templates/data/book/parts/10-introduction.md +4 -0
  65. pdfmd_cli-3.28.49/pdfmd_templates/data/book/parts/20-methods.md +7 -0
  66. pdfmd_cli-3.28.49/pdfmd_templates/data/book/parts/30-results.md +3 -0
  67. pdfmd_cli-3.28.49/pdfmd_templates/data/notes/__name__.md +25 -0
  68. pdfmd_cli-3.28.49/pdfmd_templates/data/notes/description.txt +1 -0
  69. pdfmd_cli-3.28.49/pdfmd_templates/data/notes/next.txt +1 -0
  70. pdfmd_cli-3.28.49/pdfmd_templates/data/report/__name__.md +32 -0
  71. pdfmd_cli-3.28.49/pdfmd_templates/data/report/data.csv +4 -0
  72. pdfmd_cli-3.28.49/pdfmd_templates/data/report/description.txt +1 -0
  73. pdfmd_cli-3.28.49/pdfmd_templates/data/report/next.txt +1 -0
  74. pdfmd_cli-3.28.49/pdfmd_templates/data/slides/__name__.md +20 -0
  75. pdfmd_cli-3.28.49/pdfmd_templates/data/slides/description.txt +1 -0
  76. pdfmd_cli-3.28.49/pdfmd_templates/data/slides/next.txt +1 -0
  77. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pyproject.toml +9 -4
  78. pdfmd_cli-3.28.49/tests/test_ascii.py +266 -0
  79. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_attach.py +265 -5
  80. pdfmd_cli-3.28.49/tests/test_attach_format.py +66 -0
  81. pdfmd_cli-3.28.49/tests/test_autolog.py +183 -0
  82. pdfmd_cli-3.28.49/tests/test_bopen.py +111 -0
  83. pdfmd_cli-3.28.49/tests/test_budget.py +157 -0
  84. pdfmd_cli-3.28.49/tests/test_build_record.py +133 -0
  85. pdfmd_cli-3.28.49/tests/test_calibre.py +177 -0
  86. pdfmd_cli-3.28.49/tests/test_check.py +247 -0
  87. pdfmd_cli-3.28.49/tests/test_check_source.py +96 -0
  88. pdfmd_cli-3.28.49/tests/test_chem.py +246 -0
  89. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_code_blocks.py +24 -0
  90. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_compat.py +15 -2
  91. pdfmd_cli-3.28.49/tests/test_css.py +173 -0
  92. pdfmd_cli-3.28.49/tests/test_csv_table.py +251 -0
  93. pdfmd_cli-3.28.49/tests/test_diagrams.py +335 -0
  94. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_direct.py +7 -0
  95. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_display_path.py +16 -0
  96. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_doctor.py +26 -2
  97. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_edit.py +5 -1
  98. pdfmd_cli-3.28.49/tests/test_edit_pdf.py +180 -0
  99. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_embedding.py +13 -0
  100. pdfmd_cli-3.28.49/tests/test_engine_chain.py +81 -0
  101. pdfmd_cli-3.28.49/tests/test_engine_filters.py +391 -0
  102. pdfmd_cli-3.28.49/tests/test_flat.py +444 -0
  103. pdfmd_cli-3.28.49/tests/test_header_includes.py +239 -0
  104. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_help.py +3 -0
  105. pdfmd_cli-3.28.49/tests/test_install_diagram.py +184 -0
  106. pdfmd_cli-3.28.49/tests/test_install_python.py +97 -0
  107. pdfmd_cli-3.28.49/tests/test_jobs.py +71 -0
  108. pdfmd_cli-3.28.49/tests/test_katex_scale.py +99 -0
  109. pdfmd_cli-3.28.49/tests/test_keep_source.py +212 -0
  110. pdfmd_cli-3.28.49/tests/test_labels.py +469 -0
  111. pdfmd_cli-3.28.49/tests/test_latex_errors.py +79 -0
  112. pdfmd_cli-3.28.49/tests/test_lua_trust.py +129 -0
  113. pdfmd_cli-3.28.49/tests/test_mathfont.py +109 -0
  114. pdfmd_cli-3.28.49/tests/test_mathjax.py +356 -0
  115. pdfmd_cli-3.28.49/tests/test_mhchem.py +120 -0
  116. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_native.py +4 -2
  117. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_office.py +3 -2
  118. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_office_latex.py +415 -15
  119. pdfmd_cli-3.28.49/tests/test_old_python_syntax.py +67 -0
  120. pdfmd_cli-3.28.49/tests/test_package_helper.py +94 -0
  121. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_packaging.py +10 -0
  122. pdfmd_cli-3.28.49/tests/test_pagebreak.py +234 -0
  123. pdfmd_cli-3.28.49/tests/test_picture_cache_protocol.py +131 -0
  124. pdfmd_cli-3.28.49/tests/test_plot_cache.py +168 -0
  125. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_polish.py +45 -0
  126. pdfmd_cli-3.28.49/tests/test_presets.py +154 -0
  127. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_raw.py +1 -1
  128. pdfmd_cli-3.28.49/tests/test_rawcode.py +94 -0
  129. pdfmd_cli-3.28.49/tests/test_reader.py +73 -0
  130. pdfmd_cli-3.28.49/tests/test_remote_csl.py +167 -0
  131. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_sections.py +3 -3
  132. pdfmd_cli-3.28.49/tests/test_setup.py +720 -0
  133. pdfmd_cli-3.28.49/tests/test_standalone_source.py +406 -0
  134. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_table_widths.py +2 -1
  135. pdfmd_cli-3.28.49/tests/test_templates.py +159 -0
  136. pdfmd_cli-3.28.49/tests/test_texpackages.py +105 -0
  137. pdfmd_cli-3.25.20/pdfmd_setup/registry.py +0 -246
  138. pdfmd_cli-3.25.20/tests/test_csv_table.py +0 -125
  139. pdfmd_cli-3.25.20/tests/test_setup.py +0 -218
  140. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/LICENSE +0 -0
  141. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_cli.egg-info/dependency_links.txt +0 -0
  142. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_cli.egg-info/requires.txt +0 -0
  143. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_direct/defaults.py +0 -0
  144. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_direct/typst.py +0 -0
  145. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_edit/__init__.py +0 -0
  146. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_history/__init__.py +0 -0
  147. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_history/git.py +0 -0
  148. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_history/hst.py +0 -0
  149. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_history/versions.py +0 -0
  150. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_images/__init__.py +0 -0
  151. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_images/scan.py +0 -0
  152. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_images/svg.py +0 -0
  153. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/LICENSE +0 -0
  154. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/VENDORED.md +0 -0
  155. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/__init__.py +0 -0
  156. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/_kerning_data.py +0 -0
  157. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/assets/fonts/DejaVuSans-LICENSE.txt +0 -0
  158. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/assets/fonts/DejaVuSans.ttf +0 -0
  159. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/ast.py +0 -0
  160. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/cidfont.py +0 -0
  161. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/embedded.py +0 -0
  162. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/embedded_metrics.py +0 -0
  163. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/emoji.py +0 -0
  164. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/emoji_font.py +0 -0
  165. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/fonts.py +0 -0
  166. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/html_filter.py +0 -0
  167. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/image_loader.py +0 -0
  168. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/layout.py +0 -0
  169. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/parser.py +0 -0
  170. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/pdf.py +0 -0
  171. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/py.typed +0 -0
  172. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/render.py +0 -0
  173. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/truetype.py +0 -0
  174. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_inkmd/url_filter.py +0 -0
  175. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/__init__.py +0 -0
  176. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/code.lua +0 -0
  177. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/code_wrap.tex +0 -0
  178. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/graphicx.tex +0 -0
  179. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_lua/images.lua +0 -0
  180. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/docx.py +0 -0
  181. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/docx_post.py +0 -0
  182. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/fonts.py +0 -0
  183. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/fragments.py +0 -0
  184. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/labels.py +0 -0
  185. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/spec.py +0 -0
  186. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_office/units.py +0 -0
  187. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_tables/__init__.py +0 -0
  188. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_tables/convert.py +0 -0
  189. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_tables/scan.py +0 -0
  190. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_tables/verify.py +0 -0
  191. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/__init__.py +0 -0
  192. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/_catalog.py +0 -0
  193. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/_scripts.py +0 -0
  194. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/_tessdata_catalog.py +0 -0
  195. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/colorfont.py +0 -0
  196. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/emoji.py +0 -0
  197. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/fonts.py +0 -0
  198. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/install.py +0 -0
  199. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/plan.py +0 -0
  200. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/scripts.py +0 -0
  201. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/tessdata.py +0 -0
  202. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/pdfmd_unicode/translit.py +0 -0
  203. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/setup.cfg +0 -0
  204. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_api.py +0 -0
  205. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_apple_emoji.py +0 -0
  206. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_cache_location.py +0 -0
  207. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_completion.py +0 -0
  208. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_config.py +0 -0
  209. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_docx_tables.py +0 -0
  210. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_history.py +0 -0
  211. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_images.py +0 -0
  212. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_install_ocr.py +0 -0
  213. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_lookup.py +0 -0
  214. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_markdown_features.py +0 -0
  215. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_pdf_input.py +0 -0
  216. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_soffice_parts.py +0 -0
  217. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_tables.py +0 -0
  218. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_tessdata.py +0 -0
  219. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_text_input.py +0 -0
  220. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_translit.py +0 -0
  221. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_typst_input.py +0 -0
  222. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_unicode.py +0 -0
  223. {pdfmd_cli-3.25.20 → pdfmd_cli-3.28.49}/tests/test_versions.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdfmd-cli
3
- Version: 3.25.20
3
+ Version: 3.28.49
4
4
  Summary: One command from Markdown to a good-looking PDF: a Pandoc wrapper with smart defaults, project-file discovery and a multi-engine fallback chain
5
5
  Author: Ali Perdekhan
6
- License-Expression: MIT
6
+ License-Expression: MIT AND Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/aliperdehan/pdfmd
8
8
  Project-URL: Changelog, https://github.com/aliperdehan/pdfmd/blob/main/CHANGELOG.md
9
9
  Keywords: pandoc,markdown,pdf,latex,cli
@@ -16,6 +16,7 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  License-File: pdfmd_inkmd/LICENSE
18
18
  License-File: pdfmd_inkmd/assets/fonts/DejaVuSans-LICENSE.txt
19
+ License-File: pdfmd_mhchem/LICENSE
19
20
  Requires-Dist: pyyaml
20
21
  Requires-Dist: pypdf
21
22
  Provides-Extra: math
@@ -46,10 +47,20 @@ Word or OpenDocument file that follows its page setup, fonts and LaTeX (see
46
47
 
47
48
  ```console
48
49
  $ pdfmd lecture
49
- AUTO: READER TITLE MARGIN MONOFONT. Use --verbose to see in full
50
- OK lecture.md
50
+ FOUND metadata: metadata.yaml + preamble.tex
51
+ DEFAULTS margin 1in, font STIX Two Text, code in JetBrains Mono, title from heading
52
+ AUTO: READER. Use --verbose to see in full
53
+ OK lecture.md > lecture.pdf (lualatex)
51
54
  ```
52
55
 
56
+ `FOUND` is what pdfmd picked up from the folder, `DEFAULTS` what it applied because nothing said otherwise
57
+ (the global metadata of `pdfmd --setup`, the title taken from a leading `# ` heading, a wide table whose columns it
58
+ balanced), and the `AUTO:` line the other decisions it made. Files of one folder are listed under it once
59
+ (`metadata: metadata.yaml + preamble.tex`; `--setup` can list each with its path instead). Each line is cut at the
60
+ width of the terminal (110 characters when the output is piped): `+3 more (--verbose)`. `--verbose` prints every
61
+ decision with its reason. The closing line names the file the build made, `OK lecture.md > lecture.pdf`; `--setup`
62
+ sets what stands between the two.
63
+
53
64
  In a folder with a single Markdown file you do not even need the name: `cd` into the folder and run `pdfmd`. It finds
54
65
  the file, its metadata, preamble and filters, and writes the PDF beside it (with several Markdown files it asks for
55
66
  one, or for `-b` to convert all of them or `-r` to join them). `pdfmd --help` is one short page; `pdfmd --help all`
@@ -90,6 +101,7 @@ turns that knowledge into defaults:
90
101
  given a Word recipe; what is left (tikz, chemfig, math Pandoc cannot convert) is drawn by LaTeX in the document's
91
102
  own preamble and embedded as vector pictures. `pdfmd-options: {office: {latex: auto|images|off}}`, `--no-auto
92
103
  officelatex` and `pdfmd --setup` switch it (see [Word and OpenDocument output](#word-and-opendocument-output)).
104
+ The file's properties hold the document's title and authors, and nothing of the machine that built it.
93
105
  - **It handles every script and emoji.** Text the main font cannot draw (Arabic,
94
106
  Hebrew, Chinese, Japanese, Korean, Greek, Cyrillic with Kazakh letters, Indic and
95
107
  more) is set run by run in an installed font for its script, emoji become colour
@@ -164,6 +176,11 @@ sudo pacman -S python-pipx pandoc-cli typst texlive # Arch
164
176
 
165
177
  On any Linux, `pdfmd --install full` (Pandoc and Typst) needs no package manager and no root.
166
178
 
179
+ The extras that are Python packages (`pdfmd --install math`, `tui`, `translit`, `batchocr` ...) go into the Python pdfmd runs
180
+ from; when that Python is managed by the system (Homebrew's, Debian's: "externally-managed-environment", PEP 668) pdfmd puts
181
+ them in its own folder instead, `~/.local/share/pdfmd/python/3.14` (one per Python version), which it adds to the end of
182
+ the module path when it starts. Nothing is installed into the system's Python.
183
+
167
184
  ```powershell
168
185
  py -m pip install --user pipx; py -m pipx ensurepath # Windows
169
186
  winget install --id JohnMacFarlane.Pandoc; winget install --id Typst.Typst
@@ -210,12 +227,27 @@ OK 7. weasyprint (/opt/homebrew/bin/weasyprint)
210
227
  MISS 8. wkhtmltopdf
211
228
  ...
212
229
  OK 14. soffice (/Applications/LibreOffice.app/Contents/MacOS/soffice)
230
+ OK calibre (only when named: -e calibre) (/opt/homebrew/bin/ebook-convert)
213
231
  OK quarto (only needed for .qmd files) (/usr/local/bin/quarto)
214
232
  ```
215
233
 
216
234
  The numbers are the fallback order, and also shortcuts: `-e 6` means
217
235
  `-e typst`.
218
236
 
237
+ **An order of your own.** `-e` takes a comma list, tried in the order written and nothing else:
238
+ `-e typst,calibre,lualatex` tries Typst, then Calibre, then LuaLaTeX. A word is an engine (or its alias), a family
239
+ (`tex`, `html`, `typst`: its installed members, in place) or `pandoc` (every engine Pandoc drives; never Calibre). A word
240
+ whose engine is not installed is passed over with a NOTE while another one of the list can run, and the build stops only
241
+ when none can. `pdf-engine:` in `pdfmd-options`, the front matter, a metadata file or the config takes the same list
242
+ (`pdf-engine: [typst, lualatex]`). Without `-e` the chain is the numbered one above, unchanged.
243
+
244
+ `-e calibre` prints the document with [Calibre](https://calibre-ebook.com)'s `ebook-convert`
245
+ instead: Pandoc writes one HTML page (math as MathML, which Calibre draws with its own
246
+ MathJax) and Calibre turns it into a PDF with the document's paper, margins, `fontsize:` and
247
+ language, page numbers, and bookmarks from the headings. LaTeX in the document is made native
248
+ or drawn as a picture, as for a Word file. Calibre is never tried on its own: only when you
249
+ name it (`-e calibre`, or `pdf-engine: calibre` in `pdfmd-options:`).
250
+
219
251
  For everything at once, `pdfmd --doctor` is one page on the Markdown-to-PDF tools, fonts
220
252
  and emoji, PDF reading (batchocr, Tesseract, Poppler, OCR languages), your config file and
221
253
  the cache, ending with the command that fixes each missing piece:
@@ -233,6 +265,21 @@ MISS poppler: not found
233
265
  brew install tesseract poppler
234
266
  ```
235
267
 
268
+ "Installed" is not "works": a LaTeX engine can be on the PATH and still fail on a missing package or font.
269
+ `pdfmd --doctor --deep` also builds a small page (maths, code, a table) with every engine it found, by running pdfmd
270
+ itself in a scratch folder, and says which one built it and how long that took, or why it could not:
271
+
272
+ ```console
273
+ $ pdfmd --doctor --deep
274
+ ...
275
+ Smoke test (a small page with maths, code and a table, built with each engine):
276
+ OK lualatex: built a PDF in 8.7 s
277
+ MISS xelatex: could not build it (! LaTeX Error: File `stix2.sty' not found.)
278
+ OK typst: built a PDF in 1.1 s
279
+ ```
280
+
281
+ It takes a few seconds per engine (a minute or more if TeX has to fetch packages); without `--deep` nothing is built.
282
+
236
283
  ### Tab completion
237
284
 
238
285
  `pdfmd --completion bash|zsh|fish` prints a completion script, generated from the command
@@ -248,7 +295,7 @@ pdfmd --completion fish > ~/.config/fish/completions/pdfmd.fish
248
295
 
249
296
  The oldest Pandoc `pdfmd` is tested with is **3.1.3** (what the claude.ai sandbox has); the whole test suite runs against
250
297
  it. An older one may work, and the first build with it says so once; `pdfmd --doctor` lists what a given Pandoc does
251
- without. With 3.1.3: Typst PDFs cannot show a picture `pdfmd` drew itself (before 3.2), a numbered equation in a Word file
298
+ without. With 3.1.3: a numbered equation in a Word file
252
299
  sits in a plain table instead of a borderless one (before 3.4), and `--extract-tables` leaves a table whose caption has
253
300
  a `{#tbl:id}` (before 3.8.2: Pandoc reads that as words, so the change could not be checked). A `pandoc-crossref` must be
254
301
  the release built for the Pandoc you run; one built for another is not run, with a warning, because it would put `??` where
@@ -276,7 +323,7 @@ $ pdfmd notes.md
276
323
  NOTE Pandoc was not found: building with the built-in renderer (inkmd). The output is plain ...
277
324
  NATIVE notes.md via inkmd
278
325
  WARN native (inkmd): notes.md: 2 math expression(s) set as plain text (Unicode, sub/superscripts, display math centred); ...
279
- OK notes.md
326
+ OK notes.md > notes.pdf
280
327
  ```
281
328
 
282
329
  - **[inkmd](https://github.com/eagredev/inkmd)**, written by Dylan Moir (MIT
@@ -299,6 +346,9 @@ OK notes.md
299
346
  where the built-in renderer and every engine that can draw colour emoji
300
347
  (Typst) find it; without it emoji print as `[rocket]`-style labels in the
301
348
  built-in renderer.
349
+ - `pdfmd --install math:mathjax` (MathJax 4 and its STIX Two math font, about 12 MB to download, about 2 MB on
350
+ disk) and `pdfmd --install math:katex` (KaTeX, about 1.5 MB) are for WeasyPrint's PDFs, not the built-in
351
+ renderer: they typeset its math (see "WeasyPrint does not typeset math itself" below).
302
352
  - `pdfmd --install full` leaves the fallback behind: it installs **Pandoc** (the
303
353
  real binary from PyPI's `pypandoc_binary`, about 35 MB, also `--install pandoc`
304
354
  / `pdfmd-cli[pandoc]`) and **Typst** (Typst's own release from GitHub, about
@@ -309,7 +359,8 @@ OK notes.md
309
359
 
310
360
  Every input is treated as GitHub-flavoured Markdown. Pandoc-only syntax is
311
361
  converted where possible (`\newpage` and `<!-- pagebreak -->` become a page
312
- break, footnotes become endnotes for inkmd, `$` prices are not mistaken for math)
362
+ break, as they do through Pandoc with `pagebreak:`, see *Page breaks in every
363
+ format*; footnotes become endnotes for inkmd, `$` prices are not mistaken for math)
313
364
  and removed otherwise (heading and image attributes, `:::` divs, raw LaTeX,
314
365
  `<!-- comments -->`), with one warning per kind. CSV tables
315
366
  (`::: {.csv file="data.csv"}`) work as they do with Pandoc. The title, author and date in the
@@ -368,6 +419,39 @@ letters, no tones, vowels left out where the script leaves them out. Names that
368
419
  romanize alike (homophones) are listed as ambiguous, never picked between. The
369
420
  same spelling rules find a section by its heading (`doc#tyche`).
370
421
 
422
+ ### Check a document before you build it
423
+
424
+ ```sh
425
+ pdfmd report --check # read report.md (a scaffold and its parts too) and list what is wrong; builds nothing
426
+ pdfmd a.md b.md --check # several files, one report each
427
+ pdfmd report --check --strict # warnings fail too (exit 1), for CI
428
+ pdfmd report --check --check-ignore heading-jump,link-missing
429
+ ```
430
+
431
+ `--check` reads the source, with no Pandoc and no LaTeX, and prints compiler-style lines
432
+ (`report.md:12: error: image not found: figs/a.png [image-missing]`) that an editor can jump to, then
433
+ `CHECK report.md: 1 error(s), 2 warning(s)`. It exits 1 on an error, and on a warning too with `--strict`. It finds:
434
+
435
+ | check | |
436
+ |---|---|
437
+ | `image-missing`, `file-missing`, `link-missing` | an image (`![](..)`, `<img>`, `\includegraphics`), a `file=` of a `.csv` div or a link to a local file that is not there |
438
+ | `anchor-missing` | `[x](#methods)` with no heading or `{#id}` of that name (the ids Pandoc and GitHub make from a heading count) |
439
+ | `id-duplicate`, `crossref-missing`, `ref-missing` | the same `{#id}` twice; a `@fig:x`, `@tbl:x`, `@eq:x`, `@sec:x`, `@lst:x` or `\ref{x}` nothing defines |
440
+ | `cite-missing`, `cite-no-bibliography`, `bibliography-missing` | a `@key` the `.bib`, CSL JSON or `references:` lacks (with a "did you mean"), citations with no bibliography set, a bibliography file that is missing |
441
+ | `footnote-missing`, `footnote-unused` | `[^1]` with no text, a `[^1]:` nobody uses |
442
+ | `heading-jump`, `heading-space`, `heading-empty` | `#` then `###`; `#Heading` (a paragraph); a heading with no text |
443
+ | `fence-open`, `comment-open`, `div-open`, `div-stray`, `math-open` | a code fence, `<!--`, `:::` div or `$$` that is never closed, or a stray `:::` |
444
+ | `front-matter`, `front-matter-duplicate` | YAML that does not parse (with its line) or never closes; a key set twice |
445
+
446
+ Code, comments, math and URLs are not read, so `@decorator` in a code block or `me@x.org` is not a citation. A
447
+ document in parts is checked as one: a link to `#methods` in the scaffold is found in a part. A file with no front
448
+ matter is taken for a fragment and its citations are not held against a missing bibliography, and neither are those of
449
+ a document with a Lua filter or `citation-engine` (something else may do the citing). A part checked on its own cannot
450
+ see the other parts' labels, so check the scaffold, not a part, to judge links across parts.
451
+ Leave a check out for the project with `pdfmd-options: {check-ignore: [heading-jump]}` (a document, a metadata file or
452
+ the config), or on one line with `<!-- pdfmd-check: ignore image-missing -->` on it or on the line above. `pdfmd --check`
453
+ is for Markdown; the build's own `WARN` and `--strict` still catch what only a build can see.
454
+
371
455
  ### A small editor
372
456
 
373
457
  ```sh
@@ -381,15 +465,74 @@ Ctrl-G go to a line, Ctrl-K / Ctrl-U cut and paste a line, Ctrl-Z / Ctrl-Y undo
381
465
  when there are unsaved changes); F1 lists them. Options given beside it (`pdfmd --edit lecture -e lualatex`) are used
382
466
  for the build, and a name that does not exist yet starts a new file. It is deliberately rough: a base for what comes later.
383
467
 
468
+ **Edit a PDF in place.** A PDF that carries its source (`--attach-source`; `pdfmd --check-source` says which do) can be
469
+ edited and rebuilt where it lies:
470
+
471
+ ```sh
472
+ pdfmd --edit report.pdf # the built-in editor, on the source as one file in a temporary folder
473
+ pdfmd --edit report.pdf --editor "code --wait" # your own: the folder is watched and rebuilt on every save
474
+ ```
475
+
476
+ A document is edited as the ONE file its source is: the text with its metadata, preamble, bibliography and style, and the `.tex`
477
+ and CSV files it reads, as blocks after the text (`<!-- pdfmd-at: ... -->` comments say on which line each one is); only what
478
+ is not text (your package, pictures, files in sibling folders) is beside it. You edit that file; Ctrl-B (or each save with
479
+ `--editor`) builds it, and when you leave, `report.pdf` is replaced by the rebuilt one, which carries the source again, and
480
+ the old one is kept in `.backups/` beside it. Before it is replaced pdfmd checks that the rebuilt PDF still carries its source
481
+ and everything the old one carried; a PDF without its source is refused (yours stays as it was), and what is missing is named.
482
+ The temporary folder is removed when you leave. For the files it was made from, `pdfmd --restore report.pdf` (or `--unpack`). Nothing
483
+ changes when you leave without editing, or when the last version does not build. The options of the first build are the
484
+ ones the document and its metadata record; the command-line ones are the ones you give now, and the global metadata of
485
+ `pdfmd --setup` is this machine's (a rebuild on another one can differ). A book built with `-r` is edited as a book: your editor gets every
486
+ chapter file and each save rebuilds all of them in the order the book was built (the built-in editor opens the first chapter and names the
487
+ others). `--editor CMD` also works on a Markdown file
488
+ (a watch that rebuilds on every save, until the editor closes), and `pdfmd --setup` keeps a default editor.
489
+
384
490
  ### In VS Code
385
491
 
386
- `pdfmd --init-vscode` writes a `.vscode/tasks.json` here (build, build and open, watch, extract tables; Terminal > Run
492
+ `pdfmd --init-vscode` writes a `.vscode/tasks.json` here (build, build and open, watch, check, extract tables; Terminal > Run
387
493
  Build Task). The [`vscode/`](https://github.com/aliperdehan/pdfmd/tree/main/vscode) folder of the repository is a small
388
494
  extension over the same command line: build (`Cmd/Ctrl+Alt+B`), build and open, build as Word/HTML/Typst/slides, extract
389
495
  tables (all, or chosen ones), file history, compare and restore, restore the source a PDF carries (right-click it). Every
390
496
  command it runs is written to the *pdfmd* output panel. Install it with `npx @vscode/vsce package` and
391
497
  `code --install-extension pdfmd-vscode-*.vsix`.
392
498
 
499
+ ### A size budget for images and output
500
+
501
+ ```sh
502
+ pdfmd report --max-asset-mb 5 --max-output-mb 20 # warn about an image over 5 MB and an output over 20 MB
503
+ pdfmd report --check --max-asset-mb 5 # list the images over 5 MB (asset-large), nothing is built
504
+ ```
505
+
506
+ ```yaml
507
+ pdfmd-options:
508
+ max-asset-mb: 5 # one image or data file
509
+ max-output-mb: 20 # the file that is made (a mail server's limit, a course site's upload limit)
510
+ ```
511
+
512
+ There is no budget unless one is set. With one, a build says which image is over it before it starts
513
+ (`WARN report.md: figs/scan.png is 14.2 MB, over the 5 MB asset budget`) and, when the file made is over the output
514
+ budget, names it and the three largest images behind it. They are `WARN` lines, so `--strict` fails them. `--max-asset-mb 0`
515
+ switches a document's budget off for one run.
516
+
517
+ ### Start from a template
518
+
519
+ ```sh
520
+ pdfmd --init # the templates: article, report, notes, slides, book, and yours
521
+ pdfmd --init article my-paper # my-paper/my-paper.md + refs.bib, title, author and date filled in
522
+ pdfmd --init report . # into this folder, if none of its files exist yet
523
+ pdfmd --init notes week3 -V author="A. Author" -V title="Week 3"
524
+ ```
525
+
526
+ Each template builds as it is (they are checked with `--check --strict` and built in the tests): an `article` with an
527
+ abstract, an equation, a table and a citation with its `.bib`; a `report` with a contents page, numbered sections and a
528
+ table read from a CSV file; `notes` (headings, math, a code block); `slides` (build with `-p`); and a `book`, a scaffold
529
+ with its chapters in `parts/`. The title comes from the name, the author from `-V author=` or `git config user.name`.
530
+ Nothing that exists is overwritten: pdfmd names the files in the way and writes nothing. Your own templates are a
531
+ folder (or a single `.md` file) in the `templates/` folder of pdfmd's config folder (`pdfmd --init` shows where), or any
532
+ folder or `.md` file named by its path. In their files and file names `{{name}}`, `{{title}}`, `{{author}}`, `{{date}}`
533
+ and `{{year}}` are replaced (`__name__.md` becomes `my-paper.md`); any other `{{...}}` stays as written. A
534
+ `description.txt` (one line, for the list) and a `next.txt` (what to type next) in a template folder are not copied.
535
+
393
536
  ### One section
394
537
 
395
538
  `pdfmd doc#onlyapart` builds just the section whose heading is "Only a Part"
@@ -417,6 +560,113 @@ pdfmd lecture --to typst -o lecture.typ
417
560
  pdfmd lecture -o lecture.tex # a complete, compilable .tex, not a fragment
418
561
  ```
419
562
 
563
+ ### Plain Markdown: `--to gfm`
564
+
565
+ ```sh
566
+ pdfmd report --to gfm # report.gfm.md, beside report.md, never over it
567
+ pdfmd report --to gfm -o README.md
568
+ pdfmd report --to gfm+raw # Pandoc's own gfm writer, with its HTML, as it was
569
+ ```
570
+
571
+ `--to gfm` writes Markdown that any viewer shows as it is (GitHub, VS Code, Obsidian, a chat window): no HTML, no
572
+ `{#id .class}` braces, no Pandoc-only syntax. pdfmd runs everything it runs for any other target first (includes, parts,
573
+ `::: {.csv}` tables, pandoc-crossref, citations, your filters), then flattens what is left:
574
+
575
+ - the title block is written (`# Title`, an `*Author, Author — date*` line, the abstract), since the front matter is not;
576
+ - a table caption becomes `**Table 1.** text` above the table, a figure caption the same below the figure (the label
577
+ is split at the number pandoc-crossref wrote, in any language); `{#tbl:x}` and `{#fig:x}` are gone;
578
+ - `<div>`, `<span>`, `<figure>` and the bibliography's wrappers are unwrapped; section numbers (`number-sections`) are
579
+ written into the headings; a link to a heading points at the anchor GitHub gives it, a link to a vanished id is text;
580
+ - subscripts and superscripts are Unicode where every character has one (`H₂O`, `x²`, `CO₃²⁻`) and `_(..)` / `^(..)`
581
+ where not (`--gfm-scripts unicode`, the default; `html` keeps `<sub>`, `drop` writes the plain text, `ascii` always
582
+ writes `_2`, `^(q+z)`); math stays `$..$` and `$$..$$` (`--gfm-math fenced` writes ```` ```math ````);
583
+ - raw HTML and raw LaTeX are read into Markdown (`<b>x</b>` becomes `**x**`, `\textbf{x}` too); a raw Typst piece, a LaTeX
584
+ picture (`tikzpicture`, `\chemfig`, drawn with your preamble), a PDF image and an `<img src="x.pdf">` become SVG files in
585
+ `<name>_files/` beside the output, linked relatively;
586
+ - definition lists become a bold term and a paragraph; a table Markdown cannot hold (spans, several header rows, block
587
+ cells) is written as an HTML table, the one piece of HTML that stays, and counted in a `NOTE`;
588
+ - what no Markdown can carry (Word XML, a LaTeX macro nothing read) is left out, and a `WARN` counts it and shows the
589
+ first.
590
+
591
+ ```yaml
592
+ pdfmd-options:
593
+ gfm: {scripts: unicode, math: dollars, title: true}
594
+ ```
595
+
596
+ `-o notes.gfm.md` is `--to gfm` (it is also the name a flat file gets by default from `notes.md`); `-o notes.md` alone still means Pandoc's Markdown, so name the target (`--to gfm -o notes.md`) to get the flat one under that name. The paragraphs are single lines (`--wrap=none`; pass `--wrap=auto` to Pandoc to change it). Image links stay as the document wrote them, relative to the document's folder (a `NOTE` says so when the output is written elsewhere). The result is meant to be
597
+ final: what the flattening removes (ids, cross-reference numbers become text, citations become text) is not recoverable
598
+ from it.
599
+
600
+ #### The flat file that carries its source: `--keep-source`
601
+
602
+ Flattening cannot be undone (ids, cross-reference numbers, citations and scripts are text now). So a Markdown output
603
+ can end with its whole source in one HTML comment, the same set of files `--attach-source` puts into a PDF (the
604
+ assembled Markdown, a manifest of the layout, the `.csv` data), and `--restore` writes them back:
605
+
606
+ ```sh
607
+ pdfmd report --to gfm --keep-source # report.gfm.md ends with the source, compressed (packed)
608
+ pdfmd report --to gfm --keep-source readable # the same, as escaped text you can read and diff
609
+ pdfmd --restore report.gfm.md --list # what it carries
610
+ pdfmd --restore report.gfm.md # writes report.gfm.restored/ (never overwrites anything)
611
+ ```
612
+
613
+ ```yaml
614
+ pdfmd-options:
615
+ keep-source: true # or readable; --no-keep-source turns it off for a run
616
+ ```
617
+
618
+ Nothing in the source can close the comment early: `packed` is base64 of the compressed source (no `-`, `<` or `>`
619
+ in it), `readable` escapes every `>` (so no `-->` or `--!>`), a backslash, a carriage return and a line-initial `<` or `=`,
620
+ and undoes it exactly. A source with `<!-- a <!-- b --> c -->`, `-->` in a code block, CRLF line endings or the marker
621
+ itself comes back byte for byte. The comment also stores a hash of the Markdown above it, so `--restore` can tell
622
+ you the file was edited since. Comments are stripped from the kept copy unless `strip-comments` says otherwise (as for
623
+ `--attach-source`); a whole build keeps its source, a part or a section built alone does not; a kept source over 1 MB
624
+ gets a warning, since GitHub stops showing a Markdown file that large. It works for every Markdown output: `--to gfm`,
625
+ `gfm+raw`, `markdown`, `commonmark`.
626
+
627
+ ### Plain text: `--to txt`
628
+
629
+ ```sh
630
+ pdfmd report --to txt # report.txt; the same as -o report.txt
631
+ pdfmd report --to txt --columns=100 # Pandoc's wrapping, 72 columns unless you say otherwise
632
+ pdfmd report --to plain # Pandoc's own plain writer, as it was
633
+ ```
634
+
635
+ `--to txt` is the flat build of `--to gfm` written by Pandoc's plain writer: includes, parts, `::: {.csv}` tables,
636
+ pandoc-crossref, citations, raw HTML and LaTeX and your filters all run first. What a text file shows: the title, the
637
+ author line and the abstract, then headings underlined with `=` (level 1) and `-` (level 2) and numbered when the
638
+ document numbers its sections; `Table 1. caption` above a table and `[Figure 1. caption]` for a figure; a link as
639
+ `words <https://address>` (just the words when they are the address, or the link points into the document); no `**` or
640
+ `_`; Unicode sub/superscripts (`H₂O`, `x²`, else `_(..)` / `^(..)`; `--gfm-scripts drop` or `ascii` change that, `html`
641
+ means `unicode` here); math as Pandoc's plain writer sets it (`E = mc²`). A picture cannot be shown: its caption stands
642
+ for it, and a Typst or LaTeX picture piece is left out with a `WARN`. `pdfmd-options: {txt: {scripts: unicode, title:
643
+ true}}` holds the settings. Until 3.26.7 `--to txt` and `-o x.txt` meant Pandoc's own plain writer; that is `--to plain`.
644
+
645
+ ### ASCII only: `--to ascii`
646
+
647
+ ```sh
648
+ pdfmd report --to ascii # report.ascii.txt: no byte above 127
649
+ pdfmd report --to ascii:gfm # report.ascii.gfm.md (also ascii:markdown, commonmark, rst, org, asciidoc, plain)
650
+ pdfmd report -o notes.ascii.txt # the name asks for it, as notes.gfm.md asks for --to gfm
651
+ pdfmd report -o notes.ascii.rst # any text ending after .ascii: .gfm.md, .md, .rst, .org, .adoc
652
+ pdfmd report --to ascii --ascii-missing escape # what has no ASCII form: \u65e5 instead of ?
653
+ ```
654
+
655
+ For a terminal, an old mail gateway, a legacy system. The build is that of the format after the colon (`txt` when there
656
+ is none), with the words mapped to ASCII before the writer sees them, so the writer escapes what the new spelling needs:
657
+ a `−` at the start of a line that becomes `-` is written `\-`, not taken for a list; a table's columns are measured on the
658
+ ASCII text. What is mapped, in this order: punctuation and spaces (curly quotes, `—` as `--`, `…` as `...`, no-break
659
+ spaces, soft hyphens), symbols (`≤` `<=`, `±` `+/-`, `→` `->`, `°` `deg`, `½` `1/2`, `©` `(c)`), Greek letters by name
660
+ (`α` `alpha`, `Δ` `Delta`, `μm` `um`; a Greek word is spelt: `Σοφία` `Sophia`), Cyrillic with its case (`Привет`
661
+ `Privet`), accents (`é` `e`, `ß` `ss`, `ł` `l`), subscripts and superscripts (`H_2O`, `x^2`, `CO_3^(2-)`; `--gfm-scripts
662
+ drop` writes `H2O`), then the romanization packs for Hebrew, Arabic, Armenian, Georgian, Korean and Japanese kana, and
663
+ Chinese and the rest when `pypinyin` or `anyascii` is installed (`pdfmd --install translit`). Math stays TeX, with macros
664
+ (`$\alpha \geq 2$`); a link's address is percent-encoded (`%C3%A9`), not spelt. A character with no ASCII form is
665
+ counted and named in a `WARN`, and written as `?` (`--ascii-missing question`, the default), as `\uXXXX` (`escape`), as
666
+ nothing (`drop`), or the file is not written at all (`fail`); `pdfmd-options: {ascii: {missing: escape}}` sets it per
667
+ document. `--keep-source` on an ASCII file keeps the source packed (the readable form would be Unicode). It applies to text
668
+ formats only: `--to ascii:docx` is refused.
669
+
420
670
  ### Word and OpenDocument output
421
671
 
422
672
  Plain Pandoc ignores `papersize`, `geometry`, `mainfont` and `fontsize` when it writes `.docx`
@@ -468,6 +718,13 @@ office:
468
718
  reference-doc: house.dotx
469
719
  ```
470
720
 
721
+ The same file can list `lua:` (Lua filters beside the document besides `<package>.lua`, which a document that loads the
722
+ package gets by name anyway), `draft-skip:` (`commands:` that take one argument and `spans:` of a start macro up to its stop
723
+ macro, which the label scan's draft pass need not draw, as it skips `chemfig`) and `picture-cache:` (the macro names and the
724
+ request-file suffix a package used for the picture cache before the protocol had neutral names, see "For a package author").
725
+ pdfmd names no package: all of this is found by reading the packages a document loads, in its preamble files or its
726
+ `header-includes:`.
727
+
471
728
  ```yaml
472
729
  pdfmd-options:
473
730
  office:
@@ -482,14 +739,20 @@ pdfmd-options:
482
739
  **LaTeX in the document.** Pandoc turns `$x^2$` into a Word equation and drops everything else of
483
740
  LaTeX. For `.docx` and `.odt` pdfmd adds a filter that makes it native where it can:
484
741
 
485
- - `\ce{Ag+(aq) + Cl-(aq) -> AgCl(s)}` (mhchem) and `\si{\gram\per\mole}`, `\SI{5}{\milli\liter}`,
742
+ - `\ce{Ag+(aq) + Cl-(aq) -> AgCl(s)}` (mhchem) and `\si{\gram\per\mole}`, `\qty{5}{\mL}`,
486
743
  `\num{1.5e-3}` (siunitx) become formatted text with real subscripts, charges and units, and, inside
487
- math, Word equation pieces;
744
+ math, Word equation pieces. `\ce` is read by a port of mhchem's own parser, so it comes out as LaTeX sets it;
745
+ siunitx follows your `\sisetup`, `\DeclareSIUnit`s and unit shortcuts, those of your own packages too. A
746
+ formula with words over its arrow is an equation;
747
+ the same in an HTML, EPUB, Markdown, text or Typst file and a PowerPoint deck, whose writers would drop them;
488
748
  - `\begin{equation}`, `align`, `reaction`... become Word equations with their number at the right;
489
749
  - raw `figure`, `tabular`, lists, `\emph`, `\newpage`... are read by Pandoc's own LaTeX reader;
490
750
  - `\ref`, `\eqref`, `\cref`, `\Cref`, `\pageref` and the "Figure 3." in front of a caption use the numbers
491
751
  LaTeX itself gave (pdfmd builds the PDF once, in its cache, and reads the `.aux`; reused while the sources
492
- are older), with the caption separator (`labelsep=`) and `\crefname`s of your preamble;
752
+ are older), with the caption separator (`labelsep=`) and `\crefname`s of your preamble. Each reference is a link
753
+ to what it names. A `\label` in a caption, in a block drawn as a picture or on any line of an equation becomes a
754
+ bookmark there. In OpenDocument a labelled table, figure or div, and a citation's entry in the references, get one
755
+ too, since its writer bookmarks none of them;
493
756
  - **what is left is drawn by LaTeX**: tikz, chemfig, a house style's own macros, math Pandoc cannot convert are compiled in
494
757
  *your document's own preamble* (the same fonts, packages and macros as the PDF, one fragment to a page), and the
495
758
  pages go into the Word file as vector pictures: an SVG with a 300 dpi PNG fallback (Word 2016 and later draw the SVG,
@@ -518,9 +781,10 @@ quick way to see what is left to give a recipe (see the profile below).
518
781
  (Pandoc's own behaviour). `office: {labels: off}` skips the PDF build (numbers are then counted).
519
782
 
520
783
  The same filter serves the other outputs when LaTeX is the problem: **the soffice fallback** (the Word file above, then LibreOffice: `pdfmd -e soffice report.md` is the `.docx` as LibreOffice draws it) now
521
- keeps the page size, margins and fonts, shows equations and draws what LaTeX can; a **Typst or WeasyPrint run after LaTeX
522
- failed** gets what the document says in LaTeX as native text or pictures instead of nothing; and HTML, Typst and
523
- WeasyPrint builds do it on request (`pdfmd-options: {office: {latex: auto}}`).
784
+ keeps the page size, margins and fonts, shows equations and draws what LaTeX can. A **Typst or WeasyPrint PDF** (named
785
+ with `-e`, or after LaTeX failed) gets what the document says in LaTeX as native text or pictures instead of nothing,
786
+ whenever it has LaTeX they would drop; `raw: {typst: [typst]}` (or `office: {latex: off}`) keeps Pandoc's own behaviour.
787
+ HTML and Typst *files* (`-o x.html`, `--to typst`) do it on request (`pdfmd-options: {office: {latex: auto}}`).
524
788
 
525
789
  ### Stopping part-way
526
790
 
@@ -543,6 +807,7 @@ them beside it. What the text points at otherwise (images, files a preamble
543
807
  the assembled file.
544
808
 
545
809
  ```sh
810
+ pdfmd report --merge # everything: one file that builds alone, anywhere
546
811
  pdfmd report --assemble-only --embed-metadata # metadata.yaml, preamble.tex, Lua filters, .bib/.csl
547
812
  pdfmd report --assemble-only --embed-metadata metadata preamble # only those
548
813
  pdfmd report --assemble-only --embed-metadata --lua-mode ref # name the filter instead of copying it
@@ -598,22 +863,36 @@ file you can edit again. Ask for it, on the command line or in the document:
598
863
 
599
864
  ```sh
600
865
  pdfmd report --attach-source # the source goes into report.pdf as an attachment
601
- pdfmd report --bundle # ... and the data and files its LaTeX reads
866
+ pdfmd report --bundle # ... and the image files too (the data and LaTeX inputs are carried anyway)
602
867
  pdfmd --restore report.pdf # write the folder back into report.restored/
868
+ pdfmd --check-source # which PDFs in this folder carry their source (a file or folder works too)
603
869
  ```
604
870
 
871
+ ```console
872
+ $ pdfmd --check-source
873
+ NONE WA1.pdf no WA1.md beside it
874
+ SOURCE WA3.pdf WA3.md, 52 lines, pdfmd 3.28.22
875
+ NONE WA5.pdf WA5.md is beside it: pdfmd WA5.md --attach-source
876
+ CHECK 3 PDFs: 1 with the source, 2 without
877
+ ```
878
+
879
+ `--check-source` (alias `--sources`) only reads the attachment list, so it is quick on a whole folder; it notes a
880
+ Markdown file beside the PDF that is newer than the build, and exits 1 when a PDF has no source.
881
+
605
882
  ```yaml
606
883
  pdfmd-options:
607
884
  attach-source: true # alias: embed-source
608
- bundle: true # or `all`: the whole folder, not just what the text points at
885
+ bundle: sources # the default: the files the text reads, no images
886
+ # `true`: and the images · `all`: the whole folder · `false`: the source alone
609
887
  bundle-packages: true # also your own LaTeX packages (see below)
610
888
  strip-comments: true # the default for the attached copy; see "Comments"
611
889
  attach-bibliography: used # or `all`
890
+ attach-csl: false # the default: the citation style is named, not attached (see below)
612
891
  ```
613
892
 
614
893
  Put these in the shared metadata file and every document that finds it carries
615
894
  its source. The attachment is the assembled Markdown with the metadata,
616
- preamble, Lua filters, bibliography and CSL style folded in (the file
895
+ preamble, Lua filters and bibliography folded in, and the CSL style too when `attach-csl: true` (the file
617
896
  `--assemble-only --embed-metadata` writes), plus a manifest of the original
618
897
  layout, so `--restore` gives back `report.md`, `metadata/`, `parts/` and the rest
619
898
  where they were, each as a standalone file (a symlinked metadata file or
@@ -626,17 +905,41 @@ style, a compound library, a shared bibliography and parts.
626
905
  a plain attach needs no bundle for them: a JPEG comes back byte for byte, a PNG
627
906
  as the same pixels (alpha kept), and an SVG or PDF figure as a vector PDF
628
907
  (`fig.svg` becomes `fig.pdf`, and the restored Markdown follows).
629
- - **`--bundle` is for what the PDF does not draw:** CSV data, LaTeX included
630
- with `\input`, listings. They are stored as separate attachments (`files/...`),
631
- found from the text, the preamble and, in turn, from the files found; also
632
- those only your own TeX tree resolves (`\input{library}` from `texmf-home`).
633
- `--bundle all` takes the whole folder except output and housekeeping. Over
634
- 100 MB (`bundle-max-mb`) only the source is attached. Data whose file name a
635
- macro builds cannot be found: use `all`.
908
+ - **The files the text reads travel with it.** CSV data, LaTeX included with `\input`, listings: stored as
909
+ separate attachments (`files/...`), found from the text, the preamble and, in turn, from the files found;
910
+ also those only your own TeX tree resolves (`\input{library}` from `texmf-home`). A restored report builds
911
+ again; only images are left out (the PDF has them). Over 100 MB (`bundle-max-mb`) only the source is
912
+ attached. `bundle: false` (or `--no-bundle`) keeps the source alone; `--bundle` (`bundle: true`) stores the
913
+ image files too, `--bundle all` the whole folder except output and housekeeping. Data whose file name a
914
+ macro builds cannot be found: use `all`. A Markdown output (`--keep-source`) has no PDF to take pictures
915
+ from and keeps the source alone unless you ask.
916
+ - **`--restore` and `--unpack` stay short.** They count what they write by folder; `--verbose` lists every
917
+ file, and `--restore --list` always does.
636
918
  - **Your own LaTeX packages** (a house style in `texmf-home`) are recorded with
637
919
  their version, and `--restore` tells you what is missing; `--bundle-packages`
638
- stores them too (with what they `\input` and the graphics they name).
639
- The TeX distribution's own packages, fonts and Pandoc are not carried.
920
+ stores them too: the style file, the `<package>-pdfmd.yaml` beside it (what the package tells pdfmd: its
921
+ title-page keys, its picture-cache names), what it `\input`s and the graphics it hands to `\includegraphics`
922
+ (a logo named by `\newcommand{\LogoFile}{logo}`, not every word that happens to be a file's name). A package that sits
923
+ in the document's own folder, as it does in a restored source, is kept when the source is attached again. Together
924
+ with `attach-csl` a report that sets both in its shared metadata rebuilds on a machine with nothing of yours
925
+ installed (checked in an empty home folder). The TeX distribution's own packages, fonts and Pandoc are not carried.
926
+ - **The text files are in the source's text.** The `.tex` files a document reads and its CSV data are blocks of the
927
+ attached `pdfmd-source.md`, after the text (`.tex` first, then the data) and before the bibliography and style at the
928
+ very end, so one file holds everything you edit; the pictures and your package stay separate attachments (and a file
929
+ that is not text, or too big, or whose line ends are mixed). `<!-- pdfmd-at: ... -->` comments say on which line each block is (an index after the front matter and one
930
+ before each part of the text that names a file); pdfmd writes them whenever it writes the source and removes them
931
+ wherever it reads one, so they never reach a build and a restore gives back your text as it was.
932
+ - **Files in sibling folders** (`\input{../schemes/x.tex}`, a CSV in `../ir/`) are stored too, up to two folders above
933
+ the document's (never the home folder or above), as blocks of the text like the rest (their path starts with `..`),
934
+ and `--restore` puts the folder back in the same layout: the document in `<folder>/<its folder's name>/`, the siblings
935
+ beside it. A file with Windows line ends (CRLF all through) is a block with an `eol: crlf` line and comes back byte for
936
+ byte. `pdfmd --edit report.pdf` writes those files where the document reads them before every build, so editing a
937
+ block is editing the file; a build of the source file alone (no `--edit`) never writes outside its own folder and
938
+ says so when a file it reads from there is missing. A bibliography the metadata names by the real
939
+ folder of a symlinked metadata file (a shared `nulab.bib`) is embedded, pruned to the entries the text cites.
940
+ - **A newer source is refused, not half restored.** The manifest has a format number (2 since v3.28.45, when the chain of
941
+ folders, the text files as blocks and the `..` files came in). A pdfmd that reads up to 1 stops with `was made by a
942
+ newer pdfmd (...); upgrade pdfmd to restore it`, and this one restores both 1 and 2.
640
943
  - **Comments.** Notes to yourself do not travel: the attached source loses its
641
944
  `<!-- -->` comments, the LaTeX preamble's `%` comments, the text between a
642
945
  `.bib`'s entries, a CSL file's XML comments and the `#` comments of YAML
@@ -649,9 +952,18 @@ style, a compound library, a shared bibliography and parts.
649
952
  comments and quoting included; `--restore` of such a PDF is a full source
650
953
  copy. The data files of `.csv` blocks (`tables/*.csv`) are always stored
651
954
  with the source.
955
+ - **Your global metadata (`pdfmd --setup`) stays yours.** It counts in the
956
+ source below the document's own files, as in a build, but `--restore` does
957
+ not write it back. It names its keys instead, and a build of the restored
958
+ folder uses the global metadata of the machine it runs on.
652
959
  - **Only the bibliography entries you cite** are attached (and what they
653
960
  cross-reference), not a shared file of hundreds; `attach-bibliography: all`
654
961
  keeps it whole, and `nocite: '@*'` keeps every entry.
962
+ - **The citation style is not attached unless you ask** (`--attach-csl`, `attach-csl: true`, `--embed-metadata csl` for an
963
+ assembled file). A style is 10-90 KB (apa.csl 86 KB, nu-labreport.csl 72 KB, ieee.csl 18 KB) and the global metadata sets
964
+ one for every document, cited or not. A style is only ever attached when the document cites something. Without it the
965
+ manifest records the name and `--restore` says that a build needs a style of that name (Pandoc's own `csl/` folder, or
966
+ beside the document); a house style that exists nowhere else should travel, so set `attach-csl: true` for it.
655
967
  - **It is opt-in, and it is everything you wrote.** An attached source includes
656
968
  what the author would not send in an email; check `--list` before sharing.
657
969
  - `--restore` never overwrites a file and never writes outside its folder. A
@@ -753,9 +1065,9 @@ stamped or backed up unless you ask (`stamp=True`, `backup=True`). A failure rai
753
1065
  `variables=` a dict of Pandoc variables, `extra_args=` anything else the command line takes, `cwd=` the folder it runs
754
1066
  in and `timeout=` seconds.
755
1067
 
756
- ### Other command names: `mdpdf` and `inkmd`
1068
+ ### Other command names: `mdpdf`, `inkmd` and `batchmd`
757
1069
 
758
- pdfmd also installs `mdpdf` and `inkmd` commands that take those tools' own keys
1070
+ pdfmd also installs `mdpdf`, `inkmd` and `batchmd` commands that take those tools' own keys
759
1071
  and do what they did, with pdfmd behind them:
760
1072
 
761
1073
  ```sh
@@ -763,8 +1075,14 @@ mdpdf -o out.pdf -f ",,{page}" -a "Name" -p A4 chapter1.md chapter2.md
763
1075
  inkmd notes.md -o notes.pdf --page-size a4 --family times
764
1076
  cat notes.md | inkmd > notes.pdf # standard input and output, like inkmd
765
1077
  inkmd notes.md -e lualatex # naming another engine uses it instead
1078
+ batchmd ~/notes # every .md in the folder, as pdfmd -b ~/notes
1079
+ batchmd -e inkmd # the current folder, with the built-in renderer
766
1080
  ```
767
1081
 
1082
+ `batchmd` is `pdfmd -b`: each Markdown file in the folder becomes its own PDF beside it.
1083
+ It takes the current folder when you name none (`pdfmd -b` alone refuses), and every
1084
+ other option is pdfmd's.
1085
+
768
1086
  `mdpdf` turns bookmarks and attached links on and combines several inputs into one
769
1087
  PDF. `inkmd` is `pdfmd -e inkmd`; like inkmd it writes the PDF to standard output
770
1088
  when you give `-o -`, or no `-o` while output is piped (at a terminal it writes
@@ -787,16 +1105,17 @@ pdfmd slides -p # Beamer slides; each heading starts a slide
787
1105
 
788
1106
  ```console
789
1107
  $ pdfmd notes -b
790
- AUTO: READER TITLE MARGIN MONOFONT. Use --verbose to see in full
791
- AUTO: MARGIN. Use --verbose to see in full
792
- AUTO: MARGIN. Use --verbose to see in full
793
- OK notes/lecture.md
794
- OK notes/week1.md
795
- OK notes/week2.md
1108
+ DEFAULTS margin 1in, font STIX Two Text, code in JetBrains Mono, title from heading
1109
+ AUTO: READER. Use --verbose to see in full
1110
+ OK notes/lecture.md > lecture.pdf
1111
+ OK notes/week1.md > week1.pdf
1112
+ OK notes/week2.md > week2.pdf
796
1113
  ```
797
1114
 
798
1115
  `-b` converts every `.md` in the folder into its own PDF, in parallel
799
- (`-j N` sets the number of workers). Add `--recursive` to include
1116
+ (`-j N` sets the number of workers). `--bopen SPEC` opens some of the finished files when
1117
+ the batch is done: `f5` the first five, `l5` the last five, `fl10` the first five and the last five, `e3` the third, sixth, ninth ... file, `s3` the first, fourth, seventh ... (Python's `[::3]`),
1118
+ `f2,l3` a mix, or none for all (any number works; the files open in the order the batch lists them). Add `--recursive` to include
800
1119
  subfolders, and `-o DIR` to collect the PDFs somewhere else.
801
1120
 
802
1121
  ### A book or report from several files
@@ -805,7 +1124,7 @@ subfolders, and `-o DIR` to collect the PDFs somewhere else.
805
1124
  $ pdfmd book -r -o book.pdf
806
1125
  OK book/01-intro.md
807
1126
  OK book/02-methods.md
808
- AUTO: MARGIN. Use --verbose to see in full
1127
+ DEFAULTS margin 1in, font STIX Two Text
809
1128
  OK REPORT book.pdf
810
1129
  ```
811
1130
 
@@ -851,7 +1170,36 @@ The parts are joined in filename order into one Pandoc run, so the result is
851
1170
  identical to the same text in a single file: labels, citations and numbering
852
1171
  work across parts, and paths are written relative to the scaffold's folder
853
1172
  whichever part they are in. A part rebuilt alone is much faster to compile
854
- but cannot see the others, so references to them print as `??`. See
1173
+ and still shows the numbers of the others: before it is typeset, pdfmd has
1174
+ Pandoc write the LaTeX of the whole document once more (about a second, no
1175
+ images, no engine), reads which headings, captions, equations and labels it
1176
+ holds, and has LaTeX replay them at the start of the part. A reference to a
1177
+ section, figure, table or equation outside the part then prints its number
1178
+ (`Section 2`, `Equation (3)`, a `\cref` too), in the document's own number style
1179
+ (Roman sections, numbers per chapter), as a link that leads nowhere; the part's
1180
+ own sections, figures and equations continue from the parts before it. What the
1181
+ scan cannot count is whatever the document defines itself (a macro that opens
1182
+ a figure, say): that label stays `??`, and the build says the numbers are
1183
+ approximate. So does a label after a caption in an environment the document
1184
+ defines itself (a table wrapper of a house style): it prints `??`, never the
1185
+ number of the heading before it, and the build says how many there were.
1186
+ `\pageref` is always `??`. The last full build's `.aux` (cache on,
1187
+ below) is exact and is used first; the scan fills in what it does not know.
1188
+ `pdfmd-options: {seed-labels: auto|aux|scan|draft|off}` or `--seed-labels` picks
1189
+ the source (`draft` runs LaTeX once over the whole document without output and
1190
+ without drawing its pictures, TikZ, pgfplots, chemfig and images, for exact
1191
+ numbers at a fraction of a compile, though a page reference into what was left out
1192
+ prints `??`; `--no-auto draftpictures` draws them); `off` brings back the `??`. A section of an ordinary document
1193
+ (`doc#results`) gets the same for the references it makes, but keeps numbering
1194
+ its own headings from 1.
1195
+
1196
+ For HTML, EPUB, Word, OpenDocument, Typst and PDF through an engine that is not LaTeX the
1197
+ same idea works differently: pdfmd hands Pandoc the whole document with each part in a
1198
+ marked div, lets pandoc-crossref number and resolve everything, and then keeps only the
1199
+ part you asked for (`select.lua`). Its headings, figures, tables and equations keep the
1200
+ full document's numbers, and `[@sec:x]`, `[@fig:y]` to the rest resolve (as links that
1201
+ lead nowhere). Raw LaTeX `\ref{..}` is a LaTeX-only reference: use pandoc-crossref's
1202
+ syntax for those writers. See
855
1203
  [`examples/parts/`](https://github.com/aliperdehan/pdfmd/tree/main/examples/parts/).
856
1204
 
857
1205
  #### Faster rebuilds: the cache
@@ -863,15 +1211,32 @@ pdfmd-options:
863
1211
 
864
1212
  keeps LaTeX's cross-reference files between builds (in `~/.cache/pdfmd`), so
865
1213
  an unchanged document is typeset once instead of two or three times, and a
866
- part built on its own shows the real numbers of the parts left out (taken
867
- from the last full build) instead of `??`. It never skips a build: Pandoc and
1214
+ part built on its own shows the exact numbers of the parts left out (taken
1215
+ from the last full build; without the cache they are counted from the
1216
+ sources, above). It never skips a build: Pandoc and
868
1217
  LaTeX still process the whole document from the current sources and package
869
1218
  every time, so a change shows in the next build. `cache: {plots: true}` (or
870
- `--cache-plots`, with nulabreport >= 1.26.0) additionally stores each plot as a
871
- PDF and reuses it until the package, the preamble, the engine or the plot's
872
- data file changes. Off by default; `--no-cache` for one build; `pdfmd --clear-cache`
1219
+ `--cache-plots`; LuaLaTeX) additionally stores each whole picture of a package that takes part
1220
+ (nulabreport's plots and chemical schemes do) as a
1221
+ PDF in the document's cache folder and reuses it (a part built alone uses the whole
1222
+ document's, unless its preamble differs by more than the title) until the package,
1223
+ the preamble, the engine, TeX Live's packages (a `tlmgr update`) or a file the plot
1224
+ read changes (its data file, a file of the package's own: checked by
1225
+ SHA-1 of the contents before every build). Off by default; `--no-cache` for one build; `pdfmd --clear-cache`
873
1226
  (or deleting the folder) is always safe.
874
1227
 
1228
+ *For a package author:* the protocol names no package. A style file that mentions `pdfmdCacheDir` takes part; pdfmd then
1229
+ defines `\pdfmdCacheDir` (the folder, with a trailing slash) and `\pdfmdCacheVersion` (3: the markers below are version 3) before the document. The package looks
1230
+ a picture up by its own key as `<folder>/<key>.pdf` with its size in `<key>.dim` (`\pdfmdCacheWd`, `Ht`, `Dp`), typesets
1231
+ inline on a miss, and appends `<key>@@|@@<macro>@@|@@<arguments>@@|@@<context>` to `<job>.pdfmdreq`. After the build pdfmd
1232
+ runs each request in a standalone job with the same preamble (`\pdfmdCacheRender` defined, so there is no lookup): the
1233
+ context, then `\setbox0\hbox{<macro><arguments>}`; that box is the page. A context may hold `@@plain@@` (what follows is read
1234
+ with ordinary catcodes, not expl3's: settings with spaces in their names), `@@runs=2@@` (typeset twice, for a picture
1235
+ whose arrows point at its own nodes) and `@@margin=56pt@@` (the page is the box plus that on every side, `\pdfmdCacheMargin` in
1236
+ the `.dim`: for ink that overflows its box, which you include shifted back). If the job defines `\pdfmdCachePost` after the
1237
+ box, its text comes back as `\pdfmdCachePostStored` in the `.dim`, for you to run on a hit (a global the picture changes). nulabreport's first names (`\LabPlotCacheDir`, `.plotreq`, `\Lab@pc@wd`) still work as
1238
+ aliases.
1239
+
875
1240
  **Where the cache lives.** By default in `~/.cache/pdfmd`, one folder per document.
876
1241
  Folders get moved (a lab report from Downloads into OneDrive), and a cache keyed by
877
1242
  the old path would be lost: so each cache folder records which document it is, and a
@@ -924,16 +1289,25 @@ Water,18.015,1.20
924
1289
  braces, with the identifier as `#tbl:id` there too. A caption in the attributes wins over a line after the block.
925
1290
  - A relative `file=` is found beside the document (and along the resource path), wherever Pandoc runs. With both
926
1291
  `file=` and data inside the block, the file is used.
927
- - The delimiter is `delimiter=";"` or its name (`semicolon`, `tab`, `pipe`, `space`, `colon`, `comma`); without one it
928
- comes from the extension (`.tsv` means tab) or from the first line (whichever of `,` `;` tab `|` it holds most of).
1292
+ - The delimiter is `delimiter=";"` or its name (`semicolon`, `tab`, `pipe`, `space`, `colon`, `comma`), or
1293
+ `pdfmd-options: {csv: {delimiter: semicolon}}` for every table; without one it is guessed: whichever of `,` `;` tab `|`
1294
+ splits the first lines into the same number of fields (the extension's own, comma or tab for `.tsv`, on a tie). When
1295
+ the guess is not what the file's name says (a `;` file named `.csv`), the build warns and says how to name it.
929
1296
  - Columns are aligned with `align="lcr"` (or `align="left,center,right"`), or by a second row in the data made of
930
1297
  `---`, `:--`, `:-:`, `--:` as in a pipe table; `align=` wins. If such a row is really data, say `separator="none"`.
931
1298
  `widths="5,1,1"` sets relative widths, and a second row with unequal dashes does too. Without either, pdfmd picks
932
1299
  widths that suit the contents.
933
1300
  - The first row is the header unless you add `header="false"`.
934
1301
  - Large files are capped at 10 rows × 7 columns, so a huge CSV can't
935
- silently fill 40 pages. `rows=all` or `cols=20` raise the cap. When a
936
- table is cut, the PDF itself shows a note saying so.
1302
+ silently fill 40 pages. A cut table keeps both ends: the first 7 rows, a row
1303
+ of `…`, the last 3, and the first 5 columns, a `…` column, the last 2 (about
1304
+ any cap keeps its last ⌊√cap⌋: 16 + 4 of 20, 25 + 5 of 30; `cut="head"` or `csv: {cut: head}` keeps the first
1305
+ ones only). `rows=all` or `cols=20` raise the cap. When a table is cut, the
1306
+ build warns and the PDF itself shows a note saying so. For every table of a
1307
+ document: `--csv-rows N|all` / `--csv-cols N|all`, or
1308
+ `pdfmd-options: {csv: {rows: all, cols: 12, cut: ends, delimiter: auto, header: false, reader: gfm}}`
1309
+ (in the front matter, a metadata file, or the config, where `pdfmd --setup`
1310
+ sets rows, columns, the cut and the delimiter); a div's own attributes still win.
937
1311
 
938
1312
  This works for every output format.
939
1313
 
@@ -966,6 +1340,29 @@ line above it (or under its caption); the comment survives comment stripping, be
966
1340
  A comment between a table and its caption would stop Pandoc from reading the caption as one, so there is no such
967
1341
  position.
968
1342
 
1343
+ ### One style sheet for the page: `--css`, `pdfmd.css`, `css-scope`
1344
+
1345
+ A `.css` file styles the writers that read CSS: HTML, EPUB, the PDF the HTML engines make (WeasyPrint and the rest) and
1346
+ Calibre. pdfmd finds `pdfmd.css` or `<name>.css` beside the document (and in its `metadata/` folder; `--no-auto css` turns the
1347
+ search off), takes `css:` from the front matter or a metadata file (Pandoc's own key), `pdfmd-options: {css: file.css}`
1348
+ (a name or a list; `pdfmd --setup` keeps one for every document) and `--css FILE`; they come in that order, the last after the
1349
+ others, as in CSS.
1350
+
1351
+ ```css
1352
+ @page { size: A4; margin: 2cm 2.5cm } /* paper and margins */
1353
+ body { font-family: "STIX Two Text"; font-size: 11pt; line-height: 1.3; text-indent: 1.2em }
1354
+ a { color: #0645AD } /* links */
1355
+ code, pre { font-family: "JetBrains Mono" }
1356
+ ```
1357
+
1358
+ With `css-scope: all` (`pdfmd-options`, or `--css-scope all`; the default is `html`) the sheet is read for the other writers
1359
+ too: those four rules become the paper, margins, font, size, line spacing, indent, link colour and code font that LaTeX,
1360
+ Typst and Word take, **below** what the document, its metadata and the command line set (`--verbose` says
1361
+ "body font-size 11pt -> fontsize=11pt" for each one it used, and names what it did not: headings, tables, anything else).
1362
+ Only rules that say it plainly count: `@page`, `html`/`body`/`:root`, `a`, `code`/`pre`; the last one wins; `@media print`
1363
+ counts as if it stood alone, `@media screen` and any other condition do not; a body size LaTeX has no class for (anything but 10,
1364
+ 11 and 12 pt) is named, not used. It is a small reader on purpose: a CSS cascade has no counterpart in LaTeX.
1365
+
969
1366
  ### Code: wrapping and line numbers
970
1367
 
971
1368
  With a LaTeX engine a long line of code wraps at the margin instead of running off the page (a long path or option list
@@ -995,6 +1392,42 @@ badge works, and a Pandoc built without HTTP support (Homebrew's is) no longer d
995
1392
  warning and the image's description stays. `--no-auto svg` and `--no-auto remoteimages` turn the two off, and
996
1393
  `pdfmd --doctor` says which converter will be used.
997
1394
 
1395
+ ### Diagrams written as code
1396
+
1397
+ ````markdown
1398
+ ```mermaid
1399
+ graph LR; Sample --> Reaction --> Product
1400
+ ```
1401
+
1402
+ ```{.dot #fig:flow caption="The *flow* of the experiment" width=60% engine=neato}
1403
+ digraph { sample -> reaction -> product }
1404
+ ```
1405
+
1406
+ ```d2
1407
+ sample -> reaction -> product
1408
+ ```
1409
+ ````
1410
+
1411
+ A fenced block whose class is `mermaid`, `d2`, `dot` or `graphviz` is drawn by the tool that reads that language and the
1412
+ picture takes its place: [Graphviz](https://graphviz.org) (`dot`), [D2](https://d2lang.com) (`d2`) and
1413
+ [Mermaid](https://github.com/mermaid-js/mermaid-cli) (`mmdc`). pdfmd asks each for the format the output takes: a PDF
1414
+ for LaTeX, an SVG for HTML (inside the file, so it can be sent on its own) and Typst (a PNG for Mermaid, whose SVG
1415
+ Typst cannot show), a PNG for Word and OpenDocument, and for flat Markdown (`--to gfm`) an SVG in the `_files/` folder
1416
+ beside the output, except a Mermaid block, which stays as it is because GitHub draws it. A text output keeps the source.
1417
+ Drawings are kept in the cache by their content, so a rebuild does not draw them again. `caption="..."` makes a figure
1418
+ (`{#fig:id}` with pandoc-crossref numbers it), `width=` sizes it, `engine=` picks the Graphviz layout (`dot`, `neato`,
1419
+ `fdp`, `sfdp`, `circo`, `twopi`), `theme=` the Mermaid theme, `layout=` the D2 layout (`dagre`, `elk`). A tool that is
1420
+ not installed leaves the block as code with one warning (`--strict` makes it an error) and says how to install it;
1421
+ a diagram the tool cannot parse stays as code too, and the warning gives the tool's own words. `pdfmd --install diagram:d2`
1422
+ puts D2's release binary (17 MB, checked against the SHA-256 GitHub lists) in pdfmd's tools folder, and `--install
1423
+ diagram:dot` Graphviz built to WebAssembly (2 MB, run by node, which pdfmd fetches when there is none): it writes only SVG,
1424
+ which pdfmd converts for a PDF or Word picture with `rsvg-convert` or `inkscape` (D2 needs the same), and it sizes labels
1425
+ by Graphviz's own estimate of the font, a couple of percent off the real tool's. A tool of your own on PATH is always the one
1426
+ that runs. `pdfmd --doctor` shows which tools are there, and
1427
+ `--no-auto diagrams` turns the whole thing off. The attributes need Pandoc's Markdown (a file with front matter); a file
1428
+ read as gfm takes the plain ```` ```dot ```` form. Mermaid needs Chrome (mermaid-cli downloads one); in a sandbox
1429
+ `PDFMD_MMDC_CONFIG=puppeteer.json` is handed to `mmdc -p`.
1430
+
998
1431
  ### Editable in LibreOffice, and one file that carries its data
999
1432
 
1000
1433
  `--hybrid` makes the PDF a LibreOffice *hybrid PDF*: besides its pages it carries an OpenDocument copy of the document
@@ -1040,9 +1473,36 @@ vector picture, a PDF for LaTeX, Typst and Word, an SVG for HTML. A syntax a fam
1040
1473
  included, which is odd but a clear way to say "this output has no HTML in it". A family not mentioned is left to Pandoc
1041
1474
  as it always was, `raw: all` lists everything, and `--no-raw` turns it off for a run. Pictures are kept in pdfmd's cache by
1042
1475
  their content. (An HTML file that is not self-contained points at the cache; use `--self-contained` to carry them.)
1043
- Not yet: LaTeX pieces Pandoc cannot read (tikz, chemfig) as pictures in HTML, HTML drawn as a picture, Word XML as
1476
+ A LaTeX picture Pandoc cannot read (a `tikzpicture`, `circuitikz`, `pgfpicture`, `forest`, `\chemfig`...) is drawn by a LaTeX
1477
+ engine with the `standalone` class, after the document's own preamble and `header-includes`, and placed as a vector picture
1478
+ in HTML, Typst and flat Markdown builds (an SVG for HTML and Markdown; a piece that does not compile is reported and left
1479
+ out). Not yet: HTML drawn as a picture, Word XML as
1044
1480
  anything but Word XML.
1045
1481
 
1482
+ **Page breaks in every format.** Each output understands one way of writing a page break and drops the others: LaTeX
1483
+ takes `\newpage`, WeasyPrint a CSS-break `<div>`, Word only its own XML, Typst none of them. Ask for it and every
1484
+ spelling of the families you name becomes the output's own (LaTeX `\newpage`, Typst `#pagebreak`, a CSS break for HTML,
1485
+ EPUB and WeasyPrint, a Word or OpenDocument page break, a form feed in `--to txt`, `<!-- pagebreak -->` in `--to gfm`):
1486
+
1487
+ ```yaml
1488
+ pdfmd-options:
1489
+ pagebreak: true # every family; or a list of them:
1490
+ # pagebreak: [comment, tex]
1491
+ ```
1492
+
1493
+ | family | spellings |
1494
+ |---|---|
1495
+ | `comment` | `<!-- pagebreak -->`, `<!-- page-break -->`, `<!-- newpage -->`, `<!-- new-page -->`, `<!-- pdfmd: pagebreak -->` |
1496
+ | `tex` | `\newpage`, `\pagebreak`, `\pagebreak[3]`, `\clearpage`, `\cleardoublepage` (an odd page) |
1497
+ | `html` | `<div style="page-break-after: always"></div>` (or `break-before: page`), `<div class="pagebreak"></div>`, `<hr class="pagebreak">` |
1498
+ | `div` | an empty `::: pagebreak` (or `newpage`) |
1499
+ | `typst` | a raw `` ```{=typst} `` `#pagebreak()` |
1500
+ | `word` | a raw `` ```{=openxml} `` page-break paragraph |
1501
+
1502
+ It is off unless asked (the document, a metadata file, or `pdfmd --setup` under *Universal markup*); `--pagebreak
1503
+ [KIND ...]` and `--no-pagebreak` decide for one run. A spelling already in the output's own language stays as written,
1504
+ and slides leave a break out with a note. The built-in renderer (no Pandoc) reads the comment and TeX spellings anyway.
1505
+
1046
1506
  **PDF images in HTML.** A browser does not show a PDF in `<img>`, an SVG it does. For an HTML build (a web page, an
1047
1507
  EPUB, a PDF through WeasyPrint) every image that is a PDF, `![fig](plot.pdf)` or `<img src="plot.pdf">`, is converted to
1048
1508
  an SVG with poppler's `pdftocairo` (or `mutool`, `pdf2svg`, `inkscape`) and stays vector; the first page is used and the
@@ -1057,16 +1517,16 @@ pdfmd paper.tex # compiled directly with a LaTeX engine: reruns until
1057
1517
  # no .aux/.log clutter (--keep-aux keeps them)
1058
1518
  pdfmd minutes.docx # Word/PowerPoint/Excel/ODF: converted by LibreOffice
1059
1519
  pdfmd analysis.qmd # handed to Quarto, so code chunks actually run
1060
- pdfmd page.html # built by WeasyPrint, or a browser if the page runs scripts: no Pandoc
1520
+ pdfmd page.html # built by WeasyPrint, or a browser if the page runs scripts or has MathML: no Pandoc
1061
1521
  pdfmd note.typ # compiled by Typst itself: the page setup in the file is kept
1062
1522
  pdfmd notes.rst # anything else Pandoc can read (give the extension)
1063
1523
  ```
1064
1524
 
1065
1525
  A finished `.typ` or `.html` file goes straight to its own engine, because Pandoc would read it into its own model
1066
1526
  and write it out again, and the page size, the styles and the scripts would not survive the trip. For a page that is
1067
- WeasyPrint first (it is quiet and needs no browser); a page with `<script>` goes to Chrome, Chromium, Edge or Brave
1068
- (headless, printing the page), as does one WeasyPrint cannot draw, and wkhtmltopdf, Prince, pagedjs-cli and LibreOffice
1069
- come after. `-e edge` (or `weasyprint`, `chromium`...) picks one. As with an Office file, such a document gets none of
1527
+ WeasyPrint first (it is quiet and needs no browser); a page with `<script>` or MathML (`<math>`, which WeasyPrint prints
1528
+ as flat text) goes to Chrome, Chromium, Edge or Brave (headless, printing the page), as does one WeasyPrint cannot draw,
1529
+ and wkhtmltopdf, Prince, pagedjs-cli and LibreOffice come after. `-e edge` (or `weasyprint`, `chromium`...) picks one. As with an Office file, such a document gets none of
1070
1530
  pdfmd's defaults, since it is finished; `--apply-defaults` (also in `pdfmd --setup`) gives it the title, author, date,
1071
1531
  language, font, font size, paper and margin of its `metadata.yaml`, ahead of its own settings so those win. A `.tex`
1072
1532
  file that no LaTeX engine can compile is tried through Pandoc, with a warning.
@@ -1090,10 +1550,11 @@ Most of these print an `AUTO` line, and each can be switched off individually.
1090
1550
 
1091
1551
  | `AUTO` kind | When | What happens |
1092
1552
  |---|---|---|
1093
- | `READER` | a Markdown file with no YAML front matter | reads the file as GitHub-flavoured Markdown (content-sized table columns, relaxed blank-line rules) |
1553
+ | `READER` | a Markdown file with no YAML front matter | reads the file as GitHub-flavoured Markdown (content-sized table columns, relaxed blank-line rules). If the file uses what only Pandoc's Markdown reads (`H~2~O`, `x^2^`, `{#id}` attributes, raw LaTeX, fenced divs), a `NOTE` says gfm leaves it as text; `--from markdown`, a front-matter block, or `reader:` below changes it |
1094
1554
  | `TITLE` | a Markdown file with no front matter, first line is `# Title` | that heading becomes the document title, and the remaining headings move up one level |
1095
1555
  | `MARGIN` | no margin or geometry set anywhere | 1-inch margins instead of LaTeX's wide defaults |
1096
1556
  | `MAINFONT` | no `mainfont:` and no `-f` | STIX Two Text (Times New Roman if it isn't installed), or a serif that has the letters when the document is mostly in a script STIX Two Text lacks (Kazakh Cyrillic, say); retried with DejaVu Serif if a glyph is still missing. A font you name is never changed except by `fallback: document` |
1557
+ | `MATHFONT` | pdfmd chose the main font itself (no `-f`, no `mainfont:`/`mathfont:` in the document or its metadata), the engine is LuaLaTeX, XeLaTeX, Tectonic or Typst (Pandoc 3.12+), and the companion is installed | the math font that goes with the text font: STIX Two Math for STIX Two Text, DejaVu Math TeX Gyre for DejaVu Serif, Libertinus Math, New Computer Modern Math, TeX Gyre Termes/Pagella Math; without it formulas are set in Latin Modern Math (Typst: New Computer Modern Math). `--no-auto mathfont` (or `font`) stops it |
1097
1558
  | `UNICODE` | text the main font cannot draw (Arabic, Han, Greek with accents, rare symbols...) | sets each run in an installed font for its script (see *Other scripts*), instead of printing boxes |
1098
1559
  | `MONOFONT` | the document contains code | JetBrains Mono for code (Menlo or another installed monospace font if it isn't installed) |
1099
1560
  | `tablewidth` | a pipe table with plain `---` separators and long lines | picks the column widths that give the fewest lines within the text width (a column never narrower than its longest word), and gives a table that fits its natural width back; unequal dashes (`--|-----`) are kept, and `table-widths: keep` in `pdfmd-options` leaves every table as written |
@@ -1102,8 +1563,11 @@ Most of these print an `AUTO` line, and each can be switched off individually.
1102
1563
  | `codewrap` | code blocks in a LaTeX build | long lines wrap at the margin (`--no-code-wrap` or `--no-auto codewrap` for the old behaviour) |
1103
1564
  | `YAML` / `TEX` / `LUA` | project files found | attaches `metadata.yaml`, `preamble.tex`, `<name>.lua` (see below) |
1104
1565
  | `citeproc` | `@key` / `[@key, p. 90]` citations (as Pandoc reads them: `@key` in a code span or an e-mail address is none) | adds `--citeproc`, so citations and the reference list render from your `bibliography:` without any flag (`--no-citeproc` turns it off) |
1566
+ | `remotecsl` | `csl: https://.../ieee.csl` in the front matter or a metadata file | fetches the style once and keeps it (again after 30 days), so a Pandoc built without HTTP support and a build with no network still work: offline it takes that copy, else a style of the same name in Pandoc's own `csl/` folder, with a WARN, else Pandoc's default style with a WARN (`pdfmd-options: {csl-fallback: error}` stops instead) |
1105
1567
  | `crossref` | `@fig:`/`@tbl:` references or `{#fig:...}` labels | adds the `pandoc-crossref` filter, ahead of citeproc |
1106
1568
  | `papersize` | `pagesize: a4` (a common typo) | converts it to Pandoc's real `papersize:` |
1569
+ | `texpackages` | `\ce{H2O}` (mhchem) or `\SI{25}{\celsius}`, `\num`, `\qty` (siunitx) in a LaTeX build whose preamble does not load the package | loads it, last in the preamble, unless it is loaded already (your options win), the command is defined some other way, or the package is not installed |
1570
+ | `draftpictures` | a part (or section) built alone with `seed-labels: draft` | the draft pass over the whole document does not draw TikZ pictures (pgfplots too), `\chemfig`, chemfig schemes or images: they step no counter. A page reference into what was left out prints `??`; a picture that ends inside a macro makes pdfmd run the pass again with the pictures |
1107
1571
 
1108
1572
  `-v` explains each decision and prints the exact command it runs:
1109
1573
 
@@ -1115,7 +1579,7 @@ AUTO READER lecture.md: no YAML front matter; reading as gfm
1115
1579
  AUTO TITLE lecture.md: promoted leading '# ' heading to Pandoc title metadata
1116
1580
  AUTO MARGIN lecture.md: no geometry/margin set; using geometry:margin=1in on LaTeX-family engines
1117
1581
  AUTO MONOFONT lecture.md: has code but no monofont set; using JetBrains Mono on LaTeX-family engines
1118
- OK lecture.md
1582
+ OK lecture.md > lecture.pdf (lualatex)
1119
1583
  ```
1120
1584
 
1121
1585
  The second `CMD` line is the font fallback at work: STIX Two Text was
@@ -1125,6 +1589,44 @@ file paths are shortened here.)
1125
1589
  **When a PDF doesn't look the way the Markdown suggests, run `-v` first.**
1126
1590
  The cause is usually one of these automatic decisions, and `-v` names it.
1127
1591
 
1592
+ The closing line also names the engine that made the PDF. If an earlier one failed, the line says so, so a
1593
+ build that quietly fell back to Typst does not look like one that did not:
1594
+
1595
+ ```console
1596
+ $ pdfmd paper
1597
+ WARN paper.md: lualatex failed (! Undefined control sequence.); trying xelatex...
1598
+ WARN paper.md: xelatex failed (! Undefined control sequence.); trying typst...
1599
+ OK paper.md > paper.pdf (typst; lualatex, xelatex failed)
1600
+ ```
1601
+
1602
+ When LaTeX itself stops, the warning also says where: Pandoc reports a line of the LaTeX it wrote, so pdfmd finds those
1603
+ words in your Markdown and prints `near line 9 of paper.md: ...has \badmacro`.
1604
+
1605
+ WeasyPrint does not typeset math itself. With MathJax in place, `pdfmd --install math:mathjax` (MathJax 4.1's TeX input
1606
+ and HTML output and the STIX Two math font, which goes with pdfmd's default body font: about 12 MB to download, about 2 MB
1607
+ on disk in `~/.local/share/pdfmd/mathjax`, each package pinned and checked against its SHA-256; and node, when there is
1608
+ none on your PATH: node's own release from nodejs.org, about 30 MB, checked the same way, into pdfmd's tools folder), a
1609
+ Markdown document built with `-e weasyprint` (or one that falls back to it) has its math typeset by MathJax before
1610
+ WeasyPrint prints it: fractions, roots, matrices, accents, limits, stretchy arrows and braces, `\ce` reactions, in the
1611
+ STIX Two Math, sized to the body font's x-height when the body is not STIX Two Text. (MathJax's other math fonts, New
1612
+ Computer Modern, TeX Gyre Termes and Pagella and DejaVu, are not offered yet: their tall delimiters built from pieces came
1613
+ out broken in WeasyPrint.) WeasyPrint draws some of MathJax's output a little off (an accent three points over its letter, a
1614
+ fraction's denominator too low, a bar that ran past its letter); pdfmd's own style rules put that right. A formula MathJax cannot read goes to KaTeX when `pdfmd --install math:katex` has put it in place (a `NOTE` says
1615
+ how many), and a formula neither reads (a macro from your LaTeX preamble, say) stays text, with one `WARN` for all of
1616
+ them. KaTeX alone, without MathJax, does what it did: `--no-auto mathjax` asks for that. Without either, the math is
1617
+ Pandoc's plain math, simple formulas in Unicode (`αᵢ ≤ β`) and the others as their TeX, with one `WARN`; Typst or a
1618
+ LaTeX engine typesets them. A math option of your own (`--mathml`, `--math-method=...`) is kept, and `--doctor` says
1619
+ which of them you get.
1620
+
1621
+ A link to an anchor the document does not have (`[see 13.5](#135-your-own-defaults)` quoted from another document) is
1622
+ only a warning for LaTeX and HTML, but Typst stops on it. For Typst, PDF or `.typ`, such a link becomes its text, and
1623
+ one `WARN` names the anchors.
1624
+
1625
+ `--strict` (or `pdfmd-options: {strict: true}` in the document; `--no-strict` overrides it) makes that, and every other
1626
+ warning, an error for scripts and CI: a file whose build printed a `WARN` line, or about which Pandoc warned (an image
1627
+ or citation it could not find, a LaTeX reference left undefined), is reported `FAIL` with the first warnings listed and
1628
+ the exit code is 1. The output file is kept. In a batch only that file fails.
1629
+
1128
1630
  ### Other scripts
1129
1631
 
1130
1632
  <p align="center">
@@ -1238,6 +1740,10 @@ pdfmd-options:
1238
1740
  ---
1239
1741
  ```
1240
1742
 
1743
+ `reader:` fixes the Pandoc reader of a Markdown file (`markdown`, `gfm`, `commonmark_x`, ...; `auto` is the default
1744
+ choice described under *What it does automatically*). It is `--from` for one document, or for a whole folder or all your
1745
+ documents when it sits in `metadata.yaml` or the config file's `options:`.
1746
+
1241
1747
  `pdf-engine:` takes an engine name (`lualatex`, `typst`, ...) or a family:
1242
1748
  `tex`, `typst`, `html` or `office`. A family limits the fallback chain to
1243
1749
  that kind of engine. For example, a document full of chemical structures
@@ -1261,21 +1767,45 @@ options:
1261
1767
  pdf-engine: lualatex
1262
1768
  ```
1263
1769
 
1264
- **`pdfmd --setup`** changes the same defaults from a menu, without editing the files: a numbered list (nothing to
1770
+ **`pdfmd --setup`** (or `pdfmd --config`) changes the same defaults from a menu, without editing the files: a numbered list (nothing to
1265
1771
  install, works over ssh), each setting with its choices and what they mean. It covers what a document would otherwise
1266
1772
  say in `pdfmd-options:` or its front matter, for every document:
1267
1773
 
1268
1774
  - *global metadata* (a `metadata.yaml` beside the config file, below anything a document's own folder says): author, language,
1269
1775
  paper size, font size, page geometry, main and code font, line spacing, coloured links, table of contents, and for
1270
1776
  citations the bibliography file, the CSL style and linked citations;
1777
+ The global metadata can be switched off (`--no-global-metadata`, `pdfmd-options: {global-metadata: false}`, or
1778
+ the *Use the global metadata* row; `--global-metadata` turns it back on for one run) and replaced by a **preset**: another
1779
+ file, `presets/NAME.yaml` beside the config file. `--preset lab` (or `lab.yaml`, or a path), `pdfmd-options: {preset: lab}`
1780
+ in a document or a folder's metadata, or the *Which set of global metadata* row chooses it; `--preset none` takes no global
1781
+ metadata, `default` is `metadata.yaml`. `pdfmd --setup --preset lab` edits that preset's rows (it makes the file), and
1782
+ `pdfmd --presets` lists them and marks the one a build here would use. The command line wins, then the document, then the
1783
+ folder's metadata, then the config.
1271
1784
  - characters a font lacks or none draws, fonts for other scripts, romanization packs;
1272
- - the citation engine, the PDF engine, the default output format, HTML (one file, math method), LaTeX and reference
1273
- numbers in Word files;
1274
- - PDF finishing (header, footer, bookmarks, attached links) and the source file (the "Compiled with..." stamp, backups,
1275
- comment stripping, attaching the source and its files to the PDF);
1276
- - the cache, reading `.txt` as Markdown, and which of pdfmd's automatic behaviours (`--no-auto` kinds) are off.
1277
-
1278
- Choosing 0 (for a text, `-`) gives a setting its built-in default back; `s` saves, `q` quits. The files are rewritten without your
1785
+ - the citation engine; output (the PDF engine, the default output format, defaults for `.typ` and `.html` files);
1786
+ HTML (full page, one file, style sheet, math method); tables (the rows, columns, cut and delimiter of `.csv` tables,
1787
+ pipe-table widths); code (wrapping, line numbers); Word and OpenDocument (LaTeX in them, reference numbers, the
1788
+ template);
1789
+ - plain Markdown, text and ASCII output (`--to gfm`, `txt`, `ascii`: scripts, math, title block, the source carried at
1790
+ the end);
1791
+ - PDF finishing (header, footer, bookmarks, attached links, a hybrid PDF); the build history (the "Compiled with..."
1792
+ stamp and its details); backups (their folder, names and how many are kept); the source inside the PDF (attaching
1793
+ the source, its files and its LaTeX packages, comment stripping);
1794
+ - the cache (reference numbers, plots, a part built alone); input (the Markdown reader, reading `.txt` as Markdown, raw
1795
+ pieces);
1796
+ - checks and limits (`--strict`, the size budgets, the codes `--check` leaves out), and which of pdfmd's automatic
1797
+ behaviours (`--no-auto` kinds) are off.
1798
+
1799
+ Every flag and every `pdfmd-options` key is either one of these rows or left out on purpose: `o` lists the rest (commands,
1800
+ what is about one run or one document, trust, what pdfmd writes for itself) with the reason, and a test keeps that
1801
+ complete. Choosing 0 (for a text, `-`) gives a setting its built-in default back; `s` saves, `q` quits.
1802
+
1803
+ **Switching whole features off.** `d` in `--setup` (or `disabled: [history, tables]` in `config.yaml`) switches off
1804
+ features you never use: modes, source, tables, history, code, raw, markdown, fonts, builtin, office, cache (the topics
1805
+ of `--help`; output, setup and debug stay on). Their options leave `--help`, shell completion (regenerate it with
1806
+ `--completion`) and the setup screen, and the command line refuses them; `pdfmd --disabled --history doc` uses one for a
1807
+ single run and `pdfmd --disabled --help all` shows them. A document's own `pdfmd-options` still apply, so a document
1808
+ from someone else builds the same. In the full-screen setup, `r` resets a row (it used to be `d`). The files are rewritten without your
1279
1809
  comments (the old one is kept as `.bak`). The same keys can be written by hand under `options:` of `config.yaml`. A
1280
1810
  full-screen version is optional: `pdfmd --install tui` (prompt_toolkit, about 1 MB), then `pdfmd --setup fancy`, or set
1281
1811
  "This setup screen" to fancy to make it the one `pdfmd --setup` opens. The first time pdfmd finishes a build in a terminal
@@ -1306,11 +1836,37 @@ files could apply and none is clearly meant, `pdfmd` stops and asks you to
1306
1836
  choose with `-y FILE`, rather than guessing. `-y` alone turns discovery
1307
1837
  off.
1308
1838
 
1839
+ **When two metadata files set the same key, the later one wins**, as in Pandoc:
1840
+ `<name>.yaml` over `metadata.yaml`, `report.yaml` over `metadata.yaml`, and the
1841
+ second of `-y base.yaml -y extra.yaml`. This holds for Pandoc's keys and for
1842
+ pdfmd's own (`pdfmd-options:`, `margin:`), key by key: the earlier file still
1843
+ gives whatever the later one leaves out. The document's own front matter beats
1844
+ every file. `--metadata-precedence first` (or `metadata-precedence: first` in
1845
+ `pdfmd --setup`, under Input) turns this round so that the first file wins.
1846
+ Until 3.27.22, pdfmd's own keys followed that `first` rule while Pandoc's followed
1847
+ the later file.
1848
+
1849
+ A `header-includes:` stays when a preamble file joins it: the document's own, or
1850
+ else the one of the metadata file that wins (above). The same holds
1851
+ for the header files pdfmd adds itself, such as the code-wrapping header of a
1852
+ document with code. A metadata file's lines go before `preamble.tex`, and the
1853
+ document's own go after everything. An `--include-in-header` you pass yourself
1854
+ replaces them all, as it does in Pandoc. The global `metadata.yaml` that
1855
+ `pdfmd --setup` writes is the lowest of all metadata files.
1856
+
1309
1857
  With a `metadata/` folder, a report's own folder can hold nothing but
1310
1858
  `report.md` and `report.pdf`. Relative paths inside the metadata (such as
1311
1859
  `bibliography: refs.bib`) resolve from `metadata/`, and image paths in the
1312
1860
  document still resolve from the document's own folder.
1313
1861
 
1862
+ **A Lua filter can run any command**, so pdfmd tells you about the ones it picks up by itself. The first build with a
1863
+ `<name>.lua` (or `nulabreport.lua`) it has not run before prints one `NOTE`, and so does the first build after the file
1864
+ changed; the filter runs all the same, and there is never a prompt, so a filter you edit every day, `-j`, `-w`, CI and the
1865
+ Python API are not held up. `pdfmd --trust-lua ~/work/reports` marks a folder you work in (or one filter, as it is now):
1866
+ nothing under it is noted again. Only `--strict` skips a new or edited filter outside such a folder. pdfmd remembers
1867
+ each filter's path and SHA-256 in `known-lua.txt` beside its config. This is a notice, not a lock: it does not protect
1868
+ the first build of a folder you have just downloaded, so read its `.lua` first.
1869
+
1314
1870
  One shared metadata file can also be **symlinked** into many folders. A
1315
1871
  relative `bibliography: refs.bib` inside it then finds the `refs.bib`
1316
1872
  next to the file's real copy, so you never need an absolute path.
@@ -1381,3 +1937,7 @@ read with `pdfinfo -meta`. Turn this off with `--no-stamp-pdf-metadata`.
1381
1937
  ## License
1382
1938
 
1383
1939
  [MIT](https://github.com/aliperdehan/pdfmd/blob/main/LICENSE)
1940
+
1941
+ `pdfmd_mhchem/` is a Python port of Martin Hensel's
1942
+ [mhchemParser](https://github.com/mhchem/mhchemParser) (the parser of mhchem's `\ce` and `\pu` that MathJax and KaTeX
1943
+ use) and keeps its [Apache License 2.0](https://github.com/aliperdehan/pdfmd/blob/main/pdfmd_mhchem/LICENSE).