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

View File

@@ -1,878 +1,143 @@
# etpgrf/conf.py
# Настройки по умолчанию для типографа etpgrf
# Настройки по умолчанию и "источник правды" для типографа etpgrf
from html import entities
# === КОНФИГУРАЦИИ ===
# Режимы "отдачи" результатов обработки
MODE_UNICODE = "unicode"
MODE_MNEMONIC = "mnemonic"
MODE_MIXED = "mixed"
# DEFAULT_MODE = MODE_MIXED
# Языки, поддерживаемые библиотекой
LANG_RU = 'ru' # Русский
LANG_RU_OLD = 'ruold' # Русская дореволюционная орфография
LANG_EN = 'en' # Английский
SUPPORTED_LANGS = frozenset([LANG_RU, LANG_RU_OLD, LANG_EN])
# Язык(и) по умолчанию, если не указаны пользователем и не заданы через ETPGRF_DEFAULT_LANGS_MODULE
# DEFAULT_LANGS = LANG_RU
# Значения по умолчанию для параметров Hyphenator
# DEFAULT_HYP_MAX_LEN = 10 # Максимальная длина слова без переносов
# DEFAULT_HYP_MIN_LEN = 3 # Минимальный "хвост" слова для переноса
# === Соответствия `unicode` и `mnemonic` для типографа
# === ИСТОЧНИК ПРАВДЫ ===
# --- Базовые алфавиты: Эти константы используются как для правил переноса, так и для правил кодирования ---
# Переносы
KEY_SHY = 'shy'
SHY_ENTITIES = {
KEY_SHY: ('\u00AD', '­'), # Мягкий перенос
# Русский алфавит
RU_VOWELS_UPPER = frozenset(['А', 'О', 'И', 'Е', 'Ё', 'Э', 'Ы', 'У', 'Ю', 'Я'])
RU_CONSONANTS_UPPER = frozenset(['Б', 'В', 'Г', 'Д', 'Ж', 'З', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ'])
RU_J_SOUND_UPPER = frozenset(['Й'])
RU_SIGNS_UPPER = frozenset(['Ь', 'Ъ'])
RU_ALPHABET_UPPER = RU_VOWELS_UPPER | RU_CONSONANTS_UPPER | RU_J_SOUND_UPPER | RU_SIGNS_UPPER
RU_ALPHABET_LOWER = frozenset([char.lower() for char in RU_ALPHABET_UPPER])
RU_ALPHABET_FULL = RU_ALPHABET_UPPER | RU_ALPHABET_LOWER
# Английский алфавит
EN_VOWELS_UPPER = frozenset(['A', 'E', 'I', 'O', 'U', 'Æ', 'Œ'])
EN_CONSONANTS_UPPER = frozenset(['B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z'])
EN_ALPHABET_UPPER = EN_VOWELS_UPPER | EN_CONSONANTS_UPPER
EN_ALPHABET_LOWER = frozenset([char.lower() for char in EN_ALPHABET_UPPER])
EN_ALPHABET_FULL = EN_ALPHABET_UPPER | EN_ALPHABET_LOWER
# === КОНСТАНТЫ ДЛЯ КОДИРОВАНИЯ HTML-МНЕМНОИКОВ ===
# --- ЧЕРНЫЙ СПИСОК: Символы, которые НИКОГДА не нужно кодировать в мнемоники ---
NEVER_ENCODE_CHARS = (frozenset(['!', '#', '%', '(', ')', '*', ',', '.', '/', ':', ';', '=', '?', '@',
'[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'])
| RU_ALPHABET_FULL | EN_ALPHABET_FULL)
# 2. БЕЛЫЙ СПИСОК (ДЛЯ БЕЗОПАСНОСТИ):
# Символы, которые ВСЕГДА должны превращаться в мнемоники в "безопасных" режимах вывода. Сюда добавлены символы,
# которые или не видны, или на глаз и не отличимы друг от друга в обычном тексте
SAFE_MODE_CHARS_TO_MNEMONIC = frozenset(['<', '>', '&', '"', '\'',
'\u00AD', # мягкий перенос (Soft Hyphen)
'\u00A0', # неразрывный пробел (Non-Breaking Space)
'\u200D', # нулевая ширина (с объединением) (Zero Width Joiner)
'\u200C', # нулевая ширина (без объединения) (Zero Width Non-Joiner)
'\u2002', # Полужирный пробел (En Space)
'\u2003']) # Широкий пробел (Em Space)
# 3. СПИСОК ДЛЯ ЧИСЛОВОГО КОДИРОВАНИЯ: Символы без стандартного имени.
ALWAYS_ENCODE_TO_NUMERIC_CHARS = frozenset([
'\u058F', # Знак армянского драма (֏)
'\u20BD', # Знак русского рубля (₽)
'\u20B4', # Знак украинской гривны (₴)
'\u20B8', # Знак казахстанского тенге (₸)
'\u20B9', # Знак индийской рупии (₹)
'\u20BC', # Знак азербайджанского маната
'\u20BE', # Знак грузинский лари (₾)
'\u022d', # Специальный символ LEFT-TO-RIGHT OVERRIDE (устанавливает направление текста слева-направо)
'\u022e', # Специальный символ RIGHT-TO-LEFT OVERRIDE (устанавливает направление текста справа-налево)
])
# 4. СЛОВАРЬ ПРИОРИТЕТОВ: Кастомные или предпочитаемые мнемоники.
# Эти правила применяются в последнюю очередь и имеют наивысший приоритет,
# гарантируя предсказуемый результат для символов с несколькими именами.
# Также используется для создания исключений из "черного списка" NEVER_ENCODE_CHARS.
CUSTOM_ENCODE_MAP = {
'\u2010': '&hyphen;', # Для \u2010 всегда предпочитаем &hyphen;, а не &dash;
# Исключения для букв, которые есть в алфавитах, но должны кодироваться (для обеспечения консистентности):
# 'Æ': '&AElig;',
# 'Œ': '&OElig;',
# 'æ': '&aelig;',
# 'œ': '&oelig;',
}
# Пробелы и неразрывные пробелы
KEY_NBSP = 'nbsp'
KEY_THINSP = 'thinsp'
KEY_ENSP = 'ensp'
KEY_EMSP = 'emsp'
KEY_ZWNJ = 'zwnj'
KEY_ZWJ = 'zwj'
SPACE_ENTITIES = {
KEY_NBSP: ('\u00A0', '&nbsp;'), # Неразрывный пробел
KEY_ENSP: ('\u2002', '&ensp;'), # Полу-широкий пробел (En space)
KEY_EMSP: ('\u2003', '&emsp;'), # Широкий пробел (Em space)
KEY_THINSP: ('\u2009', '&thinsp;'), # Тонкий пробел (Thin space)
KEY_ZWJ: ('\u200D', '&zwj;'), # Нулевая ширина (с объединением) (Zero Width Joiner)
KEY_ZWNJ: ('\u200C', '&zwnj;'), # Нулевая ширина (без объединения) (Zero Width Non-Joiner)
}
# === Динамическая генерация карт преобразования ===
# Тире и дефисы
DASH_ENTITIES = {
'ndash': ('\u2013', '&ndash;'), # Cреднее тире (En dash)
'mdash': ('\u2014', '&mdash;'), # Длинное тире
'hyphen': ('\u2010', '&hyphen;'), # Обычный дефис (если нужно отличать от минуса)
'horbar': ('\u2015', '&horbar;'), # Горизонтальная линия (длинная черта)
}
def _build_translation_maps() -> dict[str, str]:
"""
Создает карту для кодирования на лету, используя все доступные источники
из html.entities и строгий порядок приоритетов для обеспечения
предсказуемого и детерминированного результата.
"""
# ШАГ 1: Создаем ЕДИНУЮ и ПОЛНУЮ карту {каноническое_имя: числовой_код}.
# Это решает проблему разных форматов и дубликатов с точкой с запятой.
unified_name2codepoint = {}
# Кавычки
KEY_QUOT = 'quot'
KEY_LAQUO = 'laquo'
KEY_RAQUO = 'raquo'
KEY_LDQUO = 'ldquo'
KEY_RDQUO = 'rdquo'
QUOTE_ENTITIES = {
KEY_QUOT: ('\u0022', '&quot;'), # Двойная кавычка (универсальная) -- "
'apos': ('\u0027', '&apos;'), # Апостроф (одинарная кавычка) -- '
KEY_LAQUO: ('\u00AB', '&laquo;'), # Открывающая (левая) кавычка «ёлочка» -- «
KEY_RAQUO: ('\u00BB', '&raquo;'), # Закрывающая (правая) кавычка «ёлочка» -- »
KEY_LDQUO: ('\u201C', '&ldquo;'), # Oткрывающая (левая) двойная кавычка -- “
KEY_RDQUO: ('\u201D', '&rdquo;'), # Закрывающая (правая) двойная кавычка -- ”
'bdquo': ('\u201E', '&bdquo;'), # Нижняя двойная кавычка -- „
'lsquo': ('\u2018', '&lsquo;'), # Открывающая (левая) одинарная кавычка --
'rsquo': ('\u2019', '&rsquo;'), # Закрывающая (правая) одинарная кавычка --
'sbquo': ('\u201A', '&sbquo;'), # Нижняя одинарная кавычка --
'lsaquo': ('\u2039', '&lsaquo;'), # Открывающая французская угловая кавычка --
'rsaquo': ('\u203A', '&rsaquo;'), # Закрывающая французская угловая кавычка --
}
# Сначала обрабатываем большой исторический словарь.
for name, codepoint in entities.name2codepoint.items():
# Нормализуем имя СРАЗУ, убирая опциональную точку с запятой (в html.entities предусмотрено, что иногда
# символ `;` не ставится всякими неаккуратными верстальщиками и парсерами).
canonical_name = name.rstrip(';')
unified_name2codepoint[canonical_name] = codepoint
# Затем обновляем его современным стандартом html5.
# Это гарантирует, что если мнемоника есть в обоих, будет использована версия из html5.
for name, char in entities.html5.items():
# НОВОЕ: Проверяем, что значение является ОДИНОЧНЫМ символом.
# Наш кодек, основанный на str.translate, не может обрабатывать
# мнемоники, которые соответствуют строкам из нескольких символов
# (например, символ + вариативный селектор). Мы их игнорируем.
if len(char) != 1:
continue
# Нормализуем имя СРАЗУ.
canonical_name = name.rstrip(';')
unified_name2codepoint[canonical_name] = ord(char)
# Символы валют
CURRENCY_ENTITIES = {
'dollar': ('\u0024', '&dollar;'), # Доллар
'cent': ('\u00A2', '&cent;'), # Цент
'pound': ('\u00A3', '&pound;'), # Фунт стерлингов
'curren': ('\u00A4', '&curren;'), # Знак валюты (обычно используется для обозначения "без конкретной валюты")
'yen': ('\u00A5', '&yen;'), # Йена
'euro': ('\u20AC', '&euro;'), # Евро -- кажется нет в RFC
'ruble': ('\u20BD', '&#8381;'), # Российский рубль (₽)
}
# Теперь у нас есть полный и консистентный словарь unified_name2codepoint.
# На его основе строим нашу карту для кодирования.
encode_map = {}
# Математические символы
KEY_LT = 'lt'
KEY_GT = 'gt'
MATH_ENTITIES = {
KEY_LT: ('\u003C', '&lt;'), # Меньше (<)
KEY_GT: ('\u003E', '&gt;'), # Больше (>)
'plus': ('\u002B', '&plus;'), # Плюс (+)
'minus': ('\u2212', '&minus;'), # Минус ()
'times': ('\u00D7', '&times;'), # Умножение (×)
'divide': ('\u00F7', '&divide;'), # Деление (÷)
'equals': ('\u003D', '&equals;'), # Равно (=)
'ne': ('\u2260', '&ne;'), # Не равно (≠)
'plusmn': ('\u00B1', '&plusmn;'), # Плюс-минус (±)
'not': ('\u00AC', '&not;'), # Знак отрицания (¬)
'deg': ('\u00B0', '&deg;'), # Знак градуса (°)
'sup1': ('\u00B9', '&sup1;'), # Верхний индекс 1 (¹)
'sup2': ('\u00B2', '&sup2;'), # Верхний индекс 2 (²)
'sup3': ('\u00B3', '&sup3;'), # Верхний индекс 3 (³)
'fnof': ('\u0192', '&fnof;'), # Латинская строчная буква «f» с хвостиком или знак флорина (ƒ)
'percnt': ('\u0025', '&percnt;'), # Знак процента (%)
'permil': ('\u0089', '&permil;'), # Знак промилле (‰)
'pertenk': ('\u2031', '&pertenk;'), # Знак на десять тысяч (‱)
'forall': ('\u2200', '&forall;'), # Для всех (∀)
'comp': ('\u2201', '&comp;'), # Дополнение (∁)
'part': ('\u2202', '&part;'), # Частный дифференциал (∂)
'exist': ('\u2203', '&exist;'), # Существует (∃)
'nexist': ('\u2204', '&nexist;'), # Не существует (∄)
'empty': ('\u2205', '&empty;'), # Пустое множество (∅)
'nabla': ('\u2207', '&nabla;'), # Набла (∇)
'isin': ('\u2208', '&isin;'), # Принадлежит (∈)
'notin': ('\u2209', '&notin;'), # Не принадлежит (∉)
'ni': ('\u220B', '&ni;'), # Содержит как член (∋)
'notni': ('\u220C', '&notni;'), # Не содержит как член (∌)
'prod': ('\u220F', '&prod;'), # N-арное произведение (∏)
'coprod' : ('\u2210', '&coprod;'), # N-арный сомножитель (∐)
'sum': ('\u2211', '&sum;'), # N-арная сумма (∑)
'mnplus': ('\u2213', '&mnplus;'), # Минус-плюс (∓)
'minusd': ('\u2238', '&minusd;'), # Минус с точкой (∸)
'plusdo': ('\u2214', '&plusdo;'), # Плюс с точкой (∔)
'setminus': ('\u2216', '&setminus;'), # Разность множеств ()
'lowast': ('\u2217', '&lowast;'), # Оператор звездочка ()
'compfn': ('\u2218', '&compfn;'), # Кольцевой оператор (∘)
'radic': ('\u221A', '&radic;'), # Квадратный корень (√)
'prop': ('\u221D', '&prop;'), # Пропорционально (∝)
'infin': ('\u221E', '&infin;'), # Бесконечность (∞)
'ang': ('\u2220', '&ang;'), # Угол (∠)
'angrt': ('\u221F', '&angrt;'), # Правый угол (∟)
'angmsd': ('\u2221', '&angmsd;'), # Измеримый угол (∡)
'angsph': ('\u2222', '&angsph;'), # Сферический угол (∢)
'mid': ('\u2223', '&mid;'), # Делит ()
'nmid': ('\u2224', '&nmid;'), # Не делит (∤)
'parallel': ('\u2225', '&parallel;'), # Параллельно (∥)
'npar': ('\u2226', '&npar;'), # Не параллельно (∦)
'and': ('\u2227', '&and;'), # Логическое И (∧)
'or': ('\u2228', '&or;'), # Логическое ИЛИ ()
'cap': ('\u2229', '&cap;'), # Пересечение (∩)
'cup': ('\u222A', '&cup;'), # Объединение ()
'int': ('\u222B', '&int;'), # Интеграл (∫)
'int2': ('\u222C', '&Int;'), # Двойной интеграл (∬)
'int3': ('\u222D', '&iiint;'), # Тройной интеграл (∭)
'conint': ('\u222E', '&conint;'), # Интеграл по контуру (∮)
'Conint': ('\u222F', '&Conint;'), # Поверхностный интеграл (∯)
'Cconint': ('\u2230', '&Cconint;'), # Интеграл по объёму (∰)
'cwint': ('\u2231', '&cwint;'), # Круговой интеграл (∱)
'cwconint': ('\u2232', '&cwconint;'), # Круговой интеграл по контуру (∲)
'awconint': ('\u2233', '&awconint;'), # Антикруговой интеграл по контуру (∳)
'there4': ('\u2234', '&there4;'), # Следовательно (∴)
'because': ('\u2235', '&because;'), # Поскольку (∵)
'ratio': ('\u2236', '&ratio;'), # Отношение ()
'Colon': ('\u2237', '&Colon;'), # Пропорция (∷)
'mDDot': ('\u223A', '&mDDot;'), # Геометрическая пропорция (∺)
'homtht': ('\u223B', '&homtht;'), # Гомотетия (∻)
'sim': ('\u223C', '&sim;'), # Оператор тильда ()
'bsim': ('\u223D', '&bsim;'), # Обратная тильда (∽)
'ac': ('\u223E', '&ac;'), # Перевернутая плавная s (∾)
'acd': ('\u223F', '&acd;'), # Синусоидальная волна (∿)
'wreath': ('\u2240', '&wreath;'), # Скрученное произведение (≀)
'nsim': ('\u2241', '&nsim;'), # Не эквивалентно (≁)
'esim': ('\u2242', '&esim;'), # Тильда с минусом (≂)
'sime': ('\u2243', '&sime;'), # Асимптотически равно (≃)
'nsime': ('\u2244', '&nsime;'), # Не асимптотически равно (≄)
'cong': ('\u2245', '&cong;'), # Конгруэнтность (≅)
'asymp': ('\u2248', '&asymp;'), # Приблизительно равно (≈)
'simne': ('\u2246', '&simne;'), # Приблизительно, но не точно равно (≆)
'ncong': ('\u2247', '&ncong;'), # Не приблизительно, не фактически равно (≇)
'nap': ('\u2249', '&nap;'), # Не почти равный (≉)
'approxeq': ('\u224A', '&approxeq;'), # Почти равный или равный (≊)
'apid': ('\u224B', '&apid;'), # Тройная тильда (≋)
'bcong': ('\u224C', '&bcong;'), # Все равны (≌)
'asympeq': ('\u224D', '&asympeq;'), # Эквивалентный (≍)
'bump': ('\u224E', '&bump;'), # Геометрически эквивалентный (≎)
'bumpe': ('\u224F', '&bumpe;'), # Различие между (≏)
'esdot': ('\u2250', '&esdot;'), # Приближается к пределу (≐)
'eDot': ('\u2251', '&eDot;'), # Точка в пределах, Геометрически равный (≑)
'efDot': ('\u2252', '&efDot;'), # Приблизительно равный или образ (≒)
'erDot': ('\u2253', '&erDot;'), # Образ или приблизительно равный (≓)
'colone': ('\u2254', '&colone;'), # Двоеточие равно (≔)
'ecolon': ('\u2255', '&ecolon;'), # Равно двоеточие (≕)
'ecir': ('\u2256', '&ecir;'), # Кольцо в равно (≖)
'cire': ('\u2257', '&cire;'), # Кольцо равно (≗)
'wedgeq': ('\u2259', '&wedgeq;'), # Оценка, Равно с вектором (≙)
'veeeq': ('\u225A', '&veeeq;'), # Равноугольный (≚)
'trie': ('\u225C', '&trie;'), # Равно по определению (≜)
'equest': ('\u225F', '&equest;'), # Равно с вопросительным знаком (≟)
'equiv': ('\u2261', '&equiv;'), # Тождественно равно (≡)
'nequiv': ('\u2262', '&nequiv;'), # Не тождественно равно (≢)
'le': ('\u2264', '&le;'), # Меньше или равно (≤)
'ge': ('\u2265', '&ge;'), # Больше или равно (≥)
'lE': ('\u2266', '&lE;'), # Меньше над равно (≦)
'gE': ('\u2267', '&gE;'), # Больше над равно (≧)
'lnE': ('\u2268', '&lnE;'), # Меньше, но не равно (≨)
'gnE': ('\u2269', '&gnE;'), # Больше, но не равно (≩)
'Lt': ('\u226A', '&Lt;'), # Много меньше (≪)
'Gt': ('\u226B', '&Gt;'), # Много больше (≫)
'between': ('\u226C', '&between;'), # Между (≬)
'NotCupCap': ('\u226D', '&NotCupCap;'), # Не эквивалентно (≭)
'nlt': ('\u226E', '&nlt;'), # Не меньше (≮)
'ngt': ('\u226F', '&ngt;'), # Не больше (≯)
'nle': ('\u2270', '&nle;'), # Не меньше, не равно (≰)
'nge': ('\u2271', '&nge;'), # Не больше, не равно (≱)
'lsim': ('\u2272', '&lsim;'), # Меньше либо эквивалентно (≲)
'gsim': ('\u2273', '&gsim;'), # Больше либо эквивалентно (≳)
'nlsim': ('\u2274', '&nlsim;'), # Ни меньше, ни эквивалентно (≴)
'ngsim': ('\u2275', '&ngsim;'), # Ни больше, ни эквивалентно (≵)
'lg': ('\u2276', '&lg;'), # Меньше либо больше (≶)
'gl': ('\u2277', '&gl;'), # Больше либо меньше (≷)
'ntlg': ('\u2278', '&ntlg;'), # Ни меньше, ни больше (≸)
'ntgl': ('\u2279', '&ntgl;'), # Ни больше, ни меньше (≹)
'pr': ('\u227A', '&pr;'), # Предшествует (≺)
'sc': ('\u227B', '&sc;'), # Следует за (≻)
'prcue': ('\u227C', '&prcue;'), # Предшествует либо равно (≼)
'sccue': ('\u227D', '&sccue;'), # Следует за либо равно (≽)
'prsim': ('\u227E', '&prsim;'), # Предшествует либо эквивалентно (≾)
'scsim': ('\u227F', '&scsim;'), # Следует за либо эквивалентно (≿)
'npr': ('\u2280', '&npr;'), # Не предшествует (⊀)
'nsc': ('\u2281', '&nsc;'), # Не следует за (⊁)
'sub': ('\u2282', '&sub;'), # Подмножество (⊂)
'sup': ('\u2283', '&sup;'), # Надмножество (⊃)
'nsub': ('\u2284', '&nsub;'), # Не подмножество (⊄)
'nsup': ('\u2285', '&nsup;'), # Не надмножество (⊅)
'sube': ('\u2286', '&sube;'), # Подмножество либо совпадает (⊆)
'supe': ('\u2287', '&supe;'), # Надмножество либо совпадает (⊇)
'nsube': ('\u2288', '&nsube;'), # Ни подмножество, ни совпадает (⊈)
'nsupe': ('\u2289', '&nsupe;'), # Ни надмножество, ни совпадает (⊉)
'subne': ('\u228A', '&subne;'), # Подмножество и не совпадает (⊊)
'supne': ('\u228B', '&supne;'), # Надмножество и не совпадает (⊋)
'cupdot': ('\u228D', '&cupdot;'), # Умножение мультимножеств (⊍)
'uplus': ('\u228E', '&uplus;'), # Объединение мультимножеств, Подмножество с плюсом (⊎)
'sqsub': ('\u228F', '&sqsub;'), # Образ в квадрате (⊏)
'sqsup': ('\u2290', '&sqsup;'), # Прообраз в квадрате (⊐)
'sqsube': ('\u2291', '&sqsube;'), # Образ в квадрате либо равно (⊑)
'sqsupe': ('\u2292', '&sqsupe;'), # Прообраз в квадрате либо равно (⊒)
'sqcap': ('\u2293', '&sqcap;'), # Пересечение в квадрате (⊓)
'sqcup': ('\u2294', '&sqcup;'), # Объединение в квадрате (⊔)
'oplus': ('\u2295', '&oplus;'), # Плюс в круге (⊕)
'ominus': ('\u2296', '&ominus;'), # Минус в круге (⊖)
'otimes': ('\u2297', '&otimes;'), # Произведение в круге (⊗)
'osol': ('\u2298', '&osol;'), # Дробная черта в круге (⊘)
'odot': ('\u2299', '&odot;'), # Точка в круге (⊙)
'ocir': ('\u229A', '&ocir;'), # Кольцевой оператор в круге (⊚)
'oast': ('\u229B', '&oast;'), # Оператор звёздочка в круге (⊛)
'odash': ('\u229D', '&odash;'), # Дефис в круге (⊝)
'plusb': ('\u229E', '&plusb;'), # Плюс в квадрате (⊞)
'minusb': ('\u229F', '&minusb;'), # Минус в квадрате (⊟)
'timesb': ('\u22A0', '&timesb;'), # Произведение в квадрате (⊠)
'sdotb': ('\u22A1', '&sdotb;'), # Точка в квадрате (⊡)
'vdash': ('\u22A2', '&vdash;'), # Шеврон вправо (⊢)
'dashv': ('\u22A3', '&dashv;'), # Шеврон влево (⊣)
'top': ('\u22A4', '&top;'), # Истина, Шеврон вниз ()
'bot': ('\u22A5', '&bot;'), # Ложь, Шеврон вверх (⊥)
'models': ('\u22A7', '&models;'), # Моделирует (⊧)
'vDash': ('\u22A8', '&vDash;'), # Истина (⊨)
'Vdash': ('\u22A9', '&Vdash;'), # Влечёт (⊩)
'Vvdash': ('\u22AA', '&Vvdash;'), # Тройная вертикальная черта с перекладиной справа (⊪)
'VDash': ('\u22AB', '&VDash;'), # Двойная вертикальная черта с двойной перекладиной справа (⊫)
'nvdash': ('\u22AC', '&nvdash;'), # Не доказано (⊬)
'nvDash': ('\u22AD', '&nvDash;'), # Не истина (⊭)
'nVdash': ('\u22AE', '&nVdash;'), # Не влечёт (⊮)
'nVDash': ('\u22AF', '&nVDash;'), # Двойная вертикальная черта с двойной перекладиной справа с отрицанием (⊯)
'prurel': ('\u22B0', '&prurel;'), # Предшествует относительно (⊰)
'vltri': ('\u22B2', '&vltri;'), # Нормальная подгруппа (⊲)
'vrtri': ('\u22B3', '&vrtri;'), # Содержит как нормальную подгруппу (⊳)
'ltrie': ('\u22B4', '&ltrie;'), # Нормальная подгруппа либо совпадает (⊴)
'rtrie': ('\u22B5', '&rtrie;'), # Содержит как нормальную подгруппу либо совпадает (⊵)
'origof': ('\u22B6', '&origof;'), # Прообраз (⊶)
'imof': ('\u22B7', '&imof;'), # Образ, Импликация (⊷)
'mumap': ('\u22B8', '&mumap;'), # Многозначное отображение (⊹)
'hercon': ('\u22B9', '&hercon;'), # Эрмитово сопряжение матрицы (⊹)
'intcal': ('\u22BA', '&intcal;'), # Включение (⊺)
'veebar': ('\u22BB', '&veebar;'), # Исключающее ИЛИ (⊻)
'barvee': ('\u22BD', '&barvee;'), # Логическое ИЛИ с отрицанием (⊽)
'angrtvb': ('\u22BE', '&angrtvb;'), # Правый угол с дугой (⊾)
'lrtri': ('\u22BF', '&lrtri;'), # Треугольник вершиной вправо (⊿)
'xwedge': ('\u22C0', '&xwedge;'), # N-арное логическое И (⋀)
'xvee': ('\u22C1', '&xvee;'), # N-арное логическое ИЛИ ()
'xcap': ('\u22C2', '&xcap;'), # N-арное пересечение (⋂)
'xcup': ('\u22C3', '&xcup;'), # N-арное объединение ()
'diamond': ('\u22C4', '&diamond;'), # Ромб (⋄)
'sdot': ('\u22C5', '&sdot;'), # Оператор точка (⋅)
'Star': ('\u22C6', '&Star;'), # Оператор звёздочка (⋆)
'divonx': ('\u22C7', '&divonx;'), # Деление с умножением, Кратность деления (⋇)
'bowtie': ('\u22C8', '&bowtie;'), # Бабочка (⋈)
'ltimes': ('\u22C9', '&ltimes;'), # Полупрямое произведение с нормальным фактором слева (⋉)
'rtimes': ('\u22CA', '&rtimes;'), # Полупрямое произведение с нормальным фактором справа (⋊)
'lthree': ('\u22CB', '&lthree;'), # Левое полупрямое произведение (⋋)
'rthree': ('\u22CC', '&rthree;'), # Правое полупрямое произведение (⋌)
'bsime': ('\u22CD', '&bsime;'), # Обратное волнистое равно (⋍)
'cuvee': ('\u22CE', '&cuvee;'), # Волнистое логическое ИЛИ (⋎)
'cuwed': ('\u22CF', '&cuwed;'), # Волнистое логическое И (⋏)
'Sub': ('\u22D0', '&Sub;'), # Двойное подмножество (⋐)
'Sup': ('\u22D1', '&Sup;'), # Двойное надмножество (⋑)
'Cap': ('\u22D2', '&Cap;'), # Двойное пересечение (⋒)
'Cup': ('\u22D3', '&Cup;'), # Двойное объединение (⋓)
'fork': ('\u22D4', '&fork;'), # Вилка (⋔)
'epar': ('\u22D5', '&epar;'), # Равно и параллельно (⋕)
'ltdot': ('\u22D6', '&ltdot;'), # Меньше с точкой (⋖)
'gtdot': ('\u22D7', '&gtdot;'), # Больше с точкой (⋗)
'Ll': ('\u22D8', '&Ll;'), # Очень много меньше (⋘)
'Gg': ('\u22D9', '&Gg;'), # Очень много больше (⋙)
'leg': ('\u22DA', '&leg;'), # Меньше, равно либо больше (⋚)
'gel': ('\u22DB', '&gel;'), # Больше, равно либо меньше (⋛)
'cuepr': ('\u22DE', '&cuepr;'), # Равно либо предшествует (⋞)
'cuesc': ('\u22DF', '&cuesc;'), # Равно либо следует за (⋟)
'nprcue': ('\u22E0', '&nprcue;'), # Не предшествует либо равно (⋠)
'nsccue': ('\u22E1', '&nsccue;'), # Не следует за либо равно (⋡)
'nsqsube': ('\u22E2', '&nsqsube;'), # Не образ в квадрате либо равно (⋢)
'nsqsupe': ('\u22E3', '&nsqsupe;'), # Не прообраз в квадрате либо равно (⋣)
'lnapprox': ('\u2a89', '&lnapprox;'), # Меньше, но не приблизительно равно (⋤)
'gnapprox': ('\u2a8a', '&gnapprox;'), # Больше, но не приблизительно равно (⋥)
'lnsim': ('\u22e6', '&lnsim;'), # Меньше, но не эквивалентно (⋦)
'gnsim': ('\u22E7', '&gnsim;'), # Больше, но не эквивалентно (⋧)
'prnsim': ('\u22E8', '&prnsim;'), # Предшествует, но не эквивалентно (⋨)
'scnsim': ('\u22E9', '&scnsim;'), # Следует за, но не эквивалентно (⋩)
'nltri': ('\u22EA', '&nltri;'), # Не содержится как нормальная подгруппа (⋪
'nrtri': ('\u22EB', '&nrtri;'), # Не содержит как нормальную подгруппу (⋫)
'nltrie': ('\u22EC', '&nltrie;'), # Не содержится как нормальная подгруппа либо совпадает (⋬)
'nrtrie': ('\u22ED', '&nrtrie;'), # Не содержит как нормальную подгруппу либо совпадает (⋭)
'vellip': ('\u22EE', '&vellip;'), # Вертикальное многоточие (⋮)
'ctdot': ('\u22EF', '&ctdot;'), # Внутристрочное горизонтальное многоточие (⋯)
'utdot': ('\u22F0', '&utdot;'), # Диагональное многоточие сверху вправо (⋰)
'dtdot': ('\u22F1', '&dtdot;'), # Диагональное многоточие снизу вправо (⋱)
'disin': ('\u22F2', '&disin;'), # Принадлежит с длинным горизонтальным штрихом (⋲)
'isinsv': ('\u22F3', '&isinsv;'), # Принадлежит с вертикальной чертой в конце горизонтального штриха (⋳)
'isins': ('\u22F4', '&isins;'), # Малое принадлежит с вертикальной чертой в конце горизонтального штриха (⋴)
'isindot': ('\u22F5', '&isindot;'), # Принадлежит с точкой сверху (⋵)
'notinvc': ('\u22F6', '&notinvc;'), # Принадлежит с чертой сверху (⋶)
'notinvb': ('\u22F7', '&notinvb;'), # Малое принадлежит с чертой сверху (⋷)
'isinE': ('\u22F8', '&isinE;'), # Принадлежит с двумя горизонтальными штрихами (⋸)
'nisd': ('\u22FA', '&nisd;'), # Содержит с длинным горизонтальным штрихом (⋹)
'xnis': ('\u22FB', '&xnis;'), # Содержит с вертикальной чертой в конце горизонтального штриха (⋺)
'nis': ('\u22FC', '&nis;'), # Малое содержит с вертикальной чертой в конце горизонтального штриха (⋼)
'notnivc': ('\u22FD', '&notnivc;'), # Содержит с чертой сверху (⋽)
'notnivb': ('\u22FE', '&notnivb;'), # Малое содержит с чертой сверху (⋾)
'barwed': ('\u2305', '&barwed;'), # Вертикальная черта с горизонтальной чертой (⌅)
'Barwed': ('\u2306', '&Barwed;'), # Двойная вертикальная черта с горизонтальной чертой (⌆)
'lceil': ('\u2308', '&lceil;'), # Потолок числа, левая скобка (⌈)
'rceil': ('\u2309', '&rceil;'), # Потолок числа, правая скобка (⌉)
'lfloor': ('\u230A', '&lfloor;'), # Пол числа, левая скобка (⌊)
'rfloor': ('\u230B', '&rfloor;'), # Пол числа, правая скобка (⌋)
'lang': ('\u2329', '&lang;'), # Левая угловая скобка (〈)
'rang': ('\u232A', '&rang;'), # Правая угловая скобка (〉)
}
# ШАГ 2: Высший приоритет. Загружаем наши кастомные правила.
encode_map.update(CUSTOM_ENCODE_MAP)
# Другие символы
SYMBOL_ENTITIES = {
'copy': ('\u00A9', '&copy;'), # Копирайт (©)
'reg': ('\u00AE', '&reg;'), # Зарегистрированный товарный знак (®)
'trade': ('\u2122', '&trade;'), # Знак торговой марки (™)
'copysr': ('\u2117', '&copysr;'), # Авторское право звукозаписи, продакшн (℗)
'commat': ('\u0040', '&commat;'), # Коммерческое at, `собака` (@)
'Copf': ('\u2102', '&Copf;'), # Дважды начерченная заглавная С ()
'incare': ('\u2105', '&incare;'), # Забота о (℅)
'gscr': ('\u210A', '&gscr;'), # Каллиграфическая строчная g ()
'hamilt': ('\u210B', '&hamilt;'), # Каллиграфическая заглавная H ()
'Hfr': ('\u210C', '&Hfr;'), # Готическая заглавная H ()
'Hopf': ('\u210D', '&Hopf;'), # Дважды начерченная заглавная H ()
'planckh': ('\u210E', '&planckh;'), # Постоянная Планка ()
'planck': ('\u210F', '&planck;'), # Постоянная Планка делённая на два пи, константа Дирака (ℏ)
'Iscr': ('\u2110', '&Iscr;'), # Каллиграфическая заглавная I ()
'image': ('\u2111', '&image;'), # Готическая заглавная I ()
'Lscr': ('\u2112', '&Lscr;'), # Каллиграфическая заглавная L ()
'ell': ('\u2113', '&ell;'), # Каллиграфическая строчная l ()
'Nopf': ('\u2115', '&Nopf;'), # Дважды начерченная заглавная N ()
'numero': ('\u2116', '&numero;'), # Знак номера (№)
'weierp': ('\u2118', '&weierp;'), # Каллиграфическая заглавная P (℘)
'Popf': ('\u2119', '&Popf;'), # Дважды начерченная заглавная P ()
'Qopf': ('\u211A', '&Qopf;'), # Дважды начерченная заглавная Q ()
'Rscr': ('\u211B', '&Rscr;'), # Каллиграфическая заглавная R ()
'real': ('\u211C', '&real;'), # Готическая заглавная R ()
'Ropf': ('\u211D', '&Ropf;'), # Дважды начерченная заглавная R ()
'rx': ('\u211E', '&rx;'), # Символ рецепта (℞)
'Zopf': ('\u2124', '&Zopf;'), # Дважды начерченная заглавная Z ()
'mho': ('\u2127', '&mho;'), # Перевёрнутый знак ома (℧)
'Zfr': ('\u2128', '&Zfr;'), # Готическая заглавная Z ()
'iiota': ('\u2129', '&iiota;'), # Перевернутая греческая строчная буква йота (℩)
'bernou': ('\u212C', '&bernou;'), # Каллиграфическая заглавная B ()
'Cfr': ('\u212D', '&Cfr;'), # Готическая заглавная C ()
'escr': ('\u212F', '&escr;'), # Каллиграфическая строчная буква e ()
'Escr': ('\u2130', '&Escr;'), # Каллиграфическая заглавная E ()
'Fscr': ('\u2131', '&Fscr;'), # Каллиграфическая заглавная F ()
'Mscr': ('\u2133', '&Mscr;'), # Каллиграфическая заглавная M ()
'oscr': ('\u2134', '&oscr;'), # Каллиграфическая строчная буква o ()
'alefsym': ('\u2135', '&alefsym;'), # Символ алеф (ℵ)
'beth': ('\u2136', '&beth;'), # Символ бет (ℶ)
'gimel': ('\u2137', '&gimel;'), # Символ гимел (ℷ)
'daleth': ('\u2138', '&daleth;'), # Символ далет (ℸ)
'DD': ('\u2145', '&DD;'), # Дважды начерченная курсивная заглавная D ()
'dd': ('\u2146', '&dd;'), # Дважды начерченная курсивная строчная d ()
'ee': ('\u2147', '&ee;'), # Дважды начерченная курсивная строчная e ()
'ii': ('\u2148', '&ii;'), # Дважды начерченная курсивная строчная i ()
'ffilig': ('\uFB03', '&ffilig;'), # Лигатура "ffi" (ffi)
'fflig': ('\uFB00', '&fflig;'), # Лигатура "ff" (ff)
'filig': ('\uFB01', '&filig;'), # Лигатура "fi" (fi)
'fllig': ('\uFB02', '&fllig;'), # Лигатура "fl" (fl)
'starf': ('\u2605', '&starf;'), # Закрашенная звезда (★)
'star': ('\u2606', '&star;'), # Незакрашенная звезда (☆)
'phone': ('\u260E', '&phone;'), # Значок телефона (☎)
'female': ('\u2640', '&female;'), # Венера (женский знак) (♀)
'male': ('\u2642', '&male;'), # Марс (мужской знак) (♂)
'spades': ('\u2660', '&spades;'), # Пики закрашенные (♠)
'clubs': ('\u2663', '&clubs;'), # Трефы закрашенные (♣)
'hearts': ('\u2665', '&hearts;'), # Черви закрашенные (♥)
'diams': ('\u2666', '&diams;'), # Бубны закрашенные (♦)
'loz': ('\u25CA', '&loz;'), # Ромб (◊)
'sung': ('\u266A', '&sung;'), # Музыкальная восьмая нота (♪)
'flat': ('\u266D', '&flat;'), # Музыкальный знак бемоль (♭)
'natural': ('\u266E', '&natural;'), # Музыкальный знак бекар (♮)
'sharp': ('\u266F', '&sharp;'), # Музыкальный знак диез (♯)
'check': ('\u2713', '&check;'), # Галочка (✓)
'cross': ('\u2717', '&cross;'), # Крестик (✗)
'malt': ('\u2720', '&malt;'), # Мальтийский крест (✠)
'sext': ('\u2736', '&sext;'), # Шестиконечная закрашенная звезда (✶)
'VerticalSeparator': ('\u2758', '&VerticalSeparator;'), # Тонкая вертикальная черта (❘)
'lbbrk': ('\u2772', '&lbbrk;'), # Тонкая левая скобка панцерообразной формы ()
'rbbrk': ('\u2773', '&rbbrk;'), # Тонкая правая скобка панцерообразной формы ()
}
# ШАГ 3: Следующий приоритет. Добавляем числовое кодирование.
for char in ALWAYS_ENCODE_TO_NUMERIC_CHARS:
if char not in encode_map:
encode_map[char] = f'&#{ord(char)};'
# Знаки препинания
KEY_AMP = 'amp'
SYMBOL_PUNCTUATION = {
# 'excl': ('\u0021', '&excl;'), # Восклицательный знак (!)
# 'num': ('\u0023', '&num;'), # Решётка (#)
# 'percnt': ('\u0025', '&percnt;'), # Знак процента (%)
KEY_AMP: ('\u0026', '&amp;'), # Амперсанд (&)
# 'lpar': ('\u0028', '&lpar;'), # Левая круглая скобка (()
# 'rpar': ('\u0029', '&rpar;'), # Правая круглая скобка ())
# 'ast': ('\u002A', '&ast;'), # Звёздочка (*)
# 'comma': ('\u002C', '&comma;'), # Запятая (,)
# 'period': ('\u002E', '&period;'), # Точка (.)
# 'sol': ('\u002F', '&sol;'), # Косая черта (/)
# 'colon': ('\u003A', '&colon;'), # Двоеточие (:)
# 'semi': ('\u003B', '&semi;'), # Точка с запятой (;)
# 'quest': ('\u003F', '&quest;'), # Знак вопроса (?)
# 'lbrack': ('\u005B', '&lbrack;'), # Левая квадратная скобка ([)
# 'bsol': ('\u005C', '&bsol;'), # Обратная косая черта (\)
# 'rbrack': ('\u005D', '&rbrack;'), # Правая квадратная скобка (])
# 'Hat': ('\u005E', '&Hat;'), # Циркумфлекс (^) -- знак вставки, карет
# 'lowbar': ('\u005F', '&lowbar;'), # Нижнее подчёркивание (_)
# 'grave': ('\u0060', '&grave;'), # Гравис, Апостроф (обратная кавычка) (`)
# 'lbrace': ('\u007B', '&lbrace;'), # Левая фигурная скобка ({)
# 'vert': ('\u007C', '&vert;'), # Вертикальная черта (|)
# 'rbrace': ('\u007D', '&rbrace;'), # Правая фигурная скобка (})
# 'tilde': ('\u007E', '&tilde;'), # Тильда (~)
'circ': ('\u02C6', '&circ;'), # Модификатор буквы циркумфлекс, ударение (ˆ)
'lrm': ('\u200E', '&lrm;'), # Метка слева направо (Left-to-Right Mark)
'rlm': ('\u200F', '&rlm;'), # Метка справа налево (Right-to-Left Mark)
'iexcl': ('\u00A1', '&iexcl;'), # Перевернутый восклицательный знак (¡)
'brvbar': ('\u00A6', '&brvbar;'), # Изломанная вертикальная черта (¦)
'sect': ('\u00A7', '&sect;'), # Знак параграфа (§)
'uml': ('\u00A8', '&uml;'), # Диэрезис (¨)
'ordf': ('\u00AA', '&ordf;'), # Женский порядковый индикатор (ª)
'not': ('\u00AC', '&not;'), # Знак отрицания (¬)
'macr': ('\u00AF', '&macr;'), # Макрон (¯)
'acute': ('\u00B4', '&acute;'), # Знак ударения (´)
'micro': ('\u00B5', '&micro;'), # Знак микро (µ)
'para': ('\u00B6', '&para;'), # Знак абзаца (¶)
'middot': ('\u00B7', '&middot;'), # Точка по центру (·)
'cedil': ('\u00B8', '&cedil;'), # Седиль (¸)
'ordm': ('\u00BA', '&ordm;'), # Мужской порядковый индикатор (º)
'iquest': ('\u00BF', '&iquest;'), # Перевернутый вопросительный знак (¿)
'Vert': ('\u2016', '&Vert;'), # Двойная вертикальная черта (‖)
'dagger': ('\u2020', '&dagger;'), # Крестик (†)
'Dagger': ('\u2021', '&Dagger;'), # Двойной крестик (‡)
'bull': ('\u2022', '&bull;'), # Маркер списка (•)
'nldr': ('\u2025', '&nldr;'), # Двухточечный пунктир (‥)
'hellip': ('\u2026', '&hellip;'), # Многоточие (…)
'permil': ('\u2030', '&permil;'), # Знак промилле (‰)
'pertenk': ('\u2031', '&pertenk;'), # Знак на десять тысяч (‱)
'prime': ('\u2032', '&prime;'), # Знак штриха (одинарная минута) ()
'Prime': ('\u2033', '&Prime;'), # Двойной штрих (двойная минута) (″)
'tprime': ('\u2034', '&tprime;'), # Тройной штрих (тройная минута) (‴)
'bprime': ('\u2035', '&bprime;'), # Обратный штрих (обратная минута) ()
'oline': ('\u203E', '&oline;'), # Надчёркивание (длинная черта над текстом) (‾)
'caret': ('\u2041', '&caret;'), # Знак вставки точки ввода ()
'hybull': ('\u2043', '&hybull;'), # Маркер списка дефис ()
'frasl': ('\u2044', '&frasl;'), # Дробная наклонная черта (Fraction Slash) ()
'bsemi': ('\u204F', '&bsemi;'), # Инвертированная точка с запятой (⁏)
'qprime': ('\u2057', '&qprime;'), # Четырехкратный штрих (⁗)
}
# ШАГ 4: Низший приоритет. Заполняем все остальное из нашей
# объединенной и нормализованной карты unified_name2codepoint.
for name, codepoint in unified_name2codepoint.items():
char = chr(codepoint)
if char not in encode_map and char not in NEVER_ENCODE_CHARS:
# Теперь 'name' - это уже каноническое имя без ';',
# поэтому дополнительная нормализация не нужна. Код стал проще!
encode_map[char] = f'&{name};'
# Дробные символы и знаки
SYMBOL_FRACTIONS = {
'frac12': ('\u00BD', '&frac12;'), # Обычная дробь 1/2 (½)
'frac13': ('\u2153', '&frac13;'), # Обычная дробь 1/3 (⅓)
'frac14': ('\u00BC', '&frac14;'), # Обычная дробь 1/4 (¼)
'frac15': ('\u2155', '&frac15;'), # Обычная дробь 1/5 (⅕)
'frac16': ('\u2159', '&frac16;'), # Обычная дробь 1/6 (⅙)
# 'frac17': ('\u215A', '&frac17;'), # Обычная дробь 1/7 (⅐)
'frac18': ('\u215B', '&frac18;'), # Обычная дробь 1/8 (⅛)
# 'frac19': ('\u215C', '&frac19;'), # Обычная дробь 1/9 (⅑)
# 'frac110': ('\u215D', '&frac110;'), # Обычная дробь 1/10 (⅒)
'frac23': ('\u2154', '&frac23;'), # Обычная дробь 2/3 (⅔)
'frac25': ('\u2156', '&frac25;'), # Обычная дробь 2/5 (⅖)
'frac34': ('\u00BE', '&frac34;'), # Обычная дробь 3/4 (¾)
'frac35': ('\u2157', '&frac35;'), # Обычная дробь 3/5 (⅗)
'frac38': ('\u215A', '&frac38;'), # Обычная дробь 3/8 (⅜)
'frac45': ('\u2158', '&frac45;'), # Обычная дробь 4/5 (⅘)
'frac56': ('\u215A', '&frac56;'), # Обычная дробь 5/6 (⅚)
'frac58': ('\u215B', '&frac58;'), # Обычная дробь 5/8 (⅝)
'frac78': ('\u215B', '&frac78;'), # Обычная дробь 7/8 (⅞)
}
return encode_map
# Греческие символы
GREEK_ENTITIES = {
'Alpha': ('\u0391', '&Alpha;'), # Греческая заглавная буква Альфа (Α)
'Beta': ('\u0392', '&Beta;'), # Греческая заглавная буква Бета (Β)
'Gamma': ('\u0393', '&Gamma;'), # Греческая заглавная буква Гамма (Γ)
'Delta': ('\u0394', '&Delta;'), # Греческая заглавная буква Дельта (Δ)
'Epsilon': ('\u0395', '&Epsilon;'), # Греческая заглавная буква Эпсилон (Ε)
'Zeta': ('\u0396', '&Zeta;'), # Греческая заглавная буква Зета (Ζ)
'Eta': ('\u0397', '&Eta;'), # Греческая заглавная буква Эта (Η)
'Theta': ('\u0398', '&Theta;'), # Греческая заглавная буква Тета (Θ)
'Iota': ('\u0399', '&Iota;'), # Греческая заглавная буква Иота (Ι)
'Kappa': ('\u039A', '&Kappa;'), # Греческая заглавная буква Каппа (Κ)
'Lambda': ('\u039B', '&Lambda;'), # Греческая заглавная буква Лямбда (Λ)
'Mu': ('\u039C', '&Mu;'), # Греческая заглавная буква Мю (Μ)
'Nu': ('\u039D', '&Nu;'), # Греческая заглавная буква Ню (Ν)
'Xi': ('\u039E', '&Xi;'), # Греческая з<><D0B7>главная буква Кси (Ξ)
'Omicron': ('\u039F', '&Omicron;'), # Греческая заглавная буква Омикрон (Ο)
'Pi': ('\u03A0', '&Pi;'), # Греческая заглавная буква Пи (Π)
'Rho': ('\u03A1', '&Rho;'), # Греческая заглавная буква Ро (Ρ)
'Sigma': ('\u03A3', '&Sigma;'), # Греческая заглавная буква Сигма (Σ)
'Tau': ('\u03A4', '&Tau;'), # Греческая заглавная буква Тау (Τ)
'Upsilon': ('\u03A5', '&Upsilon;'), # Греческая заглавная буква Упсилон (Υ)
'Phi': ('\u03A6', '&Phi;'), # Греческая заглавная буква Фи (Φ)
'Chi': ('\u03A7', '&Chi;'), # Греческая заглавная буква Хи (Χ)
'Psi': ('\u03A8', '&Psi;'), # Греческая заглавная буква Пси (Ψ)
'Omega': ('\u03A9', '&Omega;'), # Греческая заглавная буква Омега (Ω)
'alpha': ('\u03B1', '&alpha;'), # Греческая строчная буква Альфа (α)
'beta': ('\u03B2', '&beta;'), # Греческая строчная буква Бета (β)
'gamma': ('\u03B3', '&gamma;'), # Греческая строчная буква Гамма (γ)
'delta': ('\u03B4', '&delta;'), # Греческая строчная буква Дельта (δ)
'epsilon': ('\u03B5', '&epsilon;'), # Греческая строчная буква Эпсилон (ε)
'zeta': ('\u03B6', '&zeta;'), # Греческая строчная буква Зета (ζ)
'eta': ('\u03B7', '&eta;'), # Греческая строчная буква Эта (η)
'theta': ('\u03B8', '&theta;'), # Греческая строчная буква Тета (θ)
'iota': ('\u03B9', '&iota;'), # Греческая строчная буква Иота (ι)
'kappa': ('\u03BA', '&kappa;'), # Греческая строчная буква Каппа (κ)
'lambda': ('\u03BB', '&lambda;'), # Греческая строчная буква Лямбда (λ)
'mu': ('\u03BC', '&mu;'), # Греческая строчная буква Мю (μ)
'nu': ('\u03BD', '&nu;'), # Греческая строчная буква Ню (ν)
'xi': ('\u03BE', '&xi;'), # Греческая строчная буква Кси (ξ)
'omicron': ('\u03BF', '&omicron;'), # Греческая строчная буква Омикрон (ο)
'pi': ('\u03C0', '&pi;'), # Греческая строчная буква Пи (π)
'rho': ('\u03C1', '&rho;'), # Греческая строчная буква Ро (ρ)
'sigma': ('\u03C3', '&sigma;'), # Греческая строчная буква Сигма (σ)
'tau': ('\u03C4', '&tau;'), # Греческая строчная буква Тау (τ)
'upsilon': ('\u03C5', '&upsilon;'), # Греческая строчная буква Упсилон (υ)
'phi': ('\u03C6', '&phi;'), # Греческая строчная буква Фи (φ)
'chi': ('\u03C7', '&chi;'), # Греческая строчная буква Хи (χ)
'psi': ('\u03C8', '&psi;'), # Греческая строчная буква Пси (ψ)
'omega': ('\u03C9', '&omega;'), # Греческая строчная буква Омега (ω)
'thetasym': ('\u03D1', '&thetasym;'), # Греческая строчная буква пи (ϖ)
'upsih': ('\u03D2', '&upsih;'), # Греческая строчная буква ро (ϱ)
'piv': ('\u03D6', '&piv;'), # Греческая строчная буква пи (ϖ)
}
# Латинские буквы и символы (умляуты, акценты и т.д.)
LATIN_SPECIAL_ENTITIES = {
'Agrave': ('\u00C0', '&Agrave;'), # Латинская заглавная буква A с грависом (À)
'Aacute': ('\u00C1', '&Aacute;'), # Латинская заглавная буква A с акутом (Á)
'Acirc': ('\u00C2', '&Acirc;'), # Латинская заглавная буква A с циркумфлексом (Â)
'Atilde': ('\u00C3', '&Atilde;'), # Латинская заглавная буква A с тильдой (Ã)
'Auml': ('\u00C4', '&Auml;'), # Латинская заглавная буква A с диэризисом/умляутом (Ä)
'Aring': ('\u00C5', '&Aring;'), # Латинская заглавная буква A с кружочком сверху (Å)
'AElig': ('\u00C6', '&AElig;'), # Лигатура, латинская заглавная буква AE (Æ)
'Ccedil': ('\u00C7', '&Ccedil;'), # Латинская заглавная буква C с седилью (Ç)
'Egrave': ('\u00C8', '&Egrave;'), # Латинская заглавная буква E с грависом (È)
'Eacute': ('\u00C9', '&Eacute;'), # Латинская заглавная буква E с акутом (É)
'Ecirc': ('\u00CA', '&Ecirc;'), # Латинская заглавная буква E с циркумфлексом (Ê)
'Euml': ('\u00CB', '&Euml;'), # Латинская заглавная буква E с диэризисом/умляутом (Ë)
'Igrave': ('\u00CC', '&Igrave;'), # Латинская заглавная буква I с грависом (Ì)
'Iacute': ('\u00CD', '&Iacute;'), # Латинская заглавная буква I с акутом (Í)
'Icirc': ('\u00CE', '&Icirc;'), # Латинская заглавная буква I с циркумфлексом (Î)
'Iuml': ('\u00CF', '&Iuml;'), # Латинская заглавная буква I с диэризисом/умляутом (Ï)
'ETH': ('\u00D0', '&ETH;'), # Латинская заглавная буква Eth (Ð)
'Ntilde': ('\u00D1', '&Ntilde;'), # Латинская заглавная буква N с тильдой (Ñ)
'Ograve': ('\u00D2', '&Ograve;'), # Латинская заглавная буква O с грависом (Ò)
'Oacute': ('\u00D3', '&Oacute;'), # Латинская заглавная буква O с акутом (Ó)
'Ocirc': ('\u00D4', '&Ocirc;'), # Латинская заглавная буква O с циркумфлексом (Ô)
'Otilde': ('\u00D5', '&Otilde;'), # Латинская заглавная буква O с тильдой (Õ)
'Ouml': ('\u00D6', '&Ouml;'), # Латинская заглавная буква O с диэризисом/умляутом (Ö)
'Oslash': ('\u00D8', '&Oslash;'), # Латинская заглавная буква O с чертой (Ø)
'Ugrave': ('\u00DD', '&Ugrave;'), # Латинская заглавная буква U с грависом (Ù)
'Uacute': ('\u00DA', '&Uacute;'), # Латинская заглавная буква U с акутом (Ú)
'Ucirc': ('\u00DB', '&Ucirc;'), # Латинская заглавная буква U с циркумфлексом (Û)
'Uuml': ('\u00DC', '&Uuml;'), # Латинская заглавная буква U с диэризисом/умляутом (Ü)
'Yacute': ('\u00DD', '&Yacute;'), # Латинская заглавная буква Y с акутом (Ý)
'THORN': ('\u00DE', '&THORN;'), # Латинская заглавная буква Thorn (Þ)
'szlig': ('\u00DF', '&szlig;'), # Латинская строчная буква Eszett (ß)
'agrave': ('\u00E0', '&agrave;'), # Латинская строчная буква a с грависом (à)
'aacute': ('\u00E1', '&aacute;'), # Латинская строчная буква a с акутом (á)
'acirc': ('\u00E2', '&acirc;'), # Латинская строчная буква a с циркумфлексом (â)
'atilde': ('\u00E3', '&atilde;'), # Латинская строчная буква a с тильдой (ã)
'auml': ('\u00E4', '&auml;'), # Латинская строчная буква a с диэризисом/умляутом (ä)
'aring': ('\u00E5', '&aring;'), # Латинская строчная буква a с кружочком сверху (å)
'aelig': ('\u00E6', '&aelig;'), # Лигатура, латинская строчная буква ae (æ)
'ccedil': ('\u00E7', '&ccedil;'), # Латинская строчная буква c с седилью (ç)
'egrave': ('\u00E8', '&egrave;'), # Латинская строчная буква e с грависом (è)
'eacute': ('\u00E9', '&eacute;'), # Латинская строчная буква e с акутом (é)
'ecirc': ('\u00EA', '&ecirc;'), # Латинская строчная буква e с циркумфлексом (ê)
'euml': ('\u00EB', '&euml;'), # Латинская строчная буква e с диэризисом/умляутом (ë)
'igrave': ('\u00EC', '&igrave;'), # Латинская строчная буква i с грависом (ì)
'iacute': ('\u00ED', '&iacute;'), # Латинская строчная буква i с акутом (í)
'icirc': ('\u00EE', '&icirc;'), # Латинская строчная буква i с циркумфлексом (î)
'iuml': ('\u00EF', '&iuml;'), # Латинская строчная буква i с диэризисом/умляутом (ï)
'eth': ('\u00F0', '&eth;'), # Латинская строчная буква eth (ð)
'ntilde': ('\u00F1', '&ntilde;'), # Латинская строчная буква n с тильдой (ñ)
'ograve': ('\u00F2', '&ograve;'), # Латинская строчная буква o с грависом (ò)
'oacute': ('\u00F3', '&oacute;'), # Латинская строчная буква o с акутом (ó)
'ocirc': ('\u00F4', '&ocirc;'), # Латинская строчная буква o с циркумфлексом (ô)
'otilde': ('\u00F5', '&otilde;'), # Латинская строчная буква o с тильдой (õ)
'ouml': ('\u00F6', '&ouml;'), # Латинская строчная буква o с диэризисом/умляутом (ö)
'oslash': ('\u00F8', '&oslash;'), # Латинская строчная буква o с чертой (ø)
'ugrave': ('\u00F9', '&ugrave;'), # Латинская строчная буква u с грависом (ù)
'uacute': ('\u00FA', '&uacute;'), # Латинская строчная буква u с акутом (ú)
'ucirc': ('\u00FB', '&ucirc;'), # Латинская строчная буква u с циркумфлексом (û)
'uuml': ('\u00FC', '&uuml;'), # Латинская строчная буква u с диэризисом/умляутом (ü)
'yacute': ('\u00FD', '&yacute;'), # Латинская строчная буква y с акутом (ý)
'thorn': ('\u00FE', '&thorn;'), # Латинская строчная буква thorn (þ)
'yuml': ('\u00FF', '&yuml;'), # Латинская строчная буква y с диэризисом/умляутом (ÿ)
'Amacr': ('\u0100', '&Amacr;'), # Латинская строчная буква a с макроном (Ā)
'amacr': ('\u0101', '&amacr;'), # Латинская строчная буква a с макроном (ā)
'Abreve': ('\u0102', '&Abreve;'), # Латинская заглавная буква A с бревисом (Ă)
'abreve': ('\u0103', '&abreve;'), # Латинская строчная буква a с бревисом (ă)
'Aogon': ('\u0104', '&Aogon;'), # Латинская заглавная буква A с огонеком (Ą)
'aogon': ('\u0105', '&aogon;'), # Латинская строчная буква a с огонеком (ą)
'Cacute': ('\u0106', '&Cacute;'), # Латинская заглавная буква C с акутом (Ć)
'cacute': ('\u0107', '&cacute;'), # Латинская строчная буква c с акутом (ć)
'Ccirc': ('\u0108', '&Ccirc;'), # Латинская заглавная буква C с циркумфлексом (Ĉ)
'ccirc': ('\u0109', '&ccirc;'), # Латинская строчная буква c с циркумфлексом (ĉ)
'Cdot': ('\u010A', '&Cdot;'), # Латинская заглавная буква C с точкой сверху (Ċ)
'cdot': ('\u010B', '&cdot;'), # Латинская строчная буква c с точкой сверху (ċ)
'Ccaron': ('\u010C', '&Ccaron;'), # Латинская заглавная буква C с гачеком/карон (Č)
'ccaron': ('\u010D', '&ccaron;'), # Латинская строчная буква c с гачеком/карон (č)
'Dcaron': ('\u010E', '&Dcaron;'), # Латинская заглавная буква D с гачеком/карон (Ď)
'dcaron': ('\u010F', '&dcaron;'), # Латинская строчная буква d с гачеком/карон (ď)
'Dstrok': ('\u0110', '&Dstrok;'), # Латинская заглавная буква D с чертой (Đ)
'dstrok': ('\u0111', '&dstrok;'), # Латинская строчная буква d с чертой (đ)
'Emacr': ('\u0112', '&Emacr;'), # Латинская заглавная буква E с макроном (Ē)
'emacr': ('\u0113', '&emacr;'), # Латинская строчная буква e с макроном (ē)
'Ebreve': ('\u0114', '&Ebreve;'), # Латинская заглавная буква E с бревисом (Ĕ)
'ebreve': ('\u0115', '&ebreve;'), # Латинская строчная буква e с бревисом (ĕ)
'Edot': ('\u0116', '&Edot;'), # Латинская заглавная буква E с точкой сверху (Ė)
'edot': ('\u0117', '&edot;'), # Латинская строчная буква e с точкой сверху (ė)
'Eogon': ('\u0118', '&Eogon;'), # Латинская заглавная буква E с огонеком (Ę)
'eogon': ('\u0119', '&eogon;'), # Латинская строчная буква e с огонеком (ę)
'Ecaron': ('\u011A', '&Ecaron;'), # Латинская заглавная буква E с гачеком/карон (Ě)
'ecaron': ('\u011B', '&ecaron;'), # Латинская строчная буква e с гачеком/карон (ě)
'Gcirc': ('\u011C', '&Gcirc;'), # Латинская заглавная буква G с циркумфлексом (Ĝ)
'gcirc': ('\u011D', '&gcirc;'), # Латинская строчная буква g с циркумфлексом (ĝ)
'Gbreve': ('\u011E', '&Gbreve;'), # Латинская заглавная буква G с бревисом (Ğ)
'gbreve': ('\u011F', '&gbreve;'), # Латинская строчная буква g с бревисом (ğ)
'Gdot': ('\u0120', '&Gdot;'), # Латинская заглавная буква G с точкой сверху (Ġ)
'gdot': ('\u0121', '&gdot;'), # Латинская строчная буква g с точкой сверху (ġ)
'Hcirc': ('\u0124', '&Hcirc;'), # Латинская заглавная буква H с циркумфлексом (Ĥ)
'hcirc': ('\u0125', '&hcirc;'), # Латинская строчная буква h с циркумфлексом (ĥ)
'Hstrok': ('\u0126', '&Hstrok;'), # Латинская заглавная буква H с чертой (Ħ)
'hstrok': ('\u0127', '&hstrok;'), # Латинская строчная буква h с чертой (ħ)
'Itilde': ('\u0128', '&Itilde;'), # Латинская заглавная буква I с тильдой (Ĩ)
'itilde': ('\u0129', '&itilde;'), # Латинская строчная буква i с тильдой (ĩ)
'Imacr': ('\u012A', '&Imacr;'), # Латинская заглавная буква I с макроном (Ī)
'imacr': ('\u012B', '&imacr;'), # Латинская строчная буква i с макроном (ī)
'Ibreve': ('\u012C', '&Ibreve;'), # Латинская заглавная буква I с бревисом (Ĭ) -- кажется нет в RFC
'ibreve': ('\u012D', '&ibreve;'), # Латинская строчная буква i с бревисом (ĭ) -- кажется нет в RFC
'Iogon': ('\u012E', '&Iogon;'), # Латинская заглавная буква I с огонеком (Į)
'iogon': ('\u012F', '&iogon;'), # Латинская строчная буква i с огонеком (į)
'Idot': ('\u0130', '&Idot;'), # Латинская заглавная буква I с точкой сверху (İ)
'dotlessi': ('\u0131', '&dotlessi;'), # Латинская строчная буква i без точки (ı)
'IJlig': ('\u0132', '&IJlig;'), # Лигатура, латинская заглавная буква IJ (IJ)
'ijlig': ('\u0133', '&ijlig;'), # Лигатура, латинская строчная буква ij (ij)
'Jcirc': ('\u0134', '&Jcirc;'), # Латинская заглавная буква J с циркумфлексом (Ĵ)
'jcirc': ('\u0135', '&jcirc;'), # Латинская строчная буква j с циркумфлексом (ĵ)
'Kcedil': ('\u0136', '&Kcedil;'), # Латинская заглавная буква K с седилью (Ķ)
'kcedil': ('\u0137', '&kcedil;'), # Латинская строчная буква k с седилью (ķ)
'kgreen': ('\u0138', '&kgreen;'), # Латинская строчная буква кра / k с гачеком/карон (ĸ)
'Lacute': ('\u0139', '&Lacute;'), # Латинская заглавная буква L с акутом (Ĺ) -- кажется нет в RFC
'lacute': ('\u013A', '&lacute;'), # Латинская строчная буква l с акутом (ĺ)
'Lcedil': ('\u013B', '&Lcedil;'), # Латинская заглавная буква L с седилью (Ļ)
'lcedil': ('\u013C', '&lcedil;'), # Латинская строчная буква l с седилью (ļ)
'Lcaron': ('\u013D', '&Lcaron;'), # Латинская заглавная буква L с гачеком/карон (Ľ)
'lcaron': ('\u013E', '&lcaron;'), # Латинская строчная буква l с гачеком/карон (ľ)
'Lmidot': ('\u013F', '&Lmidot;'), # Латинская заглавная буква L с внутристрочной точкой (Ŀ)
'lmidot': ('\u0140', '&lmidot;'), # Латинская строчная буква l с внутристрочной точкой (ŀ)
'Lstrok': ('\u0141', '&Lstrok;'), # Латинская заглавная буква L с чертой, символ Лайткоина (Ł)
'lstrok': ('\u0142', '&lstrok;'), # Латинская строчная буква l с чертой (ł)
'Nacute': ('\u0143', '&Nacute;'), # Латинская заглавная буква N с акутом (Ń)
'nacute': ('\u0144', '&nacute;'), # Латинская строчная буква n с акутом (ń)
'Ncedil': ('\u0145', '&Ncedil;'), # Латинская заглавная буква N с седилью (Ņ)
'ncedil': ('\u0146', '&ncedil;'), # Латинская строчная буква n с седилью (ņ)
'Ncaron': ('\u0147', '&Ncaron;'), # Латинская заглавная буква N с гачеком/карон (Ň)
'ncaron': ('\u0148', '&ncaron;'), # Латинская строчная буква n с гачеком/карон (ň)
'napos': ('\u0149', '&napos;'), # Латинская строчная буква n предшествующим апострофом (ʼn)
'ENG': ('\u014A', '&ENG;'), # Латинская заглавная буква Eng (Ŋ)
'eng': ('\u014B', '&eng;'), # Латинская строчная буква eng (ŋ)
'Omacr': ('\u014C', '&Omacr;'), # Латинская заглавная буква O с макроном (Ō)
'omacr': ('\u014D', '&omacr;'), # Латинская строчная буква o с макроном (ō)
'Obreve': ('\u014E', '&Obreve;'), # Латинская заглавная буква O с бревисом (Ŏ) -- кажется нет в RFC
'obreve': ('\u014F', '&obreve;'), # Латинская строчная буква o с бревисом (ŏ) -- кажется нет в RFC
'Odblac': ('\u0150', '&Odblac;'), # Латинская заглавная буква O с двойным акутом (Ő)
'odblac': ('\u0151', '&odblac;'), # Латинская строчная буква o с двойным акутом (ő)
'OElig': ('\u0152', '&OElig;'), # Лигатура, латинская заглавная буква OE (Œ)
'oelig': ('\u0153', '&oelig;'), # Лигатура, латинская строчная буква oe (œ)
'Racute': ('\u0154', '&Racute;'), # Латинская заглавная буква R с акутом (Ŕ)
'racute': ('\u0155', '&racute;'), # Латинская строчная буква r с акутом (ŕ)
'Rcedil': ('\u0156', '&Rcedil;'), # Латинская заглавная буква R с седилью (Ŗ)
'rcedil': ('\u0157', '&rcedil;'), # Латинская строчная буква r с седилью (ŗ)
'Rcaron': ('\u0158', '&Rcaron;'), # Латинская заглавная буква R с гачеком/карон (Ř)
'rcaron': ('\u0159', '&rcaron;'), # Латинская строчная буква r с гачеком/карон (ř)
'Sacute': ('\u015A', '&Sacute;'), # Латинская заглавная буква S с акутом (Ś)
'sacute': ('\u015B', '&sacute;'), # Латинская строчная буква s с акутом (ś)
'Scirc': ('\u015C', '&Scirc;'), # Латинская заглавная буква S с циркумфлексом (Ŝ)
'scirc': ('\u015D', '&scirc;'), # Латинская строчная буква s с циркумфлексом (ŝ)
'Scedil': ('\u015E', '&Scedil;'), # Латинская заглавная буква S с седилью (Ş)
'scedil': ('\u015F', '&scedil;'), # Латинская строчная буква s с седилью (ş)
'Scaron': ('\u0160', '&Scaron;'), # Латинская заглавная буква S с гачеком/карон (Š)
'scaron': ('\u0161', '&scaron;'), # Латинская строчная буква s с гачеком/карон (š)
'Tcedil': ('\u0162', '&Tcedil;'), # Латинская заглавная буква T с седилью (Ţ)
'tcedil': ('\u0163', '&tcedil;'), # Латинская строчная буква t с седилью (ţ)
'Tcaron': ('\u0164', '&Tcaron;'), # Латинская заглавная буква T с гачеком/карон (Ť)
'tcaron': ('\u0165', '&tcaron;'), # Латинская строчная буква t с гачеком/карон (ť)
'Tstrok': ('\u0166', '&Tstrok;'), # Латинская заглавная буква T с чертой (Ŧ)
'tstrok': ('\u0167', '&tstrok;'), # Латинская строчная буква t с чертой (ŧ)
'Utilde': ('\u0168', '&Utilde;'), # Латинская заглавная буква U с тильдой (Ũ)
'utilde': ('\u0169', '&utilde;'), # Латинская строчная буква u с тильдой (ũ)
'Umacr': ('\u016A', '&Umacr;'), # Латинская заглавная буква U с макроном (Ū)
'umacr': ('\u016B', '&umacr;'), # Латинская строчная буква u с макроном (ū)
'Ubreve': ('\u016C', '&Ubreve;'), # Латинская заглавная буква U с бревисом (Ŭ)
'ubreve': ('\u016D', '&ubreve;'), # Латинская строчная буква u с бревисом (ŭ)
'Uring': ('\u016E', '&Uring;'), # Латинская заглавная буква U с кружочком сверху (Ů)
'uring': ('\u016F', '&uring;'), # Латинская строчная буква u с кружочком сверху (ů)
'Udblac': ('\u0170', '&Udblac;'), # Латинская заглавная буква U с двойным акутом (Ű)
'udblac': ('\u0171', '&udblac;'), # Латинская строчная буква u с двойным акутом (ű)
'Uogon': ('\u0172', '&Uogon;'), # Латинская заглавная буква U с огонеком (Ų)
'uogon': ('\u0173', '&uogon;'), # Латинская строчная буква u с огонеком (ų)
'Wcirc': ('\u0174', '&Wcirc;'), # Латинская заглавная буква W с циркумфлексом (Ŵ)
'wcirc': ('\u0175', '&wcirc;'), # Латинская строчная буква w с циркумфлексом (ŵ)
'Ycirc': ('\u0176', '&Ycirc;'), # Латинская заглавная буква Y с циркумфлексом (Ŷ)
'ycirc': ('\u0177', '&ycirc;'), # Латинская строчная буква y с циркумфлексом (ŷ)
'Yuml': ('\u0178', '&Yuml;'), # Латинская заглавная буква Y с диэризисом/умляутом (Ÿ)
'Zacute': ('\u0179', '&Zacute;'), # Латинская заглавная буква Z с акутом (Ź)
'zacute': ('\u017A', '&zacute;'), # Латинская строчная буква z с акутом (ź)
'Zdot': ('\u017B', '&Zdot;'), # Латинская заглавная буква Z с точкой сверху (Ż)
'zdot': ('\u017C', '&zdot;'), # Латинская строчная буква z с точкой сверху (ż)
'Zcaron': ('\u017D', '&Zcaron;'), # Латинская заглавная буква Z с гачеком/карон (Ž)
'zcaron': ('\u017E', '&zcaron;'), # Латинская строчная буква z с гачеком/карон (ž)
'DownBreve': ('\u0311', '&DownBreve;'), # Комбинируемая перевернутая бреве (круглая шапочка)
}
# Стрелки и другие символы
ARROW_ENTITIES = {
'larr': ('\u2190', '&larr;'), # Левый указатель (←)
'uarr': ('\u2191', '&uarr;'), # Верхний указатель (↑)
'rarr': ('\u2192', '&rarr;'), # Правый указатель (→)
'darr': ('\u2193', '&darr;'), # Нижний указатель (↓)
'harr': ('\u2194', '&harr;'), # Двусторонний указатель (↔)
'crarr': ('\u21B5', '&crarr;'), # Указатель возврата каретки, угловая стрелка вниз-влево (↵)
'olarr': ('\u21BA', '&olarr;'), # Левый круговой указатель, по часовой стрелке (↺)
'orarr': ('\u21BB', '&orarr;'), # Правый круговой указатель, против часовой стрелки (↻)
'lharu': ('\u21BC', '&lharu;'), # Гарпун влево с зубцом вверх (↼)
'lhard': ('\u21BD', '&lhard;'), # Гарпун влево с зубцом вниз (↽)
'uharr': ('\u21BE', '&uharr;'), # Гарпун вверх с зубцом вправо (↾)
'uharl': ('\u21BF', '&uharl;'), # Гарпун вверх с зубцом влево (↿)
'rharu': ('\u21C0', '&rharu;'), # Гарпун вправо с зубцом вверх (⇀)
'rhard': ('\u21C1', '&rhard;'), # Гарпун вправо с зубцом вниз (⇁)
'dharr': ('\u21C2', '&dharr;'), # Гарпун вниз с зубцом вправо (⇂)
'dharl': ('\u21C3', '&dharl;'), # Гарпун вниз с зубцом влево (⇃)
'rlarr': ('\u21C4', '&rlarr;'), # Стрелка вправо над стрелкой влево (⇄)
'udarr': ('\u21C5', '&udarr;'), # Стрелка вверх и стрелка вниз (⇅)
'lrarr': ('\u21C6', '&lrarr;'), # Стрелка влево над стрелкой вправо (⇆)
'llarr': ('\u21C7', '&llarr;'), # Двойная стрелка влево (⇇)
'uuarr': ('\u21C8', '&uuarr;'), # Двойная стрелка вверх (⇈)
'rrarr': ('\u21C9', '&rrarr;'), # Двойная стрелка вправо (⇉)
'ddarr': ('\u21CA', '&ddarr;'), # Двойная стрелка вниз (⇊)
'lrhar': ('\u21CB', '&lrhar;'), # Двойной гарпун влево и вправо (⇋)
'rlhar': ('\u21CC', '&rlhar;'), # Двойной гарпун вправо и влево (⇌)
'nlArr': ('\u21CD', '&nlArr;'), # Перечёркнутая двойная стрелка влево (⇍)
'nhArr': ('\u21CE', '&nhArr;'), # Перечёркнутая двойная стрелка влево-вправо (⇎)
'nrArr': ('\u21CF', '&nrArr;'), # Перечёркнутая двойная стрелка вправо (⇏)
'lArr': ('\u21D0', '&lArr;'), # Двойная стрелка влево (⇐)
'uArr': ('\u21D1', '&uArr;'), # Двойная стрелка вверх (⇑)
'rArr': ('\u21D2', '&rArr;'), # Двойная стрелка вправо (⇒)
'dArr': ('\u21D3', '&dArr;'), # Двойная стрелка вниз (⇓)
'hArr': ('\u21D4', '&hArr;'), # Двойная стрелка влево-вправо (⇔)
'vArr': ('\u21D5', '&vArr;'), # Двойная стрелка вверх-вниз (⇕)
'nwArr': ('\u21D6', '&nwArr;'), # Двойная стрелка влево-вверх (⇖)
'neArr': ('\u21D7', '&neArr;'), # Двойная стрелка вправо-вверх (⇗)
'seArr': ('\u21D8', '&seArr;'), # Двойная стрелка вправо-вниз (⇘)
'swArr': ('\u21D9', '&swArr;'), # Двойная стрелка влево-вниз (⇙)
'lAarr': ('\u21DA', '&lAarr;'), # Тройная стрелка влево (⇚)
'rAarr': ('\u21DB', '&rAarr;'), # Тройная стрелка вправо (⇛)
'zigrarr': ('\u21DC', '&zigrarr;'), # Стрелка влево с тремя изгибами (⇜)
'zigrarr': ('\u21DD', '&zigrarr;'), # Стрелка вправо с тремя изгибами (⇝)
'larrb': ('\u21E4', '&larrb;'), # Стрелка влево, упирающаяся в планку (⇤)
'rarrb': ('\u21E5', '&rarrb;'), # Стрелка вправо, упирающаяся в планку (⇥)
'duarr': ('\u21F5', '&duarr;'), # Двойная стрелка вверх-вниз (⇵)
'loarr': ('\u21FD', '&loarr;'), # Стрелка влево с полым наконечником (⇽)
'roarr': ('\u21FE', '&roarr;'), # Стрелка вправо с полым наконечником (⇾)
'hoarr': ('\u21FF', '&hoarr;'), # Стрелка влево-вправо с полым наконечником (⇿)
'xlarr': ('\u27F5', '&xlarr;'), # Длинная стрелка влево (⟵)
'xrarr': ('\u27F6', '&xrarr;'), # Длинная стрелка вправо (⟶)
'xharr': ('\u27F7', '&xharr;'), # Длинная стрелка влево-вправо (⟷)
'xlArr': ('\u27F8', '&xlArr;'), # Длинная двойная стрелка влево (⟸)
'xrArr': ('\u27F9', '&xrArr;'), # Длинная двойная стрелка вправо (⟹)
'xhArr': ('\u27FA', '&xhArr;'), # Длинная двойная стрелка влево-вправо (⟺)
'dzigrarr': ('\u27FF', '&dzigrarr;'), # Длинная стрелка-пружина, направленная вправо (⟿)
'xmap': ('\u27FC', '&xmap;'), # Длинная направленная вправо от чёрточки стрелка (⟼)
'nvlArr': ('\u2902', '&nvlArr;'), # Двойная стрелка с вертикальной чертой, направленная влево (⤂)
'nvrArr': ('\u2903', '&nvrArr;'), # Двойная стрелка с вертикальной чертой, направленная вправо (⤃)
'nvHarr': ('\u2904', '&nvHarr;'), # Двойная стрелка с вертикальной чертой, направленная вправо и влево (⤄)
'Map': ('\u2905', '&Map;'), # Стрелка с двумя наконечниками направленная вправо от чёрточки стрелка (⤅)
'lbarr': ('\u290C', '&lbarr;'), # Стрелка с двойным штрихом, направленная влево (⤌)
'rbarr': ('\u290D', '&rbarr;'), # Стрелка с двойным штрихом, направленная вправо (⤍)
'lBarr': ('\u290E', '&lBarr;'), # Стрелка с тройным штрихом, направленная влево (⤎)
'rBarr': ('\u290F', '&rBarr;'), # Стрелка с тройным штрихом, направленная вправо (⤏)
'RBarr': ('\u2910', '&RBarr;'), # Стрелка с тройным штрихом с двумя наконечниками, направленная вправо (⤐)
'DDotrahd': ('\u2911', '&DDotrahd;'), # Стрелка с точечным стрежнем, направленная вправо
'UpArrowBar': ('\u2912', '&UpArrowBar;'), # Стрелка вверх, направленная к чёрточке (⤒)
'DownArrowBar': ('\u2913', '&DownArrowBar;'), # Стрелка вниз, направленная к чёрточке (⤓)
'Rarrtl': ('\u2916', '&Rarrtl;'), # Стрелка с двумя наконечниками и хвостиком, направленная вправо (⤖)
'latail': ('\u2919', '&latail;'), # Направленный влево хвост стрелы (⤙)
'ratail': ('\u291A', '&ratail;'), # Направленный вправо хвост стрелы (⤚)
'lAtail': ('\u291B', '&lAtail;'), # Направленный влево хвост стрелы с двумя наконечниками (⤛)
'rAtail': ('\u291C', '&rAtail;'), # Направленный вправо хвост стрелы с двумя наконечниками (⤜)
'larrfs': ('\u291D', '&larrfs;'), # Стрелка, направленная влево к закрашенному ромбу (⤝)
'rarrfs': ('\u291E', '&rarrfs;'), # Стрелка, направленная вправо к закрашенному ромбу (⤞)
'larrbfs': ('\u291F', '&larrbfs;'), # Стрелка, направленная влево от чёрточки к закрашенному ромбу (⤟)
'rarrbfs': ('\u2920', '&rarrbfs;'), # Стрелка, направленная вправо от чёрточки к закрашенному ромбу (⤠)
'nwarhk': ('\u2923', '&nwarhk;'), # Стрелка, направленная на северо-запад с крючком на конце (⤣)
'nearhk': ('\u2924', '&nearhk;'), # Стрелка, направленная на северо-восток с крючком на конце (⤤)
'searhk': ('\u2925', '&searhk;'), # Стрелка, направленная на юго-восток с крючком на конце (⤥)
'swarhk': ('\u2926', '&swarhk;'), # Стрелка, направленная на юго-запад с крючком на конце (⤦)
'nwnear': ('\u2927', '&nwnear;'), # Стрелка, направленная на северо-запад и стрелка, направленная на северо-восток (⤧)
'nesear': ('\u2928', '&nesear;'), # Стрелка, направленная на северо-восток и стрелка, направленная на юго-восток (⤨)
'seswar': ('\u2929', '&seswar;'), # Стрелка, направленная на юго-восток и стрелка, направленная на юго-запад (⤩)
'swnwar': ('\u292A', '&swnwar;'), # Стрелка, направленная на юго-запад и стрелка, направленная на северо-запад (⤪)
'urca': ('\u2934', '&urca;'), # Стрелка, направленная вправо и изогнутая вверх (⤴)
'drca': ('\u2935', '&drca;'), # Стрелка, направленная вправо и изогнутая вниз (⤵)
# 'ldca': ('\u2936', '&ldca;'), # Стрелка, направленная влево, затем изогнутая вниз (⤶)
# 'rdca': ('\u2937', '&rdca;'), # Стрелка, направленная вправо, затем изогнутая вверх (⤷)
# 'dlca': ('\u2939', '&dlca;'), # Стрелка, направленная вправо к закрашенному ромбу (⤹)
# Есть еще много стрелок, кажется для них есть мета-коды в HTML:
# https://symbl.cc/ru/html-entities/
# Но, кажется, по ссылке путаница в мета-кодах
# Очень жаль, что нет треугольников. Они и как стрелки очень удобны.
# \u25B2 - ▲ \u25BC - ▼ \u25BA - ► \u25C4 - ◄
}
# --- Сборка и валидация ---
# 1. Создаем единый словарь всех сущностей для удобного доступа
ALL_ENTITIES = {
**SHY_ENTITIES,
**SPACE_ENTITIES,
**DASH_ENTITIES,
**MATH_ENTITIES,
**GREEK_ENTITIES,
**LATIN_SPECIAL_ENTITIES,
**QUOTE_ENTITIES,
**CURRENCY_ENTITIES,
**SYMBOL_ENTITIES,
**SYMBOL_PUNCTUATION,
**SYMBOL_FRACTIONS,
**ARROW_ENTITIES
}
# Сущности, которые ВСЕГДА должны выводиться как мнемоники в режиме MODE_MIXED
# Указываются их ИМЕНА (ключи из словарей выше).
# NOTE: Повторное использование магических строк 'SHY', 'NBSP' и т.д. не создает новый объект в памяти. Умный Python
# когда видит одинаковую строку в коде применяет интернирование строк (string interning).
ALWAYS_MNEMONIC_IN_SAFE_MODE = frozenset([KEY_AMP, KEY_LT, KEY_GT, KEY_SHY, KEY_NBSP, KEY_ZWNJ, KEY_ZWJ])
# Создаем карту один раз при импорте модуля.
ENCODE_MAP = _build_translation_maps()
# --- Публичный API модуля ---
def get_encode_map():
"""Возвращает готовую карту для кодирования."""
return ENCODE_MAP

View File

@@ -6,24 +6,21 @@
import regex
import logging
from etpgrf.config import LANG_RU, LANG_RU_OLD, LANG_EN, KEY_SHY, ALL_ENTITIES
import html
from etpgrf.config import (
LANG_RU, LANG_RU_OLD, LANG_EN,
RU_VOWELS_UPPER, RU_CONSONANTS_UPPER, RU_J_SOUND_UPPER, RU_SIGNS_UPPER, # RU_ALPHABET_UPPER,
EN_VOWELS_UPPER, EN_CONSONANTS_UPPER # , EN_ALPHABET_UPPER
)
from etpgrf.defaults import etpgrf_settings
from etpgrf.comutil import parse_and_validate_langs, is_inside_unbreakable_segment
_RU_VOWELS_UPPER = frozenset(['А', 'О', 'И', 'Е', 'Ё', 'Э', 'Ы', 'У', 'Ю', 'Я'])
_RU_CONSONANTS_UPPER = frozenset(['Б', 'В', 'Г', 'Д', 'Ж', 'З', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ф', 'Х',
'Ц', 'Ч', 'Ш', 'Щ'])
_RU_J_SOUND_UPPER = frozenset(['Й'])
_RU_SIGNS_UPPER = frozenset(['Ь', 'Ъ'])
_RU_OLD_VOWELS_UPPER = frozenset(['І', # И-десятеричное (гласная)
'Ѣ', # Ять (гласная)
'Ѵ']) # Ижица (может быть и гласной, и согласной - сложный случай!)
_RU_OLD_CONSONANTS_UPPER = frozenset(['Ѳ',],) # Фита (согласная)
_EN_VOWELS_UPPER = frozenset(['A', 'E', 'I', 'O', 'U', 'Æ', 'Œ'])
_EN_CONSONANTS_UPPER = frozenset(['B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
'V', 'W', 'X', 'Y', 'Z'])
_EN_SUFFIXES_WITHOUT_HYPHENATION_UPPER = frozenset([
"ATION", "ITION", "UTION", "OSITY", # 5-символьные, типа: creation, position, solution, generosity
"ABLE", "IBLE", "MENT", "NESS", # 4-символьные, типа: readable, visible, development, kindness
@@ -71,7 +68,10 @@ class Hyphenator:
# Загружает наборы символов на основе self.langs
self._load_language_resources_for_hyphenation()
# Так как внутри типографа кодировка html, то символ переноса независим от режима
self._split_code: str = ALL_ENTITIES[KEY_SHY][0]
# self._split_code: str = ALL_ENTITIES[KEY_SHY][0]
# Получаем символ неразрывного пробела напрямую из стандартной библиотеки
self._split_code = chr(html.entities.name2codepoint['shy']) # <--- ИЗМЕНИТЬ
# ...
logger.debug(f"Hyphenator `__init__`. Langs: {self.langs},"
f" Max unhyphenated_len: {self.max_unhyphenated_len},"
@@ -80,21 +80,21 @@ class Hyphenator:
def _load_language_resources_for_hyphenation(self):
# Определяем наборы гласных, согласных и т.д. в зависимости языков.
if LANG_RU in self.langs:
self._vowels |= _RU_VOWELS_UPPER
self._consonants |= _RU_CONSONANTS_UPPER
self._j_sound_upper |= _RU_J_SOUND_UPPER
self._signs_upper |= _RU_SIGNS_UPPER
self._vowels |= RU_VOWELS_UPPER
self._consonants |= RU_CONSONANTS_UPPER
self._j_sound_upper |= RU_J_SOUND_UPPER
self._signs_upper |= RU_SIGNS_UPPER
self._ru_alphabet_upper |= self._vowels | self._consonants | self._j_sound_upper | self._signs_upper
if LANG_RU_OLD in self.langs:
self._vowels |= _RU_VOWELS_UPPER | _RU_OLD_VOWELS_UPPER
self._consonants |= _RU_CONSONANTS_UPPER | _RU_OLD_CONSONANTS_UPPER
self._j_sound_upper |= _RU_J_SOUND_UPPER
self._signs_upper |= _RU_SIGNS_UPPER
self._vowels |= RU_VOWELS_UPPER | _RU_OLD_VOWELS_UPPER
self._consonants |= RU_CONSONANTS_UPPER | _RU_OLD_CONSONANTS_UPPER
self._j_sound_upper |= RU_J_SOUND_UPPER
self._signs_upper |= RU_SIGNS_UPPER
self._ru_alphabet_upper |= self._vowels | self._consonants | self._j_sound_upper | self._signs_upper
if LANG_EN in self.langs:
self._vowels |= _EN_VOWELS_UPPER
self._consonants |= _EN_CONSONANTS_UPPER
self._en_alphabet_upper |= _EN_VOWELS_UPPER | _EN_CONSONANTS_UPPER
self._vowels |= EN_VOWELS_UPPER
self._consonants |= EN_CONSONANTS_UPPER
self._en_alphabet_upper |= EN_VOWELS_UPPER | EN_CONSONANTS_UPPER
# ... и для других языков, если они поддерживаются переносами