Номер телефона

Последнее обновление:

Библиотека prism.js - раскраска программного кода на вебстраницах: предостережение

Эта библиотека дает легкую возможность раскраски программного кода, имеющегося на вебстраницах. При этом можно выбрать стили раскрасок для достаточно большого количества языков. Это - как очень популярные С/С++/С#, HTML, CSS, javascript, PHP, java, Haskel, Go,... , так и менее известные. Использование этой библиотеки очень простое: нужно лишь где-нибудь (лучше в конце вебстраницы) сделать две ссылки на нее саму:

<script src="//www.site.ru/.../prism.js"></script>

А также на файл CSS-стилей, где содержатся правила (классы) для раскраски:

<link href="//www.site.ru/.../prism.css" rel="stylesheet" />

Кроме того, программный код, который следует раскрасить на вебстранице, следует заключить в теги следующего вида:

<pre class="language-ххх">
    <code class="language-ххх">
      / Программный код, который будет раскрашен /
    </code>
</pre>

Где "ххх" - это символы, обозначающие класс. Например, если необходимо раскрасить код на языке РНР, то класс будет language-php. Для языка js может быть использован language-js, ну, и т.д. Т.е. можно выбрать стиль раскраски, соответствующий конкретному языку. Достоинства данной библиотеки:

  1. Эффективная поддержка большого количества языков. Раскраска и в самом деле производится хорошо, программный код делается реально более понятным и легким для восприятия.
  2. Легкость самой библиотеки. Так, даже полные версии ее файлов занимают всего лишь 56,6 кБ (prism.js) и 2,49 кБ (prism.css). А обсфусцированные файлы занимают объем раза в два меньше. Т.е. здесь она, пожалуй, является одной из самых минимальных, наверное - рекордсменом.
  3. Легкость использования и установки. В самом деле, требуется наличие ВСЕГО ЛИШЬ двух файла (см. выше). И - подключить их на вебстраницах, после чего библиотека будет работать, качественно раскрашивать программный код везде, где он встретится в составе тегов pre, code с классами вида language-ххх. В отличие от некоторых других аналогичных библиотек, которые требуют наличия множества мелких файлов и в этом смысле не слишком удобны для использования. Ведь, в конце концов, чем компактнее библиотека, тем проще и нагляднее - не так ли?...
  4. Ну, и, наконец, лицензия на нее: практически свободная, как для коммерческого, так и некоммерческого использования. Разумеется, при использовани необходимо оставить в ее файлах авторскую инофрмацию.

Итак, библиотека, в самом деле, хорошая. Но, есть, как минимум, один нехороший нюанс.

В чем может быть проблема с prism.js?

