Выравнивание по ширине и расстановка переносов
2009-05-23 12:08Выравнивание текста и отображение его в узких столбцах известная проблема веб-верстки, которая требует как поддержки в браузере, так и средств расстановки переносов на стороне сервера. Сейчас появилось и то, и другое, и даже более-менее работает. В этой статье рассказано как и зачем это делается на python & zope3.
Justify & Hyphenation
Я люблю читать тексты, в которых граница четко выделена выравниванием текста по обеим сторонам колонки. К сожалению, в эта традиция не очень распространена в веб, из-за того, что возможности сделать это корректно долгое время просто не было.
Немного истории
Осмелюсь предположить, что такая эстетика ближе к русскому духу, чем выравнивание по одной стороне. Может быть, это связано с трудоемкостью операции, которую в древние времена на Руси выполняли крепостные книгопечатники, а в развитых странах рабочие мануфактур забивали болт на этот бесовской сервис.
Веб-технологии зародились не в России, и выравнивание текста по ширине явно не было основным требованием к браузеру. Видимо поэтому, хоть какие-то универсальные (т.е. поддерживаемые всеми браузерами) средства выравнивания появились тогда, когда веб, в основном, был заполнен и его культура сложилась. Она оказалась настолько навязчива, что даже вымирающие печатных издания вдруг стали использовать иногда выравнивание по одной стороне.
Но даже сейчас ситуация далека от совершенства: как известно, браузеры не переносят слова при выравнивании, и поэтому на узких колонках (уже 20 символов) выравнивание по ширине выглядит не очень, а уж на колонках уже 10 символов - отвратительно выглядит любое выравнивание, да и текст то и дело не влезает в колонку.
Поэтому на сайтах редко встречается выравнивание по ширине колонки (в основном, на моих и на сайте моего знакомого-полиграфиста).
Обоснование
То, что меня не выравненный текст бесит - это субъективное мнение. Объективно же достаточно трудно создать страницу с многочисленными блоками вывода, если не научится переносить и выравнивать текст.
Настоящий кошмар для вебмастера - ввод злонамеренными пользователями неразрывных строк, длина которых заведомо превосходит поле вывода: такая строка либо выходит за пределы блока, либо раздвигает блок до недозволенных размеров. Возможно, именно это является причиной частых рекомендаций дизайнерам не использовать рамки или иные способы выделить текстовые блоки: отказ от визуального выделения блоков хорошо решает проблему выхода текста за его границы. К сожалению, более читабельной страница от этого не становится.
Более приемлемое решение - форматировать текст с использованием переносов длинных слов, выравнивая его по одной или обеим сторонам.
Как это делается
На некоторых сайтах создаются паллиативы из джава-скриптов, которые занимаются переносом и выравниванием на стороне клиента. Такие поделки на джава-скрипте - вполне достойный подход, к сожалению, не всегда работающий. Расставлять переносы на стороне клиента очень хорошее решение, но вряд ли в современном многоязыковом мире в ближайшем будущем все производители браузеров договорятся между собой о стандартах на расстановку переносов и начнут поддерживать хотя бы значимое большинство языков.
В тоже время, HTML позволяет выполнить расстановку переносов на стороне сервера, используя "символ мягкого переноса": он не виден на печати и лишь обозначает, что на его месте может быть вставлен перенос. Эксперименты показали, что эта техника вполне работает, хотя еще немного сыровата.
Код символа мягкого переноса в HTML обознается ­. Его надо вставить везде, где возможен перенос, и браузер, при необходимости, перенесет слово в этом месте. В простейшем случае можно вставить перенос после каждого символа внутри слова:
re.compile(u"(?<=\w{2})(?=\w{2})",re.U).sub('­',
u"суицидальные тенденции"
)
Такая строка легко поместится в колонку шириной 3 символа, хотя выглядеть это будет странно. В тех случаях, когда проблемой является не столько выравнивание текста, сколько потребность избежать ловушки длинных, неразрывных слов, портящих дизайн, можно вставлять мягкий перенос исключительно в длинные неразрывные последовательности:
re.compile(u"(?<=\S{6})(?=\S{6})",re.U).sub('­',
u"суицидальные тенденции"
)
Это дает возможность избежать нарушения вида верстки из-за выхода длинных слов за границы текстовых блоков или расширения блоков сверх задуманного, и в тоже время будет использоваться только в случае действительной необходимости, что замаскирует глюки браузера.
Счастливые пользователи Zope3 могут воспользоваться конструкцией ZPT:
<tal:block
content="structure python:modules['pd.lib.hyphen']
.hyphen('Суицидальные тенденции')"
/>
Модуль pd.lib.hyphen содержит несложные функции, принцип действия которых описан выше, а точное описание вызова можно посмотреть в описании на модуль pd.lib.
Но тем, кто заинтересован в расстановке переносов по правилам, стоит воспользоваться модулем hyphenator, который расставляет переносы по словарю.
Вышеприведенная конструкция для Zope3 с использованием этого модуля будет выглядеть так:
<tal:block
content="structure python:modules['hyphenator']
.Hyphenator('/usr/share/hyphen/hyph_ru_RU.dic')
.inserted(u'Суицидальные тенденции',u'shy;')"
/>
Словари можно поискать на сайте OpenOffice, где лежат словари переносов даже для таких языков, для которых с трудом можно представить само понятие переноса.
Заключение
Лично я первый раз воспользовался автоматической расстановкой переносов когда писал облако тегов и потребовалось отображать крупным шрифтом длинные слова в узкой колонке. Примеры того, что получилсь, можно посмотреть в статье "Использование квантизации для визуализации данных". Сразу стало ясно, сколько проблем решает этот подход, и сейчас я использую его очень часто.
Рекомендую и вам начать использовать мягкие переносы, потому что двустороннее выравнивание и четкие визуальные границы блоков - это действительно красиво и удобно, и отказ от них изначально не является вопросом эстетики: технические причины сублимировались в эстетику, и сейчас, когда технических причин нет, этот эстетический паллиатив вообще является проблемой психиатрии.



