Files
2025-etpgrf/LIBRARY_SPECS.md

107 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Библиотека 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
### Инициализация
```python
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
```python
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)
```python
from etpgrf import Typographer
# Создаем экземпляр один раз (он stateless, кроме конфигурации)
typo = Typographer(langs='ru', process_html=True, hanging_punctuation='both')
def process_request(text):
return typo.process(text)
```