Обратите внимание, что новости можно получать по RSS.
X
-

Информационные технологии, Infused Bytes - архив

10 ноября 2001, 00:00 (5762 дня назад, №6063)Перенос и разбиение слов в HTML

При создании различных лент новостей и колонок онлайн газет, web дизайнеры и программисты сталкиваются с ситуацией, когда в тексте попадается очень длинное слово (синхрофазотрон, http://www.enlight.ru/camera/117/index.html, и т.п.). Браузер при форматировании разбивает текст в тех местах, где есть пробелы (дефисы). Длинные слова при этом остаются нетронутыми, что часто приводит к "разъезжанию" ячеек таблицы, неаккуратному внешнему виду. Каким образом можно решить эту проблему?


стандартное форматирование текста (перенос по пробелам)

Первое, что обычно приходит в голову - заранее отформатировать текст с учетом предполагаемой ширины колонки (например - php/perl/python скриптом) и выдать его браузеру уже построчно (с <br> после каждой строки). Такой подход редко приводит к желаемому результату, поскольку необходимо заранее, с точностью до пиксела знать ширину ячейки в которую будет выведен текст и ширину каждого символа в строке текста. Даже если предположить, что ширина таблицы и ячеек заданы в пикселах, все равно - разнообразие точек зрения браузеров на виды и размеры шрифтов общеизвестно. Кроме того, пользователь может изменить размеры окна браузера после загрузки страницы, так что пришлось бы переформатировать текст js скриптом по OnResize. 

Очевидно, необходим более гибкий и аккуратный метод. Посмотрим, что нам предлагают авторы браузеров и стандартов.

Microsoft предлагает хороший способ:

<P STYLE="word-wrap:break-word;width:100%;left:0">
LongWordLongWord...LongWordLongWord</P>

Или, если надо разрешить разрывы слов только на конкретном участке:

<P>LongWordLongWord...<span STYLE="word-wrap:break-word;width:100%;left:0">LongWordLongWord---LongWord</span>::LongWordLongWord,,,LongWordLongWord</P>

(знаки препинания вставлены произвольно)


word-wrap:break-word; в MSIE5.5. Видно, что
на участке ограниченном <span></span>
браузер разорвал слово и перенес его.
Однако за пределами этого участка текст
переносится как обычно - по пробелам.

В этом параграфе слово будет разбито автоматически. Одно плохо - метод работает только в MSIE 5.5 и выше (проверено в 5.5 и 6.0).

Будем смотреть дальше:

В стандарте на HTML 4 существует символ "&shy;" - так называемый "мягкий перенос". Вообще же, это стандартный символ в Unicode и Latin-1 который Windows знает, но не всегда любит [правильно] показывать.

Если его вставить в слово, например так:

LongWordLongWord&shy;LongWordLongWord

..то браузер в нормальных условиях этот символ не отобразит вообще. Однако, если места для слова не хватает, в этом месте оно должно быть автоматически перенесено на следующую строчку и появится знак переноса "-". Я говорю должно быть, поскольку браузеры - не всегда отражение стандарта на HTML.


действие &shy; в MSIE 5.0.x

Под MSIE 5.0.x все с виду работает, но в определенные моменты (при изменении размера окна браузера) определенные слова вдруг оказываются разбиты черточками без всякой на то видимой причины.
NS 4.05/Win32, NS4.7/Win32 и вовсе показывает дефисы во всех словах, независимо ни от чего.
В MSIE6 работает нормально.
В NS4.7/FreeBSD, NS6.0/Win32 не работает.


а вот так понимает &shy; NS 4.05 и 4.7

Помимо прочего, если поместить разбитую таким образом строчку в clipboard, а затем извлечь обратно - невидимые переносы превратятся в банальные "-". Это произойдет например в ICQ2000, GoldED 3.0.1/Win32, EditPlus. А Outlook и WinWord с одной стороны воспринимают "&shy;" правильно, но с другой ведут себя с такими строчками немного странно. 

Очевидно, этот метод далек от совершенства - надо думать дальше.

Если копнуть глубже, в черновом варианте стандарта HTML 3.2 упоминались применительно к Netscape любопытные тэги: <nobr> и <wbr>.
Тэгами <nobr></nobr> ограничивался участок текста, который браузер не имел права разбивать.
<wbr> напротив - указывал место, в котором слово можно было переносить на другую строчку. 
Однако, со времен HTML3.2 утекло много воды и эти тэги стали (говорю после общения с www.google.com) всенародно любимыми, но официально презираемыми. Впрочем, поддержка в браузерах осталась. Но работает странно - видимо, она отражает представление разных групп разработчиков о вселенной :)


действие тэга <wbr> в MSIE 5.0.x

В MSIE 5.0.x и NS 4.05 необходимо писать так: 

<NOBR>LongWordLongWord<WBR>LongWordLongWord</NOBR>

А вот в NS 6.x только так: 

LongWordLongWord<WBR>LongWordLongWord

причем если добавить <NOBR> - работать перестает.
В NS 4.7/Win32 и в MSIE6/Win32 работают оба варианта.
В NS4.7/FreeBSD не работает ни один.

Выводы из этой грустной истории такие:

