296 lines
27 KiB
Markdown
296 lines
27 KiB
Markdown
| in progress // в процессе разработки |
|
||
|--------------------------------------|
|
||
| --------> |
|
||
|
||
# Типограф для Web
|
||
|
||
Экранная типографика для веба — способствует повышению читабельности текста в интернете,
|
||
приближая его к печатной типографике.
|
||
|
||
### Кодировки и html-мнемоники
|
||
|
||
Внутри типографа используется кодировка UTF-8. Но при использовании может быть другие кодировки (например,
|
||
для русскоязычных текстов все ещё могут использовать Windows-1251). При таких кодировках, для отображения в браузерах
|
||
некоторых специфических символов (например, кавычек, тире, стрелочек, математических символов) используют
|
||
html-мнемоники (например, `—` для длинного тире, `«` для открывающей кавычки-ёлочки и т.д.).
|
||
|
||
tpgrf имеет три режима работы с кодировками:
|
||
- Режим `unicode` — весь вывод осуществляется в кодировке UTF-8. ВЕСЬ! Включая невидимые символы, типа неразрывных и нулевых
|
||
пробелов, мягких переносов и т.д. Это не всегда удобно зато типографированый текст (строки) будет максимально
|
||
компактен и занимать меньше места в памяти. В этом режиме в html-мнемоники преобразуются только опасные символы:
|
||
* `<` — знак меньше `<`;
|
||
* `>` — знак больше `>`;
|
||
* `&` — амперсанд `&`;
|
||
* `"` — двойные кавычки `"`;
|
||
* `'` — одинарные кавычки (апостроф) `'`.
|
||
- Режим `mixed` — вывод осуществляется в кодировке UTF-8, но наиболее критичные символы заменяются на html-мнемоники.
|
||
Они невидимы или неотличимы друг от друга на экране:
|
||
* `­` — мягкий перенос (Soft Hyphen);
|
||
* ` ` — неразрывный пробел (Non-Breaking Space);
|
||
* ` ` — полужирный пробел (En Space)
|
||
* ` ` — широкий пробел (Em Space)
|
||
* ` ` — цифровой пробел;
|
||
* ` ` — пунктуационный пробел;
|
||
* ` ` — межсимвольный пробел;
|
||
* ` ` — пробел "толщина волоса" (Hair Space);
|
||
* `​` — негативный пробел (Negative Space);
|
||
* `‍` — пробел нулевой ширины (без объединения) (Zero Width Non-Joiner);
|
||
* `‌` — нулевая ширина (с объединением) (Zero Width Joiner);
|
||
* `‎` — изменение направления текста на слева-направо (Left-to-Right Mark);
|
||
* `‏` — изменение направления текста на направо-налево (Right-to-Left Mark);
|
||
* `‐` — дефис (Hyphen);
|
||
* ` ` — средний пробел (Medium Mathematical Space);
|
||
* `⁠` — неразрывный пробел (No-Break Space);
|
||
* `⁢` — невидимый знак умножения (Invisible Times) для семантической разметки математических
|
||
выражений;
|
||
* `⁣` — невидимая запятая (Invisible Comma) для семантической разметки математических выражений.
|
||
- Режим `mnemonic` — применяются все возможные html-мнемоники (кроме русских букв) и символов первой половины ASCII
|
||
(плюс, минус, знак равенства, знаки препинания и т.д.).
|
||
|
||
Переключение режимов осуществляется с помощью параметра `mode` при конфигурировании типографа:
|
||
```python
|
||
# Задаем конфигурацию типографа
|
||
typo_mixed_mode = etpgrf.Typographer(mode='mixed')
|
||
# Обработка текста
|
||
result = typo_mixed_mode.process(text="Этот текст будет обработан в режиме mixed.")
|
||
```
|
||
|
||
### ВАЖНО:
|
||
|
||
1. Если в тексте уже есть html-мнемоники, они будут преобразованы в unicode, и после обработки типографом
|
||
будут заменены на html-мнемоники, соответствующие текущему режиму работы типографа.
|
||
2. Некоторым символам соответствуют несколько html-мнемоник. Например, `→` (стрелочка влево) может кодироваться
|
||
как `→`, `→`, `&rightarrow`, `→` и `→`. Типограф будет использовать самое
|
||
короткое из них (для компактности), а значит:
|
||
* если в исходном тексте были html-мнемоники, то они будут заменены на более короткие;
|
||
* если html-мнемоники использовались как элементы семантической разметки (например, для математических выражений),
|
||
то после замены на более короткие html-мнемоники, текст может потерять такую семантику. Например _F = A ⋂ B_:
|
||
`F = A ⋂ B` будет преобразовано в `F = A ⋂ B`;
|
||
3. Мнемоники для русских букв не используются в типографе. Все мнемоники русских букв будут преобразованы в русские
|
||
буквы и останутся в тексте в виде русских букв.
|
||
4. Все исходные html-мнемоники, которые превращаются в два unicode-символа будут превращены обратно в мнемоники каждый
|
||
как отдельный символ. Например, множество собственное другого подмножества `⊊︀` в unicode отображается
|
||
двумя символами `\u228a\ufe00` и превратится в `⊊\ufe00`. Символ `\ufe00` — это невидимый символ, cелектор
|
||
варианта начертания (Variant Selector), который изменяет начертание предыдущего символа и для него нет
|
||
html-мнемоники. К счастью, в стандарте таких мнемоник (превращающихся в два символа) исчезающе мало и они крайне
|
||
редко применяются в тексте, поэтому это не должно вызывать проблем.
|
||
|
||
|
||
### Переносы слов
|
||
|
||
Обычно в основе переносов слов лежит фонетический принцип — деление по слогам и морфемный принцип — деление по морфемам
|
||
(приставки, корни, суффиксы, окончания). В типографе etpgrf реализован эвристический подход к переносу слов,
|
||
основанный на фонетических правилах. Он не является строгим и не учитывает все нюансы языка, но обеспечивает вполне
|
||
приемлемое качество для большинства случаев. Особенно если "неразрывные" блоки задать достаточно длинными (и именно
|
||
это и требуется от хорошего типографа, ведь перенос трех-четырех букв слова на новую строку почти не улучшит
|
||
читабельность и внешний вид текста).
|
||
|
||
Настройки по умолчанию для переноса слов (в `etpgrf.defaults`):
|
||
* Длина слова которое не подлежит переносам (`MAX_UNHYPHENATED_LEN`) — 12 символов.
|
||
* Длина части слова, которое недопустимо переносить или оставлять на строке ("хвост", "сироты")
|
||
(`MIN_TAIL_LEN`) — 5 символов
|
||
|
||
Управление этими параметрами осуществляется через переопределение. Например:
|
||
```python
|
||
# Меняем настройки по умолчанию для переносов
|
||
etpgrf.defaults.etpgrf_settings.hyphenation.MAX_UNHYPHENATED_LEN = 8
|
||
etpgrf.defaults.etpgrf_settings.hyphenation.MIN_TAIL_LEN = 4
|
||
```
|
||
Или через параметры конфигурации переносов типографа:
|
||
```python
|
||
# Определяем пользовательские правила переносов
|
||
hyphen_settings = etpgrf.Hyphenator(langs='ru', max_unhyphenated_len=8)
|
||
# Передаем их в типограф
|
||
typo_hyp = etpgrf.Typographer(langs='ru', mode='mnemonic', hyphenation=hyphen_settings)
|
||
# Обработка текста с переносами
|
||
result = typo_hyp.process(text="Электрофоретическое исследование характеризуется квинтэссенциальной значимостью!")
|
||
```
|
||
|
||
Результат обработки текста с переносами будет выглядеть так:
|
||
```html
|
||
Электрофо­ретическое исследование характе­ризуется квинтэс­сенциальной значимостью!
|
||
```
|
||
|
||
### Предлоги, союзы и частицы
|
||
|
||
Правилом хорошего тона в любой типографике считается, когда короткие слова, такие как предлоги, союзы и частицы,
|
||
не остаются в конце строки в одиночестве («висеть»). Это ухудшает читаемость.
|
||
|
||
Типограф `etpgrf` автоматически решает эту проблему, «приклеивая» такие слова к последующему слову с помощью
|
||
неразрывного пробела (` `).
|
||
|
||
* `в доме` → `в доме`
|
||
* `и сказал` → `и сказал`
|
||
|
||
Это правило работает для коротких слов в русском, старорусском и английском языках.
|
||
|
||
Кроме того, обрабатываются и постпозитивные частицы (например, `ли`, `же`, `бы`), которые, наоборот, для улучшения
|
||
читабельности, «приклеиваются» к предыдущему слову:
|
||
|
||
* `сказал бы` → `сказал бы`
|
||
|
||
|
||
### Кавычки
|
||
|
||
В текстах кавычки бывают двух видов: «ёлочки» (для русского языка) и “лапки” (для английского языка). В типографе
|
||
реализована автоматическая замена кавычек на соответствующие типографские символы в зависимости от языка текста.
|
||
|
||
Большинство типографов при обработке кавычек находят парные (и определяют вложенность). В etpgrf же реализован
|
||
другой подход. Он ищет и обрабатывает кавычки, которые находятся рядом со словами. То есть какие-то буквы следуют
|
||
слева или справа от кавычки.
|
||
|
||
Преобразование рядом с цифрами (например, когда обозначаются дюймы (`17"`) или секунды (`3' 25"`)) не производится. Также
|
||
не обрабатываются кавычки окруженные пробелами. Все кавычки которые в исходном тексте уже были оформлены в виде
|
||
«ёлочек» или “лапок” — тоже не обрабатываются.
|
||
|
||
ВАЖНО1: По правилам орфографии перед закрывающей кавычкой разрешены только определенные знаки препинания:
|
||
вопросительный (?), восклицательный (!) знаки и многоточие (…). Такие конструкции используются для цитат. Это учтено
|
||
в etpgrf, и кавычки будут обработаны: `Она воскликнула: "Какая красота!"` будет преобразовано в `Она воскликнула:
|
||
«Какая красота!»`. По правилам пунктуации, точка `.` перед закрывающей кавычкой не допускается, но существуют
|
||
исключения, когда перед кавычкой стоит сокращение (например, `т. д.`, `и т. п.`). В таких случаях точка сохраняется:
|
||
`Он сказал: "Это важно, и т. д."` → `Он сказал: «Это важно, и т. д.»`. **Типограф допускает точку перед закрывающей
|
||
кавычкой.**
|
||
|
||
ВАЖНО2: Если в настройке типографа указано несколько языков (`langs='ru+en'`), то кавычки будут преобразованы по правилам
|
||
для языка который идет первым в списке. Например, для `langs='ru+en'` кавычки будут преобразованы в «ёлочки»,
|
||
|
||
Если при типорафировании преобразование не требуется, то можно обработку кавычек можно отключить с помощью
|
||
параметра `quotes=False`:
|
||
```python
|
||
# Задаем конфигурацию типографа без кавычек
|
||
typo_no_quotes = etpgrf.Typographer(langs='ru', quotes=False)
|
||
# Обработка текста без кавычек
|
||
result = typo_no_quotes.process(text='Этот "текст" будет обработан без кавычек.')
|
||
```
|
||
|
||
|
||
### Компоновка (тире, диапазоны, инициалы, единицы измерения, сокращения и т.п.)
|
||
|
||
После того как псевдографика заменена на правильные символы, в дело вступает модуль компоновки (layout), который
|
||
отвечает за расстановку неразрывных и тонких пробелов. Он применяет несколько важных правил для улучшения читаемости.
|
||
|
||
#### Тире
|
||
|
||
По правилам русской типографики, длинное тире (—) должно отбиваться пробелами от соседних слов. Чтобы тире не "повисло"
|
||
в начале строки и визуально не смешивалось с диалогами, etpgrf заменяет пробел перед тире на неразрывный ( ).
|
||
|
||
* `слово — слово` → `слово — слово`
|
||
|
||
В английской типографике, наоборот, тире пишется слитно. Типограф учитывает это при указании языка `langs='en'`.
|
||
|
||
* `word — word` → `word—word`
|
||
|
||
Если минус или диапазон стоят между числами (арабскими или римскими), то это считается обозначением числового диапазона
|
||
(или отрицательным числом, или математическим выражением), и никаких изменений не производится. Неважно есть пробелы
|
||
вокруг тире/минуса или нет. Если между цифрами тире, то это тоже считается диапазоном и неразрывные пробелы не ставятся:
|
||
`1941 — 1945` → `1941 — 1945`, `-10 — -5` → `-10 — -5`,
|
||
|
||
Если минус стоит перед числом (например, `-5`), то это считается отрицательным числом, и перед ним ставится неразрывный
|
||
пробел: `от -5 до +5` → `от -5 до +5`.
|
||
|
||
#### Инициалы и акронимы
|
||
|
||
Чтобы инициалы не отрывались друг от друга и от фамилии при переносе строки, типограф расставляет между ними
|
||
специальные пробелы:
|
||
|
||
* Неразрывный пробел (` `) ставится между фамилией и инициалом/инициалами (`А. Пушкин` → `А. Пушкин`).
|
||
Неважно стоят ли инициалы перед фамилией или после неё. Важно наличие точки и буквы (инициала), написанного
|
||
с заглавной буквы.
|
||
* Тонкая шпация ( ) ставится между самими инициалами, если они написаны слитно, для улучшения внешнего вида
|
||
(`Пушкин А. С. ` → `Пушкин А. С.`). Число инициалов не ограничено (`J.R.R. Tolkien` →
|
||
`J. R. R. Tolkien`), наличие или отсутствие пробелов между инициалами в исходном тексте неважно.
|
||
* Акронимы, написанные через точку (не слитно, например, **Н.Л.О.**), разделяются так же, как инициалы, через тонкую шпацию
|
||
(`Н.Л.О.` → `Н. Л. О.`). Наличие или отсутствие пробелов между буквами в исходном тексте неважно.
|
||
|
||
Это правило может давать побочные эффекты (в частности, тонкая шпация не является неразрывным пробелом, и в длинных
|
||
акронимах может привести к разрыву строки). Поэтому его обработку можно отключить с помощью параметра
|
||
`process_initials_and_acronyms`:
|
||
```python
|
||
typo = etpgrf.Typographer(process_initials_and_acronyms=False)
|
||
result = typo.process("А. С. Пушкин") # Останется без изменений
|
||
```
|
||
|
||
#### Единицы измерения
|
||
|
||
Типограф предотвращает отрыв единиц измерения от чисел, ставя между ним и предшествующей цифрой неразрывный пробел.
|
||
Это работает для:
|
||
|
||
* **Простых единиц:** `100 км.` → `100 км.`, `-5 °C` → `-5 °C`'
|
||
* **Составных единиц:** `120 кв.м.` → `120 кв. м.`, `50 тыс. руб.` → `50 тыс. руб.` Пробелы
|
||
(есть они или нет) между составными частями единицы изменения не важны. Между частями составной единицы измерения
|
||
ставится тонкая шпация (` `).
|
||
* **Единиц с предлогом:** `№ 5` → `№ 5`, `§ 7` → `§ 7`, `$ 100` → `$ 100`
|
||
* **Чисел, записанных и арабскими, и римскими цифрами:** `V в.н.э.` → `V в. н. э.`
|
||
* Если между единицами изменений есть математические символы (например, умножение или деление):
|
||
`10 км / ч` → `10 км/ч` (неважно есть пробелы вокруг `/` или нет). Распознаются и другие символы:
|
||
`·`, `*`, `×`, `÷`.
|
||
|
||
Библиотека "знает" множество стандартных единиц для русского и английского языков. Но не все. Вы можете расширить этот
|
||
список, передав свои кастомные единицы через параметр `process_units`:
|
||
|
||
```python
|
||
# Передаем список
|
||
typo = etpgrf.Typographer(process_units=['бочек', 'вёдер'])
|
||
# Можно передавать и с помощзью строки через пробелы
|
||
typo = etpgrf.Typographer(process_units='бочек вёдер аршин сажен')
|
||
result = typo.process("Нужно 10 бочек.") # -> "Нужно 10 бочек."
|
||
```
|
||
|
||
Если нужно отключить распознавание и обработку единиц измерения:
|
||
|
||
```python
|
||
typo = etpgrf.Typographer(process_units=False)
|
||
result = typo.process("100 км/ч") # Останется без изменений
|
||
```
|
||
|
||
#### Сокращения
|
||
|
||
Типограф также обрабатывает распространённые русскоязычные сокращения, чтобы они корректно отображались и не разрывались
|
||
при переносе строк. Правила делятся на два типа:
|
||
* Финальные сокращения. Сокращения, которые обычно стоят в конце фразы (например, и т. д., и т. п.),
|
||
обрабатываются особым образом: их части «склеиваются» тонкой шпацией, а перед всей конструкцией ставится неразрывный
|
||
пробел, чтобы она не «повисла» на новой строке. `...и так далее, и т. д.` → `...и так далее, и т. д.`
|
||
Это правило работает независимо от того, как сокращение было написано в исходном тексте (т.д. или т. д.).
|
||
* Препозиционные сокращения. Сокращения, которые стоят перед другим словом (например, и. о. директора, т. е. сказать),
|
||
также «склеиваются» внутри, но неразрывный пробел ставится после них, чтобы привязать их к последующему слову.
|
||
`Назначить и. о. директора` → `Назначить и. о. директора`
|
||
|
||
Библиотека знает небольшой набор самых распространённых сокращений. Но не все, а некоторые принципиально невозможны
|
||
к обработке. Например, сокращение `пр.` может оказаться как финальным (в значении «и так далее»), так и препозиционным
|
||
(в значении «профессор» или «проспект»). Так же типограф не обрабатывает сокращения, связанные с адресами (ул., д.,
|
||
кв., пл., наб. ...) так как они могут быть как финальными, так и препозиционными.
|
||
|
||
### Висячая типографика
|
||
|
||
Висячая типографика — это приём из классической вёрстки, когда некоторые знаки препинания (кавычки, скобки, иногда
|
||
тире и маркеры списков) выносятся на левое (и иногда и по правому, при выравнивании текст по правому краю) поле текста.
|
||
Это создаёт идеально ровный край не по формальным границам знаков, а по оптическому краю — по первым буквам строк.
|
||
Текст выглядит гораздо аккуратнее и профессиональнее.
|
||
|
||
В вебе это достигается с помощью CSS, оборачивая "висячий" символ или слово в <span> и применяя к нему, например,
|
||
отрицательный text-indent или margin-left (`<span style="margin-left:-0.44em;">«</span>`)
|
||
|
||
|
||
## P.S.
|
||
|
||
Если вам нравится этот, можете поддержать отправив любую сумму на мой Т-банк
|
||
[по ссылке](https://tbank.ru/cf/27hMw1BTFMs) или QR-коду.
|
||
|
||

|
||
|
||
Средства пойдут на улучшение моего настроения путем покупки виниловых пластинок. В списке желаний:
|
||
|
||
| Bar-Code | Artist | Album | Format | | | Label | Цена | |
|
||
|---------------|--------------------------|-----------------------------------------|--------|-------------------------|------------|---------------|---------|--------|
|
||
| 0711297924305 | SUZANNE VEGA | Flying With Angels | LP | Grey Smoke | 02.05.2025 | Cooking Vinyl | ₽ 4099 | куплен |
|
||
| 0602475914716 | CRANBERRIES | No Need To Argue | 2LP | 30th Ann, Deluxe | 15.08.2025 | Island | ₽ 5499 | куплен |
|
||
| ATL 40 022 | IRON BUTTERFLY | In-A-Gadda-Da-Vida | LP | NM/NM, Germany (винтаж) | 1973 | Atlantic | ₽ 2499 | куплен |
|
||
| 5400863145637 | EELS | So Good | LP | coloured | 15.12.2023 | | ₽ 4360 |
|
||
| 5400863157845 | EELS | Time! | LP | coloured | 07.06.2024 | | ₽ 4940 |
|
||
| 8719262034853 | NICK CAVE & WARREN ELLIS | Mars (Original Sound Track) | LP | coloured | 12.07.2024 | | ₽ 3440 |
|
||
| 5021732526007 | GORILLAZ | Demon Days Live From The Apollo Theater | 2LP | RSD2025, Red | 12.04.2025 | Warner | ₽ 5999 |
|
||
| 5021732526007 | GORILLAZ | TOMORROW COMES TODAY | EP 12" | color (white & blue) | 20.06.2025 | | ₽ 3600 |
|
||
|
||
|
||
|