markdown-to-confluence 0.4.4__py3-none-any.whl → 0.4.6__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.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/METADATA +83 -33
- markdown_to_confluence-0.4.6.dist-info/RECORD +34 -0
- {markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/licenses/LICENSE +1 -1
- md2conf/__init__.py +1 -1
- md2conf/__main__.py +35 -39
- md2conf/api.py +90 -20
- md2conf/converter.py +585 -300
- md2conf/csf.py +66 -0
- md2conf/domain.py +2 -0
- md2conf/drawio.py +18 -14
- md2conf/emoticon.py +22 -0
- md2conf/latex.py +245 -0
- md2conf/local.py +2 -2
- md2conf/markdown.py +3 -1
- md2conf/mermaid.py +38 -29
- md2conf/processor.py +1 -1
- md2conf/{application.py → publisher.py} +28 -19
- md2conf/scanner.py +46 -0
- md2conf/text.py +54 -0
- md2conf/xml.py +37 -0
- markdown_to_confluence-0.4.4.dist-info/RECORD +0 -31
- {markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/WHEEL +0 -0
- {markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/entry_points.txt +0 -0
- {markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/top_level.txt +0 -0
- {markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/zip-safe +0 -0
- /md2conf/{properties.py → environment.py} +0 -0
md2conf/scanner.py
CHANGED
|
@@ -15,6 +15,8 @@ import yaml
|
|
|
15
15
|
from strong_typing.core import JsonType
|
|
16
16
|
from strong_typing.serialization import DeserializerOptions, json_to_object
|
|
17
17
|
|
|
18
|
+
from .mermaid import MermaidConfigProperties
|
|
19
|
+
|
|
18
20
|
T = TypeVar("T")
|
|
19
21
|
|
|
20
22
|
|
|
@@ -155,3 +157,47 @@ class Scanner:
|
|
|
155
157
|
properties=properties,
|
|
156
158
|
text=text,
|
|
157
159
|
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@dataclass
|
|
163
|
+
class MermaidProperties:
|
|
164
|
+
"""
|
|
165
|
+
An object that holds the front-matter properties structure for Mermaid diagrams.
|
|
166
|
+
|
|
167
|
+
:param title: The title of the diagram.
|
|
168
|
+
:param config: Configuration options for rendering.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
title: Optional[str] = None
|
|
172
|
+
config: Optional[MermaidConfigProperties] = None
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class MermaidScanner:
|
|
176
|
+
"""
|
|
177
|
+
Extracts properties from the JSON/YAML front-matter of a Mermaid diagram.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
def read(self, content: str) -> MermaidProperties:
|
|
181
|
+
"""
|
|
182
|
+
Extracts rendering preferences from a Mermaid front-matter content.
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
---
|
|
186
|
+
title: Tiny flow diagram
|
|
187
|
+
config:
|
|
188
|
+
scale: 1
|
|
189
|
+
---
|
|
190
|
+
flowchart LR
|
|
191
|
+
A[Component A] --> B[Component B]
|
|
192
|
+
B --> C[Component C]
|
|
193
|
+
```
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
properties, text = extract_frontmatter_properties(content)
|
|
197
|
+
if properties is not None:
|
|
198
|
+
front_matter = _json_to_object(MermaidProperties, properties)
|
|
199
|
+
config = front_matter.config or MermaidConfigProperties()
|
|
200
|
+
|
|
201
|
+
return MermaidProperties(title=front_matter.title, config=config)
|
|
202
|
+
|
|
203
|
+
return MermaidProperties()
|
md2conf/text.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Publish Markdown files to Confluence wiki.
|
|
3
|
+
|
|
4
|
+
Copyright 2022-2025, Levente Hunyadi
|
|
5
|
+
|
|
6
|
+
:see: https://github.com/hunyadi/md2conf
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def wrap_text(text: str, line_length: int = 160) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Wraps text by replacing individual whitespace characters with a linefeed such that lines in the output honor the specified line length.
|
|
13
|
+
|
|
14
|
+
:param text: Input text, optionally with existing UNIX line endings.
|
|
15
|
+
:param line_length: Desired line length.
|
|
16
|
+
:returns: Wrapped output text. Long words that exceed the specified line length are not broken.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
if line_length < 1:
|
|
20
|
+
raise ValueError("expected: line_length > 0")
|
|
21
|
+
|
|
22
|
+
input = text.encode("utf-8")
|
|
23
|
+
output = bytearray(len(input))
|
|
24
|
+
pos = 0
|
|
25
|
+
length = len(input)
|
|
26
|
+
|
|
27
|
+
while pos < length:
|
|
28
|
+
end = min(pos + line_length, length)
|
|
29
|
+
|
|
30
|
+
# find any linefeed already in input
|
|
31
|
+
left = pos
|
|
32
|
+
while left < end and input[left] != 0x0A:
|
|
33
|
+
left += 1
|
|
34
|
+
if left != end:
|
|
35
|
+
output[pos : left + 1] = input[pos : left + 1]
|
|
36
|
+
pos = left + 1 # include linefeed
|
|
37
|
+
continue
|
|
38
|
+
|
|
39
|
+
# find the nearest whitespace before end of line
|
|
40
|
+
right = end
|
|
41
|
+
while right > pos and input[right - 1] not in b"\t\v\f\r ":
|
|
42
|
+
right -= 1
|
|
43
|
+
|
|
44
|
+
if right == pos or end == length:
|
|
45
|
+
# no whitespace found or at end of input; copy the rest
|
|
46
|
+
output[pos:end] = input[pos:end]
|
|
47
|
+
pos = end
|
|
48
|
+
else:
|
|
49
|
+
# replace the whitespace with a newline
|
|
50
|
+
output[pos : right - 1] = input[pos : right - 1]
|
|
51
|
+
output[right - 1] = 0x0A # linefeed '\n'
|
|
52
|
+
pos = right # skip the whitespace (already replaced)
|
|
53
|
+
|
|
54
|
+
return output.decode("utf-8")
|
md2conf/xml.py
CHANGED
|
@@ -87,6 +87,8 @@ def is_xml_equal(
|
|
|
87
87
|
"""
|
|
88
88
|
Compare two XML documents for equivalence, ignoring leading/trailing whitespace differences and attribute definition order.
|
|
89
89
|
|
|
90
|
+
Elements may be excluded, in which case they compare equal to any element of the same type that has the same tail text.
|
|
91
|
+
|
|
90
92
|
:param tree1: XML document as an element tree.
|
|
91
93
|
:param tree2: XML document as an element tree.
|
|
92
94
|
:param skip_attributes: Attributes to exclude, in `{namespace}name` notation.
|
|
@@ -101,3 +103,38 @@ def element_to_text(node: ET._Element) -> str:
|
|
|
101
103
|
"Returns all text contained in an element as a concatenated string."
|
|
102
104
|
|
|
103
105
|
return "".join(node.itertext()).strip()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def unwrap_substitute(name: str, root: ET._Element) -> None:
|
|
109
|
+
"""
|
|
110
|
+
Substitutes all occurrences of an element with its contents.
|
|
111
|
+
|
|
112
|
+
:param name: Element tag name to find and replace.
|
|
113
|
+
:param root: Top-most element at which to start.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
for node in root.iterdescendants(name):
|
|
117
|
+
if node.text:
|
|
118
|
+
# append first piece of text in this element at the end of previous sibling, or text contained by parent
|
|
119
|
+
if (prev_node := node.getprevious()) is not None:
|
|
120
|
+
prev_node.tail = (prev_node.tail or "") + node.text
|
|
121
|
+
elif (parent_node := node.getparent()) is not None: # always true except for root
|
|
122
|
+
parent_node.text = (parent_node.text or "") + node.text
|
|
123
|
+
else:
|
|
124
|
+
raise NotImplementedError("must always have a previous sibling or a parent")
|
|
125
|
+
if node.tail:
|
|
126
|
+
if len(node) > 0:
|
|
127
|
+
# append text immediately following the closing tag of this element to the last child element of this element
|
|
128
|
+
last_node = node[-1]
|
|
129
|
+
last_node.tail = (last_node.tail or "") + node.tail
|
|
130
|
+
else: # node has no child elements, only text
|
|
131
|
+
if (prev_node := node.getprevious()) is not None:
|
|
132
|
+
prev_node.tail = (prev_node.tail or "") + node.tail
|
|
133
|
+
elif (parent_node := node.getparent()) is not None: # always true except for root
|
|
134
|
+
parent_node.text = (parent_node.text or "") + node.tail
|
|
135
|
+
else:
|
|
136
|
+
raise NotImplementedError("must always have a previous sibling or a parent")
|
|
137
|
+
for child in node.iterchildren(reversed=True):
|
|
138
|
+
node.addnext(child)
|
|
139
|
+
if (parent_node := node.getparent()) is not None: # always true except for root
|
|
140
|
+
parent_node.remove(node)
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
markdown_to_confluence-0.4.4.dist-info/licenses/LICENSE,sha256=Pv43so2bPfmKhmsrmXFyAvS7M30-1i1tzjz6-dfhyOo,1077
|
|
2
|
-
md2conf/__init__.py,sha256=nfPrvkkECt_Szpol9kTkli5cL-tFqFzn8JefKlCyb3s,402
|
|
3
|
-
md2conf/__main__.py,sha256=RImfFrO2m9C5iebmBrHKlLjosy_A8AY4O7PK9CmiWSw,11120
|
|
4
|
-
md2conf/api.py,sha256=-UrtFi3pFOVMsYj7VTgCqHIBinHsSLUucmGSeureEaE,37253
|
|
5
|
-
md2conf/application.py,sha256=MBV4Lg6s40Q0Z4SK7W9cSo-k2A-ckmu8wosuwo_2XWM,8301
|
|
6
|
-
md2conf/collection.py,sha256=EobgMRJgkYloWlY03NZJ52MRC_SGLpTVCHkltDbQyt0,837
|
|
7
|
-
md2conf/converter.py,sha256=WNfxGEacibINQYCZXszaMoUvJIP4Rq8IDMjz5RSH0IY,51162
|
|
8
|
-
md2conf/csf.py,sha256=tEbl3e5UQmbRSQK3lQqmpADoy638tlJihutqJoWhumA,4374
|
|
9
|
-
md2conf/domain.py,sha256=tA9V0vb5Vo9Nt0eQvwAFARaM9TX88LBVQ73nVvdcaqA,1851
|
|
10
|
-
md2conf/drawio.py,sha256=P_t7Wp7Tg9XkZM2ZchWCWWEdBaU1KgZ_YX9ZlkZo4Dk,8293
|
|
11
|
-
md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
|
|
12
|
-
md2conf/extra.py,sha256=VuMxuOnnC2Qwy6y52ukIxsaYhrZArRqMmRHRE4QZl8g,687
|
|
13
|
-
md2conf/local.py,sha256=mUe2QBHhdZesygmYq5kXyGyl_ZmfUECgxDxylQwTa7g,3732
|
|
14
|
-
md2conf/markdown.py,sha256=z9sVTA_Hcn551DZgdO7Nbod-IZ-43B4eJLklrYQ2KYI,3141
|
|
15
|
-
md2conf/matcher.py,sha256=m5rZjYZSjhKfdeKS8JdPq7cG861Mc6rVZBkrIOZTHGE,6916
|
|
16
|
-
md2conf/mermaid.py,sha256=f0x7ISj-41ZMh4zTAFPhIWwr94SDcsVZUc1NWqmH_G4,2508
|
|
17
|
-
md2conf/metadata.py,sha256=LzZM-oPNnzCULmLhF516tPlV5zZBknccwMHt8Nan-xg,1007
|
|
18
|
-
md2conf/processor.py,sha256=z2d2KMPEYWaxflOtH2UTwrjzpPU8TtLSEUvor85ez1Q,9732
|
|
19
|
-
md2conf/properties.py,sha256=RC1jY_TKVbOv2bJxXn27Fj4fNWzyoNUQt6ltgUyVQAQ,3987
|
|
20
|
-
md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
|
|
21
|
-
md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
md2conf/scanner.py,sha256=Cyvjab8tBvKgubttQvNagS8nailuTvFBqUGoiX5MNp8,5351
|
|
23
|
-
md2conf/toc.py,sha256=hpqqDbFgNJg5-ul8qWjOglI3Am0sbwR-TLwGN5G9Qo0,2447
|
|
24
|
-
md2conf/uri.py,sha256=KbLBdRFtZTQTZd8b4j0LtE8Pb68Ly0WkemF4iW-EAB4,1158
|
|
25
|
-
md2conf/xml.py,sha256=ERkGLuJgVFrOkzsMLd1RHU5SGFfFSxxNFZAeKrfdtRs,3454
|
|
26
|
-
markdown_to_confluence-0.4.4.dist-info/METADATA,sha256=Ql8vwKX6wtZNtUVoT0z35HgiFQcW-fFWsWFUMLkNErw,32306
|
|
27
|
-
markdown_to_confluence-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
28
|
-
markdown_to_confluence-0.4.4.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
|
|
29
|
-
markdown_to_confluence-0.4.4.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
|
|
30
|
-
markdown_to_confluence-0.4.4.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
31
|
-
markdown_to_confluence-0.4.4.dist-info/RECORD,,
|
|
File without changes
|
{markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{markdown_to_confluence-0.4.4.dist-info → markdown_to_confluence-0.4.6.dist-info}/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|