mod: изменения перед переработкой модуля висячей пунктуации

This commit is contained in:
2026-03-15 14:05:10 +03:00
parent c7d8b18c68
commit 321c2efc26
3 changed files with 52 additions and 42 deletions

View File

@@ -727,7 +727,6 @@ ABBR_COMMON_PREPOSITION = [
PROTECTED_HTML_TAGS = ['style', 'script', 'pre', 'code', 'kbd', 'samp', 'math'] PROTECTED_HTML_TAGS = ['style', 'script', 'pre', 'code', 'kbd', 'samp', 'math']
# === КОНСТАНТЫ ДЛЯ ВИСЯЧЕЙ ТИПОГРАФИКИ === # === КОНСТАНТЫ ДЛЯ ВИСЯЧЕЙ ТИПОГРАФИКИ ===
HANGING_PUNCTUATION_MODE_LEFT = 'left' HANGING_PUNCTUATION_MODE_LEFT = 'left'
HANGING_PUNCTUATION_MODE_RIGHT = 'right' HANGING_PUNCTUATION_MODE_RIGHT = 'right'
HANGING_PUNCTUATION_MODES = frozenset([ HANGING_PUNCTUATION_MODES = frozenset([
@@ -766,49 +765,60 @@ HANGING_PUNCTUATION_SPACE_CHARS = frozenset([
# ВАЖНО: кавычки второго уровня (CHAR_EN_QUOT2_OPEN = '„' и CHAR_RU_QUOT2_OPEN = '„') НЕ ВКЛЮЧЕНЫ, # ВАЖНО: кавычки второго уровня (CHAR_EN_QUOT2_OPEN = '„' и CHAR_RU_QUOT2_OPEN = '„') НЕ ВКЛЮЧЕНЫ,
# т.к. CHAR_RU_QUOT2_CLOSE == CHAR_EN_QUOT1_OPEN и невозможно отличить закрывающую кавычку (ru) # т.к. CHAR_RU_QUOT2_CLOSE == CHAR_EN_QUOT1_OPEN и невозможно отличить закрывающую кавычку (ru)
# от открывающей кавычки (en) и однозначно решить к какую сторону делать вывешивание. # от открывающей кавычки (en) и однозначно решить к какую сторону делать вывешивание.
# TODO: в будущем можно попробовать определять это по прилегающему пробелу (слева или справа). HANGING_PUNCTUATION_CHARS = {
HANGING_PUNCTUATION_LEFT_CHARS = frozenset([ HANGING_PUNCTUATION_MODE_LEFT: frozenset([
CHAR_RU_QUOT1_OPEN, # « CHAR_RU_QUOT1_OPEN, # «
CHAR_EN_QUOT1_OPEN, # “ CHAR_EN_QUOT1_OPEN, # “
CHAR_LPAR, # ( CHAR_LPAR, # (
CHAR_LSQB, # [ CHAR_LSQB, # [
CHAR_LCUB, # { CHAR_LCUB, # {
]) ]),
HANGING_PUNCTUATION_MODE_RIGHT: frozenset([
CHAR_RU_QUOT1_CLOSE, # »
CHAR_EN_QUOT1_CLOSE, # ”
CHAR_RPAR, # )
CHAR_RSQB, # ]
CHAR_RCUB, # }
CHAR_DOT, # .
CHAR_COMMA, # ,
CHAR_COLON, # :
]),
}
# 2. Набор символов, которые могут "висеть" справа # Сохраняем старые имена ради совместимости, пока модуль не переписан полностью
HANGING_PUNCTUATION_RIGHT_CHARS = frozenset([ HANGING_PUNCTUATION_LEFT_CHARS = HANGING_PUNCTUATION_CHARS[HANGING_PUNCTUATION_MODE_LEFT]
CHAR_RU_QUOT1_CLOSE, # » HANGING_PUNCTUATION_RIGHT_CHARS = HANGING_PUNCTUATION_CHARS[HANGING_PUNCTUATION_MODE_RIGHT]
CHAR_EN_QUOT1_CLOSE, # ”
CHAR_RPAR, # )
CHAR_RSQB, # ]
CHAR_RCUB, # }
CHAR_DOT, # .
CHAR_COMMA, # ,
CHAR_COLON, # :
])
# 3. Словарь, сопоставляющий символ с его CSS-классом # 3. Словарь, сопоставляющий символ с его CSS-классом
HANGING_PUNCTUATION_SYMBOLS_CLASSES = { HANGING_PUNCTUATION_SYMBOLS_CLASSES = {
# Левая пунктуация: все классы начинаются с 'etp-l' HANGING_PUNCTUATION_MODE_LEFT: {
CHAR_RU_QUOT1_OPEN: 'etp-laquo', # ` «` -- левая открывающая кавычка-ёлочка # Левая пунктуация: все классы начинаются с 'etp-l'
CHAR_EN_QUOT1_OPEN: 'etp-ldquo', # ` ` -- левая открывающая кавычка-лапка CHAR_RU_QUOT1_OPEN: 'etp-laquo', # ` «` -- левая открывающая кавычка-ёлочка
CHAR_LPAR: 'etp-lpar', # ` (` -- левая открывающая скобка CHAR_EN_QUOT1_OPEN: 'etp-ldquo', # ` ` -- левая открывающая кавычка-лапка
CHAR_LSQB: 'etp-lsqb', # ` [` -- левая открывающая квадратная скобка CHAR_LPAR: 'etp-lpar', # ` (` -- левая открывающая скобка
CHAR_LCUB: 'etp-lcub', # ` {` -- левая открывающая фигурная скобка CHAR_LSQB: 'etp-lsqb', # ` [` -- левая открывающая квадратная скобка
# Правая пунктуация: все классы начинаются с 'etp-r' CHAR_LCUB: 'etp-lcub', # ` {` -- левая открывающая фигурная скобка
CHAR_RU_QUOT1_CLOSE: 'etp-raquo', # `» ` -- правая закрывающая кавычка-ёлочка },
CHAR_EN_QUOT1_CLOSE: 'etp-rdquo', # `” ` -- правая закрывающая кавычка-лапка HANGING_PUNCTUATION_MODE_RIGHT: {
CHAR_RPAR: 'etp-rpar', # `) ` -- правая закрывающая скобка # Правая пунктуация: все классы начинаются с 'etp-r'
CHAR_RSQB: 'etp-rsqb', # `] ` -- правая закрывающая квадратная скобка CHAR_RU_QUOT1_CLOSE: 'etp-raquo', # `» ` -- правая закрывающая кавычка-ёлочка
CHAR_RCUB: 'etp-rcub', # `} ` -- правая закрывающая фигурная скобка CHAR_EN_QUOT1_CLOSE: 'etp-rdquo', # ` ` -- правая закрывающая кавычка-лапка
CHAR_DOT: 'etp-r-dot', # `. ` -- точка (обычно в конце предложения и висит справа) CHAR_RPAR: 'etp-rpar', # `) ` -- правая закрывающая скобка
CHAR_COMMA: 'etp-r-comma', # `, ` -- запятая (обычно висит справа) CHAR_RSQB: 'etp-rsqb', # `] ` -- правая закрывающая квадратная скобка
CHAR_COLON: 'etp-r-colon', # `: ` -- двоеточие (обычно висит справа) CHAR_RCUB: 'etp-rcub', # `} ` -- правая закрывающая фигурная скобка
CHAR_DOT: 'etp-r-dot', # `. ` -- точка (обычно в конце предложения и висит справа)
CHAR_COMMA: 'etp-r-comma', # `, ` -- запятая (обычно висит справа)
CHAR_COLON: 'etp-r-colon', # `: ` -- двоеточие (обычно висит справа)
},
}
HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT = {
**HANGING_PUNCTUATION_SYMBOLS_CLASSES[HANGING_PUNCTUATION_MODE_LEFT],
**HANGING_PUNCTUATION_SYMBOLS_CLASSES[HANGING_PUNCTUATION_MODE_RIGHT],
} }
# 4. Словарь, сопоставляющий классам висячей пунктуации классы для компенсационных пробелов # 4. Словарь, сопоставляющий классам висячей пунктуации классы для компенсационных пробелов
HANGING_PUNCTUATION_SPACE_CLASSES = { HANGING_PUNCTUATION_SPACE_CLASSES = {
'left': { HANGING_PUNCTUATION_MODE_LEFT: {
# Для левой пунктуации (компенсационный пробел слева от висячей пунктуации) # Для левой пунктуации (компенсационный пробел слева от висячей пунктуации)
CHAR_RU_QUOT1_OPEN: 'etp-sp-laquo', # ` «` -- для пробела пред открывающей кавычкой-ёлочкой CHAR_RU_QUOT1_OPEN: 'etp-sp-laquo', # ` «` -- для пробела пред открывающей кавычкой-ёлочкой
CHAR_EN_QUOT1_OPEN: 'etp-sp-ldquo', # ` “` -- для пробела пред открывающей кавычкой-лапкой CHAR_EN_QUOT1_OPEN: 'etp-sp-ldquo', # ` “` -- для пробела пред открывающей кавычкой-лапкой
@@ -816,7 +826,7 @@ HANGING_PUNCTUATION_SPACE_CLASSES = {
CHAR_LSQB: 'etp-sp-lsqb', # ` [` -- для пробела пред левой открывающей квадратной скобкой CHAR_LSQB: 'etp-sp-lsqb', # ` [` -- для пробела пред левой открывающей квадратной скобкой
CHAR_LCUB: 'etp-sp-lcub', # ` {` -- для пробела пред левой открывающей фигурной скобкой CHAR_LCUB: 'etp-sp-lcub', # ` {` -- для пробела пред левой открывающей фигурной скобкой
}, },
'right': { HANGING_PUNCTUATION_MODE_RIGHT: {
# Для правой пунктуации (компенсационный пробел справа от висячей пунктуации) # Для правой пунктуации (компенсационный пробел справа от висячей пунктуации)
CHAR_RU_QUOT1_CLOSE: 'etp-sp-raquo', # `» ` -- для пробела после закрывающей кавычки-ёлочки CHAR_RU_QUOT1_CLOSE: 'etp-sp-raquo', # `» ` -- для пробела после закрывающей кавычки-ёлочки
CHAR_EN_QUOT1_CLOSE: 'etp-sp-rdquo', # `” ` -- для пробела после закрывающей кавычки-лапки CHAR_EN_QUOT1_CLOSE: 'etp-sp-rdquo', # `” ` -- для пробела после закрывающей кавычки-лапки
@@ -843,6 +853,6 @@ HANGING_PUNCTUATION_SPACE_CLASSES_FLAT = {
} }
HANGING_PUNCTUATION_CLASSES = { HANGING_PUNCTUATION_CLASSES = {
**HANGING_PUNCTUATION_SYMBOLS_CLASSES, **HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT,
**HANGING_PUNCTUATION_SPACE_CLASSES_FLAT, **HANGING_PUNCTUATION_SPACE_CLASSES_FLAT,
} }

View File

@@ -6,7 +6,7 @@ from bs4 import BeautifulSoup, NavigableString, Tag
from .config import ( from .config import (
HANGING_PUNCTUATION_LEFT_CHARS, HANGING_PUNCTUATION_LEFT_CHARS,
HANGING_PUNCTUATION_RIGHT_CHARS, HANGING_PUNCTUATION_RIGHT_CHARS,
HANGING_PUNCTUATION_SYMBOLS_CLASSES, HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT,
HANGING_PUNCTUATION_MODE_LEFT, HANGING_PUNCTUATION_MODE_LEFT,
HANGING_PUNCTUATION_MODE_RIGHT, HANGING_PUNCTUATION_MODE_RIGHT,
) )
@@ -47,7 +47,7 @@ class HangingPunctuationProcessor:
# Предварительно фильтруем карту классов, оставляя только активные символы # Предварительно фильтруем карту классов, оставляя только активные символы
self.char_to_class = { self.char_to_class = {
char: cls char: cls
for char, cls in HANGING_PUNCTUATION_SYMBOLS_CLASSES.items() for char, cls in HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT.items()
if char in self.active_chars if char in self.active_chars
} }

View File

@@ -5,7 +5,7 @@ import logging
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from .config import (SANITIZE_ALL_HTML, SANITIZE_ETPGRF, SANITIZE_NONE, from .config import (SANITIZE_ALL_HTML, SANITIZE_ETPGRF, SANITIZE_NONE,
PROTECTED_HTML_TAGS, PROTECTED_HTML_TAGS,
HANGING_PUNCTUATION_SYMBOLS_CLASSES, HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT,
HANGING_PUNCTUATION_SPACE_CLASSES_FLAT, HANGING_PUNCTUATION_SPACE_CLASSES_FLAT,
CHARS_SYMBOLS_TO_BAN) CHARS_SYMBOLS_TO_BAN)
@@ -31,7 +31,7 @@ class SanitizerProcessor:
# Оптимизация: заранее готовим CSS-селектор для поиска висячей пунктуации # Оптимизация: заранее готовим CSS-селектор для поиска висячей пунктуации
if self.mode == SANITIZE_ETPGRF: if self.mode == SANITIZE_ETPGRF:
# Собираем уникальные классы из отдельных коллекций (чтобы избежать пустого селектора) # Собираем уникальные классы из отдельных коллекций (чтобы избежать пустого селектора)
symbol_classes = set(HANGING_PUNCTUATION_SYMBOLS_CLASSES.values()) symbol_classes = set(HANGING_PUNCTUATION_SYMBOLS_CLASSES_FLAT.values())
space_classes = set(HANGING_PUNCTUATION_SPACE_CLASSES_FLAT.values()) space_classes = set(HANGING_PUNCTUATION_SPACE_CLASSES_FLAT.values())
unique_classes = sorted(symbol_classes | space_classes) unique_classes = sorted(symbol_classes | space_classes)
# Формируем селектор вида: span.class1, span.class2, ... # Формируем селектор вида: span.class1, span.class2, ...