Нами выявлен небольшой баг этой библиотеки. Если это можно назвать багом. Т.е., еще раз: библиотека вполне выполняет свои функции, но лишь тогда, когда html-код соответствующей вебстраницы является валидным, т.е. соответствующим необходимым синтаксическим правилам. Вообще, валидность ныне - не слишком популярна. Ряд вебмастеров, разработчиков сайтов склонны даже не то, что пренебрегать валидностью, а еще и насмехаться над теми, кто все-таки стремится делать корректный код html, скрупулезно соблюдая ВСЕ правила. И тому, увы, есть немало причин:

  1. Во-первых, это - укоренившаяся ныне тенденция размывания языка html, что выразилось в итоге в концепции html5. Так, она ВПОЛНЕ допускает незакрытые теги (которые согласно стандарту должны быть закрыты). Она допускает вложенность блочных тегов (типа block) в... строчные (типа inline). Она... ну, и т.д. Лично нам совершенно очевидно, что такая свобода разнузданность языка в версии html5 в итоге, несомненно, приведет к его распаду и невозможности использования на практике. Со временем (это несомненно) в тех или иных браузерах будут накапливаться баги, вызванные попыткой обработать некорректный html-код. А это приведет, в свою очередь, к "войне браузеров", что уже вполне было лет 10...20 назад. Но, вот с какой целью это допускается его разработчиками?... Решительно непонятно. Ну, да ладно, разговор здесь не об этом.
  2. Потворствование некорректному, ошибочному html-коду даже на сайтах КРУПНЫХ компаний, типа Google. Попробуйте, для интереса, взять какую-нибудь страницу Google и проверить ее на валидаторе. Скорее всего, увидите много-много "интересного". Специалистам-вебмастерам мы настоятельно НЕ рекомендуем делать это перед сном, так как масса неприятных ощущений, скорее всего, будет гарантирована. Не говоря уже о неких "авторских" псевдо-разработчиках, типа набившего уже оскомину А. Лебедева. Который однажды дошел до того, что начал высказываться примерно в таком духе: нужно, мол, не гнаться за валидностью, а смотреть, правильно ли отображается страница в браузере. Ибо, мол, не валидатор, а браузер является на практике средством проверки. Что тут сказать? Глупость - тем более, от уже порядком взрослого дяденьки? Разумеется! Тем более, что для более-менее опытного вебразработчика вообще не составляет труда писать корректный html-код. Это быстро входит в привычку. Что же тогда подвигло пресловутого А. Лебедева и иже с ним на подобные рассуждения? Скажем так, некие странности в психике?... Или, все-таки, желание (пока - тайное) - способствовать развалу языка html?... Да кто ж его знает. Может, лет через 10...20 одумается таки.
  3. Нынешняя тенденция отказа от "ручного" написания html-страниц в пользу разного рода движков, а то и... генераторов (особенно таких ,которые "для домохозяек"). Которые нередко содержат баги и выдают грязный, некорректный html-код. Понятно, что рано или поздно подобные баги устраняются их разработчиками. Но... взамен появляются новые. Также понятно, что вебмастерам, привыкшим делать вебстраницы при помощи подобных генераторов, устранить их баги самостоятельно совершенно не под силу. Ибо это - уже гораздо более высокая ступень профессионализма. Примерно как в армии генерал отличается от сержанта. Или, если взять пример из науки - как профессор отличается от студента (двоечника) 2-го курса.
  4. Наконец, вносит свой черный вклад и само по себе усложнение языка html, массовое добавление туда совершенно ненужных функций, возможностей. Которые или попросту излишни, или легко реализуются средствами javascript (а этот язык, вообще-то, изначально и предназначался как раз для того. чтобы корректировать внешний вид html-страниц). Разумеется, разработчикам html5 гораздо проще и быстрее выдать "на гора" нечто новое, чем шлифовать, совершенствовать, дорабатывать уже имеющееся, годами опробованное. Но, в итоге, это и приводит к нехорошим последствиям. Причем, не всегда, а выборочно. И оттого эти последствия бывает сложно "отловить". По причине усложнения движков браузеров и, как следствие, появления все новых и новых браузерных багов.

Так вот, обсудим небольшой баг библиотеки prism.js

Еще раз: если "всё хорошо" (т.е. если код html-валиден, является качественным), то проблем с нею, вроде бы, не наблюдается. По крайней мере, судя по нашему опыту. Но, что, если html-код, выполненным разнузданным вебмастером-разработчиком, НЕ является валидным? Что тогда? Будет ли эта библиотека функционировать все так же правильно? Не внесет ли она ошибок в функционирование сайта? Чтобы не быть голословными, давайте посмотрим конкретные примеры. Для простоты, ограничимся примерами банальных html-страниц, чтобы было нагляднее.

1. Валидный код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
       <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/>
       <link href="//www.site.ru/lib/prism.css" rel="stylesheet" />
       <script type="text/javascript" src="//www.site.ru/lib/prism.js"></script>
   </head>
<body style="background-color: grey">
<div>
    <pre class="language-cpp">
       <code class="language-cpp">
           a = 0;
       </code>
   </pre>

   <div style="color: blue">Обращаем Ваше внимание </div>
</div>
</body>
</html>

Пример валидного кода, раскрашенного при помощи библиотеки prism.js

И вот как отображается этот код в браузере (Firefox). Все, как положено. Строчка программного кода (а = 0;) раскрасилась в соответствии с правилами класса language-cpp, а текст ниже - синим цветом, как и указано в стиле для его элемента. Фон документа (тег body) тоже окрасился согласно заданному для него стилю. Ниже, в целях экономии места, будем менять только ту часть кода тестируемой страницы html, которая обозначена красным цветом (см. выше).

2. НЕвалидный код

Пример НЕвалидного кода, раскрашенного при помощи библиотеки prism.js

