stringtranslate.com

Перенос строк и перенос слов

Разрыв строк , также известный как перенос слов , разбивает часть текста на строки так, чтобы она вписывалась в доступную ширину страницы, окна или другой области отображения. При отображении текста перенос строки продолжается на новой строке, когда строка заполнена, так что каждая строка помещается в просматриваемое окно, что позволяет читать текст сверху вниз без горизонтальной прокрутки . Перенос слов — это дополнительная функция большинства текстовых редакторов , текстовых процессоров и веб-браузеров , позволяющая разрывать строки между словами, а не внутри слов, где это возможно. Перенос по словам исключает необходимость жесткого кодирования разделителей новой строки внутри абзацев и позволяет отображать текст гибко и динамически адаптироваться к дисплеям различных размеров.

Мягкая и жесткая отдача

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

В качестве альтернативы «мягкий возврат» может означать намеренный сохраненный разрыв строки, который не является разрывом абзаца. Например, почтовые адреса обычно печатаются в многострочном формате, но несколько строк считаются одним абзацем. Разрывы строк необходимы для разделения слов адреса на строки соответствующей длины.

В современных графических текстовых процессорах Microsoft Word и OpenOffice.org пользователи должны вводить возврат каретки ( ) между каждым абзацем. Настройки форматирования, такие как отступы первой строки или интервалы между абзацами, вступают в силу, когда возврат каретки отмечает разрыв. Разрыв строки без абзаца, который представляет собой мягкий возврат, вставляется с помощью + или через меню и предусмотрен для случаев, когда текст должен начинаться с новой строки, но другие побочные эффекты начала нового абзаца нежелательны. .EnterShiftEnter

В текстовых языках разметки мягкий возврат обычно предлагается в виде тега разметки. Например, в HTML есть тег <br>, который имеет то же назначение, что и мягкий возврат в текстовых процессорах, описанный выше.

Юникод

Алгоритм разрыва строки Unicode определяет набор позиций, известных как возможности разрыва , которые являются подходящими местами для начала новой строки. Фактические позиции разрыва строки выбираются среди возможностей разрыва программным обеспечением более высокого уровня, которое вызывает алгоритм, а не самим алгоритмом, поскольку только программное обеспечение более высокого уровня знает ширину дисплея, на котором отображается текст, и ширину глифы, составляющие отображаемый текст. [1]

Набор символов Юникода предоставляет символ-разделитель строк, а также разделитель абзацев для представления семантики мягкого и жесткого возврата.

0x2028 РАЗДЕЛИТЕЛЬ СТРОК
* может использоваться для однозначного представления этой семантики
0x2029 РАЗДЕЛИТЕЛЬ АБЗАЦОВ
* может использоваться для однозначного представления этой семантики

Границы слов, расстановка переносов и пробелы

Мягкие возвраты обычно размещаются после окончания полных слов или после знаков препинания, следующих за полными словами. Однако перенос слов может также произойти после дефиса внутри слова. Иногда это нежелательно, и его можно заблокировать, используя неразрывный дефис или жесткий дефис вместо обычного дефиса.

Слово без дефисов можно сделать переносимым, добавив в него мягкие дефисы . Если слово не перенесено (т. е. не разбито на строки), мягкий дефис не виден. Но если слово переносится по строкам, это делается на мягком дефисе, после чего оно отображается как видимый дефис в верхней строке, где слово разбито. (В том редком случае, когда слово предназначено для переноса путем разбиения его на строки, но без появления дефиса, в разрешенных точках разрыва в слове помещается пробел нулевой ширины .)

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

Перенос слов в тексте, содержащем китайский, японский и корейский языки.

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

Однако при определенных обстоятельствах перенос слов нежелателен. Например,

Большинство существующих текстовых процессоров и программ для набора текста не могут справиться ни с одним из вышеперечисленных сценариев.

Пунктуация CJK может соответствовать или не соответствовать правилам, аналогичным вышеупомянутым особым обстоятельствам. В CJK это регулируется правилами нарушения линии .

Однако всегда применяется особый случай правил переноса строк в CJK: перенос строки никогда не должен происходить внутри тире и многоточия CJK. Несмотря на то, что каждый из этих знаков препинания должен быть представлен двумя символами из-за ограничений всех существующих кодировок символов , каждый из них по своей сути представляет собой один знак препинания шириной в две em , а не два знака препинания шириной в одну em.

Алгоритм

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

Минимальное количество строк

Простой способ переноса слов — использовать жадный алгоритм , который помещает в строку как можно больше слов, а затем переходит к следующей строке и делает то же самое до тех пор, пока не останется слов для размещения. Этот метод используется многими современными текстовыми процессорами, такими как OpenOffice.org Writer и Microsoft Word. [ нужна цитация ] Этот алгоритм всегда использует минимально возможное количество строк, но может привести к получению строк различной длины. Следующий псевдокод реализует этот алгоритм:

