markdown-to-confluence 0.5.3__tar.gz → 0.5.5__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 (171) hide show
  1. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/PKG-INFO +275 -208
  2. markdown_to_confluence-0.5.3/markdown_to_confluence.egg-info/PKG-INFO → markdown_to_confluence-0.5.5/README.md +269 -248
  3. markdown_to_confluence-0.5.3/README.md → markdown_to_confluence-0.5.5/markdown_to_confluence.egg-info/PKG-INFO +315 -202
  4. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/SOURCES.txt +8 -1
  5. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/requires.txt +5 -5
  6. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/__init__.py +1 -1
  7. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/__main__.py +61 -189
  8. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/api.py +35 -69
  9. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/attachment.py +4 -3
  10. markdown_to_confluence-0.5.5/md2conf/clio.py +226 -0
  11. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/compatibility.py +5 -0
  12. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/converter.py +239 -147
  13. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/csf.py +89 -9
  14. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/drawio/extension.py +3 -3
  15. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/drawio/render.py +2 -0
  16. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/extension.py +4 -0
  17. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/external.py +25 -8
  18. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/frontmatter.py +18 -6
  19. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/image.py +17 -14
  20. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/latex.py +8 -1
  21. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/markdown.py +68 -1
  22. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/mermaid/render.py +1 -1
  23. markdown_to_confluence-0.5.5/md2conf/options.py +187 -0
  24. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/plantuml/extension.py +7 -7
  25. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/plantuml/render.py +6 -7
  26. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/png.py +10 -6
  27. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/processor.py +24 -3
  28. markdown_to_confluence-0.5.5/md2conf/publisher.py +384 -0
  29. markdown_to_confluence-0.5.5/md2conf/reflection.py +74 -0
  30. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/scanner.py +16 -6
  31. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/serializer.py +12 -1
  32. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/svg.py +131 -109
  33. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/toc.py +72 -0
  34. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/xml.py +45 -0
  35. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/pyproject.toml +7 -6
  36. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/alert.md +2 -2
  37. markdown_to_confluence-0.5.5/tests/source/skip_nodes.md +36 -0
  38. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/alert.xml +2 -6
  39. markdown_to_confluence-0.5.5/tests/target/skip_nodes.xml +33 -0
  40. markdown_to_confluence-0.5.5/tests/test_clio.py +66 -0
  41. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_conversion.py +33 -26
  42. markdown_to_confluence-0.5.5/tests/test_dockerhub_description.py +49 -0
  43. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_document.py +17 -3
  44. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_png.py +6 -9
  45. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_processor.py +13 -1
  46. markdown_to_confluence-0.5.5/tests/test_svg.py +143 -0
  47. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_text.py +1 -1
  48. markdown_to_confluence-0.5.5/tests/test_toc.py +149 -0
  49. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_unit.py +38 -75
  50. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_xml.py +2 -0
  51. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/utility.py +24 -1
  52. markdown_to_confluence-0.5.3/md2conf/options.py +0 -116
  53. markdown_to_confluence-0.5.3/md2conf/publisher.py +0 -227
  54. markdown_to_confluence-0.5.3/tests/test_svg.py +0 -167
  55. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/LICENSE +0 -0
  56. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/MANIFEST.in +0 -0
  57. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/dependency_links.txt +0 -0
  58. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/entry_points.txt +0 -0
  59. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/top_level.txt +0 -0
  60. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/markdown_to_confluence.egg-info/zip-safe +0 -0
  61. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/coalesce.py +0 -0
  62. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/collection.py +0 -0
  63. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/drawio/__init__.py +0 -0
  64. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/emoticon.py +0 -0
  65. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/entities.dtd +0 -0
  66. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/environment.py +0 -0
  67. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/formatting.py +0 -0
  68. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/local.py +0 -0
  69. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/matcher.py +0 -0
  70. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/mermaid/__init__.py +0 -0
  71. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/mermaid/config.py +0 -0
  72. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/mermaid/extension.py +0 -0
  73. {markdown_to_confluence-0.5.3/md2conf → markdown_to_confluence-0.5.5/md2conf/mermaid}/puppeteer-config.json +0 -0
  74. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/mermaid/scanner.py +0 -0
  75. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/metadata.py +0 -0
  76. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/plantuml/__init__.py +0 -0
  77. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/plantuml/config.py +0 -0
  78. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/plantuml/scanner.py +0 -0
  79. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/py.typed +0 -0
  80. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/text.py +0 -0
  81. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/md2conf/uri.py +0 -0
  82. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/setup.cfg +0 -0
  83. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/setup.py +0 -0
  84. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/__init__.py +0 -0
  85. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/emoji.py +0 -0
  86. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/relative.txt +0 -0
  87. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/scanner/frontmatter.md +0 -0
  88. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/scanner/id_only.md +0 -0
  89. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/scanner/id_space_title.md +0 -0
  90. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/.mdignore +0 -0
  91. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/admonition.md +0 -0
  92. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/alignment.md +0 -0
  93. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/anchors.md +0 -0
  94. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/basic.md +0 -0
  95. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/code.md +0 -0
  96. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/collapsed.md +0 -0
  97. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/docs/sample.docx +0 -0
  98. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/docs/sample.ods +0 -0
  99. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/docs/sample.odt +0 -0
  100. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/docs/sample.pdf +0 -0
  101. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/docs/sample.xlsx +0 -0
  102. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/fenced.md +0 -0
  103. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/figure/diagram.drawio +0 -0
  104. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/figure/diagram.drawio.png +0 -0
  105. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/figure/diagram.drawio.svg +0 -0
  106. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/figure/raster.png +0 -0
  107. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/figure/vector.svg +0 -0
  108. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/footnote.md +0 -0
  109. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/ignore.md +0 -0
  110. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/images/images.md +0 -0
  111. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/images.md +0 -0
  112. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/macro.md +0 -0
  113. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/math.md +0 -0
  114. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/mermaid.md +0 -0
  115. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/missing.md +0 -0
  116. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/plantuml.md +0 -0
  117. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/sections.md +0 -0
  118. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/skip_title_heading.md +0 -0
  119. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/skip_title_heading_abstract.md +0 -0
  120. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/skip_title_heading_frontmatter.md +0 -0
  121. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/skip_title_heading_multiple.md +0 -0
  122. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/status.md +0 -0
  123. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/table.md +0 -0
  124. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/tags.md +0 -0
  125. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/tasklist.md +0 -0
  126. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/title.md +0 -0
  127. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/source/toc.md +0 -0
  128. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/admonition.xml +0 -0
  129. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/alignment.xml +0 -0
  130. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/anchors.xml +0 -0
  131. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/basic.xml +0 -0
  132. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/code.xml +0 -0
  133. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/collapsed.xml +0 -0
  134. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/fenced.xml +0 -0
  135. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/footnote.xml +0 -0
  136. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/images/images.xml +0 -0
  137. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/images.xml +0 -0
  138. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/macro.xml +0 -0
  139. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/math.xml +0 -0
  140. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/class.mmd +0 -0
  141. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/mindmap.mmd +0 -0
  142. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/pie.mmd +0 -0
  143. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/quadrant.mmd +0 -0
  144. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/sequence.mmd +0 -0
  145. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid/timeline.mmd +0 -0
  146. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/mermaid.xml +0 -0
  147. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/missing.xml +0 -0
  148. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/panel.xml +0 -0
  149. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/plantuml/class.puml +0 -0
  150. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/plantuml/component.puml +0 -0
  151. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/plantuml/sequence.puml +0 -0
  152. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/plantuml/usecase.puml +0 -0
  153. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/plantuml.xml +0 -0
  154. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/sections.xml +0 -0
  155. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading.xml +0 -0
  156. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_abstract.xml +0 -0
  157. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_abstract_removed.xml +0 -0
  158. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_frontmatter.xml +0 -0
  159. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_multiple.xml +0 -0
  160. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_preserved.xml +0 -0
  161. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/skip_title_heading_removed.xml +0 -0
  162. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/status.xml +0 -0
  163. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/table.xml +0 -0
  164. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/tags.xml +0 -0
  165. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/tasklist.xml +0 -0
  166. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/target/toc.xml +0 -0
  167. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_drawio.py +0 -0
  168. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_matcher.py +0 -0
  169. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_mermaid.py +0 -0
  170. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_plantuml.py +0 -0
  171. {markdown_to_confluence-0.5.3 → markdown_to_confluence-0.5.5}/tests/test_scanner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-to-confluence