Теперь уберем из кода закрывающий тег </code>. Т.е. библиотеке prism.js придется как-то работать в невалидных условиях. Хотя, получившийся результат не требует пояснений, все-таки, заметим, что они теперь применились КО ВСЕЙ ПОСЛЕДУЮЩЕЙ части html-кода вебстраницы - вплоть до конца документа. Результат очевиден: так как нет закрывающего тега </code>, браузер пытается как то выправить ситуацию и добавляет его. НО: при этом он вставляет начальный тег <code class="language-cpp"> и за пределы тегов <pre>... </pre>. Но, это еще одно. Также любопытно то, что тега <div> со строчкой style="color: blue" вообще ИСЧЕЗ! Чтобы убедиться в этом - нужно выделить всё на странице и посмотреть (через контекстное меню) код выделенного фрагмента. Или, что проще, через "Исследовать элемент", "Инспектор". Как видим, тега <div class="language-cpp"> и в самом деле нет. Вместо него появился тег <code class="language-cpp">. Поэтому, очевидно, и строчка "Обращаем Ваше внимание" окрашена теперь черным цветом, а не синим, как раньше. Также видно, что вместо одной пары тегов <code>... </code> появилось несколько. Так что, вот пример, к чему может привести нарушение СТРОГИХ стандартов. Если уточнить, то это может привести к полному разрушению всего того, что находится ниже невалидного места на странице. Как минимум.

Практически то же самое будет, если class="language-cpp" убрать из тега <pre>, оставив его к теге <code>

3. Тоже НЕвалидный код, но без класса language-cpp в теге code

Пример НЕвалидного кода, раскрашенного при помощи библиотеки prism.js

Как видим, теперь, по крайней мере, сохранился тег <div class="language-cpp">. Соответственно, текст в нем окрашивается, как и при валидном коде, синим цветом. Однако, в результате "доработок" браузера этот тег помещен теперь внутрь тегов <code>... </code>, поэтому гарнитура шрифта изменилась сообразно (стандартному) правилу для этого тега. При этом, что характерно, класс language-cpp в тег <code> вставлен коректно (т.е. это - работа библиотеки prism.js).

Является ли это багом библиотеки?

И да, и нет. С одной стороны, ее разработчик не предусмотрел, что вебстраницу вполне могут разрабатывать то ли криворукие "программисты", которые, по аналогии с заветами А. Лебедева и иже с ним, забудут или попросту не захотят закрыть тег <code>. То ли у них генераторы какие-то "такие". Понятно, что разработчик-то библиотеки надеялся на то, что стандарты html (а то и XHTML - на сегодняшний день речь идет о XHTML5) все-таки будут соблюдаться. А с другой стороны, разработчик мог бы, конечно, услышать громогласный "зов" некоторых современных вебмастеров-бездельников и как-то попытаться обработать подобные некорректные ситуации. Вплоть до того, что выдать на страницу сообщение примерно такого содержания: "К сожалению, данная страница выполнена некорректно, поэтому раскраска програмного кода (библиотека prism.js) работать не будет. Для полноценной работы этой библиотеки следует проверить валидность html-кода страницы и исправить его".

Правда, есть большое подозрение, что как только это сообщение увидят вебмастера-бездельники (коих - очень немало), то скажут, мол, да ну, эта библиотека толком не хочет работать. Ее автор, мол, какой-то "неадекватный", почему-то валидацию требует проходить. Ну, и что, мол, что на странице есть ошибки? До этой библиотеки "всё работало", и "ничего". На многих, даже на крупных ресурсах масса ошибок, "и ничего", там "всё работает". Лучше, мол, поискать более "качественную библиотеку". Ведь, в самом деле, бездельник обычно склонен обвинять в своих неудачах, наверное, всех... кроме самого себя. А в итоге - библиотека будет пользоваться меньшим спросом. И это приведет к тому, что разработчики (особенно, молодые) могут и не узнать о ней, вместо неёиспользуя некие громоздкие API из облачных хранилищ. Которые, да, будут загружаться в браузеры пользователей медленно, не спеша. Пользователи будут, естественно, сильно ругаться или жаловаться на "медленный интернет". Но, зато бездельники-вебмастера будут в плюсе: у них "наконец-то всё заработало".

