Обновил добавление обновлений
This commit is contained in:
103
app.py
103
app.py
@@ -1958,12 +1958,107 @@ def _format_update_date(value: str | None) -> str:
|
||||
return value
|
||||
|
||||
|
||||
def _paragraphs_html(value: str | None) -> str:
|
||||
lines = _split_lines(value)
|
||||
def _inline_update_markup(value: str | None) -> str:
|
||||
"""Безопасное мини-форматирование для текста обновлений.
|
||||
|
||||
Поддерживаем в админке:
|
||||
- `F5` или `1` — выделенная клавиша/команда;
|
||||
- **важный текст** — зелёное выделение.
|
||||
Остальной текст обязательно экранируется, чтобы не сломать HTML.
|
||||
"""
|
||||
source = _clean_update_text(value)
|
||||
if not source:
|
||||
return ""
|
||||
|
||||
token_re = re.compile(r"(`[^`]+`|\*\*.+?\*\*)")
|
||||
result: list[str] = []
|
||||
last_pos = 0
|
||||
|
||||
for match in token_re.finditer(source):
|
||||
result.append(html.escape(source[last_pos:match.start()], quote=True))
|
||||
token = match.group(0)
|
||||
|
||||
if token.startswith("`") and token.endswith("`"):
|
||||
inner = token[1:-1].strip()
|
||||
if inner:
|
||||
result.append(f'<kbd class="update-key">{html.escape(inner, quote=True)}</kbd>')
|
||||
elif token.startswith("**") and token.endswith("**"):
|
||||
inner = token[2:-2].strip()
|
||||
if inner:
|
||||
result.append(f'<span class="update-highlight">{html.escape(inner, quote=True)}</span>')
|
||||
|
||||
last_pos = match.end()
|
||||
|
||||
result.append(html.escape(source[last_pos:], quote=True))
|
||||
return "".join(result)
|
||||
|
||||
|
||||
def _flush_update_list(buffer: list[str], list_type: str) -> str:
|
||||
if not buffer:
|
||||
return ""
|
||||
|
||||
tag = "ol" if list_type == "numbered" else "ul"
|
||||
items = "\n".join(f" <li>{item}</li>" for item in buffer)
|
||||
return (
|
||||
f' <{tag} class="update-pretty-list update-pretty-list--{list_type}">\n'
|
||||
f"{items}\n"
|
||||
f" </{tag}>"
|
||||
)
|
||||
|
||||
|
||||
def _rich_update_text_html(value: str | None) -> str:
|
||||
"""Текст обновления с красивыми списками и мини-выделениями.
|
||||
|
||||
Поддерживаемые форматы в textarea:
|
||||
1. Первый пункт -> красивый нумерованный список
|
||||
- Первый пункт -> красивый маркированный список
|
||||
`F5` -> выделенная клавиша/команда
|
||||
**важно** -> выделенное слово/фраза
|
||||
"""
|
||||
raw_lines = [line.strip() for line in (value or "").splitlines()]
|
||||
lines = [line for line in raw_lines if line]
|
||||
if not lines:
|
||||
return "<p>Описание не заполнено.</p>"
|
||||
|
||||
return "\n".join(f"<p>{_escape_text(line)}</p>" for line in lines)
|
||||
html_parts: list[str] = []
|
||||
list_buffer: list[str] = []
|
||||
current_list_type = ""
|
||||
|
||||
def close_list() -> None:
|
||||
nonlocal list_buffer, current_list_type
|
||||
if list_buffer:
|
||||
html_parts.append(_flush_update_list(list_buffer, current_list_type))
|
||||
list_buffer = []
|
||||
current_list_type = ""
|
||||
|
||||
for line in lines:
|
||||
numbered_match = re.match(r"^\d+[\.)]\s+(.+)$", line)
|
||||
bullet_match = re.match(r"^[-*•]\s+(.+)$", line)
|
||||
|
||||
if numbered_match:
|
||||
if current_list_type and current_list_type != "numbered":
|
||||
close_list()
|
||||
current_list_type = "numbered"
|
||||
list_buffer.append(_inline_update_markup(numbered_match.group(1)))
|
||||
continue
|
||||
|
||||
if bullet_match:
|
||||
if current_list_type and current_list_type != "bullet":
|
||||
close_list()
|
||||
current_list_type = "bullet"
|
||||
list_buffer.append(_inline_update_markup(bullet_match.group(1)))
|
||||
continue
|
||||
|
||||
close_list()
|
||||
html_parts.append(f"<p>{_inline_update_markup(line)}</p>")
|
||||
|
||||
close_list()
|
||||
return "\n".join(html_parts)
|
||||
|
||||
|
||||
def _paragraphs_html(value: str | None) -> str:
|
||||
# Оставлено как совместимый алиас: теперь описание умеет списки, клавиши и выделения.
|
||||
return _rich_update_text_html(value)
|
||||
|
||||
|
||||
def _normalize_update_image_path(value: str | None) -> str:
|
||||
@@ -2012,7 +2107,7 @@ def _build_update_block(
|
||||
|
||||
actions = _split_lines(operator_actions)
|
||||
if actions:
|
||||
actions_html = "\n".join(f"<li>{_escape_text(action)}</li>" for action in actions)
|
||||
actions_html = "\n".join(f"<li>{_inline_update_markup(action)}</li>" for action in actions)
|
||||
else:
|
||||
actions_html = "<li>Ознакомиться с обновлением перед работой с матчем.</li>"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user