Можно ждать, когда все перестанут пользоваться старыми браузерами, а новые поголовно начнут поддерживать &shy; (и не переносить его в clipboard в виде дефисов).
Можно комбинировать &shy; с <WBR> (именно в таком порядке):

LongWordLongWord&shy;<WBR>LongWordLongWord

Другой вариант (возможно - лучший) - определять тип браузера и взависимости от этого генерировать текст с разбивкой нужными тэгами. Я написал для этого небольшую PHP функцию, возможно кому-то она будет полезна, после усовершенствования:

# -----------------------------------------------------------------------------
# Если в строке $s встречается слово (последовательность символов без пробелов)
# длиннее чем $wordmaxlen , оно ограничивается тэгами $leftlimit, $rightlimit и 
# разбивается тэгами $hyp на несколько слов, каждое из которых не 
# длиннее $wordmaxlen. Тэги бывшие в $s изначально - не затрагиваются.
#
# Примеры:
# ($s,2,'<nobr>','</nobr>','<wbr>')
# ($s,2,'','','<wbr>')
# ($s,2,'','','&shy;')
# ($s,2,'','','&shy;<wbr>')
# -----------------------------------------------------------------------------

function SplitText($s,$wordmaxlen,$leftlimit,$rightlimit,$hyp) 
{ 

$marker = "\x01";

# Сохраняем все тэги чтобы уберечь их от разбивки
preg_match_all('/(<.*?\>)/si',$s,$tags);

# Заменяем все тэги на маркеры
$s =  preg_replace('/(<.*?\>)/si', $marker, $s);

# Разбиваем текст на слова
$words = split(' ',$s);

for ($i=0; $i<count($words); $i++)
{
# Каждое слово >= $wordmaxlen разбиваем
  if (strlen($words[$i])>=$wordmaxlen)
    $words[$i] = $leftlimit . chunk_split($words[$i],$wordmaxlen,$hyp) . $rightlimit;
}#for

# Собираем строку из уже разбитых на части слов
$s = implode(' ',$words);

# Восстанавливаем тэги, места которых были отмечены маркерами
for ($i=0; $i<count($tags[1]); $i++)
  $s =  preg_replace("/$marker/si", $tags[1][$i], $s, 1);

return $s;
}#SplitText

Из остальных браузеров которые были под рукой: Opera 4.02, 5.12 вообще игнорирует все перечисленные способы. Lynx 2.8.4pre.5 напротив - поддерживает все, кроме варианта с "word-wrap:break-word;".

Хотя идеального решения проблемы не найдено, но, надеюсь, кому-то я сберег время и нервы. Или наоборот - расшатал :)

Что можно сказать в итоге? Все мы не питаем особой любви к Microsoft и другим крупным корпорациям-монополиям.
Однако, с точки зрения стандартизации, конкуренция - не самое полезное явление. Странная и безвыходная (казалось бы) получается ситуация: 
Если фирма укрупняется - получаем монополию, которая творит что ей вздумается, однако поддерживает стандарты, имеет возможность проводить серьезные (требующие капиталовложений) исследования.
Если разбиваем монополию на мелкие фирмы - они начинают конкурировать между собой, придумывать в пику друг другу разные тэги, торопятся выкатывать сырые и громоздкие продукты из боязни, что сосед выкатит свой продукт первым..

Может, плоха не монополия, а то, что она существует для своих владельцев, а не для заинтересованного в стандартах и прогрессе общества?

 

Петр Соболев  

(Благодарности: Theta, Riddle, AngelDust)  

Опубликовано: Пётр Соболев

Случайная заметка

6127 дней назад, 03:1310 ноября 2000 Хочу поделиться личными впечатлениями от мыши Genius Netscroll Optical. Это оптическая мышь (без шарика) не требующая, в отличие от старых оптических мышей, коврика. Внутри установлена примитивная телекамера, которая отслеживает движение мыши по практически любой поверхности. Проверка показала, что это действительно так. То есть за ...далее

Избранное

107 дней назад, 01:575 мая 2017 Часть 1: От четырёх до восьми Я люблю читать воспоминания людей, заставших первые шаги вычислительной техники в их стране. В них всегда есть какая-то романтика, причём какого она рода — сильно зависит от того, с каких компьютеров люди начали. Обычно это определяется обстоятельствами — местом работы, учёбы, а иногда и вовсе — ...далее

1612 дня назад, 00:5922 марта 2013 Прочёл тут книжку - iWoz ( ссылка ) , 2006 года. Это автобиография Стива Возняка. Похоже, что на русский её не переводили (в отличие от книг про Стива Джобса). В этой парочке, как известно, Возняк был инженером (собственно, и спроектировавшим Apple I и II), а Джобс - скорее предпринимателем. В книге есть довольно интересные ...далее

716 дней назад, 23:404 сентября 2015 Небольшое видео про CC'2015 ( версия без фоновой музыки здесь: ссылка )

1084 дня назад, 03:121 сентября 2014 Мой семинар на Chaos Constructions'2014 (слайды можно в виде PDF скачать здесь: ссылка ) и несколько интервью с разными людьми: Вячеслав Славинский (svo) о Vectrex: ссылка Вячеслав Славинский (svo) о 3D Imager для Vectrex: ссылка Вячеслав Славинский (svo) о световом пере для Vectrex: ссылка ...далее