Files
GostGenerator/web/backend/app/services/espd/skeletons.py
T
2026-09-09 13:29:39 +03:00

111 lines
4.6 KiB
Python

"""Default HTML skeletons for ESPD rich-text editors (visible outlines)."""
from __future__ import annotations
from app.services.espd.models import DocumentType
# Placeholder paragraph shown under each heading so the outline is obvious in TipTap.
_HINT = "<p><em>Заполните раздел…</em></p>"
def _h2(title: str) -> str:
return f"<h2>{title}</h2>{_HINT}"
def _h3(title: str) -> str:
return f"<h3>{title}</h3>{_HINT}"
SKELETONS: dict[str, str] = {
DocumentType.RO.value: "\n".join(
[
_h2("1. Назначение программы"),
_h3("1.1. Функциональное назначение"),
_h3("1.2. Эксплуатационное назначение"),
_h2("2. Условия выполнения программы"),
_h3("2.1. Требования к техническим средствам"),
_h3("2.2. Требования к программным средствам"),
_h3("2.3. Требования к персоналу"),
_h2("3. Установка программы"),
_h3("3.1. Состав дистрибутива"),
_h3("3.2. Порядок установки"),
_h2("4. Работа с программой"),
_h3("4.1. Запуск программы"),
_h3("4.2. Основные операции"),
_h3("4.3. Завершение работы"),
_h2("5. Сообщения оператору"),
]
),
DocumentType.RP.value: "\n".join(
[
_h2("1. Назначение программы"),
_h2("2. Условия выполнения программы"),
_h2("3. Характеристики программы"),
_h2("4. Обращение к программе"),
_h2("5. Входные и выходные данные"),
_h2("6. Сообщения"),
]
),
DocumentType.RSP.value: "\n".join(
[
_h2("1. Общие сведения о программе"),
_h2("2. Структура программы"),
_h2("3. Настройка программы"),
_h2("4. Проверка программы"),
_h2("5. Дополнительные возможности"),
_h2("6. Сообщения системному программисту"),
]
),
DocumentType.PMI.value: "\n".join(
[
_h2("1. Объект испытаний"),
_h2("2. Цель испытаний"),
_h2("3. Требования к программе"),
_h2("4. Требования к программной документации"),
_h2("5. Средства и порядок испытаний"),
_h2("6. Методы испытаний"),
]
),
DocumentType.TEXT.value: "\n".join(
[
_h2("1. Общие сведения"),
"<p><em>Краткое описание состава текста программы.</em></p>",
_h2("2. Текст программы"),
"<pre><code>// Вставьте листинг или фрагменты исходного кода…\n</code></pre>",
_h2("3. Примечания"),
]
),
DocumentType.IMP.value: "\n".join(
[
_h2("1. Перечень исполняемых модулей"),
"<p><em>Таблица файлов формируется из загруженного ZIP при генерации DOCX. "
"Здесь можно указать пояснения к составу поставки.</em></p>",
_h2("2. Инструкция по установке / размещению"),
_h2("3. Проверка контрольных сумм"),
"<p><em>Контрольная сумма ZIP подставляется автоматически при генерации.</em></p>",
]
),
}
def get_skeleton(doc_type: str | DocumentType) -> str:
key = doc_type.value if isinstance(doc_type, DocumentType) else str(doc_type)
return SKELETONS.get(key, "")
def all_skeletons() -> dict[str, str]:
return dict(SKELETONS)
def is_blank_html(html: str | None) -> bool:
"""True if editor content is empty / only whitespace or empty tags."""
if not html or not str(html).strip():
return True
import re
from html import unescape
text = re.sub(r"<[^>]+>", " ", str(html))
text = unescape(text)
text = re.sub(r"\s+", " ", text).strip()
return text == ""