in progress // в процессе разработки
-------->

Типограф для Web

Экранная типографика для веба — способствует повышению читабельности текста в интернете, приближая его к печатной типографике.

Кодировки и html-мнемоники

Внутри типографа используется кодировка UTF-8. Но при использовании может быть другие кодировки (например, для русскоязычных текстов все ещё могут использовать Windows-1251). При таких кодировках, для отображения в браузерах некоторых специфических символов (например, кавычек, тире, стрелочек, математических символов) используют html-мнемоники (например, — для длинного тире, « для открывающей кавычки-ёлочки и т.д.).

tpgrf имеет три режима работы с кодировками:

  • Режим unicode — весь вывод осуществляется в кодировке UTF-8. ВЕСЬ! Включая невидимые символы, типа неразрывных и нулевых пробелов, мягких переносов и т.д. Это не всегда удобно зато типографированый текст (строки) будет максимально компактен и занимать меньше места в памяти. В этом режиме в html-мнемоники преобразуются только опасные символы:
    • &lt; — знак меньше <;
    • &gt; — знак больше >;
    • &amp; — амперсанд &;
    • &quot; — двойные кавычки ";
    • &apos; — одинарные кавычки (апостроф) '.
  • Режим mixed — вывод осуществляется в кодировке UTF-8, но наиболее критичные символы заменяются на html-мнемоники. Они невидимы или неотличимы друг от друга на экране:
    • &shy; — мягкий перенос (Soft Hyphen);
    • &nbsp; — неразрывный пробел (Non-Breaking Space);
    • &ensp; — полужирный пробел (En Space)
    • &emsp; — широкий пробел (Em Space)
    • &numsp; — цифровой пробел;
    • &puncsp; — пунктуационный пробел;
    • &thinsp; — межсимвольный пробел;
    • &hairsp; — пробел "толщина волоса" (Hair Space);
    • &NegativeThinSpace; — негативный пробел (Negative Space);
    • &zwj; — пробел нулевой ширины (без объединения) (Zero Width Non-Joiner);
    • &zwnj; — нулевая ширина (с объединением) (Zero Width Joiner);
    • &lrm; — изменение направления текста на слева-направо (Left-to-Right Mark);
    • &rlm; — изменение направления текста на направо-налево (Right-to-Left Mark);
    • &dash; — дефис (Hyphen);
    • &MediumSpace; — средний пробел (Medium Mathematical Space);
    • &NoBreak; — неразрывный пробел (No-Break Space);
    • &InvisibleTimes; — невидимый знак умножения (Invisible Times) для семантической разметки математических выражений;
    • &InvisibleComma; — невидимая запятая (Invisible Comma) для семантической разметки математических выражений.
  • Режим mnemonic — применяются все возможные html-мнемоники (кроме русских букв) и символов первой половины ASCII (плюс, минус, знак равенства, знаки препинания и т.д.).

Переключение режимов осуществляется с помощью параметра mode при конфигурировании типографа:

# Задаем конфигурацию типографа
typo_mixed_mode = etpgrf.Typographer(mode='mixed')
# Обработка текста 
result = typo_mixed_mode.process(text="Этот текст будет обработан в режиме mixed.")

ВАЖНО:

  1. Если в тексте уже есть html-мнемоники, они будут преобразованы в unicode, и после обработки типографом будут заменены на html-мнемоники, соответствующие текущему режиму работы типографа.
  2. Некоторым символам соответствуют несколько html-мнемоник. Например, (стрелочка влево) может кодироваться как &rarr;, &srarr;, &rightarrow, &RightArrow; и &ShortRightArrow;. Типограф будет использовать самое короткое из них (для компактности), а значит:
    • если в исходном тексте были html-мнемоники, то они будут заменены на более короткие;
    • если html-мнемоники использовались как элементы семантической разметки (например, для математических выражений), то после замены на более короткие html-мнемоники, текст может потерять такую семантику. Например F = A ⋂ B: F = A &Intersection; B будет преобразовано в F = A &xcap; B;
  3. Мнемоники для русских букв не используются в типографе. Все мнемоники русских букв будут преобразованы в русские буквы и останутся в тексте в виде русских букв.
  4. Все исходные html-мнемоники, которые превращаются в два unicode-символа будут превращены обратно в мнемоники каждый как отдельный символ. Например, множество собственное другого подмножества &varsubsetneq; в unicode отображается двумя символами \u228a\ufe00 и превратится в &subne;\ufe00. Символ \ufe00 — это невидимый символ, cелектор варианта начертания (Variant Selector), который изменяет начертание предыдущего символа и для него нет html-мнемоники. К счастью, в стандарте таких мнемоник (превращающихся в два символа) исчезающе мало и они крайне редко применяются в тексте, поэтому это не должно вызывать проблем.

