markdown-to-confluence 0.5.2__py3-none-any.whl → 0.5.4__py3-none-any.whl

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 (54) hide show
  1. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/METADATA +258 -157
  2. markdown_to_confluence-0.5.4.dist-info/RECORD +55 -0
  3. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/licenses/LICENSE +1 -1
  4. md2conf/__init__.py +2 -2
  5. md2conf/__main__.py +83 -44
  6. md2conf/api.py +30 -10
  7. md2conf/attachment.py +72 -0
  8. md2conf/coalesce.py +43 -0
  9. md2conf/collection.py +1 -1
  10. md2conf/{extra.py → compatibility.py} +1 -1
  11. md2conf/converter.py +240 -657
  12. md2conf/csf.py +13 -11
  13. md2conf/drawio/__init__.py +0 -0
  14. md2conf/drawio/extension.py +116 -0
  15. md2conf/{drawio.py → drawio/render.py} +1 -1
  16. md2conf/emoticon.py +3 -3
  17. md2conf/environment.py +2 -2
  18. md2conf/extension.py +82 -0
  19. md2conf/external.py +66 -0
  20. md2conf/formatting.py +135 -0
  21. md2conf/frontmatter.py +70 -0
  22. md2conf/image.py +128 -0
  23. md2conf/latex.py +4 -183
  24. md2conf/local.py +8 -8
  25. md2conf/markdown.py +1 -1
  26. md2conf/matcher.py +1 -1
  27. md2conf/mermaid/__init__.py +0 -0
  28. md2conf/mermaid/config.py +20 -0
  29. md2conf/mermaid/extension.py +109 -0
  30. md2conf/{mermaid.py → mermaid/render.py} +10 -38
  31. md2conf/mermaid/scanner.py +55 -0
  32. md2conf/metadata.py +1 -1
  33. md2conf/{domain.py → options.py} +75 -16
  34. md2conf/plantuml/__init__.py +0 -0
  35. md2conf/plantuml/config.py +20 -0
  36. md2conf/plantuml/extension.py +158 -0
  37. md2conf/plantuml/render.py +138 -0
  38. md2conf/plantuml/scanner.py +56 -0
  39. md2conf/png.py +206 -0
  40. md2conf/processor.py +55 -13
  41. md2conf/publisher.py +127 -39
  42. md2conf/scanner.py +38 -129
  43. md2conf/serializer.py +2 -2
  44. md2conf/svg.py +144 -103
  45. md2conf/text.py +1 -1
  46. md2conf/toc.py +73 -1
  47. md2conf/uri.py +1 -1
  48. md2conf/xml.py +1 -1
  49. markdown_to_confluence-0.5.2.dist-info/RECORD +0 -36
  50. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/WHEEL +0 -0
  51. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/entry_points.txt +0 -0
  52. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/top_level.txt +0 -0
  53. {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/zip-safe +0 -0
  54. /md2conf/{puppeteer-config.json → mermaid/puppeteer-config.json} +0 -0
md2conf/toc.py CHANGED
@@ -1,12 +1,14 @@
1
1
  """
2
2
  Publish Markdown files to Confluence wiki.
3
3
 
4
- Copyright 2022-2025, Levente Hunyadi
4
+ Copyright 2022-2026, Levente Hunyadi
5
5
 
6
6
  :see: https://github.com/hunyadi/md2conf
7
7
  """
8
8
 
9
+ import re
9
10
  from dataclasses import dataclass
11
+ from typing import Iterable, Iterator
10
12
 
11
13
 
12
14
  @dataclass(eq=True)
@@ -86,3 +88,73 @@ class TableOfContentsBuilder:
86
88
  return self.tree[0].text
87
89
  else:
88
90
  return None
91
+
92
+
93
+ _FENCED_CODE_REGEXP = re.compile(r"^\s*(?:`{3,}|~{3,})", re.MULTILINE)
94
+ _ATX_HEADING_REGEXP = re.compile(r"^(#{1,6})\s+(.*?)$", re.MULTILINE)
95
+ _SETEXT_HEADING_REGEXP = re.compile(r"^(=+|-+)\s*?$", re.MULTILINE)
96
+
97
+
98
+ def headings(lines: Iterable[str]) -> Iterator[tuple[int, str]]:
99
+ fence_marker: str | None = None
100
+ heading_text: str | None = None
101
+
102
+ for line in lines:
103
+ # fenced code blocks
104
+ fence_match = _FENCED_CODE_REGEXP.match(line)
105
+ if fence_match:
106
+ marker = fence_match.group()
107
+ if fence_marker is None:
108
+ fence_marker = marker
109
+ elif marker == fence_marker:
110
+ fence_marker = None
111
+ heading_text = None
112
+ continue
113
+
114
+ if fence_marker is not None:
115
+ heading_text = None
116
+ continue
117
+
118
+ # ATX headings
119
+ atx = _ATX_HEADING_REGEXP.match(line)
120
+ if atx is not None:
121
+ level = len(atx.group(1))
122
+ title = atx.group(2).rstrip().rstrip("#").rstrip() # remove decorative text: `## Section 1.2 ##`
123
+ yield level, title
124
+
125
+ heading_text = None
126
+ continue
127
+
128
+ # Setext headings
129
+ setext = _SETEXT_HEADING_REGEXP.match(line)
130
+ if setext is not None and heading_text is not None:
131
+ match setext.group(1)[0:1]:
132
+ case "=":
133
+ level = 1
134
+ case "-":
135
+ level = 2
136
+ case _:
137
+ level = 0
138
+ yield level, heading_text.rstrip()
139
+
140
+ heading_text = None
141
+ continue
142
+
143
+ # candidate for Setext title
144
+ heading_text = line
145
+
146
+
147
+ def unique_title(content: str) -> str | None:
148
+ """
149
+ Returns a proposed document title.
150
+
151
+ The proposed title is text of the top-level heading if and only if that heading is unique.
152
+
153
+ :returns: Title text, or `None` if no title can be inferred.
154
+ """
155
+
156
+ builder = TableOfContentsBuilder()
157
+ for heading in headings(content.splitlines(keepends=True)):
158
+ level, text = heading
159
+ builder.add(level, text)
160
+ return builder.get_title()
md2conf/uri.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Publish Markdown files to Confluence wiki.
3
3
 
4
- Copyright 2022-2025, Levente Hunyadi
4
+ Copyright 2022-2026, Levente Hunyadi
5
5
 
6
6
  :see: https://github.com/hunyadi/md2conf
7
7
  """
md2conf/xml.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Publish Markdown files to Confluence wiki.
3
3
 
4
- Copyright 2022-2025, Levente Hunyadi
4
+ Copyright 2022-2026, Levente Hunyadi
5
5
 
6
6
  :see: https://github.com/hunyadi/md2conf
7
7
  """
@@ -1,36 +0,0 @@
1
- markdown_to_confluence-0.5.2.dist-info/licenses/LICENSE,sha256=56L-Y0dyZwyVlINRJRz3PNw-ka-oLVaAq-7d8zo6qlc,1077
2
- md2conf/__init__.py,sha256=TZU4q64xgFKmFudp0-NIfMbAgcFihMCih-5sjAybGKs,402
3
- md2conf/__main__.py,sha256=GdYd7v6YpIbOcvaUNh_5TZXwnEGbaxlsIS0sJtMmyhE,13152
4
- md2conf/api.py,sha256=v4QXiNFGHyIhYZWb36uG-AR4HBPoj2GZI939ao9SOIQ,41989
5
- md2conf/collection.py,sha256=nghFS5kK4kPbpLE7IHi4rprJK-Mu4KXNxjHYM9Rc5SQ,824
6
- md2conf/converter.py,sha256=S6JiC-v5jqEVv4lcvCKxfLO-dZpHNLEfuocFBslIpaA,79924
7
- md2conf/csf.py,sha256=rugs3qC2aJQCJSTczeBw9WhqSZZtMq14LjwT0V1b6Hc,6476
8
- md2conf/domain.py,sha256=opq_O_NOz097HC4Q8VA7aNba6Snq09euTCi-Ag-bvAo,2685
9
- md2conf/drawio.py,sha256=IqFlAegrKM5SQf5CqHD8STIzskH7Rpm9RtWwn_nXVTc,8581
10
- md2conf/emoticon.py,sha256=P2L5oQvnRXeVifJQ3sJ2Ck-6ptbxumq2vsT-rM0W0Ms,484
11
- md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
12
- md2conf/environment.py,sha256=BhI7YktY7G26HOhGlUvTkH2Vmfa4E_dhu2snzbBgMvE,3902
13
- md2conf/extra.py,sha256=VuMxuOnnC2Qwy6y52ukIxsaYhrZArRqMmRHRE4QZl8g,687
14
- md2conf/latex.py,sha256=vZJakhwiSPkprz5IkJZOUw9H4FVXj_kksgMKoF8N_pI,7747
15
- md2conf/local.py,sha256=Ou-j7kZWbHxC8Si8Yg7myqtTQ1He6mYQW1NpX3LLIcY,3704
16
- md2conf/markdown.py,sha256=t-z19Zs_91_jzRvwmOsWqCDt0Tdghmk5bpNUON0YlKc,3148
17
- md2conf/matcher.py,sha256=hkM49osFM9nrXRXe4pwcGCg0rrLsmKep7AYY_S01kNY,6774
18
- md2conf/mermaid.py,sha256=9P4VV69dooaFBNUjdTIpzq7BFA8rDMqEif1O7XKWPdM,2617
19
- md2conf/metadata.py,sha256=_kt_lh4gCzVRRhhrDk-cJCk9WMcX9ZDWB6hL0Lw3xoI,976
20
- md2conf/processor.py,sha256=8Y-NSxAuqSHMSN9vhw_83HisGAmq87XAY98dis_xZ0Y,9690
21
- md2conf/publisher.py,sha256=ma0E_Kcxd86Qe_ywdhiTydkoJFRp6MI_Hy2ImFMKWsA,8752
22
- md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
23
- md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- md2conf/scanner.py,sha256=xxzNm3IRnlS0yAkStTHCigeLd6hUyvMYIBKFpTBEPf4,6776
25
- md2conf/serializer.py,sha256=JrBj8Z9zP8PjBeVAlRRqnMKDoz6IvkRbTd6K-JgFVow,1757
26
- md2conf/svg.py,sha256=LImoEKerVdXGkTnR6SogKvsR7WJNDVvMN1Ju_usbrNs,10306
27
- md2conf/text.py,sha256=fHOrUaPXAjE4iRhHqFq-CiI-knpo4wvyHCWp0crewqA,1736
28
- md2conf/toc.py,sha256=ZrfUfTv_Jiv27G4SBNjK3b-1ClYKoqN5yPRsEWp6IXk,2413
29
- md2conf/uri.py,sha256=KbLBdRFtZTQTZd8b4j0LtE8Pb68Ly0WkemF4iW-EAB4,1158
30
- md2conf/xml.py,sha256=Fu00Eg8c0VgMHIjRDBJBSNWtui8obEtowkiR7gHTduM,5526
31
- markdown_to_confluence-0.5.2.dist-info/METADATA,sha256=fts0cqy6A_o_QztqMmfVGWoY1kLEDftLNPKGhPsoMQo,40071
32
- markdown_to_confluence-0.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
- markdown_to_confluence-0.5.2.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
34
- markdown_to_confluence-0.5.2.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
35
- markdown_to_confluence-0.5.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
36
- markdown_to_confluence-0.5.2.dist-info/RECORD,,