Итак, из-за некоей мелочи вполне может наступить крах работы вебстраницы. Ну, а теперь стоит вспомнить, СКОЛЬКО сейчас пишется разных скриптов/библиотек/фреймворков. Есть даже мнение, что число написанных библиотек на javascript превышает число самих разработчиков. Да, и бывают еще и конфликты между библиотеками. И добро, если подобные ситуации обнаруживаются сразу, т.е. если они способны "вылазить наружу" через короткое время. А ведь бывает и иначе. Когда баги/проблемы проявляются ИЗРЕДКА. Только в некоторых случаях. По аналогии с двойным кодированием в UTF-8 и обратно заглавной русской буквы И (в языке РНР). Для всех остальных русских букв, равно как и латинских, а также для цифр, специальных символов, имеющихся на клавиатуре типичного десктопного компьютера, такой проблемы не наблюдается. А вот для И - проблема есть. И потому если тестировщик сайта по каким-то причинам не будет использовать в своих тестах букву И, то он и не заметит ошибки. Собственно. даже если и БУДЕТ использовать - и то не всегда ошибка будет обнаружена.

А как может случиться ситуация, что закрывающий тег <code> может отсутствовать?

Элементарно. И не только в результате забывчивости или игнорирования стандартов и валидации страницы. Например, это может случиться и в результате вполне корректной работы функции saveXML(), которая превращает XML-представление документа в строку. У нее такая особенность, что пустые теги <div style="..."></div> она преобразует, увы, в самозакрывающиеся, т.е. в <div style="..."/>.

Есть, конечно, у нее параметр, который предотвращает такое поведение, но это, пожалуй, даже хуже: при этом ВСЕ самозакрывающиеся теги будут принудительно развернуты в парные, т.е., скажем, <img style="..."/> превратится в <img style="..."></img>. Едва ли это именно то, о чем мечтает разработчик. Кстати, подобным поведением, вроде бы, грешит и известная библиотека Simple_PHP_DOM. Правда, это - по памяти, так как уж давненько от нее пришлось отказаться.

Как выйти из подобной ситуации? Как вариант, проверять (на стороне сервера), не является ли какая-то пара тегов пустой. Если да, то вставлять между ними что-нибудь. Например, пробел или перенос строки - PHP_EOL. Да, это, как говорят, костыль, но иного простого способа ликвидации ошибки пока не обнаруживается.

Вывод

Вывод можно сделать такой. Так как prism.js сама дополняет требуемый класс в теге <code>, то целесообразно НЕ ВКЛЮЧАТЬ его в html-страницах, хотя разработчик и рекомендует это делать. В теге <pre> класс должен быть, разумеется, вставлен, как полагается. При этом, правда, нижняя часть вебстраницы будет отображаться несколько странно, но, по крайней мере, не будет ее краха, т.е. со страницей можно будет, худо-бедно работать. Т.е. мы предлагаем использовать вариант №3. Если код страницы будет валидным - всё хорошо, проблемы не будет. А если невалидным - то, по крайней мере, верстка страницы не нарушится (наверное).

Ну, и следует помнить, что если Вы, помимо prism.js, используете и другие библиотеки, API (разные jQuerry и протчая, и протчая), то тогда при невалидном коде вебстраницы результат может быть, вообще-то, непредсказуемым. И, самом печальное, что, еще раз, обнаружить это может получиться не сразу, а лишь через время. Добро, если короткое.

И последнее замечание

Как видно, выше использовался класс language-cpp. Он нам показался наиболее универсальным. Т.е. при его применении более-менее подсвечиваются многие "основные" языки программирования. Пусть и не полностью, хоть как-то, но - подсвечиваются. А это означает, что вместо набора пользовательских кнопок для каждого языка программирования (с соответствующими классами вида language-ххх) вполне можно обойтись одной кнопкой. Это будет полезно для сайтов типа нашего, к примеру. А вот для программистских сайтов, конечно, такой совет едва ли приемлем; там, для большей наглядности, очень желательно подсвечивать код на каждом языке программирования, исходя из его конкретных особенностей синтаксиса.

Удачи Вам в использовании библиотеки prism.js для подсветки программного кода!


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



Подписаться на комментарии на этой странице

Мы можем выполнить

Другие услуги
Интересная и полезная
информация
НАПИШИТЕ НАМ
Яндекс.Метрика
Номер телефона
© Copyright Все права защищены 2013-2024 Научный консалтинг