add: обработка кавычек

This commit is contained in:
2025-08-17 01:12:09 +03:00
parent 73fa57e47e
commit b4248db063
5 changed files with 251 additions and 6 deletions

74
etpgrf/quotes.py Normal file
View File

@@ -0,0 +1,74 @@
# etpgrf/quotes.py
# Модуль для расстановки кавычек в тексте
import regex
import logging
from .config import LANG_RU, LANG_EN, RU_QUOT1_OPEN, RU_QUOT1_CLOSE, EN_QUOT1_OPEN, EN_QUOT1_CLOSE, \
RU_QUOT2_OPEN, RU_QUOT2_CLOSE, EN_QUOT2_OPEN, EN_QUOT2_CLOSE
from .comutil import parse_and_validate_langs
# --- Настройки логирования ---
logger = logging.getLogger(__name__)
# Определяем стили кавычек для разных языков
# Формат: (('открывающая_ур1', 'закрывающая_ур1'), ('открывающая_ур2', 'закрывающая_ур2'))
_QUOTE_STYLES = {
LANG_RU: ((RU_QUOT1_OPEN, RU_QUOT1_CLOSE), (RU_QUOT2_OPEN, RU_QUOT2_CLOSE)),
LANG_EN: ((EN_QUOT1_OPEN, EN_QUOT1_CLOSE), (EN_QUOT2_OPEN, EN_QUOT2_CLOSE)),
}
class QuotesProcessor:
"""
Обрабатывает прямые кавычки ("), превращая их в типографские
в зависимости от языка и контекста.
"""
def __init__(self, langs: str | list[str] | tuple[str, ...] | frozenset[str] | None = None):
self.langs = parse_and_validate_langs(langs)
# Выбираем стиль кавычек на основе первого поддерживаемого языка
self.open_quote = '"'
self.close_quote = '"'
for lang in self.langs:
if lang in _QUOTE_STYLES:
self.open_quote = _QUOTE_STYLES[lang][0][0]
self.close_quote = _QUOTE_STYLES[lang][0][1]
logger.debug(
f"QuotesProcessor: выбран стиль кавычек для языка '{lang}': '{self.open_quote}...{self.close_quote}'")
break # Используем стиль первого найденного языка
# Паттерн для открывающей кавычки: " перед буквой/цифрой,
# которой предшествует пробел, начало строки или открывающая скобка.
# (?<=^|\s|[\(\[„\"\']) - "просмотр назад" на начало строки... ищет пробел \s или знак из набора ([„"'
# (?=\p{L}) - "просмотр вперед" на букву \p{L} (но не цифру).
self._opening_quote_pattern = regex.compile(r'(?<=^|\s|[\(\[„\"\'])\"(?=\p{L})')
# self._opening_quote_pattern = regex.compile(r'(?<=^|\s|\p{Pi}|["\'\(\)])\"(?=\p{L})')
# Паттерн для закрывающей кавычки: " после буквы/цифры,
# за которой следует пробел, пунктуация или конец строки.
# (?<=\p{L}|[?!…]) - "просмотр назад" на букву или ?!…
# (?=\s|[.,;:!?\)\"»”’]|\Z) - "просмотр вперед" на пробел, пунктуацию или конец строки (\Z).
self._closing_quote_pattern = regex.compile(r'(?<=\p{L}|[?!…])\"(?=\s|[\.,;:!?\)\]»”’\"\']|\Z)')
# self._closing_quote_pattern = regex.compile(r'(?<=\p{L}|\p{N})\"(?=\s|[\.,;:!?\)\"»”’]|\Z)')
# self._closing_quote_pattern = regex.compile(r'(?<=\p{L}|[?!…])\"(?=\s|[\p{Po}\p{Pf}"\']|\Z)')
def process(self, text: str) -> str:
"""
Применяет правила замены кавычек к тексту.
"""
if '"' not in text:
# Быстрый выход, если в тексте нет прямых кавычек
return text
processed_text = text
# 1. Заменяем открывающие кавычки
# Заменяем только найденную кавычку, так как просмотр вперед не захватывает символы.
processed_text = self._opening_quote_pattern.sub(self.open_quote, processed_text)
# 2. Заменяем закрывающие кавычки
processed_text = self._closing_quote_pattern.sub(self.close_quote, processed_text)
return processed_text