0.4.1
Python application / build (push) Has been cancelled

- fix Не собиралось само список всех приложений
This commit is contained in:
Igor20264
2026-09-04 22:48:33 +03:00
parent b38661f588
commit 2ba6fe2673
3 changed files with 113 additions and 3 deletions
+3 -1
View File
@@ -42,7 +42,9 @@ CLI (тот же движок)
# *ЗАКЛЮЧЕНИЕ
# *СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
# *ПРИЛОЖЕНИЯ
(после ПРИЛОЖЕНИЯ — перечень основным текстом, затем ## Приложение А Название)
(перечень «Приложение А — …» собирается сам из ## Приложение А Название;
можно написать вручную — тогда автосписок не дублируется)
## Приложение А Название
Нумерованные разделы: # 1 Название ## 1.1 Подраздел
Точку в конце заголовка не ставить.
+72 -2
View File
@@ -121,8 +121,9 @@ class Renderer:
self._layout_tracker.set_page_size(max_height, max_width)
def process(self, renderables: list[Renderable]):
for i in range(len(renderables)):
self.render(renderables[i])
items = self._ensure_appendix_index(list(renderables))
for i in range(len(items)):
self.render(items[i])
self._flush_to_new_screen()
# If document had no TOC, still add page numbers to the only section
@@ -132,6 +133,75 @@ class Renderer:
if self._debugger:
self._debugger.after_rendered()
def _ensure_appendix_index(self, renderables: list[Renderable]) -> list[Renderable]:
"""Insert «Приложение X — Title» list after # *ПРИЛОЖЕНИЯ if missing (method guide §6)."""
sec_i = None
first_app_i = None
entries: list[tuple[str, str]] = []
for i, r in enumerate(renderables):
if not isinstance(r, Heading):
continue
text = (r.text or "").strip()
upper = text.upper().replace("Ё", "Е")
if upper in ("ПРИЛОЖЕНИЯ", "ПРИЛОЖЕНИЕ") and sec_i is None:
sec_i = i
continue
m = re.match(r"(?i)^Приложение\s+([А-ЯA-ZЁ])(?:\s+(.+))?$", text)
if not m:
continue
letter = m.group(1).upper().replace("Ё", "Е")
title = (m.group(2) or "").strip()
if first_app_i is None:
first_app_i = i
entries.append((letter, title))
if sec_i is None or first_app_i is None or not entries:
return renderables
if self._has_appendix_list_between(renderables, sec_i, first_app_i):
return renderables
from .profiles import dash_separator
dash = dash_separator()
index_paras: list[Renderable] = []
for letter, title in entries:
line = f"Приложение {letter}"
if title:
line = f"{line} {dash} {title}"
index_paras.append(self._make_appendix_index_paragraph(line))
return renderables[: sec_i + 1] + index_paras + renderables[sec_i + 1 :]
@staticmethod
def _has_appendix_list_between(
renderables: list[Renderable], sec_i: int, first_app_i: int
) -> bool:
"""True if author already put a list/prose between ПРИЛОЖЕНИЯ and first appendix."""
for r in renderables[sec_i + 1 : first_app_i]:
if isinstance(r, Heading):
continue
text = ""
if isinstance(r, Paragraph):
text = (r._docx_paragraph.text or "").strip()
elif hasattr(r, "text"):
text = (getattr(r, "text", None) or "").strip()
if not text:
continue
if re.search(r"(?i)приложение\s+[А-ЯA-ZЁ]", text):
return True
if re.search(r"[А-Яа-яA-Za-z]{3,}", text):
return True
return False
def _make_appendix_index_paragraph(self, text: str) -> Paragraph:
"""Body-text line in the appendix list under ПРИЛОЖЕНИЯ (no first-line indent)."""
p = Paragraph(self._document._body)
p.add_run(text)
p.style = "Normal"
p.first_line_indent = Cm(0)
pf = p._docx_paragraph.paragraph_format
pf.left_indent = Cm(0)
return p
@staticmethod
def _rewrite_heading_text(heading: Heading, text: str) -> None:
runs = heading._docx_paragraph.runs