mkdocs2confluence 0.10.1__tar.gz → 0.10.2__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.
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/PKG-INFO +1 -1
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/pyproject.toml +1 -1
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/PKG-INFO +1 -1
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/emitter/xhtml.py +13 -9
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/parser/markdown.py +62 -8
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_emitter.py +26 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_parser.py +43 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/LICENSE +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/README.md +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/setup.cfg +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/SOURCES.txt +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/dependency_links.txt +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/entry_points.txt +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/requires.txt +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/top_level.txt +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/cli.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/emitter/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/document.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/nodes.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/treeutil.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/config.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/extra_css.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/nav.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/page.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/parser/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/generator.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/render.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/abbrevs.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/fence.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/frontmatter.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/icons.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/includes.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/linkdefs.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/render.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/server.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/client.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/pipeline.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/anchoring.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/command.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/comments.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/github.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/platform.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/state.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/__init__.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/abbrevs.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/assets.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/editlink.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/footer.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/images.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/internallinks.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/mermaid.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_abbrevs.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_children_macro.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_cli.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_editlink.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_extra_css.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_footer.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_frontmatter.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_icons.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_images.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_internallinks.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_ir.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_linkdefs.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_loader.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_mermaid.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_page_loader.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_pdf.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_preprocess.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_preview.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_publish_client.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_publish_config.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_publish_pipeline.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_server.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_sync_anchoring.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_sync_command.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_sync_comments.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_sync_github.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_sync_state.py +0 -0
- {mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/tests/test_treeutil.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mkdocs2confluence"
|
|
3
|
-
version = "0.10.
|
|
3
|
+
version = "0.10.2"
|
|
4
4
|
description = "Publish MkDocs Material pages to Confluence Cloud — admonitions, Mermaid diagrams, tabs, page properties and more"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "GPL-3.0-or-later" }
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/emitter/xhtml.py
RENAMED
|
@@ -422,15 +422,19 @@ def _emit_task_item(item: ListItem) -> str:
|
|
|
422
422
|
|
|
423
423
|
|
|
424
424
|
def _emit_list_item(item: ListItem) -> str:
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
425
|
+
first_block = next(
|
|
426
|
+
(i for i, c in enumerate(item.children) if isinstance(c, _LIST_BLOCK_TYPES)), None
|
|
427
|
+
)
|
|
428
|
+
if first_block is None:
|
|
429
|
+
# All inline — standard tight rendering.
|
|
430
|
+
inner = _emit_inlines(item.children)
|
|
431
|
+
return f" <li><p>{inner}</p></li>\n"
|
|
432
|
+
# Mixed: inline prefix (if any) wrapped in <p>, followed by block children.
|
|
433
|
+
parts: list[str] = []
|
|
434
|
+
if first_block > 0:
|
|
435
|
+
parts.append(f"<p>{_emit_inlines(item.children[:first_block])}</p>\n")
|
|
436
|
+
parts.append(emit(item.children[first_block:]))
|
|
437
|
+
return f" <li>{''.join(parts).strip()}</li>\n"
|
|
434
438
|
|
|
435
439
|
|
|
436
440
|
def _emit_table(node: Table) -> str:
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/parser/markdown.py
RENAMED
|
@@ -158,6 +158,7 @@ class _BlockQuoteToken:
|
|
|
158
158
|
class _ListItemData:
|
|
159
159
|
text: str
|
|
160
160
|
task: bool | None = None # None=regular, True=checked, False=unchecked
|
|
161
|
+
sub_tokens: list[_Token] = field(default_factory=list)
|
|
161
162
|
|
|
162
163
|
|
|
163
164
|
@dataclass
|
|
@@ -501,7 +502,8 @@ def _tokenize(text: str) -> list[_Token]:
|
|
|
501
502
|
task = task_m.group("state").lower() == "x"
|
|
502
503
|
item_text = task_m.group("rest")
|
|
503
504
|
i += 1
|
|
504
|
-
# Collect continuation
|
|
505
|
+
# Collect continuation and indented sub-list lines.
|
|
506
|
+
sub_lines: list[str] = []
|
|
505
507
|
while i < len(lines) and lines[i].strip():
|
|
506
508
|
cont = lines[i]
|
|
507
509
|
bullet_m = _BULLET_RE.match(cont)
|
|
@@ -510,9 +512,18 @@ def _tokenize(text: str) -> list[_Token]:
|
|
|
510
512
|
ordered_m2 and not ordered_m2.group("indent")
|
|
511
513
|
):
|
|
512
514
|
break
|
|
513
|
-
|
|
515
|
+
if (bullet_m and bullet_m.group("indent")) or (
|
|
516
|
+
ordered_m2 and ordered_m2.group("indent")
|
|
517
|
+
) or sub_lines:
|
|
518
|
+
sub_lines.append(cont)
|
|
519
|
+
else:
|
|
520
|
+
item_text = item_text.rstrip() + " " + cont.strip()
|
|
514
521
|
i += 1
|
|
515
|
-
|
|
522
|
+
_sub: list[_Token] = []
|
|
523
|
+
if sub_lines:
|
|
524
|
+
_ind = min(len(ln) - len(ln.lstrip()) for ln in sub_lines if ln.strip())
|
|
525
|
+
_sub = _tokenize("\n".join(ln[_ind:] for ln in sub_lines))
|
|
526
|
+
list_items.append(_ListItemData(text=item_text, task=task, sub_tokens=_sub))
|
|
516
527
|
tokens.append(_BulletListToken(items=list_items))
|
|
517
528
|
continue
|
|
518
529
|
|
|
@@ -537,7 +548,8 @@ def _tokenize(text: str) -> list[_Token]:
|
|
|
537
548
|
break
|
|
538
549
|
item_text = om.group("text")
|
|
539
550
|
i += 1
|
|
540
|
-
# Collect continuation
|
|
551
|
+
# Collect continuation and indented sub-list lines.
|
|
552
|
+
sub_lines_ord: list[str] = []
|
|
541
553
|
while i < len(lines) and lines[i].strip():
|
|
542
554
|
cont = lines[i]
|
|
543
555
|
ordered_m3 = _ORDERED_RE.match(cont)
|
|
@@ -546,9 +558,18 @@ def _tokenize(text: str) -> list[_Token]:
|
|
|
546
558
|
bullet_m2 and not bullet_m2.group("indent")
|
|
547
559
|
):
|
|
548
560
|
break
|
|
549
|
-
|
|
561
|
+
if (ordered_m3 and ordered_m3.group("indent")) or (
|
|
562
|
+
bullet_m2 and bullet_m2.group("indent")
|
|
563
|
+
) or sub_lines_ord:
|
|
564
|
+
sub_lines_ord.append(cont)
|
|
565
|
+
else:
|
|
566
|
+
item_text = item_text.rstrip() + " " + cont.strip()
|
|
550
567
|
i += 1
|
|
551
|
-
|
|
568
|
+
_sub_ord: list[_Token] = []
|
|
569
|
+
if sub_lines_ord:
|
|
570
|
+
_ind_ord = min(len(ln) - len(ln.lstrip()) for ln in sub_lines_ord if ln.strip())
|
|
571
|
+
_sub_ord = _tokenize("\n".join(ln[_ind_ord:] for ln in sub_lines_ord))
|
|
572
|
+
ord_items.append(_ListItemData(text=item_text, sub_tokens=_sub_ord))
|
|
552
573
|
tokens.append(_OrderedListToken(start=start, items=ord_items))
|
|
553
574
|
continue
|
|
554
575
|
|
|
@@ -1030,6 +1051,32 @@ class _OpenSection:
|
|
|
1030
1051
|
children: list[IRNode] = field(default_factory=list)
|
|
1031
1052
|
|
|
1032
1053
|
|
|
1054
|
+
def _build_sub_list_nodes(tokens: list[_Token], fn_map: dict[str, int] | None) -> tuple[IRNode, ...]:
|
|
1055
|
+
"""Recursively convert sub-list tokens (from indented continuation) to IR nodes."""
|
|
1056
|
+
nodes: list[IRNode] = []
|
|
1057
|
+
for token in tokens:
|
|
1058
|
+
if isinstance(token, _BulletListToken):
|
|
1059
|
+
items = tuple(
|
|
1060
|
+
ListItem(
|
|
1061
|
+
children=_parse_inline(item.text, fn_map=fn_map)
|
|
1062
|
+
+ _build_sub_list_nodes(item.sub_tokens, fn_map),
|
|
1063
|
+
task=item.task,
|
|
1064
|
+
)
|
|
1065
|
+
for item in token.items
|
|
1066
|
+
)
|
|
1067
|
+
nodes.append(BulletList(items=items))
|
|
1068
|
+
elif isinstance(token, _OrderedListToken):
|
|
1069
|
+
items = tuple(
|
|
1070
|
+
ListItem(
|
|
1071
|
+
children=_parse_inline(item.text, fn_map=fn_map)
|
|
1072
|
+
+ _build_sub_list_nodes(item.sub_tokens, fn_map),
|
|
1073
|
+
)
|
|
1074
|
+
for item in token.items
|
|
1075
|
+
)
|
|
1076
|
+
nodes.append(OrderedList(items=items, start=token.start))
|
|
1077
|
+
return tuple(nodes)
|
|
1078
|
+
|
|
1079
|
+
|
|
1033
1080
|
def _build_tree(
|
|
1034
1081
|
tokens: list[_Token],
|
|
1035
1082
|
fn_map: dict[str, int] | None = None,
|
|
@@ -1101,14 +1148,21 @@ def _build_tree(
|
|
|
1101
1148
|
|
|
1102
1149
|
elif isinstance(token, _BulletListToken):
|
|
1103
1150
|
items = tuple(
|
|
1104
|
-
ListItem(
|
|
1151
|
+
ListItem(
|
|
1152
|
+
children=_parse_inline(item.text, fn_map=_fn)
|
|
1153
|
+
+ _build_sub_list_nodes(item.sub_tokens, _fn),
|
|
1154
|
+
task=item.task,
|
|
1155
|
+
)
|
|
1105
1156
|
for item in token.items
|
|
1106
1157
|
)
|
|
1107
1158
|
_append_content(BulletList(items=items), stack, root)
|
|
1108
1159
|
|
|
1109
1160
|
elif isinstance(token, _OrderedListToken):
|
|
1110
1161
|
items = tuple(
|
|
1111
|
-
ListItem(
|
|
1162
|
+
ListItem(
|
|
1163
|
+
children=_parse_inline(item.text, fn_map=_fn)
|
|
1164
|
+
+ _build_sub_list_nodes(item.sub_tokens, _fn),
|
|
1165
|
+
)
|
|
1112
1166
|
for item in token.items
|
|
1113
1167
|
)
|
|
1114
1168
|
_append_content(OrderedList(items=items, start=token.start), stack, root)
|
|
@@ -235,6 +235,32 @@ class TestListEmitters:
|
|
|
235
235
|
assert "<ul>" in out
|
|
236
236
|
assert "<ac:task-list>" not in out
|
|
237
237
|
|
|
238
|
+
def test_nested_bullet_list(self) -> None:
|
|
239
|
+
nested = BulletList(items=(ListItem((TextNode("child"),)),))
|
|
240
|
+
items = (ListItem((TextNode("parent"), nested)),)
|
|
241
|
+
out = emit((BulletList(items=items),))
|
|
242
|
+
assert out.count("<ul>") == 2
|
|
243
|
+
assert out.count("</ul>") == 2
|
|
244
|
+
assert "<p>parent</p>" in out
|
|
245
|
+
assert "<p>child</p>" in out
|
|
246
|
+
|
|
247
|
+
def test_nested_ordered_list(self) -> None:
|
|
248
|
+
nested = OrderedList(items=(ListItem((TextNode("sub"),)),))
|
|
249
|
+
items = (ListItem((TextNode("top"), nested)),)
|
|
250
|
+
out = emit((OrderedList(items=items),))
|
|
251
|
+
assert "<ol>" in out
|
|
252
|
+
assert "<ul>" not in out
|
|
253
|
+
assert "<p>top</p>" in out
|
|
254
|
+
assert "<p>sub</p>" in out
|
|
255
|
+
|
|
256
|
+
def test_nested_list_no_inline_prefix(self) -> None:
|
|
257
|
+
"""A list item with only a nested sub-list (no inline text) renders cleanly."""
|
|
258
|
+
nested = BulletList(items=(ListItem((TextNode("only child"),)),))
|
|
259
|
+
items = (ListItem((nested,)),)
|
|
260
|
+
out = emit((BulletList(items=items),))
|
|
261
|
+
assert out.count("<ul>") == 2
|
|
262
|
+
assert "<p>only child</p>" in out
|
|
263
|
+
|
|
238
264
|
|
|
239
265
|
class TestHorizontalRule:
|
|
240
266
|
def test_hr(self) -> None:
|
|
@@ -1021,6 +1021,49 @@ class TestListParsing:
|
|
|
1021
1021
|
)
|
|
1022
1022
|
assert "Continuation" in item_text or "First point" in item_text
|
|
1023
1023
|
|
|
1024
|
+
def test_nested_bullet_list(self) -> None:
|
|
1025
|
+
md = "- item 1\n - nested 1\n - nested 2\n- item 2\n"
|
|
1026
|
+
nodes = parse(md)
|
|
1027
|
+
bl = first(nodes, BulletList)
|
|
1028
|
+
assert isinstance(bl, BulletList)
|
|
1029
|
+
assert len(bl.items) == 2
|
|
1030
|
+
# First item must have a nested BulletList as a child.
|
|
1031
|
+
nested = next((c for c in bl.items[0].children if isinstance(c, BulletList)), None)
|
|
1032
|
+
assert nested is not None, "expected nested BulletList in first item"
|
|
1033
|
+
assert len(nested.items) == 2
|
|
1034
|
+
assert nested.items[0].children[0].text == "nested 1" # type: ignore[union-attr]
|
|
1035
|
+
assert nested.items[1].children[0].text == "nested 2" # type: ignore[union-attr]
|
|
1036
|
+
|
|
1037
|
+
def test_nested_ordered_list(self) -> None:
|
|
1038
|
+
md = "1. first\n 1. sub one\n 2. sub two\n2. second\n"
|
|
1039
|
+
nodes = parse(md)
|
|
1040
|
+
ol = first(nodes, OrderedList)
|
|
1041
|
+
assert isinstance(ol, OrderedList)
|
|
1042
|
+
nested = next((c for c in ol.items[0].children if isinstance(c, OrderedList)), None)
|
|
1043
|
+
assert nested is not None, "expected nested OrderedList in first item"
|
|
1044
|
+
assert len(nested.items) == 2
|
|
1045
|
+
|
|
1046
|
+
def test_deeply_nested_bullet_list(self) -> None:
|
|
1047
|
+
md = "- a\n - b\n - c\n"
|
|
1048
|
+
nodes = parse(md)
|
|
1049
|
+
bl = first(nodes, BulletList)
|
|
1050
|
+
assert isinstance(bl, BulletList)
|
|
1051
|
+
level2 = next((c for c in bl.items[0].children if isinstance(c, BulletList)), None)
|
|
1052
|
+
assert level2 is not None
|
|
1053
|
+
level3 = next((c for c in level2.items[0].children if isinstance(c, BulletList)), None)
|
|
1054
|
+
assert level3 is not None
|
|
1055
|
+
assert level3.items[0].children[0].text == "c" # type: ignore[union-attr]
|
|
1056
|
+
|
|
1057
|
+
def test_mixed_nested_list(self) -> None:
|
|
1058
|
+
"""Bullet list item containing an ordered sub-list."""
|
|
1059
|
+
md = "- item\n 1. sub one\n 2. sub two\n"
|
|
1060
|
+
nodes = parse(md)
|
|
1061
|
+
bl = first(nodes, BulletList)
|
|
1062
|
+
assert isinstance(bl, BulletList)
|
|
1063
|
+
nested_ol = next((c for c in bl.items[0].children if isinstance(c, OrderedList)), None)
|
|
1064
|
+
assert nested_ol is not None
|
|
1065
|
+
assert len(nested_ol.items) == 2
|
|
1066
|
+
|
|
1024
1067
|
|
|
1025
1068
|
# ── Definition list parsing ───────────────────────────────────────────────────
|
|
1026
1069
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/requires.txt
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs2confluence.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/emitter/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/document.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/ir/treeutil.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/config.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/extra_css.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/nav.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/loader/page.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/parser/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/generator.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/pdf/render.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/abbrevs.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/fence.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preprocess/icons.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/render.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/preview/server.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/client.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/publisher/pipeline.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/__init__.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/anchoring.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/command.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/comments.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/github.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/platform.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/sync/state.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/abbrevs.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/assets.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/footer.py
RENAMED
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/images.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs2confluence-0.10.1 → mkdocs2confluence-0.10.2}/src/mkdocs_to_confluence/transforms/mermaid.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|