Files
2025-etpgrf/LIBRARY_SPECS.md

8.1 KiB
Raw Permalink Blame History

Библиотека etpgrf: Контекст и Спецификация

Этот документ описывает архитектуру и API библиотеки etpgrf (Electro-Typographer), предназначенной для типографирования текста в вебе. Используйте этот контекст при разработке зависимых проектов (например, веб-сайтов).

1. Назначение

Библиотека выполняет комплексную обработку текста для улучшения его читаемости и внешнего вида в браузере:

  • Замена кавычек («ёлочки», „лапки“).
  • Расстановка неразрывных пробелов (предлоги, союзы, инициалы, единицы измерения).
  • Замена дефисов на тире (—, ).
  • Преобразование псевдографики (... -> , (c) -> ©).
  • Расстановка мягких переносов (­).
  • Висячая пунктуация (оборачивание символов в <span>).
  • Санитизация (очистка HTML от старой типографики).

2. Архитектура

  • Язык: Python 3.10+.
  • Зависимости: beautifulsoup4, lxml, regex.
  • Главный класс: etpgrf.Typographer.
  • Принцип работы (Pipeline):
    1. Анализ структуры: Типограф проверяет, является ли входной текст полным HTML-документом (есть <html>, <body>) или фрагментом. Это важно для корректной сборки на выходе.
    2. Парсинг и Санитизация: Текст парсится через BeautifulSoup (предпочтительно lxml). Если включен санитайзер, происходит очистка от старой разметки (удаление висячей пунктуации или всех тегов).
    3. Подготовка (Токенизация): Извлекаются все текстовые узлы (NavigableString), которые склеиваются в одну "супер-строку". Это позволяет правилам видеть контекст через границы тегов (например, кавычка в <b> и слово после него).
    4. Контекстная обработка: К "супер-строке" применяются правила, требующие глобального контекста:
      • QuotesProcessor: расстановка кавычек.
      • Unbreakables: привязка предлогов и союзов.
    5. Восстановление структуры: Обработанная "супер-строка" аккуратно нарезается обратно и раскладывается по исходным текстовым узлам DOM-дерева.
    6. Локальная обработка: Запускается рекурсивный обход дерева. К каждому текстовому узлу применяются локальные правила:
      • SymbolsProcessor: псевдографика.
      • LayoutProcessor: тире, спецсимволы.
      • Hyphenator: расстановка переносов.
    7. Висячая пунктуация: Модифицируется само DOM-дерево. Символы пунктуации оборачиваются в теги <span> с классами для CSS-коррекции.
    8. Финальная сборка: Дерево сериализуется в строку. Если на входе был фрагмент, возвращается только содержимое <body>, чтобы не плодить лишние теги.

3. API: Класс Typographer

Инициализация

from etpgrf import Typographer

typo = Typographer(
    langs='ru',                 # Языки: 'ru', 'en', 'ru+en'
    mode='mixed',               # Режим вывода: 'unicode', 'mnemonic', 'mixed'
    process_html=True,          # Обрабатывать HTML-теги (иначе экранирует их)
    
    # Модули (можно отключить, передав False)
    hyphenation=True,           # Переносы слов
    quotes=True,                # Кавычки
    unbreakables=True,          # Неразрывные пробелы (предлоги, союзы)
    layout=True,                # Тире, спецсимволы, инициалы, единицы измерения
    symbols=True,               # Псевдографика (стрелочки, копирайт)
    
    # Специфические настройки
    sanitizer='etp',            # Очистка перед обработкой: 'etp' (удалить висячую), 'html' (удалить все теги)
    hanging_punctuation='both'  # Висячая пунктуация: 'left', 'right', 'both', None
)

Метод process

html = '<p>Привет, мир!</p>'
result = typo.process(html)
# Результат: '<p>Привет, мир!</p>' (с неразрывными пробелами и т.д.)

4. Особенности модулей

4.1. Висячая пунктуация (hanging.py)

  • Оборачивает символы («, , (, ., , и др.) в теги <span class="etp-...">.
  • Логика:
    • Левые символы («): оборачиваются, если в начале узла ИЛИ перед ними пробел/другой левый символ.
    • Правые символы (», .): оборачиваются, если в конце узла ИЛИ после них пробел/другой правый символ.
  • Классы CSS: etp-laquo, etp-r-dot, etp-r-comma и т.д. (см. config.py).
  • Важно: Не добавляет компенсирующие пробелы. Визуализация — задача CSS.

4.2. Санитайзер (sanitizer.py)

  • Запускается до основного типографирования.
  • mode='etp': Удаляет теги <span> с классами висячей пунктуации (unwrap), сохраняя текст.
  • mode='html': Удаляет ВСЕ теги, возвращает чистый текст.

4.3. Переносы (hyphenation.py)

  • Использует алгоритм Ляна-Кнута (портирован из hyphen).
  • Вставляет &shy; (мягкий перенос).
  • Настройки: MAX_UNHYPHENATED_LEN (не переносить длинные слова), MIN_TAIL_LEN (минимальный остаток).

4.4. Компоновка (layout.py)

  • Тире: - -> &nbsp;— (рус), (анг).
  • Инициалы: А. С. Пушкин -> А.&nbsp;С.&thinsp;Пушкин.
  • Единицы измерения: 10 км -> 10&nbsp;км.
  • Сокращения: и т.д. -> и&nbsp;т.&thinsp;д..

5. Конфигурация (config.py)

Все константы (списки слов, коды символов, CSS-классы) находятся здесь.

  • HANGING_PUNCTUATION_CLASSES: словарь {символ: класс}.
  • PROTECTED_HTML_TAGS: теги, внутри которых типографика не применяется (script, code, pre...).

6. Пример использования (FastAPI/Flask/Django)

from etpgrf import Typographer

# Создаем экземпляр один раз (он stateless, кроме конфигурации)
typo = Typographer(langs='ru', process_html=True, hanging_punctuation='both')

def process_request(text):
    return typo.process(text)