add: config.py как единый источник правды (на базе html.entities)

This commit is contained in:
2025-08-03 20:00:59 +03:00
parent cf047a2552
commit 134f3807b2
4 changed files with 243 additions and 991 deletions

View File

@@ -3,22 +3,25 @@
import regex
import html
from etpgrf.config import (ALL_ENTITIES, ALWAYS_MNEMONIC_IN_SAFE_MODE, MODE_MNEMONIC, MODE_MIXED)
from . import config
# from etpgrf.config import (ALL_ENTITIES, ALWAYS_MNEMONIC_IN_SAFE_MODE, MODE_MNEMONIC, MODE_MIXED)
# --- Создаем словарь для кодирования Unicode -> Mnemonic ---
# {'\u00A0': ' ', '\u2014': '—', ...}
_ENCODE_MAP = {}
# Получаем готовую карту для кодирования один раз при импорте
_ENCODE_MAP = config.get_encode_map()
# Создаем таблицу для быстрой замены через str.translate
_TRANSLATE_TABLE = str.maketrans(_ENCODE_MAP)
for name, (uni_char, mnemonic) in ALL_ENTITIES.items():
_ENCODE_MAP[uni_char] = mnemonic
#
# for name, (uni_char, mnemonic) in ALL_ENTITIES.items():
# _ENCODE_MAP[uni_char] = mnemonic
# --- Основные функции кодека ---
def decode_to_unicode(text: str) -> str:
"""
Преобразует все известные HTML-мнемоники в их Unicode-эквиваленты,
используя стандартную библиотеку html.
Преобразует все известные HTML-мнемоники и числовые коды в их
Unicode-эквиваленты, используя стандартную библиотеку html.
"""
if not text or '&' not in text:
return text
@@ -29,26 +32,27 @@ def encode_from_unicode(text: str, mode: str) -> str:
"""
Преобразует Unicode-символы в HTML-мнемоники в соответствии с режимом.
"""
if not text or mode not in [MODE_MNEMONIC, MODE_MIXED]:
# В режиме 'unicode' или неизвестном режиме ничего не делаем
if not text:
# Если текст пустой, просто возвращаем его
return text
if mode == config.MODE_UNICODE:
# В режиме 'unicode' ничего не делаем
return text
# 1. Определяем, какие символы нужно заменить
if mode == MODE_MNEMONIC:
# В режиме 'mnemonic' заменяем все известные нам символы
chars_to_replace = set(_ENCODE_MAP.keys())
else: # mode == MODE_MIXED
# В смешанном режиме заменяем только "безопасные" символы
# (те, что могут вызывать проблемы с отображением или переносами)
safe_chars = {ALL_ENTITIES[name][0] for name in ALWAYS_MNEMONIC_IN_SAFE_MODE}
chars_to_replace = set(_ENCODE_MAP.keys()) & safe_chars
if mode == config.MODE_MNEMONIC:
# В режиме 'mnemonic' заменяем все известные символы, используя
# заранее скомпилированную таблицу для максимальной производительности.
return text.translate(_TRANSLATE_TABLE)
if mode == config.MODE_MIXED:
# Создаем временную карту только для "безопасных" символов
safe_map = {
char: _ENCODE_MAP[char]
for char in config.SAFE_MODE_CHARS_TO_MNEMONIC
if char in _ENCODE_MAP
}
if not safe_map:
return text
return text.translate(str.maketrans(safe_map))
if not chars_to_replace:
return text
# 2. Создаем паттерн для поиска только нужных символов
# regex.escape важен, если в наборе будут спецсимволы, например, '-'
pattern = regex.compile(f"[{regex.escape(''.join(chars_to_replace))}]")
# 3. Заменяем найденные символы, используя нашу карту
return pattern.sub(lambda m: _ENCODE_MAP[m.group(0)], text)
# Возвращаем исходный текст, если режим не распознан
return text