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.
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/METADATA +258 -157
- markdown_to_confluence-0.5.4.dist-info/RECORD +55 -0
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/licenses/LICENSE +1 -1
- md2conf/__init__.py +2 -2
- md2conf/__main__.py +83 -44
- md2conf/api.py +30 -10
- md2conf/attachment.py +72 -0
- md2conf/coalesce.py +43 -0
- md2conf/collection.py +1 -1
- md2conf/{extra.py → compatibility.py} +1 -1
- md2conf/converter.py +240 -657
- md2conf/csf.py +13 -11
- md2conf/drawio/__init__.py +0 -0
- md2conf/drawio/extension.py +116 -0
- md2conf/{drawio.py → drawio/render.py} +1 -1
- md2conf/emoticon.py +3 -3
- md2conf/environment.py +2 -2
- md2conf/extension.py +82 -0
- md2conf/external.py +66 -0
- md2conf/formatting.py +135 -0
- md2conf/frontmatter.py +70 -0
- md2conf/image.py +128 -0
- md2conf/latex.py +4 -183
- md2conf/local.py +8 -8
- md2conf/markdown.py +1 -1
- md2conf/matcher.py +1 -1
- md2conf/mermaid/__init__.py +0 -0
- md2conf/mermaid/config.py +20 -0
- md2conf/mermaid/extension.py +109 -0
- md2conf/{mermaid.py → mermaid/render.py} +10 -38
- md2conf/mermaid/scanner.py +55 -0
- md2conf/metadata.py +1 -1
- md2conf/{domain.py → options.py} +75 -16
- md2conf/plantuml/__init__.py +0 -0
- md2conf/plantuml/config.py +20 -0
- md2conf/plantuml/extension.py +158 -0
- md2conf/plantuml/render.py +138 -0
- md2conf/plantuml/scanner.py +56 -0
- md2conf/png.py +206 -0
- md2conf/processor.py +55 -13
- md2conf/publisher.py +127 -39
- md2conf/scanner.py +38 -129
- md2conf/serializer.py +2 -2
- md2conf/svg.py +144 -103
- md2conf/text.py +1 -1
- md2conf/toc.py +73 -1
- md2conf/uri.py +1 -1
- md2conf/xml.py +1 -1
- markdown_to_confluence-0.5.2.dist-info/RECORD +0 -36
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/WHEEL +0 -0
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/entry_points.txt +0 -0
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/top_level.txt +0 -0
- {markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/zip-safe +0 -0
- /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-
|
|
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
md2conf/xml.py
CHANGED
|
@@ -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,,
|
|
File without changes
|
{markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{markdown_to_confluence-0.5.2.dist-info → markdown_to_confluence-0.5.4.dist-info}/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|