markdown-to-confluence 0.4.7__tar.gz → 0.4.8__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 (104) hide show
  1. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/PKG-INFO +25 -11
  2. markdown_to_confluence-0.4.7/markdown_to_confluence.egg-info/PKG-INFO → markdown_to_confluence-0.4.8/README.md +17 -49
  3. markdown_to_confluence-0.4.7/README.md → markdown_to_confluence-0.4.8/markdown_to_confluence.egg-info/PKG-INFO +63 -3
  4. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/requires.txt +7 -7
  5. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/__init__.py +1 -1
  6. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/converter.py +21 -13
  7. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/pyproject.toml +7 -7
  8. markdown_to_confluence-0.4.8/tests/source/tasklist.md +19 -0
  9. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/panel.xml +11 -11
  10. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/tasklist.xml +12 -0
  11. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_matcher.py +1 -0
  12. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_mermaid.py +4 -25
  13. markdown_to_confluence-0.4.7/tests/source/tasklist.md +0 -6
  14. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/LICENSE +0 -0
  15. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/MANIFEST.in +0 -0
  16. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/SOURCES.txt +0 -0
  17. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/dependency_links.txt +0 -0
  18. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/entry_points.txt +0 -0
  19. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/top_level.txt +0 -0
  20. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/markdown_to_confluence.egg-info/zip-safe +0 -0
  21. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/__main__.py +0 -0
  22. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/api.py +0 -0
  23. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/collection.py +0 -0
  24. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/csf.py +0 -0
  25. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/domain.py +0 -0
  26. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/drawio.py +0 -0
  27. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/emoticon.py +0 -0
  28. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/entities.dtd +0 -0
  29. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/environment.py +0 -0
  30. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/extra.py +0 -0
  31. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/latex.py +0 -0
  32. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/local.py +0 -0
  33. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/markdown.py +0 -0
  34. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/matcher.py +0 -0
  35. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/mermaid.py +0 -0
  36. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/metadata.py +0 -0
  37. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/processor.py +0 -0
  38. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/publisher.py +0 -0
  39. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/puppeteer-config.json +0 -0
  40. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/py.typed +0 -0
  41. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/scanner.py +0 -0
  42. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/text.py +0 -0
  43. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/toc.py +0 -0
  44. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/uri.py +0 -0
  45. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/md2conf/xml.py +0 -0
  46. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/setup.cfg +0 -0
  47. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/setup.py +0 -0
  48. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/__init__.py +0 -0
  49. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/emoji.py +0 -0
  50. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/admonition.md +0 -0
  51. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/alert.md +0 -0
  52. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/alignment.md +0 -0
  53. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/anchors.md +0 -0
  54. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/basic.md +0 -0
  55. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/code.md +0 -0
  56. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/collapsed.md +0 -0
  57. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/fenced.md +0 -0
  58. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/figure/diagram.drawio +0 -0
  59. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/figure/diagram.drawio.png +0 -0
  60. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/figure/diagram.drawio.svg +0 -0
  61. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/figure/raster.png +0 -0
  62. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/figure/vector.svg +0 -0
  63. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/footnote.md +0 -0
  64. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/ignore.md +0 -0
  65. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/images/images.md +0 -0
  66. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/images.md +0 -0
  67. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/macro.md +0 -0
  68. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/math.md +0 -0
  69. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/mermaid.md +0 -0
  70. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/missing.md +0 -0
  71. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/sections.md +0 -0
  72. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/status.md +0 -0
  73. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/table.md +0 -0
  74. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/tags.md +0 -0
  75. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/title.md +0 -0
  76. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/source/toc.md +0 -0
  77. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/admonition.xml +0 -0
  78. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/alert.xml +0 -0
  79. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/alignment.xml +0 -0
  80. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/anchors.xml +0 -0
  81. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/basic.xml +0 -0
  82. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/code.xml +0 -0
  83. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/collapsed.xml +0 -0
  84. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/fenced.xml +0 -0
  85. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/footnote.xml +0 -0
  86. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/images/images.xml +0 -0
  87. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/images.xml +0 -0
  88. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/macro.xml +0 -0
  89. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/math.xml +0 -0
  90. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/mermaid.xml +0 -0
  91. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/missing.xml +0 -0
  92. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/sections.xml +0 -0
  93. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/status.xml +0 -0
  94. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/table.xml +0 -0
  95. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/tags.xml +0 -0
  96. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/target/toc.xml +0 -0
  97. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_conversion.py +0 -0
  98. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_drawio.py +0 -0
  99. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_processor.py +0 -0
  100. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_scanner.py +0 -0
  101. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_text.py +0 -0
  102. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_unit.py +0 -0
  103. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/test_xml.py +0 -0
  104. {markdown_to_confluence-0.4.7 → markdown_to_confluence-0.4.8}/tests/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-to-confluence