Переносы слов

Обычно в основе переносов слов лежит фонетический принцип — деление по слогам и морфемный принцип — деление по морфемам (приставки, корни, суффиксы, окончания). В типографе etpgrf реализован эвристический подход к переносу слов, основанный на фонетических правилах. Он не является строгим и не учитывает все нюансы языка, но обеспечивает вполне приемлемое качество для большинства случаев. Особенно если "неразрывные" блоки задать достаточно длинными (и именно это и требуется от хорошего типографа, ведь перенос трех-четырех букв слова на новую строку почти не улучшит читабельность и внешний вид текста).

Настройки по умолчанию для переноса слов (в etpgrf.defaults):

  • Длина слова которое не подлежит переносам (MAX_UNHYPHENATED_LEN) — 12 символов.
  • Длина части слова, которое недопустимо переносить или оставлять на строке ("хвост", "сироты") (MIN_TAIL_LEN) — 5 символов

Управление этими параметрами осуществляется через переопределение. Например:

# Меняем настройки по умолчанию для переносов
etpgrf.defaults.etpgrf_settings.hyphenation.MAX_UNHYPHENATED_LEN = 8
etpgrf.defaults.etpgrf_settings.hyphenation.MIN_TAIL_LEN = 4

Или через параметры конфигурации переносов типографа:

# Определяем пользовательские правила переносов
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="Электрофоретическое исследование характеризуется квинтэссенциальной значимостью!")

Результат обработки текста с переносами будет выглядеть так:

Электрофо&shy;ретическое исследование характе&shy;ризуется квинтэс&shy;сенциальной значимостью!

Предлоги, союзы и частицы

Правилом хорошего тона в любой типографике считается, когда короткие слова, такие как предлоги, союзы и частицы, не остаются в конце строки в одиночестве («висеть»). Это ухудшает читаемость.

Типограф etpgrf автоматически решает эту проблему, «приклеивая» такие слова к последующему слову с помощью неразрывного пробела (&nbsp;).

  • в домев&nbsp;доме
  • и сказали&nbsp;сказал

Это правило работает для коротких слов в русском, старорусском и английском языках.

Кроме того, обрабатываются и постпозитивные частицы (например, ли, же, бы), которые, наоборот, для улучшения читабельности, «приклеиваются» к предыдущему слову:

  • сказал бысказал&nbsp;бы

Кавычки

В текстах кавычки бывают двух видов: «ёлочки» (для русского языка) и “лапки” (для английского языка). В типографе реализована автоматическая замена кавычек на соответствующие типографские символы в зависимости от языка текста.

Большинство типографов при обработке кавычек находят парные (и определяют вложенность). В etpgrf же реализован другой подход. Он ищет и обрабатывает кавычки, которые находятся рядом со словами. То есть какие-то буквы следуют слева или справа от кавычки.

Преобразование рядом с цифрами (например, когда обозначаются дюймы (17") или секунды (3' 25")) не производится. Также не обрабатываются кавычки окруженные пробелами. Все кавычки которые в исходном тексте уже были оформлены в виде «ёлочек» или “лапок” — тоже не обрабатываются.