3
- Version: 0.5.3
3
+ Version: 0.5.5
4
4
  Summary: Publish Markdown files to Confluence wiki
5
5
  Author-email: Levente Hunyadi <hunyadi@gmail.com>
6
6
  Maintainer-email: Levente Hunyadi <hunyadi@gmail.com>
@@ -27,18 +27,18 @@ Requires-Dist: cattrs>=25.3
27
27
  Requires-Dist: lxml>=6.0
28
28
  Requires-Dist: markdown>=3.10
29
29
  Requires-Dist: orjson>=3.11
30
- Requires-Dist: pymdown-extensions>=10.19
30
+ Requires-Dist: pymdown-extensions>=10.20
31
31
  Requires-Dist: PyYAML>=6.0
32
32
  Requires-Dist: requests>=2.32
33
33
  Requires-Dist: truststore>=0.10
34
- Requires-Dist: typing-extensions>=4.15; python_version < "3.12"
34
+ Requires-Dist: typing-extensions>=4.15; python_version < "3.11"
35
35
  Provides-Extra: dev
36
- Requires-Dist: markdown_doc>=0.1.6; extra == "dev"
37
- Requires-Dist: types-lxml>=2025.11.25; extra == "dev"
36
+ Requires-Dist: markdown_doc>=0.1.7; extra == "dev"
37
+ Requires-Dist: types-lxml>=2026.1.1; extra == "dev"
38
38
  Requires-Dist: types-markdown>=3.10; extra == "dev"
39
39
  Requires-Dist: types-PyYAML>=6.0; extra == "dev"
40
40
  Requires-Dist: types-requests>=2.32; extra == "dev"
41
- Requires-Dist: mypy>=1.19; extra == "dev"
41
+ Requires-Dist: mypy[faster-cache]>=1.19; extra == "dev"
42
42
  Requires-Dist: ruff>=0.14; extra == "dev"
43
43
  Provides-Extra: formulas
44
44
  Requires-Dist: matplotlib>=3.9; extra == "formulas"
@@ -62,7 +62,6 @@ This Python package
62
62
  * Text with **bold**, *italic*, `monospace`, <ins>underline</ins> and ~~strikethrough~~
