Files
2026-etpgrf-site/ETPGRF_SPECS.md

101 lines
6.2 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: Контекст и Спецификация для LLM
Этот документ описывает архитектуру и API библиотеки `etpgrf` (Electro-Typographer), предназначенной для типографирования текста в вебе. Используйте этот контекст при разработке зависимых проектов (например, веб-сайтов).
## 1. Назначение
Библиотека выполняет комплексную обработку текста для улучшения его читаемости и внешнего вида в браузере:
* Замена кавычек («ёлочки», „лапки“).
* Расстановка неразрывных пробелов (предлоги, союзы, инициалы, единицы измерения).
* Замена дефисов на тире (—, ).
* Преобразование псевдографики (`...` -> `…`, `(c)` -> `©`).
* Расстановка мягких переносов (`­`).
* **Висячая пунктуация** (оборачивание символов в `<span>`).
* **Санитизация** (очистка HTML от старой типографики).
## 2. Архитектура
* **Язык:** Python 3.10+.
* **Зависимости:** `beautifulsoup4`, `lxml`, `regex`.
* **Главный класс:** `etpgrf.Typographer`.
* **Принцип работы:**
1. Принимает текст или HTML.
2. Если HTML: парсит через `BeautifulSoup` (lxml), очищает от старой разметки (Sanitizer).
3. Извлекает текстовые узлы, склеивает их в "супер-строку" для контекстных правил (кавычки).
4. Применяет правила к тексту.
5. Восстанавливает структуру HTML.
6. Применяет висячую пунктуацию (модификация дерева DOM).
7. Возвращает строку.
## 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)
```