ВАЖНО1: По правилам орфографии перед закрывающей кавычкой разрешены только определенные знаки препинания: вопросительный (?), восклицательный (!) знаки и многоточие (…). Такие конструкции используются для цитат. Это учтено в etpgrf, и кавычки будут обработаны: Она воскликнула: "Какая красота!" будет преобразовано в Она воскликнула: «Какая красота!». По правилам пунктуации, точка . перед закрывающей кавычкой не допускается, но существуют исключения, когда перед кавычкой стоит сокращение (например, т. д., и т. п.). В таких случаях точка сохраняется: Он сказал: "Это важно, и т. д."Он сказал: «Это важно, и т. д.». Типограф допускает точку перед закрывающей кавычкой.

ВАЖНО2: Если в настройке типографа указано несколько языков (langs='ru+en'), то кавычки будут преобразованы по правилам для языка который идет первым в списке. Например, для langs='ru+en' кавычки будут преобразованы в «ёлочки»,

Если при типорафировании преобразование не требуется, то можно обработку кавычек можно отключить с помощью параметра quotes=False:

# Задаем конфигурацию типографа без кавычек
typo_no_quotes = etpgrf.Typographer(langs='ru', quotes=False)
# Обработка текста без кавычек
result = typo_no_quotes.process(text='Этот "текст" будет обработан без кавычек.')

Компоновка (тире, диапазоны, инициалы, единицы измерения, сокращения и т.п.)

После того как псевдографика заменена на правильные символы, в дело вступает модуль компоновки (layout), который отвечает за расстановку неразрывных и тонких пробелов. Он применяет несколько важных правил для улучшения читаемости.

Тире

По правилам русской типографики, длинное тире (—) должно отбиваться пробелами от соседних слов. Чтобы тире не "повисло" в начале строки и визуально не смешивалось с диалогами, etpgrf заменяет пробел перед тире на неразрывный ( ).

  • слово — словослово&nbsp;— слово

В английской типографике, наоборот, тире пишется слитно. Типограф учитывает это при указании языка langs='en'.

  • word — wordword—word

Если минус или диапазон стоят между числами (арабскими или римскими), то это считается обозначением числового диапазона (или отрицательным числом, или математическим выражением), и никаких изменений не производится. Неважно есть пробелы вокруг тире/минуса или нет. Если между цифрами тире, то это тоже считается диапазоном и неразрывные пробелы не ставятся: 1941 — 19451941 — 1945, -10 — -5-10 — -5,

Если минус стоит перед числом (например, -5), то это считается отрицательным числом, и перед ним ставится неразрывный пробел: от -5 до +5от&nbsp;-5 до +5.

Инициалы и акронимы

Чтобы инициалы не отрывались друг от друга и от фамилии при переносе строки, типограф расставляет между ними специальные пробелы:

  • Неразрывный пробел (&nbsp;) ставится между фамилией и инициалом/инициалами (А. ПушкинА.&nbsp;Пушкин). Неважно стоят ли инициалы перед фамилией или после неё. Важно наличие точки и буквы (инициала), написанного с заглавной буквы.
  • Тонкая шпация () ставится между самими инициалами, если они написаны слитно, для улучшения внешнего вида (Пушкин А. С. Пушкин&nbsp;А.&thinsp;С.). Число инициалов не ограничено (J.R.R. TolkienJ.&thinsp;R.&thinsp;R.&nbsp;Tolkien), наличие или отсутствие пробелов между инициалами в исходном тексте неважно.
  • Акронимы, написанные через точку (не слитно, например, Н.Л.О.), разделяются так же, как инициалы, через тонкую шпацию (Н.Л.О.Н.&thinsp;Л.&thinsp;О.). Наличие или отсутствие пробелов между буквами в исходном тексте неважно.

Это правило может давать побочные эффекты (в частности, тонкая шпация не является неразрывным пробелом, и в длинных акронимах может привести к разрыву строки). Поэтому его обработку можно отключить с помощью параметра process_initials_and_acronyms:

typo = etpgrf.Typographer(process_initials_and_acronyms=False)
result = typo.process("А. С. Пушкин") # Останется без изменений

