markdown-to-confluence 0.5.2__tar.gz → 0.5.4__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 (167) hide show
  1. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/LICENSE +1 -1
  2. markdown_to_confluence-0.5.4/MANIFEST.in +13 -0
  3. {markdown_to_confluence-0.5.2/markdown_to_confluence.egg-info → markdown_to_confluence-0.5.4}/PKG-INFO +258 -157
  4. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/README.md +257 -156
  5. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4/markdown_to_confluence.egg-info}/PKG-INFO +258 -157
  6. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/SOURCES.txt +52 -6
  7. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/__init__.py +2 -2
  8. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/__main__.py +83 -44
  9. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/api.py +30 -10
  10. markdown_to_confluence-0.5.4/md2conf/attachment.py +72 -0
  11. markdown_to_confluence-0.5.4/md2conf/coalesce.py +43 -0
  12. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/collection.py +1 -1
  13. markdown_to_confluence-0.5.2/md2conf/extra.py → markdown_to_confluence-0.5.4/md2conf/compatibility.py +1 -1
  14. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/converter.py +240 -657
  15. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/csf.py +13 -11
  16. markdown_to_confluence-0.5.4/md2conf/drawio/extension.py +116 -0
  17. markdown_to_confluence-0.5.2/md2conf/drawio.py → markdown_to_confluence-0.5.4/md2conf/drawio/render.py +1 -1
  18. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/emoticon.py +3 -3
  19. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/environment.py +2 -2
  20. markdown_to_confluence-0.5.4/md2conf/extension.py +82 -0
  21. markdown_to_confluence-0.5.4/md2conf/external.py +66 -0
  22. markdown_to_confluence-0.5.4/md2conf/formatting.py +135 -0
  23. markdown_to_confluence-0.5.4/md2conf/frontmatter.py +70 -0
  24. markdown_to_confluence-0.5.4/md2conf/image.py +128 -0
  25. markdown_to_confluence-0.5.4/md2conf/latex.py +66 -0
  26. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/local.py +8 -8
  27. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/markdown.py +1 -1
  28. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/matcher.py +1 -1
  29. markdown_to_confluence-0.5.4/md2conf/mermaid/config.py +20 -0
  30. markdown_to_confluence-0.5.4/md2conf/mermaid/extension.py +109 -0
  31. markdown_to_confluence-0.5.2/md2conf/mermaid.py → markdown_to_confluence-0.5.4/md2conf/mermaid/render.py +10 -38
  32. markdown_to_confluence-0.5.4/md2conf/mermaid/scanner.py +55 -0
  33. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/metadata.py +1 -1
  34. markdown_to_confluence-0.5.2/md2conf/domain.py → markdown_to_confluence-0.5.4/md2conf/options.py +75 -16
  35. markdown_to_confluence-0.5.4/md2conf/plantuml/__init__.py +0 -0
  36. markdown_to_confluence-0.5.4/md2conf/plantuml/config.py +20 -0
  37. markdown_to_confluence-0.5.4/md2conf/plantuml/extension.py +158 -0
  38. markdown_to_confluence-0.5.4/md2conf/plantuml/render.py +138 -0
  39. markdown_to_confluence-0.5.4/md2conf/plantuml/scanner.py +56 -0
  40. markdown_to_confluence-0.5.2/md2conf/latex.py → markdown_to_confluence-0.5.4/md2conf/png.py +107 -146
  41. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/processor.py +55 -13
  42. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/publisher.py +127 -39
  43. markdown_to_confluence-0.5.4/md2conf/py.typed +0 -0
  44. markdown_to_confluence-0.5.4/md2conf/scanner.py +112 -0
  45. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/serializer.py +2 -2
  46. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/svg.py +144 -103
  47. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/text.py +1 -1
  48. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/toc.py +73 -1
  49. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/uri.py +1 -1
  50. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/xml.py +1 -1
  51. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/pyproject.toml +6 -2
  52. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/setup.py +1 -1
  53. markdown_to_confluence-0.5.4/tests/__init__.py +0 -0
  54. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/emoji.py +2 -4
  55. markdown_to_confluence-0.5.4/tests/relative.txt +2 -0
  56. markdown_to_confluence-0.5.4/tests/scanner/frontmatter.md +21 -0
  57. markdown_to_confluence-0.5.4/tests/scanner/id_only.md +5 -0
  58. markdown_to_confluence-0.5.4/tests/scanner/id_space_title.md +10 -0
  59. markdown_to_confluence-0.5.4/tests/source/.mdignore +7 -0
  60. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/alignment.md +2 -1
  61. markdown_to_confluence-0.5.4/tests/source/docs/sample.docx +0 -0
  62. markdown_to_confluence-0.5.4/tests/source/docs/sample.ods +0 -0
  63. markdown_to_confluence-0.5.4/tests/source/docs/sample.odt +0 -0
  64. markdown_to_confluence-0.5.4/tests/source/docs/sample.pdf +0 -0
  65. markdown_to_confluence-0.5.4/tests/source/docs/sample.xlsx +0 -0
  66. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/images.md +6 -0
  67. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/mermaid.md +4 -2
  68. markdown_to_confluence-0.5.4/tests/source/plantuml.md +98 -0
  69. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/table.md +6 -0
  70. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/images.xml +6 -6
  71. markdown_to_confluence-0.5.4/tests/target/mermaid/class.mmd +6 -0
  72. markdown_to_confluence-0.5.4/tests/target/mermaid/mindmap.mmd +17 -0
  73. markdown_to_confluence-0.5.4/tests/target/mermaid/pie.mmd +3 -0
  74. markdown_to_confluence-0.5.4/tests/target/mermaid/quadrant.mmd +8 -0
  75. markdown_to_confluence-0.5.4/tests/target/mermaid/sequence.mmd +9 -0
  76. markdown_to_confluence-0.5.4/tests/target/mermaid/timeline.mmd +10 -0
  77. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/mermaid.xml +6 -7
  78. markdown_to_confluence-0.5.4/tests/target/plantuml/class.puml +22 -0
  79. markdown_to_confluence-0.5.4/tests/target/plantuml/component.puml +20 -0
  80. markdown_to_confluence-0.5.4/tests/target/plantuml/sequence.puml +13 -0
  81. markdown_to_confluence-0.5.4/tests/target/plantuml/usecase.puml +6 -0
  82. markdown_to_confluence-0.5.4/tests/target/plantuml.xml +59 -0
  83. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/table.xml +3 -3
  84. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_conversion.py +151 -39
  85. markdown_to_confluence-0.5.4/tests/test_dockerhub_description.py +41 -0
  86. markdown_to_confluence-0.5.4/tests/test_document.py +105 -0
  87. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_drawio.py +2 -2
  88. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_matcher.py +1 -1
  89. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_mermaid.py +2 -2
  90. markdown_to_confluence-0.5.4/tests/test_plantuml.py +62 -0
  91. markdown_to_confluence-0.5.4/tests/test_png.py +80 -0
  92. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_processor.py +7 -7
  93. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_scanner.py +23 -23
  94. markdown_to_confluence-0.5.4/tests/test_svg.py +143 -0
  95. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_text.py +1 -1
  96. markdown_to_confluence-0.5.4/tests/test_toc.py +149 -0
  97. markdown_to_confluence-0.5.4/tests/test_unit.py +114 -0
  98. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/test_xml.py +1 -1
  99. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/utility.py +25 -2
  100. markdown_to_confluence-0.5.2/MANIFEST.in +0 -8
  101. markdown_to_confluence-0.5.2/md2conf/scanner.py +0 -203
  102. markdown_to_confluence-0.5.2/tests/test_svg.py +0 -167
  103. markdown_to_confluence-0.5.2/tests/test_unit.py +0 -164
  104. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/dependency_links.txt +0 -0
  105. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/entry_points.txt +0 -0
  106. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/requires.txt +0 -0
  107. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/top_level.txt +0 -0
  108. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/markdown_to_confluence.egg-info/zip-safe +0 -0
  109. {markdown_to_confluence-0.5.2/tests → markdown_to_confluence-0.5.4/md2conf/drawio}/__init__.py +0 -0
  110. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/md2conf/entities.dtd +0 -0
  111. /markdown_to_confluence-0.5.2/md2conf/py.typed → /markdown_to_confluence-0.5.4/md2conf/mermaid/__init__.py +0 -0
  112. {markdown_to_confluence-0.5.2/md2conf → markdown_to_confluence-0.5.4/md2conf/mermaid}/puppeteer-config.json +0 -0
  113. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/setup.cfg +0 -0
  114. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/admonition.md +0 -0
  115. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/alert.md +0 -0
  116. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/anchors.md +0 -0
  117. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/basic.md +0 -0
  118. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/code.md +0 -0
  119. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/collapsed.md +0 -0
  120. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/fenced.md +0 -0
  121. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/figure/diagram.drawio +0 -0
  122. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/figure/diagram.drawio.png +0 -0
  123. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/figure/diagram.drawio.svg +0 -0
  124. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/figure/raster.png +0 -0
  125. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/figure/vector.svg +0 -0
  126. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/footnote.md +0 -0
  127. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/ignore.md +0 -0
  128. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/images/images.md +0 -0
  129. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/macro.md +0 -0
  130. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/math.md +0 -0
  131. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/missing.md +0 -0
  132. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/sections.md +0 -0
  133. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/skip_title_heading.md +0 -0
  134. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/skip_title_heading_abstract.md +0 -0
  135. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/skip_title_heading_frontmatter.md +0 -0
  136. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/skip_title_heading_multiple.md +0 -0
  137. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/status.md +0 -0
  138. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/tags.md +0 -0
  139. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/tasklist.md +0 -0
  140. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/title.md +0 -0
  141. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/source/toc.md +0 -0
  142. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/admonition.xml +0 -0
  143. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/alert.xml +0 -0
  144. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/alignment.xml +0 -0
  145. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/anchors.xml +0 -0
  146. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/basic.xml +0 -0
  147. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/code.xml +0 -0
  148. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/collapsed.xml +0 -0
  149. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/fenced.xml +0 -0
  150. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/footnote.xml +0 -0
  151. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/images/images.xml +0 -0
  152. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/macro.xml +0 -0
  153. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/math.xml +0 -0
  154. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/missing.xml +0 -0
  155. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/panel.xml +0 -0
  156. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/sections.xml +0 -0
  157. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading.xml +0 -0
  158. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_abstract.xml +0 -0
  159. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_abstract_removed.xml +0 -0
  160. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_frontmatter.xml +0 -0
  161. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_multiple.xml +0 -0
  162. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_preserved.xml +0 -0
  163. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/skip_title_heading_removed.xml +0 -0
  164. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/status.xml +0 -0
  165. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/tags.xml +0 -0
  166. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/tasklist.xml +0 -0
  167. {markdown_to_confluence-0.5.2 → markdown_to_confluence-0.5.4}/tests/target/toc.xml +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022-2025 Levente Hunyadi
