107 lines
8.1 KiB
Markdown
107 lines
8.1 KiB
Markdown
# Библиотека 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`).
|
||
* Вставляет `­` (мягкий перенос).
|
||
* Настройки: `MAX_UNHYPHENATED_LEN` (не переносить длинные слова), `MIN_TAIL_LEN` (минимальный остаток).
|
||
|
||
### 4.4. Компоновка (`layout.py`)
|
||
* Тире: ` - ` -> ` — ` (рус), `—` (анг).
|
||
* Инициалы: `А. С. Пушкин` -> `А. С. Пушкин`.
|
||
* Единицы измерения: `10 км` -> `10 км`.
|
||
* Сокращения: `и т.д.` -> `и т. д.`.
|
||
|
||
## 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)
|
||
```
|