3
- Version: 0.4.7
3
+ Version: 0.4.8
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>
@@ -26,20 +26,20 @@ License-File: LICENSE
26
26
  Requires-Dist: certifi>=2025.8.3; python_version < "3.10"
27
27
  Requires-Dist: json_strong_typing>=0.4
28
28
  Requires-Dist: lxml>=6.0
29
- Requires-Dist: markdown>=3.8
29
+ Requires-Dist: markdown>=3.9
30
30
  Requires-Dist: pymdown-extensions>=10.16
31
31
  Requires-Dist: PyYAML>=6.0
32
32
  Requires-Dist: requests>=2.32
33
33
  Requires-Dist: truststore>=0.10; python_version >= "3.10"
34
- Requires-Dist: typing-extensions>=4.14; python_version < "3.12"
34
+ Requires-Dist: typing-extensions>=4.15; python_version < "3.12"
35
35
  Provides-Extra: dev
36
- Requires-Dist: markdown_doc>=0.1.4; python_version >= "3.10" and extra == "dev"
37
- Requires-Dist: types-lxml>=2025.3.30; extra == "dev"
38
- Requires-Dist: types-markdown>=3.8; extra == "dev"
36
+ Requires-Dist: markdown_doc>=0.1.5; python_version >= "3.10" and extra == "dev"
37
+ Requires-Dist: types-lxml>=2025.8.25; extra == "dev"
38
+ Requires-Dist: types-markdown>=3.9; 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.16; extra == "dev"
42
- Requires-Dist: ruff>=0.12; extra == "dev"
41
+ Requires-Dist: mypy>=1.18; extra == "dev"
42
+ Requires-Dist: ruff>=0.13; extra == "dev"
43
43
  Provides-Extra: formulas
44
44
  Requires-Dist: matplotlib>=3.9; extra == "formulas"
45
45
  Dynamic: license-file
@@ -425,9 +425,9 @@ Use the pseudo-language `csf` in a Markdown code block to pass content directly
425
425
 
426
426
  ### Ignoring files
427
427
 
428
- Skip files 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.
428
+ 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.
429
429
 
430
- Files that don't have the extension `*.md` are skipped automatically. Hidden directories (whose name starts with `.`) are not recursed into.
430
+ 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 `/`.
431
431
 
432
432
  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.
433
433
 
@@ -501,7 +501,7 @@ You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documen
501
501
 
502
502
  *md2conf* offers two options to publish the diagram:
503
503
 
504
- 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. This is the approach we use and support.
504
+ 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.
505
505
  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.
506
506
 
507
507
  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:
@@ -512,6 +512,14 @@ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
512
512
 
513
513
  Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
514
514
 
515
+ 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.
516
+
517
+ ### Alignment
518
+
519
+ 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.
520
+
521
+ 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.
522
+
515
523
  ### Links to attachments
516
524
 
517
525
  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.
@@ -586,6 +594,12 @@ options:
586
594
  --use-panel Transform admonitions and alerts into a Confluence custom panel.
