93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""Numbered lists with nested 1 / 1.1 / 2.1 markers."""
|
||
|
||
from md2gost.parser_ import Parser
|
||
from md2gost.renderable.list import List
|
||
from word2md.classify import look_like_list_item, parse_list_item
|
||
from word2md.emit import emit_markdown
|
||
from word2md.blocks import ListBlock
|
||
|
||
from . import _create_test_document
|
||
|
||
|
||
NESTED_MD = """
|
||
1. Первый
|
||
1. Подпункт а
|
||
2. Подпункт б
|
||
2. Второй
|
||
1. Подпункт в
|
||
2. Подпункт г
|
||
"""
|
||
|
||
|
||
def _markers(lst: List) -> list[str]:
|
||
out = []
|
||
for paragraph in lst._paragraphs:
|
||
runs = paragraph._docx_paragraph.runs
|
||
assert runs, "list item has no runs"
|
||
out.append((runs[0].text or "").replace("\t", ""))
|
||
return out
|
||
|
||
|
||
def test_nested_ordered_list_uses_hierarchical_markers():
|
||
doc, *_ = _create_test_document()
|
||
lst = List(doc._body, ordered=True)
|
||
lst.add_item(1).add_run("Первый")
|
||
lst.add_item(2).add_run("Подпункт а")
|
||
lst.add_item(2).add_run("Подпункт б")
|
||
lst.add_item(1).add_run("Второй")
|
||
lst.add_item(2).add_run("Подпункт в")
|
||
lst.add_item(2).add_run("Подпункт г")
|
||
assert _markers(lst) == ["1.", "1.1.", "1.2.", "2.", "2.1.", "2.2."]
|
||
|
||
|
||
def test_parser_nested_ordered_markdown():
|
||
doc, *_ = _create_test_document()
|
||
renderables = list(Parser(doc, NESTED_MD).parse())
|
||
assert len(renderables) == 1
|
||
lst = renderables[0]
|
||
assert isinstance(lst, List)
|
||
assert _markers(lst) == ["1.", "1.1.", "1.2.", "2.", "2.1.", "2.2."]
|
||
|
||
|
||
def test_flat_ordered_list_stays_single_level():
|
||
doc, *_ = _create_test_document()
|
||
lst = List(doc._body, ordered=True)
|
||
lst.add_item(1).add_run("анализ")
|
||
lst.add_item(1).add_run("проектирование")
|
||
lst.add_item(1).add_run("реализация")
|
||
assert _markers(lst) == ["1.", "2.", "3."]
|
||
|
||
|
||
def test_nested_bullet_list_keeps_en_dash():
|
||
doc, *_ = _create_test_document()
|
||
lst = List(doc._body, ordered=False)
|
||
lst.add_item(1).add_run("первый")
|
||
lst.add_item(2).add_run("вложенный")
|
||
assert _markers(lst) == ["–", "–"]
|
||
|
||
|
||
def test_word2md_strips_hierarchical_marker():
|
||
assert parse_list_item("1.\tПервый") == (True, 1, "Первый")
|
||
assert parse_list_item("1.1.\tПодпункт а") == (True, 2, "Подпункт а")
|
||
assert parse_list_item("2.1. Подпункт в") == (True, 2, "Подпункт в")
|
||
assert look_like_list_item("1.1.\tПодпункт а") == (True, True, "Подпункт а")
|
||
|
||
|
||
def test_word2md_emits_nested_markdown():
|
||
md = emit_markdown(
|
||
[
|
||
ListBlock(
|
||
ordered=True,
|
||
items=["Первый", "Подпункт а", "Подпункт б", "Второй", "Подпункт в"],
|
||
item_levels=[1, 2, 2, 1, 2],
|
||
)
|
||
]
|
||
)
|
||
assert md.splitlines() == [
|
||
"1. Первый",
|
||
" 1. Подпункт а",
|
||
" 2. Подпункт б",
|
||
"2. Второй",
|
||
" 1. Подпункт в",
|
||
]
|