63
63
  * Link to [sections on the same page](#getting-started) or [external locations](http://example.com/)
64
64
  * Subscript and superscript
65
- * Math formulas with LaTeX notation
66
65
  * Emoji
67
66
  * Ordered and unordered lists
68
67
  * Block quotes
@@ -76,6 +75,8 @@ This Python package
76
75
  * [Tasklists](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-tasklists)
77
76
  * draw\.io diagrams
78
77
  * [Mermaid diagrams](https://mermaid.live/)
78
+ * PlantUML diagrams
79
+ * Math formulas with LaTeX notation
79
80
  * Confluence status labels and date widget
80
81
 
81
82
  Whenever possible, the implementation uses [Confluence REST API v2](https://developer.atlassian.com/cloud/confluence/rest/v2/) to fetch space properties, and get, create or update page content.
@@ -198,50 +199,54 @@ If you lack appropriate permissions, you will get an *Unauthorized* response fro
198
199
 
199
200
  ### Associating a Markdown file with a wiki page
200
201
 
201
- Each Markdown file is associated with a Confluence wiki page with a Markdown comment:
202
+ Each Markdown file is associated with a Confluence wiki page either *explicitly* or *implicitly*.
203
+
204
+ #### Explicit association
205
+
206
+ We associate a Markdown document with a Confluence page explicitly by specifying the related Confluence page ID in a Markdown comment:
202
207
 
203
208
  ```markdown
204
209
  <!-- confluence-page-id: 20250001023 -->
205
210
  ```
206
211
 
207
- The above tells the tool to synchronize the Markdown file with the given Confluence page ID. This implies that the Confluence wiki page must exist such that it has an ID. The comment can be placed anywhere in the source file.
212
+ The above tells the tool to synchronize the Markdown file with the given Confluence page ID. The Confluence wiki page must be created beforehand. The comment can be placed anywhere in the source file.
208
213
 
209
- ### Setting the Confluence space
214
+ #### Implicit association
210
215
 
211
- If you work in an environment where there are multiple Confluence spaces, and some Markdown pages may go into one space, whereas other pages may go into another, you can set the target space on a per-document basis:
216
+ Each Markdown document is automatically paired with a Confluence page in the target space if they have the same title.
212
217
 
213
- ```markdown
214
- <!-- confluence-space-key: SPACE -->
215
- ```
218
+ If a Confluence page with the given title doesn't exist, it is created automatically, and its identifier is injected into the source as a Markdown comment.
216
219
 
217
- This overrides the default space set via command-line arguments or environment variables.
220
+ If a Confluence page already exists whose title matches the Markdown document title, additional precautions are taken to avoid overwriting an unrelated page. Each implicitly associated page has to trace back to a trusted well-known Confluence page via parent-child relationships before its content would be synchronized. Trusted Confluence pages include:
218
221
 
219
- ### Setting generated-by prompt text for wiki pages
222
+ * the *root page* whose page ID is
223
+ * specified in the command line, or
224
+ * extracted from the index file of a directory that is being synchronized
225
+ * a page associated with a Markdown document via a page ID
226
+ * embedded as a Markdown comment, or
227
+ * specified in the Markdown front-matter
220
228
 
221
- In order to ensure readers are not editing a generated document, the tool adds a warning message at the top of the Confluence page as an *info panel*. You can customize the text that appears. The text can contain markup as per the [Confluence Storage Format](https://confluence.atlassian.com/doc/confluence-storage-format-790796544.html), and is emitted directly into the *info panel* macro.
229
+ If a Confluence page doesn't have a trusted ancestor, synchronization fails. This restricts updates to subtrees of well-known pages.
222
230
 
223
- Provide generated-by prompt text in the Markdown file with a tag:
231
+ ### Setting the Confluence space
232
+
233
+ If you work in an environment where there are multiple Confluence spaces, and some Markdown pages may go into one space, whereas other pages may go into another, you can set the target space on a per-document basis:
224
234
 
225
235
  ```markdown
226
- <!-- generated-by: Do not edit! Check out the <a href="https://example.com/project">original source</a>. -->
236
+ <!-- confluence-space-key: SPACE -->
227
237
  ```
228
238
 
229
- Alternatively, use the `--generated-by GENERATED_BY` option. The tag takes precedence.
230
-
231
- The generated-by text can also be templated with the following variables:
239
+ This overrides the default space set via command-line arguments or environment variables.
232
240
 
233
- - `%{filename}`: the name of the Markdown file
234
- - `%{filestem}`: the name of the Markdown file without the extension
235
- - `%{filepath}`: the path of the Markdown file relative to the _source root_
236
- - `%{filedir}`: the dirname of the `%{filepath}` (the path without the filename)
241
+ ### Page title
237
242
 
238
- When publishing a directory hierarchy, the *source root* is the directory in which *md2conf* is launched. When publishing a single file, this is the directory in which the Markdown file resides.
243
+ *md2conf* makes a best-effort attempt at setting the Confluence wiki page title when it publishes a Markdown document the first time. The following act as sources for deriving a page title:
239
244
 
240
- It can be used with the CLI `--generated-by` option or directly in the files:
245
+ 1. The `title` attribute set in the [front-matter](https://daily-dev-tips.com/posts/what-exactly-is-frontmatter/). Front-matter is a block delimited by `---` at the beginning of a Markdown document. Both JSON and YAML syntax are supported.
246
+ 2. The text of the topmost unique Markdown heading (`#`). For example, if a document has a single first-level heading (e.g. `# My document`), its text is used. However, if there are multiple first-level headings, this step is skipped.
247
+ 3. The file name (without the extension `.md`) and a digest. The digest is included to ensure the title is unique across the Confluence space.
241
248
 
242
- ```markdown
243
- <!-- generated-by: Do not edit! Check out the file %{filepath} in the repo -->
244
- ```
249
+ If the `title` attribute (in the front-matter) or the topmost unique heading (in the document body) changes, the Confluence page title is updated. A warning is raised if the new title conflicts with the title of another page, and thus cannot be updated.
245
250
 
246
251
  ### Publishing a single page
247
252
 
@@ -267,7 +272,7 @@ The title of each Markdown file (either the text of the topmost unique heading (
267
272
 
268
273
  ```
269
274
  docs
270
- ├── index.md: Root page
275
+ ├── index.md: Eternal golden braid
271
276
  ├── computer-science
272
277
  │ ├── index.md: Introduction to computer science
273
278
  │ ├── algebra.md: Linear algebra
@@ -278,7 +283,7 @@ docs
278
283
  │ └── statistics
279
284
  │ ├── index.md: Introduction to statistics
280
285
  │ └── median.md: Mean vs. median
281
- └── ethics.md: Ethical considerations
286
+ └── ethics.md: History of ethics
282
287
  ```
283
288
 
284
289
  #### Page hierarchy in Confluence
@@ -286,7 +291,7 @@ docs
286
291
  Observe how `index.md` and `README.md` files have assumed parent (or ancestor) role for any Markdown files in the same directory (or below).
287
292
 
288
293
  ```
289
- Root page
294
+ Eternal golden braid
290
295
  ├── Introduction to computer science
291
296
  │ ├── Linear algebra
292
297
  │ └── Theory of algorithms
@@ -294,7 +299,7 @@ Root page
294
299
  │ ├── Consciousness and intelligence
295
300
  │ └── Introduction to statistics
296
301
  │ └── Mean vs. median
297
- └── Ethical considerations
302
+ └── History of ethics
298
303
  ```
299
304
 
300
305
  ### Subscript and superscript
@@ -313,57 +318,6 @@ The short name notation `:smile:` in a Markdown document is converted into the c
313
318
  <ac:emoticon ac:name="smile" ac:emoji-shortname=":smile:" ac:emoji-id="1f604" ac:emoji-fallback="&#128516;"/>
314
319
  ```
315
320
 
316
- ### Colors
317
-
318
- Confluence allows setting text color and highlight color. Even though Markdown doesn't directly support colors, it is possible to set text and highlight color via the HTML element `<span>` and the CSS attributes `color` and `background-color`, respectively:
319
-
320
- Text in <span style="color: rgb(255,86,48);">red</span>, <span style="color: rgb(54,179,126);">green</span> and <span style="color: rgb(76,154,255);">blue</span>:
321
-
322
- ```markdown
323
- Text in <span style="color: rgb(255,86,48);">red</span>, <span style="color: rgb(54,179,126);">green</span> and <span style="color: rgb(76,154,255);">blue</span>.
324
- ```
325
-
326
- Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <span style="background-color: rgb(211,241,167);">lime</span> and <span style="background-color: rgb(254,222,200);">yellow</span>:
327
-
328
- ```markdown
329
- Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <span style="background-color: rgb(211,241,167);">lime</span> and <span style="background-color: rgb(254,222,200);">yellow</span>.
330
- ```
331
-
332
- Highlighting is also supported via `==marks==`. However, the background color is not customizable.
333
-
334
- The following table shows standard text colors (CSS `color`) that are available via Confluence UI:
335
-
336
- | Color name | CSS attribute value |
337
- | :------------ | :------------------ |
338
- | bold blue | rgb(7,71,166) |
339
- | blue | rgb(76,154,255) |
340
- | subtle blue | rgb(179,212,255) |
341
- | bold teal | rgb(0,141,166) |
342
- | teal | rgb(0,184,217) |
343
- | subtle teal | rgb(179,245,255) |
344
- | bold green | rgb(0,102,68) |
345
- | green | rgb(54,179,126) |
346
- | subtle green | rgb(171,245,209) |
347
- | bold orange | rgb(255,153,31) |
348
- | yellow | rgb(255,196,0) |
349
- | subtle yellow | rgb(255,240,179) |
350
- | bold red | rgb(191,38,0) |
351
- | red | rgb(255,86,48) |
352
- | subtle red | rgb(255,189,173) |
353
- | bold purple | rgb(64,50,148) |
354
- | purple | rgb(101,84,192) |
355
- | subtle purple | rgb(234,230,255) |
356
-
357
- The following table shows standard highlight colors (CSS `background-color`) that are available via Confluence UI:
358
-
359
- | Color name | CSS attribute value |
360
- | ------------- | ------------------- |
361
- | teal | rgb(198,237,251) |
362
- | lime | rgb(211,241,167) |
363
- | yellow | rgb(254,222,200) |
364
- | magenta | rgb(253,208,236) |
365
- | purple | rgb(223,216,253) |
366
-
367
321
  ### Lists and tables
368
322
 
369
323
  If your Markdown lists or tables don't appear in Confluence as expected, verify that the list or table is delimited by a blank line both before and after, as per strict Markdown syntax. While some previewers accept a more lenient syntax (e.g. an itemized list immediately following a paragraph), *md2conf* uses [Python-Markdown](https://python-markdown.github.io/) internally to convert Markdown into XHTML, which expects the Markdown document to adhere to the stricter syntax.
@@ -396,6 +350,34 @@ Unfortunately, Confluence struggles with SVG images, e.g. they may only show in
396
350
 
397
351
  External images referenced with an absolute URL retain the original URL.
398
352
 
353
+ ### draw\.io diagrams
354
+
355
+ With the command-line option `--no-render-drawio` (default), editable diagram data is extracted from images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`), and uploaded to Confluence as attachments. Files that match `*.drawio` or `*.drawio.xml` are uploaded as-is. You need a [marketplace app](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts) to view and edit these diagrams on a Confluence page.
356
+
357
+ With the command-line option `--render-drawio`, images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`) are uploaded unchanged, and shown on the Confluence page as images. These diagrams are not editable in Confluence. When both an SVG and a PNG image is available, PNG is preferred. Files that match `*.drawio` or `*.drawio.xml` are converted into PNG or SVG images by invoking draw\.io as a command-line utility, and the generated images are uploaded to Confluence as attachments, and shown as images.
358
+
359
+ ### Mermaid diagrams
360
+
361
+ You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documents to create visual representations of systems, processes, and relationships. There are two ways to include a Mermaid diagram:
362
+
363
+ * an image reference to a `.mmd` or `.mermaid` file, i.e. `![My diagram](figure/diagram.mmd)`, or
364
+ * a fenced code block with the language specifier `mermaid`.
365
+
366
+ *md2conf* offers two options to publish the diagram:
367
+
368
+ 1. Pre-render into an image (command-line option `--render-mermaid`). The source file or code block is interpreted by and converted into a PNG or SVG image with the Mermaid diagram utility [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). The generated image is then uploaded to Confluence as an attachment to the page.
369
+ 2. Display on demand (command-line option `--no-render-mermaid`). The code block is transformed into a [diagram macro](https://stratus-addons.atlassian.net/wiki/spaces/MDFC/overview), which is processed by Confluence. You need a separate [marketplace app](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence) to turn macro definitions into images when a Confluence page is visited.
370
+
371
+ If you are running into issues with the pre-rendering approach (e.g. misaligned labels in the generated image), verify if `mermaid-cli` can process the Mermaid source:
372
+
373
+ ```sh
374
+ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
375
+ ```
376
+
377
+ Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
378
+
379
+ Note that `mermaid-cli` has some implicit dependencies (e.g. a headless browser) that may not be immediately available in a CI/CD environment such as GitHub Actions. Refer to the `Dockerfile` in the *md2conf* project root, or [mermaid-cli documentation](https://github.com/mermaid-js/mermaid-cli) on how to install these dependencies such as a `chromium-browser` and various fonts.
380
+
399
381
  ### LaTeX math formulas
400
382
 
401
383
  Inline formulas can be enclosed with `$` signs, or delimited with `\(` and `\)`, i.e.
@@ -413,16 +395,15 @@ is shown as
413
395
 
414
396
  $$\int _{a}^{b}f(x)dx=F(b)-F(a)$$
415
397
 
416
- Displaying math formulas in Confluence requires the extension [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
398
+ If installed, *md2conf* can pre-render math formulas with [Matplotlib](https://matplotlib.org/). This approach doesn't require a third-party Confluence extension.
417
399
 
418
- ### HTML in Markdown
400
+ Displaying math formulas in Confluence (without pre-rendering) requires the extension [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
419
401
 
420
- *md2conf* relays HTML elements nested in Markdown content to Confluence (such as `e<sup>x</sup>` for superscript). However, Confluence uses an extension of XHTML, i.e. the content must qualify as valid XML too. In particular, unterminated tags (e.g. `<br>` or `<img ...>`) or inconsistent nesting (e.g. `<b><i></b></i>`) are not permitted, and will raise an XML parsing error. When an HTML element has no content such as `<br>` or `<img>`, use a self-closing tag:
402
+ ### Alignment
421
403
 
422
- ```html
423
- <br/>
424
- <img src="image.png" width="24" height="24" />
425
- ```
404
+ You can configure diagram and image alignment using the JSON/YAML front-matter attribute `alignment` or the command-line argument of the same name. Possible values are `center` (default), `left` and `right`. The value configured in the Markdown file front-matter takes precedence.
405
+
406
+ Unfortunately, not every third-party app supports every alignment variant. For example, the draw\.io marketplace app supports left and center but not right alignment; and diagrams produced by the Mermaid marketplace app are always centered, ignoring the setting for alignment.
426
407
 
427
408
  ### Confluence widgets
428
409
 
@@ -456,39 +437,108 @@ Use the pseudo-language `csf` in a Markdown code block to pass content directly
456
437
  ```
457
438
  ````
458
439
 
459
- ### Ignoring files
440
+ ### Implicit URLs
460
441
 
461
- Skip files and subdirectories in a directory with rules defined in `.mdignore`. Each rule should occupy a single line. Rules follow the syntax (and constraints) of [fnmatch](https://docs.python.org/3/library/fnmatch.html#fnmatch.fnmatch). Specifically, `?` matches any single character, and `*` matches zero or more characters. For example, use `up-*.md` to exclude Markdown files that start with `up-`. Lines that start with `#` are treated as comments.
442
+ *md2conf* implicitly defines some URLs, as if you included the following at the start of the Markdown document for each URL:
462
443
 
463
- Files that don't have the extension `*.md` are skipped automatically. Hidden directories (whose name starts with `.`) are not recursed into. To skip an entire directory, add the name of the directory without a trailing `/`.
444
+ ```markdown
445
+ [CUSTOM-URL]: https://example.com/path/to/resource
446
+ ```
464
447
 
465
- Relative paths to items in a nested directory are not supported. You must put `.mdignore` in the same directory where the items to be skipped reside.
448
+ Specifically, image references for status labels (e.g. `![My label][STATUS-RED]`) are automatically resolved into internally defined URLs via this mechanism.
466
449
 
467
- If you add the `synchronized` attribute to JSON or YAML front-matter with the value `false`, the document content (including attachments) and metadata (e.g. tags) will not be synchronized with Confluence:
450
+ ### Colors
468
451
 
469
- ```yaml
470
- ---
471
- title: "Collaborating with other teams"
472
- page_id: "19830101"
473
- synchronized: false
474
- ---
452
+ Confluence allows setting text color and highlight color. Even though Markdown doesn't directly support colors, it is possible to set text and highlight color via the HTML element `<span>` and the CSS attributes `color` and `background-color`, respectively:
475
453
 
476
- This Markdown document is neither parsed, nor synchronized with Confluence.
454
+ Text in <span style="color: rgb(255,86,48);">red</span>, <span style="color: rgb(54,179,126);">green</span> and <span style="color: rgb(76,154,255);">blue</span>:
455
+
456
+ ```markdown
457
+ Text in <span style="color: rgb(255,86,48);">red</span>, <span style="color: rgb(54,179,126);">green</span> and <span style="color: rgb(76,154,255);">blue</span>.
477
458
  ```
478
459
 
479
- This is useful if you have a page in a hierarchy that participates in parent-child relationships but whose content is edited directly in Confluence. Specifically, these documents can be referenced with relative links from other Markdown documents in the file system tree.
460
+ Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <span style="background-color: rgb(211,241,167);">lime</span> and <span style="background-color: rgb(254,222,200);">yellow</span>:
480
461
 
481
- ### Page title
462
+ ```markdown
463
+ Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <span style="background-color: rgb(211,241,167);">lime</span> and <span style="background-color: rgb(254,222,200);">yellow</span>.
464
+ ```
482
465
 
483
- *md2conf* makes a best-effort attempt at setting the Confluence wiki page title when it publishes a Markdown document the first time. The following act as sources for deriving a page title:
466
+ Highlighting is also supported via `==marks==`. However, the background color is not customizable.
484
467
 
485
- 1. The `title` attribute set in the [front-matter](https://daily-dev-tips.com/posts/what-exactly-is-frontmatter/). Front-matter is a block delimited by `---` at the beginning of a Markdown document. Both JSON and YAML syntax are supported.
486
- 2. The text of the topmost unique Markdown heading (`#`). For example, if a document has a single first-level heading (e.g. `# My document`), its text is used. However, if there are multiple first-level headings, this step is skipped.
487
- 3. The file name (without the extension `.md`) and a digest. The digest is included to ensure the title is unique across the Confluence space.
468
+ The following table shows standard text colors (CSS `color`) that are available via Confluence UI:
488
469
 
489
- If the `title` attribute (in the front-matter) or the topmost unique heading (in the document body) changes, the Confluence page title is updated. A warning is raised if the new title conflicts with the title of another page, and thus cannot be updated.
470
+ | Color name | CSS attribute value |
471
+ | :------------ | :------------------ |
472
+ | bold blue | rgb(7,71,166) |
473
+ | blue | rgb(76,154,255) |
474
+ | subtle blue | rgb(179,212,255) |
475
+ | bold teal | rgb(0,141,166) |
476
+ | teal | rgb(0,184,217) |
477
+ | subtle teal | rgb(179,245,255) |
478
+ | bold green | rgb(0,102,68) |
479
+ | green | rgb(54,179,126) |
480
+ | subtle green | rgb(171,245,209) |
481
+ | bold orange | rgb(255,153,31) |
482
+ | yellow | rgb(255,196,0) |
483
+ | subtle yellow | rgb(255,240,179) |
484
+ | bold red | rgb(191,38,0) |
485
+ | red | rgb(255,86,48) |
486
+ | subtle red | rgb(255,189,173) |
487
+ | bold purple | rgb(64,50,148) |
488
+ | purple | rgb(101,84,192) |
489
+ | subtle purple | rgb(234,230,255) |
490
+
491
+ The following table shows standard highlight colors (CSS `background-color`) that are available via Confluence UI:
492
+
493
+ | Color name | CSS attribute value |
494
+ | ------------- | ------------------- |
495
+ | teal | rgb(198,237,251) |
496
+ | lime | rgb(211,241,167) |
497
+ | yellow | rgb(254,222,200) |
498
+ | magenta | rgb(253,208,236) |
499
+ | purple | rgb(223,216,253) |
500
+
501
+ ### HTML in Markdown
502
+
503
+ *md2conf* relays HTML elements nested in Markdown content to Confluence (such as `e<sup>x</sup>` for superscript). However, Confluence uses an extension of XHTML, i.e. the content must qualify as valid XML too. In particular, unterminated tags (e.g. `<br>` or `<img ...>`) or inconsistent nesting (e.g. `<b><i></b></i>`) are not permitted, and will raise an XML parsing error. When an HTML element has no content such as `<br>` or `<img>`, use a self-closing tag:
504
+
505
+ ```html
506
+ <br/>
507
+ <img src="image.png" width="24" height="24" />
508
+ ```
509
+
510
+ ### Links to attachments
511
+
512
+ If *md2conf* encounters a Markdown link that points to a file in the directory hierarchy being synchronized, it automatically uploads the file as an attachment to the Confluence page. Activating the link in Confluence downloads the file. Typical examples include PDFs (`*.pdf`), word processor documents (`*.docx`), spreadsheets (`*.xlsx`), plain text files (`*.txt`) or logs (`*.log`). The MIME type is set based on the file type.
513
+
514
+ ### Setting generated-by prompt text for wiki pages
515
+
516
+ In order to ensure readers are not editing a generated document, the tool adds a warning message at the top of the Confluence page as an *info panel*. You can customize the text that appears. The text can contain markup as per the [Confluence Storage Format](https://confluence.atlassian.com/doc/confluence-storage-format-790796544.html), and is emitted directly into the *info panel* macro.
517
+
518
+ Provide generated-by prompt text in the Markdown file with a tag:
519
+
520
+ ```markdown
521
+ <!-- generated-by: Do not edit! Check out the <a href="https://example.com/project">original source</a>. -->
522
+ ```
523
+
524
+ Alternatively, use the `--generated-by GENERATED_BY` option. The tag takes precedence.
525
+
526
+ The generated-by text can also be templated with the following variables:
527
+
528
+ - `%{filename}`: the name of the Markdown file
529
+ - `%{filestem}`: the name of the Markdown file without the extension
530
+ - `%{filepath}`: the path of the Markdown file relative to the _source root_
531
+ - `%{filedir}`: the dirname of the `%{filepath}` (the path without the filename)
532
+
533
+ When publishing a directory hierarchy, the *source root* is the directory in which *md2conf* is launched. When publishing a single file, this is the directory in which the Markdown file resides.
534
+
535
+ It can be used with the CLI `--generated-by` option or directly in the files:
536
+
537
+ ```markdown
538
+ <!-- generated-by: Do not edit! Check out the file %{filepath} in the repo -->
539
+ ```
490
540
 
491
- #### Avoiding duplicate titles
541
+ ### Avoiding duplicate titles
492
542
 
493
543
  By default, when *md2conf* extracts a page title from the first unique heading in a Markdown document, the heading remains in the document body. This means the title appears twice on the Confluence page: once as the page title at the top, and once as the first heading in the content.
494
544
 
@@ -540,84 +590,87 @@ While the structure remains semantically correct, the visual separation is lost.
540
590
  2. **Use an admonition block:** Wrap the abstract in an info/note block
541
591
  3. **Use front-matter title:** Set `title` in front-matter to keep the heading in the body
542
592
 
543
- ### Labels
544
-
545
- If a Markdown document has the front-matter attribute `tags`, *md2conf* assigns the specified tags to the Confluence page as labels.
546
-
547
- ```yaml
548
- ---
549
- title: "Example document"
550
- tags: ["markdown", "md", "wiki"]
551
- ---
552
- ```
553
-
554
- Any previously assigned labels are discarded. As per Confluence terminology, new labels have the `prefix` of `global`.
593
+ ### Ignoring files
555
594
 
556
- If a document has no `tags` attribute, existing Confluence labels are left intact.
595
+ Skip files and subdirectories in a directory with rules defined in `.mdignore`. Each rule should occupy a single line. Rules follow the syntax (and constraints) of [fnmatch](https://docs.python.org/3/library/fnmatch.html#fnmatch.fnmatch). Specifically, `?` matches any single character, and `*` matches zero or more characters. For example, use `up-*.md` to exclude Markdown files that start with `up-`. Lines that start with `#` are treated as comments.
557
596
 
558
- ### Content properties
597
+ Files that don't have the extension `*.md` are skipped automatically. Hidden directories (whose name starts with `.`) are not recursed into. To skip an entire directory, add the name of the directory without a trailing `/`.
559
598
 
560
- The front-matter attribute `properties` in a Markdown document allows setting Confluence content properties on a page. Confluence content properties are a way to store structured metadata in the form of key-value pairs directly on Confluence content. The values in content properties are represented as JSON objects.
599
+ Relative paths to items in a nested directory are not supported. You must put `.mdignore` in the same directory where the items to be skipped reside.
561
600
 
562
- Some content properties have special meaning to Confluence. For example, the following properties cause Confluence to display a wiki page with content confined to a fixed width in regular view mode, and taking the full page width in draft mode:
601
+ If you add the `synchronized` attribute to JSON or YAML front-matter with the value `false`, the document content (including attachments) and metadata (e.g. tags) will not be synchronized with Confluence:
563
602
 
564
603
  ```yaml
565
604
  ---
566
- properties:
567
- content-appearance-published: fixed-width
568
- content-appearance-draft: full-width
605
+ title: "Collaborating with other teams"
606
+ page_id: "19830101"
607
+ synchronized: false
569
608
  ---
570
- ```
571
609
 
572
- The attribute `properties` is parsed as a dictionary with keys of type string and values of type JSON. *md2conf* passes JSON values to Confluence REST API unchanged.
610
+ This Markdown document is neither parsed, nor synchronized with Confluence.
611
+ ```
573
612
 
574
- ### draw\.io diagrams
613
+ This is useful if you have a page in a hierarchy that participates in parent-child relationships but whose content is edited directly in Confluence. Specifically, these documents can be referenced with relative links from other Markdown documents in the file system tree.
575
614
 
576
- With the command-line option `--no-render-drawio` (default), editable diagram data is extracted from images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`), and uploaded to Confluence as attachments. Files that match `*.drawio` or `*.drawio.xml` are uploaded as-is. You need a [marketplace app](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts) to view and edit these diagrams on a Confluence page.
615
+ ### Excluding content sections
577
616
 
578
- With the command-line option `--render-drawio`, images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`) are uploaded unchanged, and shown on the Confluence page as images. These diagrams are not editable in Confluence. When both an SVG and a PNG image is available, PNG is preferred. Files that match `*.drawio` or `*.drawio.xml` are converted into PNG or SVG images by invoking draw\.io as a command-line utility, and the generated images are uploaded to Confluence as attachments, and shown as images.
617
+ When maintaining documentation in both Git repositories and Confluence, you may want certain content to appear only in the repository but not on Confluence pages. Use HTML comment markers to wrap and exclude specific sections from synchronization:
579
618
 
580
- ### Mermaid diagrams
619
+ ```markdown
620
+ # Project Documentation
581
621
 
582
- You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documents to create visual representations of systems, processes, and relationships. There are two ways to include a Mermaid diagram:
622
+ This content appears in both Git and Confluence.
583
623
 
584
- * an image reference to a `.mmd` or `.mermaid` file, i.e. `![My diagram](figure/diagram.mmd)`, or
585
- * a fenced code block with the language specifier `mermaid`.
624
+ <!-- confluence-skip-start -->
625
+ ## Internal References
626
+ - See [internal design doc](../internal/design.md)
627
+ - Related to issue #123
628
+ - Development notes for the team
629
+ <!-- confluence-skip-end -->
586
630
 
587
- *md2conf* offers two options to publish the diagram:
631
+ ## Getting Started
632
+ This section is published to Confluence.
633
+ ```
588
634
 
589
- 1. Pre-render into an image (command-line option `--render-mermaid`). The source file or code block is interpreted by and converted into a PNG or SVG image with the Mermaid diagram utility [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). The generated image is then uploaded to Confluence as an attachment to the page.
590
- 2. Display on demand (command-line option `--no-render-mermaid`). The code block is transformed into a [diagram macro](https://stratus-addons.atlassian.net/wiki/spaces/MDFC/overview), which is processed by Confluence. You need a separate [marketplace app](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence) to turn macro definitions into images when a Confluence page is visited.
635
+ Content between `<!-- confluence-skip-start -->` and `<!-- confluence-skip-end -->` markers is removed before conversion and will not appear on the Confluence page. This is useful for:
591
636
 
592
- If you are running into issues with the pre-rendering approach (e.g. misaligned labels in the generated image), verify if `mermaid-cli` can process the Mermaid source:
637
+ - Repository-specific navigation and cross-references
638
+ - GitLab/GitHub-specific metadata
639
+ - Content relevant only for developers with repository access
593
640
 
594
- ```sh
595
- mmdc -i sample.mmd -o sample.png -b transparent --scale 2
596
- ```
641
+ Multiple exclusion blocks can be used in the same document.
597
642
 
598
- Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
599
643
 
600
- Note that `mermaid-cli` has some implicit dependencies (e.g. a headless browser) that may not be immediately available in a CI/CD environment such as GitHub Actions. Refer to the `Dockerfile` in the *md2conf* project root, or [mermaid-cli documentation](https://github.com/mermaid-js/mermaid-cli) on how to install these dependencies such as a `chromium-browser` and various fonts.
644
+ ### Labels
601
645
 
602
- ### Alignment
646
+ If a Markdown document has the front-matter attribute `tags`, *md2conf* assigns the specified tags to the Confluence page as labels.
603
647
 
604
- You can configure diagram and image alignment using the JSON/YAML front-matter attribute `alignment` or the command-line argument of the same name. Possible values are `center` (default), `left` and `right`. The value configured in the Markdown file front-matter takes precedence.
648
+ ```yaml
649
+ ---
650
+ title: "Example document"
651
+ tags: ["markdown", "md", "wiki"]
652
+ ---
653
+ ```
605
654
 
606
- Unfortunately, not every third-party app supports every alignment variant. For example, the draw\.io marketplace app supports left and center but not right alignment; and diagrams produced by the Mermaid marketplace app are always centered, ignoring the setting for alignment.
655
+ Any previously assigned labels are discarded. As per Confluence terminology, new labels have the `prefix` of `global`.
607
656
 
608
- ### Links to attachments
657
+ If a document has no `tags` attribute, existing Confluence labels are left intact.
609
658
 
610
- If *md2conf* encounters a Markdown link that points to a file in the directory hierarchy being synchronized, it automatically uploads the file as an attachment to the Confluence page. Activating the link in Confluence downloads the file. Typical examples include PDFs (`*.pdf`), word processor documents (`*.docx`), spreadsheets (`*.xlsx`), plain text files (`*.txt`) or logs (`*.log`). The MIME type is set based on the file type.
659
+ ### Content properties
611
660
 
612
- ### Implicit URLs
661
+ The front-matter attribute `properties` in a Markdown document allows setting Confluence content properties on a page. Confluence content properties are a way to store structured metadata in the form of key-value pairs directly on Confluence content. The values in content properties are represented as JSON objects.
613
662
 
614
- *md2conf* implicitly defines some URLs, as if you included the following at the start of the Markdown document for each URL:
663
+ Some content properties have special meaning to Confluence. For example, the following properties cause Confluence to display a wiki page with content confined to a fixed width in regular view mode, and taking the full page width in draft mode:
615
664
 
616
- ```markdown
617
- [CUSTOM-URL]: https://example.com/path/to/resource
665
+ ```yaml
666
+ ---
667
+ properties:
668
+ content-appearance-published: fixed-width
669
+ content-appearance-draft: full-width
670
+ ---
618
671
  ```
619
672
 
620
- Specifically, image references for status labels (e.g. `![My label][STATUS-RED]`) are automatically resolved into internally defined URLs via this mechanism.
673
+ The attribute `properties` is parsed as a dictionary with keys of type string and values of type JSON. *md2conf* passes JSON values to Confluence REST API unchanged.
621
674
 
622
675
  ### Local output
623
676
 
@@ -637,7 +690,7 @@ Use the `--help` switch to get a full list of supported command-line options:
637
690
 
638
691
  ```console
639
692
  $ python3 -m md2conf --help
640
- usage: md2conf mdpath [OPTIONS]
693
+ usage: md2conf mdpath [mdpath ...] [OPTIONS]
641
694
 
642
695
  positional arguments:
643
696
  mdpath Path to Markdown file or directory to convert and publish.
@@ -657,35 +710,46 @@ options:
657
710
  Use this option to set the log verbosity.
658
711
  -r ROOT_PAGE Root Confluence page to create new pages. If omitted, will raise exception when creating new pages.
659
712
  --keep-hierarchy Maintain source directory structure when exporting to Confluence.
660
- --flatten-hierarchy Flatten directories with no index.md or README.md when exporting to Confluence.
713
+ --skip-hierarchy Flatten directories with no `index.md` or `README.md` when exporting to Confluence.
661
714
  --generated-by MARKDOWN
662
- Add prompt to pages (default: 'This page has been generated with a tool.').
715
+ Add prompt to pages.
663
716
  --no-generated-by Do not add 'generated by a tool' prompt to pages.
664
- --render-drawio Render draw.io diagrams as image files. (Installed utility required to covert.)
717
+ --skip-update Skip saving Confluence page ID in Markdown files.
718
+ --heading-anchors Place an anchor at each section heading with GitHub-style same-page identifiers.
719
+ --no-heading-anchors Omit the extra anchor from section headings. (May break manually placed same-page references.) (default)
720
+ --force-valid-url Raise an error when relative URLs point to an invalid location. (default)
721
+ --no-force-valid-url Emit a warning but otherwise ignore relative URLs that point to an invalid location.
722
+ --skip-title-heading Remove the first heading from document body when it is used as the page title (does not apply if title comes from front-matter).
723
+ --keep-title-heading Keep the first heading in document body even when used as page title. (default)
724
+ --prefer-raster Prefer PNG over SVG when both exist. (default)
725
+ --no-prefer-raster Use SVG files directly instead of preferring PNG equivalents.
726
+ --render-drawio Render draw.io diagrams as image files. (Installed utility required to covert.) (default)
665
727
  --no-render-drawio Upload draw.io diagram sources as Confluence page attachments. (Marketplace app required to display.)
666
- --render-mermaid Render Mermaid diagrams as image files. (Installed utility required to convert.)
728
+ --render-mermaid Render Mermaid diagrams as image files. (Installed utility required to convert.) (default)
667
729
  --no-render-mermaid Upload Mermaid diagram sources as Confluence page attachments. (Marketplace app required to display.)
668
- --render-plantuml Render PlantUML diagrams as image files. (Installed utility required to convert.)
730
+ --render-plantuml Render PlantUML diagrams as image files. (Installed utility required to convert.) (default)
669
731
  --no-render-plantuml Upload PlantUML diagram sources as Confluence page attachments. (Marketplace app required to display.)
670
- --render-latex Render LaTeX formulas as image files. (Matplotlib required to convert.)
732
+ --render-latex Render LaTeX formulas as image files. (Matplotlib required to convert.) (default)
671
733
  --no-render-latex Inline LaTeX formulas in Confluence page. (Marketplace app required to display.)
672
734
  --diagram-output-format {png,svg}
673
- Format for rendering Mermaid and draw.io diagrams (default: 'png').
674
- --prefer-raster Prefer PNG over SVG when both exist (default: enabled).
675
- --no-prefer-raster Use SVG files directly instead of preferring PNG equivalents.
676
- --heading-anchors Place an anchor at each section heading with GitHub-style same-page identifiers.
677
- --no-heading-anchors Don't place an anchor at each section heading.
678
- --ignore-invalid-url Emit a warning but otherwise ignore relative URLs that point to ill-specified locations.
679
- --skip-title-heading Skip the first heading from document body when it is used as the page title (does not apply if title comes from front-matter).
680
- --no-skip-title-heading
681
- Keep the first heading in document body even when used as page title (default).
682
- --title-prefix TEXT String to prepend to Confluence page title for each published page.
735
+ Format for rendering Mermaid and draw.io diagrams. (default: png)
683
736
  --webui-links Enable Confluence Web UI links. (Typically required for on-prem versions of Confluence.)
684
- --alignment {center,left,right}
685
- Alignment for block-level images and formulas (default: 'center').
686
- --max-image-width MAX_IMAGE_WIDTH
687
- Maximum display width for images [px]. Wider images are scaled down for page display. Original size kept for full-size viewing.
737
+ --no-webui-links Use hierarchical links including space and page ID. (default)
688
738
  --use-panel Transform admonitions and alerts into a Confluence custom panel.
739
+ --no-use-panel Use standard Confluence macro types for admonitions and alerts (info, tip, note and warning). (default)
740
+ --layout-image-alignment {center,left,right,None}
741
+ Alignment for block-level images and formulas.
742
+ --layout-image-max-width INT
743
+ Maximum display width for images [px]. Wider images are scaled down for page display.
744
+ --layout-table-width INT
745
+ Maximum table width in pixels.
746
+ --layout-table-display-mode {responsive,fixed}
747
+ Set table display mode. (default: responsive)
748
+ --layout-alignment {center,left,right,None}
749
+ Default alignment for block-level content.
750
+ --ignore-invalid-url Emit a warning but otherwise ignore relative URLs that point to ill-specified locations.
751
+ --title-prefix TEXT String to prepend to Confluence page title for each published page.
752
+ --line-numbers Inject line numbers in Markdown source to help localize conversion errors.
689
753
  --local Write XHTML-based Confluence Storage Format files locally without invoking Confluence API.
690
754
  --headers KEY=VALUE [KEY=VALUE ...]
691
755
  Apply custom headers to all Confluence API requests.
@@ -698,46 +762,49 @@ options:
698
762
  ```python
699
763
  from md2conf.api import ConfluenceAPI
700
764
  from md2conf.environment import ConnectionProperties
701
- from md2conf.options import ConverterOptions, DocumentOptions, ImageLayoutOptions, LayoutOptions, TableLayoutOptions
765
+ from md2conf.options import ConfluencePageID, ConverterOptions, DocumentOptions, ImageLayoutOptions, LayoutOptions, TableLayoutOptions
702
766
  from md2conf.publisher import Publisher
703
767
 
704
768
  properties = ConnectionProperties(
705
- api_url=...,
706
- domain=...,
707
- base_path=...,
708
- user_name=...,
709
- api_key=...,
710
- space_key=...,
711
- headers=...,
769
+ domain=str() or None,
770
+ base_path=str() or None,
771
+ space_key=str() or None,
772
+ api_url=str() or None,
773
+ user_name=str() or None,
774
+ api_key=str(),
775
+ headers={str(): str()} or None,
712
776
  )
713
777
  options = DocumentOptions(
714
- root_page_id=...,
715
- keep_hierarchy=...,
716
- title_prefix=...,
717
- generated_by=...,
778
+ root_page_id=ConfluencePageID() or None,
779
+ keep_hierarchy=bool(),
780
+ title_prefix=str() or None,
781
+ generated_by=str() or None,
782
+ skip_update=bool(),
718
783
  converter=ConverterOptions(
719
- heading_anchors=...,
720
- ignore_invalid_url=...,
721
- skip_title_heading=...,
722
- prefer_raster=...,
723
- render_drawio=...,
724
- render_mermaid=...,
725
- render_plantuml=...,
726
- render_latex=...,
727
- diagram_output_format=...,
728
- webui_links=...,
729
- use_panel=...,
784
+ heading_anchors=bool(),
785
+ force_valid_url=bool(),
786
+ skip_title_heading=bool(),
787
+ prefer_raster=bool(),
788
+ render_drawio=bool(),
789
+ render_mermaid=bool(),
790
+ render_plantuml=bool(),
791
+ render_latex=bool(),
792
+ diagram_output_format='png' or 'svg',
793
+ webui_links=bool(),
794
+ use_panel=bool(),
730
795
  layout=LayoutOptions(
731
796
  image=ImageLayoutOptions(
732
- alignment=...,
733
- max_width=...,
797
+ alignment='center' or 'left' or 'right' or None,
798
+ max_width=int() or None,
734
799
  ),
735
800
  table=TableLayoutOptions(
736
- width=...,
737
- display_mode=...,
801
+ width=int() or None,
802
+ display_mode='responsive' or 'fixed',
738
803
  ),
804
+ alignment='center' or 'left' or 'right' or None,
739
805
  ),
740
806
  ),
807
+ line_numbers=bool(),
741
808
  )
742
809
  with ConfluenceAPI(properties) as api:
743
810
  Publisher(api, options).process(mdpath)