587
595
  ```
588
596
 
597
+ ### Confluence REST API v1 vs. v2
598
+
599
+ *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.
600
+
601
+ If you are restricted to an environment with Confluence REST API v1, we recommend *md2conf* [version 0.2.7](https://pypi.org/project/markdown-to-confluence/0.2.7/). Even though we don't actively support it, we are not aware of any major issues, making it a viable option in an on-premise environment with only Confluence REST API v1 support.
602
+
589
603
  ### Using the Docker container
590
604
 
591
605
  You can run the Docker container via `docker run` or via `Dockerfile`. Either can accept the environment variables or arguments similar to the Python options. The final argument `./` corresponds to `mdpath` in the command-line utility.
@@ -1,49 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: markdown-to-confluence
3
- Version: 0.4.7
4
- Summary: Publish Markdown files to Confluence wiki
5
- Author-email: Levente Hunyadi <hunyadi@gmail.com>
6
- Maintainer-email: Levente Hunyadi <hunyadi@gmail.com>
7
- License-Expression: MIT
8
- Project-URL: Homepage, https://github.com/hunyadi/md2conf
9
- Project-URL: Source, https://github.com/hunyadi/md2conf
10
- Keywords: markdown,converter,confluence
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Environment :: Console
13
- Classifier: Intended Audience :: End Users/Desktop
14
- Classifier: Operating System :: OS Independent
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.9
17
- Classifier: Programming Language :: Python :: 3.10
18
- Classifier: Programming Language :: Python :: 3.11
19
- Classifier: Programming Language :: Python :: 3.12
20
- Classifier: Programming Language :: Python :: 3.13
21
- Classifier: Programming Language :: Python :: 3 :: Only
22
- Classifier: Typing :: Typed
23
- Requires-Python: >=3.9
24
- Description-Content-Type: text/markdown
25
- License-File: LICENSE
26
- Requires-Dist: certifi>=2025.8.3; python_version < "3.10"
27
- Requires-Dist: json_strong_typing>=0.4
28
- Requires-Dist: lxml>=6.0
29
- Requires-Dist: markdown>=3.8
30
- Requires-Dist: pymdown-extensions>=10.16
31
- Requires-Dist: PyYAML>=6.0
32
- Requires-Dist: requests>=2.32
33
- Requires-Dist: truststore>=0.10; python_version >= "3.10"
34
- Requires-Dist: typing-extensions>=4.14; python_version < "3.12"
35
- Provides-Extra: dev
36
- Requires-Dist: markdown_doc>=0.1.4; python_version >= "3.10" and extra == "dev"
37
- Requires-Dist: types-lxml>=2025.3.30; extra == "dev"
38
- Requires-Dist: types-markdown>=3.8; extra == "dev"
39
- Requires-Dist: types-PyYAML>=6.0; extra == "dev"
40
- Requires-Dist: types-requests>=2.32; extra == "dev"
41
- Requires-Dist: mypy>=1.16; extra == "dev"
42
- Requires-Dist: ruff>=0.12; extra == "dev"
43
- Provides-Extra: formulas
44
- Requires-Dist: matplotlib>=3.9; extra == "formulas"
45
- Dynamic: license-file
46
-
47
1
  # Publish Markdown files to Confluence wiki
48
2
 
49
3
  Contributors to software projects typically write documentation in Markdown format and host Markdown files in collaborative version control systems (VCS) such as GitHub or GitLab to track changes and facilitate the review process. However, not everyone at a company has access to VCS, and documents are often circulated in Confluence wiki instead.
@@ -425,9 +379,9 @@ Use the pseudo-language `csf` in a Markdown code block to pass content directly
425
379
 
426
380
  ### Ignoring files
427
381
 
428
- Skip files 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.
382
+ 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.
429
383
 
430
- Files that don't have the extension `*.md` are skipped automatically. Hidden directories (whose name starts with `.`) are not recursed into.
384
+ 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 `/`.
431
385
 
432
386
  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.
433
387
 
@@ -501,7 +455,7 @@ You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documen
501
455
 
502
456
  *md2conf* offers two options to publish the diagram:
503
457
 
504
- 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. This is the approach we use and support.
458
+ 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.
505
459
  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.
506
460
 
507
461
  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:
@@ -512,6 +466,14 @@ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
512
466
 
513
467
  Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
514
468
 
469
+ 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.
470
+
471
+ ### Alignment
472
+
473
+ 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.
474
+
475
+ 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.
476
+
515
477
  ### Links to attachments
516
478
 
517
479
  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.
@@ -586,6 +548,12 @@ options:
586
548
  --use-panel Transform admonitions and alerts into a Confluence custom panel.
587
549
  ```
588
550
 