3
+ Copyright (c) 2022-2026 Levente Hunyadi
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,13 @@
1
+ recursive-include tests *.py
2
+ recursive-include tests *.md
3
+ recursive-include tests *.txt
4
+ recursive-include tests .mdignore
5
+ recursive-include tests/source *.drawio
6
+ recursive-include tests/source *.png
7
+ recursive-include tests/source *.svg
8
+ include tests/source/docs/sample.*
9
+ exclude tests/source/emoji.md
10
+ recursive-include tests/target *.xml
11
+ recursive-include tests/target *.mmd
12
+ recursive-include tests/target *.puml
13
+ exclude tests/target/emoji.xml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-to-confluence
3
- Version: 0.5.2
3
+ Version: 0.5.4
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>
@@ -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.
@@ -98,6 +99,15 @@ pip install markdown-to-confluence
98
99
  npm install -g @mermaid-js/mermaid-cli
99
100
  ```
100
101
 
102
+ **Optional.** Pre-rendering PlantUML diagrams into PNG or SVG images requires Java, Graphviz and [PlantUML](https://plantuml.com/). (Refer to `--render-plantuml`.)
103
+
104
+ 1. **Install Java**: Version 8 or later from [Adoptium](https://adoptium.net/) or [Oracle](https://www.oracle.com/java/technologies/downloads/)
105
+ 2. **Install Graphviz**: Required for most diagram types in PlantUML (except sequence diagrams)
106
+ * **Ubuntu/Debian**: `sudo apt-get install Graphviz`
107
+ * **macOS**: `brew install graphviz`
108
+ * **Windows**: Download from [graphviz.org](https://graphviz.org/download/)
109
+ 3. **Download PlantUML JAR**: Download [plantuml.jar](https://github.com/plantuml/plantuml/releases) and set `PLANTUML_JAR` environment variable to point to it
110
+
101
111
  **Optional.** Converting formulas and equations to PNG or SVG images requires [Matplotlib](https://matplotlib.org/):
102
112
 
103
113
  ```sh
