"""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. Подпункт в", ]