551
+ ### Confluence REST API v1 vs. v2
552
+
553
+ *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.
554
+
555
+ If you are restricted to an environment with Confluence REST API v1, we recommend *md2conf* [version 0.2.7](https://pypi.org/project/markdown-to-confluence/0.2.7/). Even though we don't actively support it, we are not aware of any major issues, making it a viable option in an on-premise environment with only Confluence REST API v1 support.
556
+
589
557
  ### Using the Docker container
590
558
 
591
559
  You can run the Docker container via `docker run` or via `Dockerfile`. Either can accept the environment variables or arguments similar to the Python options. The final argument `./` corresponds to `mdpath` in the command-line utility.
@@ -1,3 +1,49 @@
1
+ Metadata-Version: 2.4
2
+ Name: markdown-to-confluence
3
+ Version: 0.4.8
4
+ Summary: Publish Markdown files to Confluence wiki
5
+ Author-email: Levente Hunyadi <hunyadi@gmail.com>
6
+ Maintainer-email: Levente Hunyadi <hunyadi@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/hunyadi/md2conf
9
+ Project-URL: Source, https://github.com/hunyadi/md2conf
10
+ Keywords: markdown,converter,confluence
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: certifi>=2025.8.3; python_version < "3.10"
27
+ Requires-Dist: json_strong_typing>=0.4
28
+ Requires-Dist: lxml>=6.0
29
+ Requires-Dist: markdown>=3.9
30
+ Requires-Dist: pymdown-extensions>=10.16
31
+ Requires-Dist: PyYAML>=6.0
32
+ Requires-Dist: requests>=2.32
33
+ Requires-Dist: truststore>=0.10; python_version >= "3.10"
34
+ Requires-Dist: typing-extensions>=4.15; python_version < "3.12"
35
+ Provides-Extra: dev
36
+ Requires-Dist: markdown_doc>=0.1.5; python_version >= "3.10" and extra == "dev"
37
+ Requires-Dist: types-lxml>=2025.8.25; extra == "dev"
38
+ Requires-Dist: types-markdown>=3.9; extra == "dev"
39
+ Requires-Dist: types-PyYAML>=6.0; extra == "dev"
40
+ Requires-Dist: types-requests>=2.32; extra == "dev"
41
+ Requires-Dist: mypy>=1.18; extra == "dev"
42
+ Requires-Dist: ruff>=0.13; extra == "dev"
43
+ Provides-Extra: formulas
44
+ Requires-Dist: matplotlib>=3.9; extra == "formulas"
45
+ Dynamic: license-file
46
+
1
47
  # Publish Markdown files to Confluence wiki
2
48
 
3
49
  Contributors to software projects typically write documentation in Markdown format and host Markdown files in collaborative version control systems (VCS) such as GitHub or GitLab to track changes and facilitate the review process. However, not everyone at a company has access to VCS, and documents are often circulated in Confluence wiki instead.
@@ -379,9 +425,9 @@ Use the pseudo-language `csf` in a Markdown code block to pass content directly
379
425
 
380
426
  ### Ignoring files
381
427
 
382
- Skip files 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.
428
+ 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.
383
429
 
384
- Files that don't have the extension `*.md` are skipped automatically. Hidden directories (whose name starts with `.`) are not recursed into.
430
+ 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 `/`.
385
431
 
386
432
  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.
387
433
 
@@ -455,7 +501,7 @@ You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documen
455
501
 
456
502
  *md2conf* offers two options to publish the diagram:
457
503
 
458
- 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. This is the approach we use and support.
504
+ 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.
459
505
  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.
460
506
 
461
507
  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:
@@ -466,6 +512,14 @@ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
466
512
 
467
513
  Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
468
514
 
515
+ 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.
516
+
517
+ ### Alignment
518
+
519
+ 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.
520
+
521
+ 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.
522
+
469
523
  ### Links to attachments
470
524
 
471
525
  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.
@@ -540,6 +594,12 @@ options:
540
594
  --use-panel Transform admonitions and alerts into a Confluence custom panel.
541
595
  ```
542
596
 
597
+ ### Confluence REST API v1 vs. v2
598
+
599
+ *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.
600
+
601
+ If you are restricted to an environment with Confluence REST API v1, we recommend *md2conf* [version 0.2.7](https://pypi.org/project/markdown-to-confluence/0.2.7/). Even though we don't actively support it, we are not aware of any major issues, making it a viable option in an on-premise environment with only Confluence REST API v1 support.
602
+
543
603
  ### Using the Docker container
544
604
 
545
605
  You can run the Docker container via `docker run` or via `Dockerfile`. Either can accept the environment variables or arguments similar to the Python options. The final argument `./` corresponds to `mdpath` in the command-line utility.
@@ -1,6 +1,6 @@
1
1
  json_strong_typing>=0.4
2
2
  lxml>=6.0
3
- markdown>=3.8
3
+ markdown>=3.9
4
4
  pymdown-extensions>=10.16
5
5
  PyYAML>=6.0
6
6
  requests>=2.32
@@ -9,21 +9,21 @@ requests>=2.32
9
9
  certifi>=2025.8.3
10
10
 
11
11
  [:python_version < "3.12"]
12
- typing-extensions>=4.14
12
+ typing-extensions>=4.15
13
13
 
14
14
  [:python_version >= "3.10"]
15
15
  truststore>=0.10
16
16
 
17
17
  [dev]
18
- types-lxml>=2025.3.30
19
- types-markdown>=3.8
18
+ types-lxml>=2025.8.25
19
+ types-markdown>=3.9
20
20
  types-PyYAML>=6.0
21
21
  types-requests>=2.32
22
- mypy>=1.16
23
- ruff>=0.12
22
+ mypy>=1.18
23
+ ruff>=0.13
24
24
 
25
25
  [dev:python_version >= "3.10"]
26
- markdown_doc>=0.1.4
26
+ markdown_doc>=0.1.5
27
27
 
28
28
  [formulas]
29
29
  matplotlib>=3.9
@@ -5,7 +5,7 @@ Parses Markdown files, converts Markdown content into the Confluence Storage For
5
5
  Confluence API endpoints to upload images and content.
6
6
  """
7
7
 
8
- __version__ = "0.4.7"
8
+ __version__ = "0.4.8"
9
9
  __author__ = "Levente Hunyadi"
10
10
  __copyright__ = "Copyright 2022-2025, Levente Hunyadi"
11
11
  __license__ = "MIT"
@@ -405,18 +405,18 @@ class ConfluencePanel:
405
405
 
406
406
 
407
407
  ConfluencePanel.from_class = {
408
- "attention": ConfluencePanel("❗", "exclamation", "#F9F9F9"), # rST admonition
409
- "caution": ConfluencePanel("❌", "x", "#FFEBE9"),
410
- "danger": ConfluencePanel("☠️", "skull_crossbones", "#FFE5E5"), # rST admonition
411
- "disclaimer": ConfluencePanel("❗", "exclamation", "#F9F9F9"), # GitLab
412
- "error": ConfluencePanel("❌", "x", "#FFEBE9"), # rST admonition
413
- "flag": ConfluencePanel("🚩", "triangular_flag_on_post", "#FDECEA"), # GitLab
414
- "hint": ConfluencePanel("💡", "bulb", "#DAFBE1"), # rST admonition
415
- "info": ConfluencePanel("ℹ️", "information_source", "#DDF4FF"),
416
- "note": ConfluencePanel("📝", "pencil", "#DDF4FF"),
417
- "tip": ConfluencePanel("💡", "bulb", "#DAFBE1"),
418
- "important": ConfluencePanel("❗", "exclamation", "#FBEFFF"),
419
- "warning": ConfluencePanel("⚠️", "warning", "#FFF8C5"),
408
+ "attention": ConfluencePanel("❗", "exclamation", "var(--ds-background-accent-gray-subtlest)"), # rST admonition
409
+ "caution": ConfluencePanel("❌", "x", "var(--ds-background-accent-orange-subtlest)"),
410
+ "danger": ConfluencePanel("☠️", "skull_crossbones", "var(--ds-background-accent-red-subtlest)"), # rST admonition
411
+ "disclaimer": ConfluencePanel("❗", "exclamation", "var(--ds-background-accent-gray-subtlest)"), # GitLab
412
+ "error": ConfluencePanel("❌", "x", "var(--ds-background-accent-red-subtlest)"), # rST admonition
413
+ "flag": ConfluencePanel("🚩", "triangular_flag_on_post", "var(--ds-background-accent-orange-subtlest"), # GitLab
414
+ "hint": ConfluencePanel("💡", "bulb", "var(--ds-background-accent-green-subtlest)"), # rST admonition
415
+ "info": ConfluencePanel("ℹ️", "information_source", "var(--ds-background-accent-blue-subtlest)"),
416
+ "note": ConfluencePanel("📝", "pencil", "var(--ds-background-accent-teal-subtlest)"),
417
+ "tip": ConfluencePanel("💡", "bulb", "var(--ds-background-accent-green-subtlest)"),
418
+ "important": ConfluencePanel("❗", "exclamation", "var(--ds-background-accent-purple-subtlest)"),
419
+ "warning": ConfluencePanel("⚠️", "warning", "var(--ds-background-accent-yellow-subtlest)"),
420
420
  }
421
421
 
422
422
 
@@ -817,6 +817,14 @@ class ConfluenceStorageFormatConverter(NodeVisitor):
817
817
  str(attrs.height),
818
818
  ),
819
819
  )
820
+ if attrs.alignment is ImageAlignment.CENTER:
821
+ parameters.append(
822
+ AC_ELEM(
823
+ "parameter",
824
+ {AC_ATTR("name"): "pCenter"},
825
+ str(1),
826
+ ),
827
+ )
820
828
 
821
829
  local_id = str(uuid.uuid4())
822
830
  macro_id = str(uuid.uuid4())
@@ -1650,7 +1658,7 @@ class ConfluenceStorageFormatConverter(NodeVisitor):
1650
1658
  # <li>[x] ...</li>
1651
1659
  # </ul>
1652
1660
  elif child.tag == "ul":
1653
- if len(child) > 0 and element_text_starts_with_any(child[0], ["[ ]", "[x]", "[X]"]):
1661
+ if len(child) > 0 and all(element_text_starts_with_any(item, ["[ ]", "[x]", "[X]"]) for item in child):
1654
1662
  return self._transform_tasklist(child)
1655
1663
 
1656
1664
  return None
@@ -33,24 +33,24 @@ dependencies = [
33
33
  "certifi >= 2025.8.3; python_version<'3.10'",
34
34
  "json_strong_typing >= 0.4",
35
35
  "lxml >= 6.0",
36
- "markdown >= 3.8",
36
+ "markdown >= 3.9",
37
37
  "pymdown-extensions >= 10.16",
38
38
  "PyYAML >= 6.0",
39
39
  "requests >= 2.32",
40
40
  "truststore >= 0.10; python_version>='3.10'",
41
- "typing-extensions >= 4.14; python_version < '3.12'"
41
+ "typing-extensions >= 4.15; python_version < '3.12'"
42
42
  ]
43
43
  dynamic = ["version"]
44
44
 
45
45
  [project.optional-dependencies]
46
46
  dev = [
47
- "markdown_doc >= 0.1.4; python_version >= '3.10'",
48
- "types-lxml >= 2025.3.30",
49
- "types-markdown >= 3.8",
47
+ "markdown_doc >= 0.1.5; python_version >= '3.10'",
48
+ "types-lxml >= 2025.8.25",
49
+ "types-markdown >= 3.9",
50
50
  "types-PyYAML >= 6.0",
51
51
  "types-requests >= 2.32",
52
- "mypy >= 1.16",
53
- "ruff >= 0.12"
52
+ "mypy >= 1.18",
53
+ "ruff >= 0.13"
54
54
  ]
55
55
  formulas = [
56
56
  "matplotlib >= 3.9"
@@ -0,0 +1,19 @@
1
+ <!-- confluence-page-id: 00000000000 -->
2
+
3
+ ## Tasklist
4
+
5
+ ### Examples
6
+
7
+ - [x] **Finished** action
8
+ - [ ] **Unfinished** action
9
+
10
+ ### Counter-examples
11
+
12
+ - first item is not a task
13
+ - [x] **finished** action
14
+ - [ ] **unfinished** action
15
+
16
+ <!-- separates consecutive lists -->
17
+ - [x] **finished** action
18
+ - [ ] **unfinished** action
19
+ - last item is not a task
@@ -8,7 +8,7 @@
8
8
  <ac:parameter ac:name="panelIcon">:information_source:</ac:parameter>
9
9
  <ac:parameter ac:name="panelIconId">2139-fe0f</ac:parameter>
10
10
  <ac:parameter ac:name="panelIconText">ℹ️</ac:parameter>
11
- <ac:parameter ac:name="bgColor">#DDF4FF</ac:parameter>
11
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-blue-subtlest)</ac:parameter>
12
12
  <ac:rich-text-body>
13
13
  <p><strong>Info</strong></p>
14
14
  <p>This is an information panel.</p>
@@ -18,7 +18,7 @@
18
18
  <ac:parameter ac:name="panelIcon">:information_source:</ac:parameter>
19
19
  <ac:parameter ac:name="panelIconId">2139-fe0f</ac:parameter>
20
20
  <ac:parameter ac:name="panelIconText">ℹ️</ac:parameter>
21
- <ac:parameter ac:name="bgColor">#DDF4FF</ac:parameter>
21
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-blue-subtlest)</ac:parameter>
22
22
  <ac:rich-text-body>
23
23
  <p><strong>Optional explicit title</strong></p>
24
24
  <p>This is an information panel with an explicit title.</p>
@@ -29,7 +29,7 @@
29
29
  <ac:parameter ac:name="panelIcon">:bulb:</ac:parameter>
30
30
  <ac:parameter ac:name="panelIconId">1f4a1</ac:parameter>
31
31
  <ac:parameter ac:name="panelIconText">💡</ac:parameter>
32
- <ac:parameter ac:name="bgColor">#DAFBE1</ac:parameter>
32
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-green-subtlest)</ac:parameter>
33
33
  <ac:rich-text-body>
34
34
  <p><strong>Tip of the day</strong></p>
35
35
  <p>This is a structured macro panel showing a tip.</p>
@@ -39,7 +39,7 @@
39
39
  <ac:parameter ac:name="panelIcon">:pencil:</ac:parameter>
40
40
  <ac:parameter ac:name="panelIconId">1f4dd</ac:parameter>
41
41
  <ac:parameter ac:name="panelIconText">📝</ac:parameter>
42
- <ac:parameter ac:name="bgColor">#DDF4FF</ac:parameter>
42
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-teal-subtlest)</ac:parameter>
43
43
  <ac:rich-text-body>
44
44
  <p><strong>A note</strong></p>
45
45
  <p>This is a structured macro panel showing a note.</p>
@@ -48,7 +48,7 @@
48
48
  <ac:parameter ac:name="panelIcon">:warning:</ac:parameter>
49
49
  <ac:parameter ac:name="panelIconId">26a0-fe0f</ac:parameter>
50
50
  <ac:parameter ac:name="panelIconText">⚠️</ac:parameter>
51
- <ac:parameter ac:name="bgColor">#FFF8C5</ac:parameter>
51
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-yellow-subtlest)</ac:parameter>
52
52
  <ac:rich-text-body>
53
53
  <p><strong>A warning message</strong></p>
54
54
  <p>This is a structured macro panel showing a warning.</p>
@@ -57,7 +57,7 @@
57
57
  <ac:parameter ac:name="panelIcon">:exclamation:</ac:parameter>
58
58
  <ac:parameter ac:name="panelIconId">2757</ac:parameter>
59
59
  <ac:parameter ac:name="panelIconText">❗</ac:parameter>
60
- <ac:parameter ac:name="bgColor">#F9F9F9</ac:parameter>
60
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-gray-subtlest)</ac:parameter>
61
61
  <ac:rich-text-body>
62
62
  <p><strong>Attention</strong></p>
63
63
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -66,7 +66,7 @@
66
66
  <ac:parameter ac:name="panelIcon">:x:</ac:parameter>
67
67
  <ac:parameter ac:name="panelIconId">274c</ac:parameter>
68
68
  <ac:parameter ac:name="panelIconText">❌</ac:parameter>
69
- <ac:parameter ac:name="bgColor">#FFEBE9</ac:parameter>
69
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-orange-subtlest)</ac:parameter>
70
70
  <ac:rich-text-body>
71
71
  <p><strong>Caution</strong></p>
72
72
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -75,7 +75,7 @@
75
75
  <ac:parameter ac:name="panelIcon">:skull_crossbones:</ac:parameter>
76
76
  <ac:parameter ac:name="panelIconId">2620-fe0f</ac:parameter>
77
77
  <ac:parameter ac:name="panelIconText">☠️</ac:parameter>
78
- <ac:parameter ac:name="bgColor">#FFE5E5</ac:parameter>
78
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-red-subtlest)</ac:parameter>
79
79
  <ac:rich-text-body>
80
80
  <p><strong>Danger</strong></p>
81
81
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -84,7 +84,7 @@
84
84
  <ac:parameter ac:name="panelIcon">:x:</ac:parameter>
85
85
  <ac:parameter ac:name="panelIconId">274c</ac:parameter>
86
86
  <ac:parameter ac:name="panelIconText">❌</ac:parameter>
87
- <ac:parameter ac:name="bgColor">#FFEBE9</ac:parameter>
87
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-red-subtlest)</ac:parameter>
88
88
  <ac:rich-text-body>
89
89
  <p><strong>Error</strong></p>
90
90
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -94,7 +94,7 @@
94
94
  <ac:parameter ac:name="panelIcon">:bulb:</ac:parameter>
95
95
  <ac:parameter ac:name="panelIconId">1f4a1</ac:parameter>
96
96
  <ac:parameter ac:name="panelIconText">💡</ac:parameter>
97
- <ac:parameter ac:name="bgColor">#DAFBE1</ac:parameter>
97
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-green-subtlest)</ac:parameter>
98
98
  <ac:rich-text-body>
99
99
  <p><strong>Hint</strong></p>
100
100
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -104,7 +104,7 @@
104
104
  <ac:parameter ac:name="panelIcon">:exclamation:</ac:parameter>
105
105
  <ac:parameter ac:name="panelIconId">2757</ac:parameter>
106
106
  <ac:parameter ac:name="panelIconText">❗</ac:parameter>
107
- <ac:parameter ac:name="bgColor">#FBEFFF</ac:parameter>
107
+ <ac:parameter ac:name="bgColor">var(--ds-background-accent-purple-subtlest)</ac:parameter>
108
108
  <ac:rich-text-body>
109
109
  <p><strong>Important</strong></p>
110
110
  <p>This is a structured macro panel defined in rST syntax.</p>
@@ -4,6 +4,7 @@
4
4
  </ac:rich-text-body>
5
5
  </ac:structured-macro>
6
6
  <h2>Tasklist</h2>
7
+ <h3>Examples</h3>
7
8
  <ac:task-list>
8
9
  <ac:task>
9
10
  <ac:task-id>1</ac:task-id>
@@ -18,3 +19,14 @@
18
19
  <ac:task-body><strong>Unfinished</strong> action</ac:task-body>
19
20
  </ac:task>
20
21
  </ac:task-list>
22
+ <h3>Counter-examples</h3>
23
+ <ul>
24
+ <li><p>first item is not a task</p></li>
25
+ <li><p>[x] <strong>finished</strong> action</p></li>
26
+ <li><p>[ ] <strong>unfinished</strong> action</p></li>
27
+ </ul>
28
+ <ul>
29
+ <li><p>[x] <strong>finished</strong> action</p></li>
30
+ <li><p>[ ] <strong>unfinished</strong> action</p></li>
31
+ <li><p>last item is not a task</p></li>
32
+ </ul>
@@ -63,6 +63,7 @@ class TestMatcher(TypedTestCase):
63
63
  def test_rules(self) -> None:
64
64
  directory = Path(os.path.dirname(__file__)) / "source"
65
65
  expected = sorted(Entry(entry.name, entry.is_dir()) for entry in os.scandir(directory) if entry.is_dir() or entry.name.endswith(".md"))
66
+ expected.remove(Entry("docs", True))
66
67
  expected.remove(Entry("ignore.md", False))
67
68
  expected.remove(Entry("anchors.md", False))
68
69
  expected.remove(Entry("missing.md", False))
@@ -8,11 +8,9 @@ Copyright 2022-2025, Levente Hunyadi
8
8
 
9
9
  import logging
10
10
  import os
11
- import shutil
12
11
  import unittest
13
- from pathlib import Path
12
+ import xml.etree.ElementTree as ET
14
13
 
15
- from md2conf.extra import override
16
14
  from md2conf.mermaid import has_mmdc, render_diagram
17
15
  from tests.utility import TypedTestCase
18
16
 
@@ -32,29 +30,10 @@ graph TD
32
30
  @unittest.skipUnless(has_mmdc(), "mmdc is not available")
33
31
  @unittest.skipUnless(os.getenv("TEST_MERMAID"), "mermaid tests are disabled")
34
32
  class TestMermaidRendering(TypedTestCase):
35
- out_dir: Path
36
-
37
- @override
38
- def setUp(self) -> None:
39
- self.maxDiff = 1024
40
-
41
- test_dir = Path(__file__).parent
42
- parent_dir = test_dir.parent
43
-
44
- self.out_dir = test_dir / "output"
45
- self.sample_dir = parent_dir / "sample"
46
- os.makedirs(self.out_dir, exist_ok=True)
47
-
48
- @override
49
- def tearDown(self) -> None:
50
- shutil.rmtree(self.out_dir)
51
-
52
33
  def test_render_simple_svg(self) -> None:
53
- svg = render_diagram(MERMAID_SOURCE, output_format="svg").decode()
54
-
55
- self.assertIn("transform=", svg)
56
- self.assertIn("translate(", svg)
57
- self.assertIn("<rect height=", svg)
34
+ svg = render_diagram(MERMAID_SOURCE, output_format="svg")
35
+ root = ET.fromstring(svg)
36
+ self.assertTrue(root.tag.lower() == "svg" or root.tag.endswith("}svg"))
58
37
 
59
38
  def test_render_simple_png(self) -> None:
60
39
  png = render_diagram(MERMAID_SOURCE)
@@ -1,6 +0,0 @@
1
- <!-- confluence-page-id: 00000000000 -->
2
-
3
- ## Tasklist
4
-
5
- - [x] **Finished** action
6
- - [ ] **Unfinished** action