Главная
Программы
Устранение висячих слов в HTML-страницах
Устранение висячих предлогов
и других висячих служебных слов
в HTML-страницах
Последнее обновление страницы: 09.12.2025 23:36:28
В статье «GREP-стили для устранения висячих предлогов…» мы подробно описали проблемы, связанные с висячими предлогами и другими висячими служебными словами в конце строк, и предложили способ борьбы с ними в InDesign’е. Теперь рассмотрим, как можно решить эту проблему при подготовке HTML-страниц, и в конце предложим написанный для этих целей программный модуль на VBA.
Самый простой способ – заменить пробелы в нужных местах неразрывными пробелами, которые кодируются спецсимволом « ». Именно так и работала в своё время первая версия нашего модуля. Однако неразрывный пробел имеет фиксированную ширину, и визуально сильно заметна разница между нормальными междусловными пробелами в строке и неразрывными пробелами. Ситуация усугубляется тем, что браузеры не поддерживают автоматический перенос слов по слогам, а это ещё больше увеличивает расстояние между словами, делая текст совсем уж некрасивым.
Здесь нужно сделать важное замечание. Замена обычного пробела спецсимволом « » приводит к тому, что не будут отрываться друг от друга два слова, между которыми вставлен этот спецсимвол. Однако понятие «слово» здесь имеет не привычный нам лингвистический смысл, а компьютерный смысл, т. е. набор русских и латинских букв и цифр, который выделяется целиком двойным щелчком мыши, и который находится при поиске, когда мы устанавливаем флажок «Только слово целиком» (в английском интерфейсе – «Whole word only»). Таким образом, «текст» и «2025» являются словом, а «что-то» – двумя словами, и добавление « » до или после «что-то» не запретит сделать перенос после дефиса.
В HTML, помимо неразрывного пробела, имеется CSS-свойство «white-space», значение которого «nowrap» запрещает разрывать текст, помеченный этим свойством, не влияя при этом на ширину междусловных пробелов. Этим свойством можно «обернуть» произвольный фрагмент текста. В результате удаётся решить проблему, которую невозможно решить с помощью неразрывных пробелов, а именно: запретить перенос слов в конструкциях, содержащих дефис. Это прежде всего предлоги типа «из-за», наречия «кое-что», «всё-таки» и т. п., а также порядковые числительные типа «2025-й». Вторая версия описываемого модуля, с помощью которой подготовлены все страницы нашего сайта, «обёртывала» тэгами со свойством «white-space» оба слова, которые нельзя отрывать друг от друга:
«<span style="white-space:nowrap;">не переносить</span>».
Для улучшения читаемости кода HTML громоздкая конструкция «style="white-space:nowrap;"» была заменена классом «nobr», который в CSS-стилях определяется следующим образом:
.nobr { white-space:nowrap; }
В результате вышеприведённая конструкция приобретает более компактный вид:
«<span class="nobr">не переносить</span>».
В процессе работы с текстами, выкладываемыми на нашем сайте, выяснилось, что такой способ «обёртывания» всей неразрываемой конструкции является не очень удобным, поскольку затрудняет разметку текстов в ситуациях, когда одни служебные слова привязываются к последующему тексту (в частности, предлоги), другие – к предыдущему тексту (частицы, а также наименования физических и денежных единиц и т. п.). Поэтому в версии 3.0 нашей программы использовано следующее свойство пробела: если его окружить тэгом неразрывности, то он «приклеивается» как к предыдущему, так и к последующему слову. Таким образом, следующие три конструкции в плане неразрывности ведут себя одинаково:
«<span class="nobr">не переносить</span>»
«не<span class="nobr"> </span>переносить»
«не переносить».
Однако вторая конструкция является совершенно нечитаемой. Поэтому было принято следующее решение: в тех случаях, когда служебное слово должно быть «приклеено» к последующему тексту, оно окружается тэгом неразрывности вместе с последующим пробелом, а когда это слово должно быть «приклеено» к предыдущему тексту, оно окружается тэгом неразрывности вместе с предыдущим пробелом. В результате приведённая выше конструкция приобретает вид:
«<span class="nobr">не </span>переносить».
При таком подходе легко решается задача объединения нескольких следующих друг за другом предлогов в единый неразрывный блок, что заметно улучшает читаемость кода и уменьшает его объём. Например:
«<span class="nobr">Да ни за </span>что!»
К сожалению, ни дефисы, ни тире не обладают тем свойством, которое характерно для пробела: если их «обернуть» тэгом неразрывности, то они не будут «приклеиваться» ни к предыдущему, ни к последующему тексту. Например, не приведёт ни к какому результату такая замена:
«почему<span class="nobr">-</span>то»
Более того, в конструкции «почему<span class="nobr">-то</span>», если она окажется в конце строки, «-то» будет перенесено на новую строку. Поэтому в таких случаях тэгами неразрывности нужно «оборачивать» всю конструкцию, внутри которой присутствует дефис или тире.
* * *
Предлагаемый программный модуль, написанный на VBA, выполняет разметку открытого в Word’е текста описанными HTML-тэгами с целью устранения в нём возможных висячих предлогов и других висячих служебных слов. Этот модуль является функциональной частью программы, предназначенной для конвертирования документа, подготовленного в Word’е, в HTML-файл, однако вполне может использоваться самостоятельно.
К сожалению, в Word’е реализовано весьма усечённое подмножество регулярных выражений, носящее название «Подстановочные знаки». Оно не позволяет описать все возможные случаи висячих слов набором из всего лишь 15-ти поисковых выражений, как это сделано в InDesign’е. Наиболее болезненными являются следующие два принципиально важных ограничения:
- отсутствует возможность указать, что искомое выражение должно встретиться «ноль или более раз» или «ни разу или один раз»: нижняя граница должна быть не меньше единицы. В результате в поисковом выражении невозможно описать, например, такое правило: «пробел может присутствовать, а может отсутствовать».
- отсутствует функция «или» («|»), позволяющая перечислить в одном поисковом выражении все предлоги, союзы и частицы, которые нельзя отрывать от следующего слова.
При этом VBA работает не очень быстро, поэтому увеличение количества операций поиска/замены заметно увеличивает время обработки документа. К сожалению, для этой цели не получается использовать библиотеку «Microsoft VBScript Regular Expressions 5.5», поскольку она работает с текстовыми строками, а не с форматированным текстом, и все найденные с помощью неё случаи висячих предлогов придётся вставлять в текст «поштучно» в цикле, что резко увеличит время обработки документа.
Тем не менее, всё-таки удалось уменьшить время обработки документа с помощью разнообразных ухищрений – в ущерб наглядности. Например, все двухбуквенные служебные слова:
«во|въ|да|до|за|из|ко|къ|на|не|ни|но|ну|об|от|по|со|съ|то»
описываются в данном модуле следующим поисковым выражением:
«<[вдзикнопстВДЗИКНОПСТ][абезиотуъ]>»
Как видно из этого примера, с помощью предлагаемого программного модуля можно обрабатывать тексты в старой орфографии.
Скачать программный модуль ReplaceNonBreakSpace.bas
После распаковки можно импортировать модуль в используемый по умолчанию шаблон Normal.dotm. Для этого нужно, находясь в Word’е, нажать горячую клавишу Alt+F11: откроется Visual Basic. В нём нужно в панели «Project» щёлкнуть правой кнопкой мыши по «Normal», и в открывшемся контекстном меню выбрать «Import File…». В открывшемся окне найти распакованный файл «ReplaceNonBreakSpace.bas» и открыть его. После этого в стандартном окне макросов в Word’е появится макрос «ReplaceNonBreakSpace». При желании можно назначить ему горячую клавишу. Обрабатывать этим макросом можно как весь текст целиком, так и только выделенный фрагмент.