@@ -112,7 +122,11 @@ As authors of *md2conf*, we don't endorse or support any particular Confluence m
112
122
 
113
123
  **Optional.** Displaying Mermaid diagrams in Confluence without pre-rendering in the synchronization phase requires a [marketplace app](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence). (Refer to `--no-render-mermaid`.)
114
124
 
115
- **Optional.** Displaying formulas and equations in Confluence requires [marketplace app](https://marketplace.atlassian.com/apps/1226109/latex-math-for-confluence-math-formula-equations), refer to [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
125
+ **Optional.** PlantUML diagrams are embedded with compressed source data and are displayed using the [PlantUML Diagrams for Confluence](https://marketplace.atlassian.com/apps/1215115/plantuml-diagrams-for-confluence) app (if installed). (Refer to `--no-render-plantuml`.)
126
+
127
+ Installing `plantuml.jar` (see above) helps display embedded diagrams with pre-calculated optimal dimensions.
128
+
129
+ **Optional.** Displaying formulas and equations in Confluence requires [marketplace app](https://marketplace.atlassian.com/apps/1226109/latex-math-for-confluence-math-formula-equations), refer to [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/). (Refer to `--no-render-latex`.)
116
130
 
117
131
  ## Getting started
118
132
 
@@ -185,48 +199,54 @@ If you lack appropriate permissions, you will get an *Unauthorized* response fro
185
199
 
186
200
  ### Associating a Markdown file with a wiki page
187
201
 
188
- 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:
189
207
 
190
208
  ```markdown
191
209
  <!-- confluence-page-id: 20250001023 -->
192
210
  ```
193
211
 
194
- 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.
195
213
 
196
- ### Setting the Confluence space
214
+ #### Implicit association
197
215
 
198
- 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.
199
217
 
200
- ```markdown
201
- <!-- confluence-space-key: SPACE -->
202
- ```
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.
203
219
 
204
- 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:
205
221
 
206
- ### 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
207
228
 
208
- 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.
209
230
 
210
- 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:
211
234
 
212
235
  ```markdown
213
- <!-- generated-by: Do not edit! Check out the <a href="https://example.com/project">original source</a>. -->
236
+ <!-- confluence-space-key: SPACE -->
214
237
  ```
215
238
 
216
- Alternatively, use the `--generated-by GENERATED_BY` option. The tag takes precedence.
217
-
218
- 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.
219
240
 
220
- - `%{filename}`: the name of the Markdown file
221
- - `%{filepath}`: the path of the Markdown file relative to the *source root*
241
+ ### Page title
222
242
 
223
- 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:
224
244
 
225
- 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.
226
248
 
227
- ```markdown
228
- <!-- generated-by: Do not edit! Check out the file %{filepath} in the repo -->
229
- ```
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.
230
250
 
231
251
  ### Publishing a single page
232
252
 
@@ -252,7 +272,7 @@ The title of each Markdown file (either the text of the topmost unique heading (
252
272
 
253
273
  ```
254
274
  docs
255
- ├── index.md: Root page
275
+ ├── index.md: Eternal golden braid
256
276
  ├── computer-science
257
277
  │ ├── index.md: Introduction to computer science
258
278
  │ ├── algebra.md: Linear algebra
@@ -263,7 +283,7 @@ docs
263
283
  │ └── statistics
264
284
  │ ├── index.md: Introduction to statistics
265
285
  │ └── median.md: Mean vs. median
266
- └── ethics.md: Ethical considerations
286
+ └── ethics.md: History of ethics
267
287
  ```
268
288
 
269
289
  #### Page hierarchy in Confluence
@@ -271,7 +291,7 @@ docs
271
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).
272
292
 
273
293
  ```
274
- Root page
294
+ Eternal golden braid
275
295
  ├── Introduction to computer science
276
296
  │ ├── Linear algebra
277
297
  │ └── Theory of algorithms
@@ -279,7 +299,7 @@ Root page
279
299
  │ ├── Consciousness and intelligence
280
300
  │ └── Introduction to statistics
281
301
  │ └── Mean vs. median
282
- └── Ethical considerations
302
+ └── History of ethics
283
303
  ```
284
304
 
285
305
  ### Subscript and superscript
@@ -298,57 +318,6 @@ The short name notation `:smile:` in a Markdown document is converted into the c
298
318
  <ac:emoticon ac:name="smile" ac:emoji-shortname=":smile:" ac:emoji-id="1f604" ac:emoji-fallback="&#128516;"/>
299
319
  ```
300
320
 
301
- ### Colors
302
-
303
- 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:
304
-
305
- 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>:
306
-
307
- ```markdown
308
- 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>.
309
- ```
310
-
311
- 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>:
312
-
313
- ```markdown
314
- 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>.
315
- ```
316
-
317
- Highlighting is also supported via `==marks==`. However, the background color is not customizable.
318
-
319
- The following table shows standard text colors (CSS `color`) that are available via Confluence UI:
320
-
321
- | Color name | CSS attribute value |
322
- | :------------ | :------------------ |
323
- | bold blue | rgb(7,71,166) |
324
- | blue | rgb(76,154,255) |
325
- | subtle blue | rgb(179,212,255) |
326
- | bold teal | rgb(0,141,166) |
327
- | teal | rgb(0,184,217) |
328
- | subtle teal | rgb(179,245,255) |
329
- | bold green | rgb(0,102,68) |
330
- | green | rgb(54,179,126) |
331
- | subtle green | rgb(171,245,209) |
332
- | bold orange | rgb(255,153,31) |
333
- | yellow | rgb(255,196,0) |
334
- | subtle yellow | rgb(255,240,179) |
335
- | bold red | rgb(191,38,0) |
336
- | red | rgb(255,86,48) |
337
- | subtle red | rgb(255,189,173) |
338
- | bold purple | rgb(64,50,148) |
339
- | purple | rgb(101,84,192) |
340
- | subtle purple | rgb(234,230,255) |
341
-
342
- The following table shows standard highlight colors (CSS `background-color`) that are available via Confluence UI:
343
-
344
- | Color name | CSS attribute value |
345
- | ------------- | ------------------- |
346
- | teal | rgb(198,237,251) |
347
- | lime | rgb(211,241,167) |
348
- | yellow | rgb(254,222,200) |
349
- | magenta | rgb(253,208,236) |
350
- | purple | rgb(223,216,253) |
351
-
352
321
  ### Lists and tables
353
322
 
354
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.
@@ -372,10 +341,43 @@ Likewise, if you have a nested list, make sure that nested items are indented by
372
341
 
373
342
  Local images referenced in a Markdown file are automatically published to Confluence as attachments to the page.
374
343
 
344
+ * Relative paths (e.g. `path/to/image.png` or `../to/image.png`) resolve to absolute paths w.r.t. the Markdown document location.
345
+ * Absolute paths (e.g. `/path/to/image.png`) are interpreted w.r.t. to the synchronization root (typically the shell current directory).
346
+
347
+ As a security measure, resolved paths can only reference files that are in the directory hierarchy of the synchronization root; you can't use `..` to leave the top-level directory of the synchronization root.
348
+
375
349
  Unfortunately, Confluence struggles with SVG images, e.g. they may only show in *edit* mode, display in a wrong size or text labels in the image may be truncated. (This seems to be a known issue in Confluence.) In order to mitigate the issue, whenever *md2conf* encounters a reference to an SVG image in a Markdown file, it checks whether a corresponding PNG image also exists in the same directory, and if a PNG image is found, it is published instead.
376
350
 
377
351
  External images referenced with an absolute URL retain the original URL.
378
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
+
379
381
  ### LaTeX math formulas
380
382
 
381
383
  Inline formulas can be enclosed with `$` signs, or delimited with `\(` and `\)`, i.e.
@@ -393,16 +395,15 @@ is shown as
393
395
 
394
396
  $$\int _{a}^{b}f(x)dx=F(b)-F(a)$$
395
397
 
396
- 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.
397
399
 
398
- ### 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/).
399
401
 
400
- *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
401
403
 
402
- ```html
403
- <br/>
404
- <img src="image.png" width="24" height="24" />
405
- ```
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.
406
407
 
407
408
  ### Confluence widgets
408
409
 
@@ -436,39 +437,108 @@ Use the pseudo-language `csf` in a Markdown code block to pass content directly
436
437
  ```
437
438
  ````
438
439
 
439
- ### Ignoring files
440
+ ### Implicit URLs
440
441
 
441
- 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:
442
443
 
443
- 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
+ ```
444
447
 
445
- 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.
446
449
 
447
- 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
448
451
 
449
- ```yaml
450
- ---
451
- title: "Collaborating with other teams"
452
- page_id: "19830101"
453
- synchronized: false
454
- ---
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:
455
453
 
456
- 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>.
457
458
  ```
458
459
 
459
- 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>:
460
461
 
461
- ### 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
+ ```
462
465
 
463
- *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.
464
467
 
465
- 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.
466
- 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.
467
- 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:
468
469
 
469
- 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) |
470
490
 
471
- #### Avoiding duplicate titles
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
+ ```
540
+
541
+ ### Avoiding duplicate titles
472
542
 
473
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.
474
544
 
@@ -520,6 +590,28 @@ While the structure remains semantically correct, the visual separation is lost.
520
590
  2. **Use an admonition block:** Wrap the abstract in an info/note block
521
591
  3. **Use front-matter title:** Set `title` in front-matter to keep the heading in the body
522
592
 
593
+ ### Ignoring files
594
+
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.
596
+
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 `/`.
598
+
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.
600
+
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:
602
+
603
+ ```yaml
604
+ ---
605
+ title: "Collaborating with other teams"
606
+ page_id: "19830101"
607
+ synchronized: false
608
+ ---
609
+
610
+ This Markdown document is neither parsed, nor synchronized with Confluence.
611
+ ```
612
+
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.
614
+
523
615
  ### Labels
524
616
 
525
617
  If a Markdown document has the front-matter attribute `tags`, *md2conf* assigns the specified tags to the Confluence page as labels.
@@ -551,61 +643,15 @@ properties:
551
643
 
552
644
  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.
553
645
 
554
- ### draw\.io diagrams
555
-
556
- 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.
557
-
558
- 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.
559
-
560
- ### Mermaid diagrams
561
-
562
- 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:
563
-
564
- * an image reference to a `.mmd` or `.mermaid` file, i.e. `![My diagram](figure/diagram.mmd)`, or
565
- * a fenced code block with the language specifier `mermaid`.
566
-
567
- *md2conf* offers two options to publish the diagram:
568
-
569
- 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.
570
- 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.
571
-
572
- 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:
573
-
574
- ```sh
575
- mmdc -i sample.mmd -o sample.png -b transparent --scale 2
576
- ```
577
-
578
- Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
579
-
580
- 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.
581
-
582
- ### Alignment
583
-
584
- 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.
585
-
586
- 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.
587
-
588
- ### Links to attachments
589
-
590
- 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.
591
-
592
- ### Implicit URLs
593
-
594
- *md2conf* implicitly defines some URLs, as if you included the following at the start of the Markdown document for each URL:
595
-
596
- ```markdown
597
- [CUSTOM-URL]: https://example.com/path/to/resource
598
- ```
599
-
600
- Specifically, image references for status labels (e.g. `![My label][STATUS-RED]`) are automatically resolved into internally defined URLs via this mechanism.
601
-
602
646
  ### Local output
603
647
 
604
648
  *md2conf* supports local output, in which the tool doesn't communicate with the Confluence REST API. Instead, it reads a single Markdown file or a directory of Markdown files, and writes Confluence Storage Format (`*.csf`) output for each document. (Confluence Storage Format is a derivative of XHTML with Confluence-specific tags for complex elements such as images with captions, code blocks, info panels, collapsed sections, etc.) You can push the generated output to Confluence by invoking the API (e.g. with `curl`).
605
649
 
606
650
  ### Running the tool
607
651
 
608
- You execute the command-line tool `md2conf` to synchronize the Markdown file with Confluence:
652
+ #### Command line
653
+
654
+ You can synchronize a (directory of) Markdown file(s) with Confluence using the command-line tool `md2conf`:
609
655
 
610
656
  ```sh
611
657
  $ python3 -m md2conf sample/index.md
@@ -615,7 +661,7 @@ Use the `--help` switch to get a full list of supported command-line options:
615
661
 
616
662
  ```console
617
663
  $ python3 -m md2conf --help
618
- usage: md2conf mdpath [OPTIONS]
664
+ usage: md2conf mdpath [mdpath ...] [OPTIONS]
619
665
 
620
666
  positional arguments:
621
667
  mdpath Path to Markdown file or directory to convert and publish.
@@ -639,10 +685,13 @@ options:
639
685
  --generated-by MARKDOWN
640
686
  Add prompt to pages (default: 'This page has been generated with a tool.').
641
687
  --no-generated-by Do not add 'generated by a tool' prompt to pages.
688
+ --skip-update Skip saving Confluence page ID in Markdown files.
642
689
  --render-drawio Render draw.io diagrams as image files. (Installed utility required to covert.)
643
690
  --no-render-drawio Upload draw.io diagram sources as Confluence page attachments. (Marketplace app required to display.)
644
691
  --render-mermaid Render Mermaid diagrams as image files. (Installed utility required to convert.)
645
692
  --no-render-mermaid Upload Mermaid diagram sources as Confluence page attachments. (Marketplace app required to display.)
693
+ --render-plantuml Render PlantUML diagrams as image files. (Installed utility required to convert.)
694
+ --no-render-plantuml Upload PlantUML diagram sources as Confluence page attachments. (Marketplace app required to display.)
646
695
  --render-latex Render LaTeX formulas as image files. (Matplotlib required to convert.)
647
696
  --no-render-latex Inline LaTeX formulas in Confluence page. (Marketplace app required to display.)
648
697
  --diagram-output-format {png,svg}
@@ -667,6 +716,58 @@ options:
667
716
  Apply custom headers to all Confluence API requests.
668
717
  ```
669
718
 
719
+ #### Python
720
+
721
+ *md2conf* has a Python interface. Create a `ConnectionProperties` object to set connection parameters to the Confluence server, and a `DocumentOptions` object to configure how Markdown files are converted into pages on a Confluence wiki site. Open a connection to the Confluence server with the context manager `ConfluenceAPI`, and instantiate a `Publisher` to start converting documents.
722
+
723
+ ```python
724
+ from md2conf.api import ConfluenceAPI
725
+ from md2conf.environment import ConnectionProperties
726
+ from md2conf.options import ConverterOptions, DocumentOptions, ImageLayoutOptions, LayoutOptions, TableLayoutOptions
727
+ from md2conf.publisher import Publisher
728
+
729
+ properties = ConnectionProperties(
730
+ api_url=...,
731
+ domain=...,
732
+ base_path=...,
733
+ user_name=...,
734
+ api_key=...,
735
+ space_key=...,
736
+ headers=...,
737
+ )
738
+ options = DocumentOptions(
739
+ root_page_id=...,
740
+ keep_hierarchy=...,
741
+ title_prefix=...,
742
+ generated_by=...,
743
+ converter=ConverterOptions(
744
+ heading_anchors=...,
745
+ ignore_invalid_url=...,
746
+ skip_title_heading=...,
747
+ prefer_raster=...,
748
+ render_drawio=...,
749
+ render_mermaid=...,
750
+ render_plantuml=...,
751
+ render_latex=...,
752
+ diagram_output_format=...,
753
+ webui_links=...,
754
+ use_panel=...,
755
+ layout=LayoutOptions(
756
+ image=ImageLayoutOptions(
757
+ alignment=...,
758
+ max_width=...,
759
+ ),
760
+ table=TableLayoutOptions(
761
+ width=...,
762
+ display_mode=...,
763
+ ),
764
+ ),
765
+ ),
766
+ )
767
+ with ConfluenceAPI(properties) as api:
768
+ Publisher(api, options).process(mdpath)
769
+ ```
770
+
670
771
  ### Confluence REST API v1 vs. v2
671
772
 
672
773
  *md2conf* version 0.3.0 has switched to using [Confluence REST API v2](https://developer.atlassian.com/cloud/confluence/rest/v2/) for API calls such as retrieving current page content. Earlier versions used [Confluence REST API v1](https://developer.atlassian.com/cloud/confluence/rest/v1/) exclusively. Unfortunately, Atlassian has decommissioned Confluence REST API v1 for several endpoints in Confluence Cloud as of due date March 31, 2025, and we don't have access to an environment where we could test retired v1 endpoints.