Единицы измерения

Типограф предотвращает отрыв единиц измерения от чисел, ставя между ним и предшествующей цифрой неразрывный пробел. Это работает для:

  • Простых единиц: 100 км.100&nbsp;км., -5 °C-5&nbsp;°C'
  • Составных единиц: 120 кв.м.120&nbsp;кв.&thinsp;м., 50 тыс. руб.50&nbsp;тыс.&thinsp;руб. Пробелы (есть они или нет) между составными частями единицы изменения не важны. Между частями составной единицы измерения ставится тонкая шпация (&thinsp;).
  • Единиц с предлогом: № 5№&nbsp;5, § 7§&nbsp;7, $ 100$&nbsp;100
  • Чисел, записанных и арабскими, и римскими цифрами: V в.н.э.V&nbsp;в.&thinsp;н.&thinsp;э.
  • Если между единицами изменений есть математические символы (например, умножение или деление): 10 км / ч10&nbsp;км/ч (неважно есть пробелы вокруг / или нет). Распознаются и другие символы: ·, *, ×, ÷.

Библиотека "знает" множество стандартных единиц для русского и английского языков. Но не все. Вы можете расширить этот список, передав свои кастомные единицы через параметр process_units:

# Передаем список
typo = etpgrf.Typographer(process_units=['бочек', 'вёдер'])
# Можно передавать и с помощзью строки через пробелы 
typo = etpgrf.Typographer(process_units='бочек вёдер аршин сажен')
result = typo.process("Нужно 10 бочек.")       # -> "Нужно 10&nbsp;бочек."

Если нужно отключить распознавание и обработку единиц измерения:

typo = etpgrf.Typographer(process_units=False)
result = typo.process("100 км/ч")               # Останется без изменений

Сокращения

Типограф также обрабатывает распространённые русскоязычные сокращения, чтобы они корректно отображались и не разрывались при переносе строк. Правила делятся на два типа:

  • Финальные сокращения. Сокращения, которые обычно стоят в конце фразы (например, и т. д., и т. п.), обрабатываются особым образом: их части «склеиваются» тонкой шпацией, а перед всей конструкцией ставится неразрывный пробел, чтобы она не «повисла» на новой строке. ...и так далее, и т. д....и так далее, и&nbsp;т.&thinsp;д. Это правило работает независимо от того, как сокращение было написано в исходном тексте (т.д. или т. д.).
  • Препозиционные сокращения. Сокращения, которые стоят перед другим словом (например, и. о. директора, т. е. сказать), также «склеиваются» внутри, но неразрывный пробел ставится после них, чтобы привязать их к последующему слову. Назначить и. о. директораНазначить и.&thinsp;о.&nbsp;директора

Библиотека знает небольшой набор самых распространённых сокращений. Но не все, а некоторые принципиально невозможны к обработке. Например, сокращение пр. может оказаться как финальным (в значении «и так далее»), так и препозиционным (в значении «профессор» или «проспект»). Так же типограф не обрабатывает сокращения, связанные с адресами (ул., д., кв., пл., наб. ...) так как они могут быть как финальными, так и препозиционными.

Висячая типографика

Висячая типографика — это приём из классической вёрстки, когда некоторые знаки препинания (кавычки, скобки, иногда тире и маркеры списков) выносятся на левое (и иногда и по правому, при выравнивании текст по правому краю) поле текста. Это создаёт идеально ровный край не по формальным границам знаков, а по оптическому краю — по первым буквам строк. Текст выглядит гораздо аккуратнее и профессиональнее.

В вебе это достигается с помощью CSS, оборачивая "висячий" символ или слово в и применяя к нему, например, отрицательный text-indent или margin-left (<span style="margin-left:-0.44em;">&laquo;</span>)

P.S.

Если вам нравится этот, можете поддержать отправив любую сумму на мой Т-банк по ссылке или 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
Description
E-Типограф — экранная типографика для веб (IN PROGRESS)
Readme 1.3 MiB
Languages
Python 100%