Пробелслефт := Ширина линиидля каждого слова в тексте if (Ширина (Word) + SpaceWidth) > SpaceLeft вставить разрыв строки перед Word в тексте SpaceLeft := LineWidth - Ширина (Слово) еще SpaceLeft := SpaceLeft - (Ширина(Слово) + SpaceWidth)

Где LineWidth— ширина линии, SpaceLeftоставшаяся ширина места в строке для заполнения, SpaceWidthширина одного пробельного символа, Textвходной текст для перебора и Wordслово в этом тексте.

Минимальная рваность

Другой алгоритм, используемый в TeX , минимизирует сумму квадратов длин пробелов в конце строк для получения более эстетичного результата. В следующем примере этот метод сравнивается с жадным алгоритмом, который не всегда минимизирует квадраты пространства.

Для ввода текста

ААА ББ СС ДДДДД

с шириной линии 6 жадный алгоритм выдаст:

------ Ширина линии: 6AAA BB Осталось места: 0CC Осталось места: 4ДДДДД Осталось места: 1

Сумма квадратов пространства, оставшегося в результате этого метода, равна . Однако оптимальное решение дает меньшую сумму :

------ Ширина линии: 6AAA Осталось места: 3BB CC Осталось места: 1ДДДДД Осталось места: 1

Разница здесь в том, что первая строка разрывается до, BBа не после нее, что дает лучшее правое поле и меньшую стоимость 11.

Используя алгоритм динамического программирования для выбора позиций разрыва строки, вместо жадного выбора разрывов, решение с минимальной неровностью может быть найдено за время , где - количество слов во входном тексте. Обычно функцию стоимости для этого метода следует изменить так, чтобы она не учитывала пространство, оставшееся в последней строке абзаца; эта модификация позволяет абзацу заканчиваться в середине строки без каких-либо штрафов. Также можно применить ту же технику динамического программирования для минимизации более сложных функций стоимости, которые сочетают в себе другие факторы, такие как количество строк или затраты на расстановку переносов в длинных словах. [3] Более быстрые, но более сложные алгоритмы с линейным временем , основанные на алгоритме SMAWK , также известны для задачи минимальной неровности и для некоторых других функций стоимости, имеющих аналогичные свойства. [4] [5]

История

Примитивная функция разрыва строки была использована в 1955 году в «блоке управления страничным принтером», разработанном Western Union . В этой системе использовались реле, а не программируемые цифровые компьютеры, и поэтому требовался простой алгоритм, который можно было бы реализовать без буферов данных . В системе Western Union каждая строка разрывалась на первом пробеле, появлявшемся после 58-го символа, или на 70-м символе, если пробел не был найден. [6]

Жадный алгоритм разрыва строк предшествует методу динамического программирования, изложенному Дональдом Кнутом в неопубликованной записке 1977 года, описывающей его систему набора текста TeX [7] и позднее более подробно опубликованной Кнутом и Плассом (1981).

Смотрите также

Рекомендации

  1. ^ Хенингер, Энди, изд. (25 января 2013 г.). «Алгоритм разрыва строк в Юникоде» (PDF) . Технические отчеты . Приложение № 14 (Предлагаемое обновление стандарта Unicode): 2 . Проверено 10 марта 2015 г. WORD JOINER следует использовать, если цель состоит в том, чтобы просто предотвратить разрыв строки.
  2. ^ Лунде, Кен (1999), Обработка информации CJKV: китайские, японские, корейские и вьетнамские вычисления, O'Reilly Media, Inc., стр. 352, ISBN 9781565922242.
  3. ^ Кнут, Дональд Э .; Пласс, Майкл Ф. (1981), «Разбиение абзацев на строки», Software: Practice and Experience , 11 (11): 1119–1184, doi : 10.1002/spe.4380111102, S2CID  206508107.
  4. ^ Уилбер, Роберт (1988), «Ещё раз к проблеме вогнутой подпоследовательности наименьшего веса», Journal of Algorithms , 9 (3): 418–425, doi : 10.1016/0196-6774(88)90032-6, MR  0955150.
  5. ^ Галил, Цви ; Парк, Кунсу (1990), «Алгоритм линейного времени для вогнутого одномерного динамического программирования», Information Processing Letters , 33 (6): 309–311, doi : 10.1016/0020-0190(90)90215-J , MR  1045521.
  6. ^ Харрис, Роберт В. (январь 1956 г.), «Стандартизация клавиатуры», Технический обзор Western Union , 10 (1): 37–42, заархивировано из оригинала 03 августа 2015 г. , получено 7 апреля 2013 г..
  7. ^ Кнут, Дональд (1977), TEXDR.AFT , получено 7 апреля 2013 г.. Перепечатано в Кнуте, Дональде (1999), Цифровая типография , Конспекты лекций CSLI, том. 78, Стэнфорд, Калифорния: Центр изучения языка и информации, ISBN. 1-57586-010-4.

Внешние ссылки

Алгоритм Кнута

Другие ссылки-переносы по словам