Подсветка программного кода при веб публикации, проблема не новая, но я с ней столкнулся первый раз и
как то не задумывался, как это делает, например библиотека
phpDocumentor или некоторые движки форумов. И вот понадобилось.
Собственно написать такой функционал для программиста средней руки - не проблема, достаточно хорошо знать регулярные выражения, и я бы начал этот труд, но при нормальном современном процессе веб-разработки, сроки реализации обычно "вчера", и с этим трудно что либо поделать. Дополнительная сложность состояла в том, что 50% кода требущего подстветки являл собой HTML, отображать и редактировать который любой онлайновый HTML WISIWIG редактор по естественным причинам не может. Да и не хочется изобретать велосипед, если процесс его изобретения ничего интересного для тебя не представляет.
Слава богу не все такие "ленивые и нелюбопытные" и инструменты для решения подобных задачь уже созданы.
Впрочем употребляя множественное число я наверное погорячился, аналогов известной JavaScript библиотеке
SyntaxHighlighter я не нашёл.И не сильно этому огорчился - библиотека замечательная, а о возможных сложностях её применения я сейчас расскажу.Сначала скачаем SyntaxHighlighter, с сайта разработчика (http://alexgorbatchev.com/wiki/SyntaxHighlighter:Download сайт канадский. но что то в его названии мне намекает...). Важно скачать именно последнею версиию, тапк как синтаксис применения ранних версий библиотеки здорово отличается.
Скачав, не будем спешить распаковывать полученный архив на територию нашего веб сайта. Сначала посмотрим, что мы добыли (Рис. 1).
как видете у нас три папки, в двух из которых находятся скрипты, которые и занимаются парсингом и подсветкой кода, разница состоит в том, что в папке scripts они находятся в сжатом виде, а в папке src - в первозданном ( в последних релизах там только миниум). Для подключения библиотеке необходимо вклчить в код веб страницы два javascript файла - ядро библиотеки и интерпритатор нужного языка. Допустим, для PHP код будет следующим:
Рис. 1
Библиотека SyntaxHighlighter
<script type="text/javascript" src="js/shCore.js"></script> <script type="text/javascript" src="js/shBrushPhp.js"></script>
Теперь идём в папку styles и берём от туда файл shCore.css и css файл соответствующий какому нибудь либо стилю подсветки (Midnight Commander, Emac и др. Я выбрал Defoult):
<link href='css/shCore.css' rel='stylesheet' type='text/css'/> <link href='css/shThemeDefault.css' rel='stylesheet' type='text/css'/>
И инициализируем библиотеку:
<script type='text/javascript'> SyntaxHighlighter.config.bloggerMode = true; SyntaxHighlighter.all(); </script>Теперь оформляем публикуемый код следующим образом:
<pre class="brush: php">
$foo="test";
function bar($one, $second=1){
phpinfo();
}
</pre>
Если всё сдедано правильно результат должен выглчядеть вот так:
$foo="test"; function bar($one, $second=1){ phpinfo(); }
Теперь попробуем подсвечивать HTML код. Добавляем соответствующею кисть:
<script type="text/javascript" src="js/shCore.js"></script> <script type="text/javascript" src="js/shBrushPhp.js"></script> <script type="text/javascript" src="js/shBrushXml.js"></script>
Да да, именно xml (не будем забывать, что html, вернее xhtml яdляется подмножество xml). Нстоящая прроблема с html разметкой немного в другом. если она будет сохранена в первозданном виде, браузер не будет её отображать, он будет её интерпретировать. Это кстати относиться к символам <? или <% в php или asp коде соответственно. Выход из этой ситуации есть и я его исполюзлвал, в честности для пнаписания предыдущего предложения. Нужно использовать html сущности, и вместо < и > писать "<" и ">"
Смотрим пример:
<pre class="brush: html">
<div id="test1" >
Текст
</div >
<img src="logo.png"/>
</pre>
Должно получиться следующее:
<div id="test1" > Текст </div > <img src="logo.png"/>
Тут нужно обратить внимание на brush: html. В данном случае я использовал псевдоним для «кисти» Xml. Псевдонимы «кистей» и их названия есть в документации по SyntaxHighlighter , но для особо ленивых я приведу табличку нативно поддерживаемых языков:
Название | Псевдоним | Имя файла |
---|---|---|
ActionScript3 | as3, actionscript3 | shBrushAS3.js |
Bash/shell | bash, shell | shBrushBash.js |
ColdFusion | cf, coldfusion | shBrushColdFusion.js |
C# | c-sharp, csharp | shBrushCSharp.js |
C++ | cpp, c | shBrushCpp.js |
CSS | css | shBrushCss.js |
Delphi | delphi, pas, pascal | shBrushDelphi.js |
Diff | diff, patch | shBrushDiff.js |
Erlang | erl, erlang | shBrushErlang.js |
Groovy | groovy | shBrushGroovy.js |
JavaScript | js, jscript, javascript | shBrushJScript.js |
Java | java | shBrushJava.js |
JavaFX | jfx, javafx | shBrushJavaFX.js |
Perl | perl, pl | shBrushPerl.js |
PHP | php | shBrushPhp.js |
Plain Text | plain, text | shBrushPlain.js |
PowerShell | ps, powershell | shBrushPowerShell.js |
Python | py, python | shBrushPython.js |
Ruby | rails, ror, ruby | shBrushRuby.js |
Scala | scala | shBrushScala.js |
SQL | sql | shBrushSql.js |
Visual Basic | vb, vbnet | shBrushVb.js |
XML | xml, xhtml, xslt, html, xhtml | shBrushXml.js |
Впрочем на этом список поддерживаемсых языков не заканчивается. Со списоко языков с которыми можно работать прямо сейчас и в ближайшем будущем представлен здесь:
http://www.undermyhat.org/blog/2009/09/list-of-brushes-syntaxhighligher/
Более того, если вы не обнаружили в смиске ваш любимый Algol 68 то отчаивается не следует. Библиотека расширяема, как с точки зрения архитектуры, так и лицензии. желающих принять участие в её расширении прошу вот сюда:
http://alexgorbatchev.com/wiki/SyntaxHighlighter:Brushes:Custom
и наверное сюда
http://alexgorbatchev.com/wiki/SyntaxHighlighter:API
Ну а нам, простым пользователям остаётся ознакомиться с базовыми функкциями.
Опции конфигурирования SyntaxHighlighter
При инициализации можно задать несколько параметров подсветки. Их немного, поэтому перечислю все:
tagName - название тега, которым обрамляется подсвечиваемый код. По умолчанию это разумеется "pre". устанавливается так:
SyntaxHighlighter.config.tagName = "div";
"view source" или "Can't find brush for: " (это сообщение пояляется если вы используете кисть, которую забыли подключить. Использовать её следует так: |
|
SyntaxHighlighter.config.strings.viewSource = "Посмотреть исходный код";
Опция stripBrs - предназначена для борьбы с некоторыми HTML и не только редакторами, которые автоматически добавляют тег
в концекаждой строки. По умолчанию false.
Опции toolbarItemWidth и
toolbarItemHeight отвечают за размеры иконок панели инструментов (по умолчанию 16X16)
clipboardSwf - показывает расположение иконки "скопировать в буфер обмена". По умолчанию NULL, то есть иконка не показывается.
И наконец загадочная для меня опция bloggerMode. По дукоментации её надо включать (устанавливать значение в true), если библиотека используется на блоге blogger.com. По видимому это для какой то цели нужно автору и посему я её вклчил.
Следущий уровень настройки работы
SyntaxHighlighter заключается в атрибутах, прописываемых для обрампляющего тега. Применяются они следующим образом:
<pre class="brush: php; first-line: 10; gutter: false;" &qt;...</pre&qt;
Тут параметров немного больше:
auto-links - отключае/включает гиперсылки в коде
class-name - позволяет задавать дополнительное имя класса, для создания пользовательских стилей.
collapse - при значении true показывает код в свёрнутом виде. Вот так:
function foo() { var bar="test"; return 0; }
first-line - задаёт номер первой строки при нумерации строк
gutter - включает/выкключает нумерацию строк
highlight -используется для выделения одной или нескольких строк:
function foo() { var bar="test"; document.write("Hello!"); det=document.getElementById("det"); return 0; }
опция html-script очень пригодиться для илюсьрации вставки какпого лиюо кода в html разметку. При веб программировании это до сих пор довольно актуально. Применяется это так:
< class="brush: php; html-script: true">
<html>
<body>
<div style="font-weight: bold"><?= str_replace("\n", "<br/>", $var) ?></div>
<?php
/***********************************
** Multiline block comments
**********************************/
$stringWithUrl = "http://alexgorbatchev.com";
$stringWithUrl = 'http://alexgorbatchev.com';
ob_start("parseOutputBuffer"); // Start Code Buffering
session_start();
?>
</body>
</html>
</pre>
Результат:
<html> <body> <div style="font-weight: bold"><?= str_replace("\n", "<br/>", $var) ?></div> <?php /*********************************** ** Multiline block comments **********************************/ $stringWithUrl = "http://alexgorbatchev.com"; $stringWithUrl = 'http://alexgorbatchev.com'; ob_start("parseOutputBuffer"); // Start Code Buffering session_start(); ?> </body> </html>
ligh - моя любимая опция, отключающая панель инструментов и нумерацию строк.
smart-tabs - как видно из назвапния, при значении true пытается самомтоятельно упорядочить отступы в коде.
tab-size - устанавливает размер таб-отступа.
toolbar -включае/выключает панель инструментов
wrap-lines - включает/выключает перенос длинных строк, не впещающихся в стандарный размер страницы с кодом. при значении false (по умолчанию - true), строки не переносятся, и появляется горизонтальный скрол-бар.
Вроде всё. Теперь мы готовы для практического применения SyntaxHighlighter
WISIWIG HTML online редакторы
Публикация статей. новостей, прочего контента сейчас делается посредством этих программ. И не важно, что ты сам программист, ты не обязан знать HTML и уж точно не обязан возиться с вёрсткой, всякий раз, когда ты решил осчастливить мир новой публикацией. Как быть там с подсветкой кода?
Большинсво, если не все такого рода редакторов позволяют работать непосредственно с тегами HTML. Но приэтом теряется преимущество такого способы публикации и существует опастность интепретации редапрпрпрктором эти тегов так как ему а не вам нужно.
На счастье для наиболее распространённых online редакторов уже есть плагины, поддерживающие SyntaxHighlighter.
Для редактора TinyMCE используется плагин SyntaxHL от RichGuk. Скачиваем архив и помещаем папку syntaxhl в директорию плагинов редактора (tiny_mce/plugins/). Привызове редактора на веб-странице, внесём этот плагин в список загружаемых, и добавим иконку syntaxhl на панель интструментов:
Для редактора TinyMCE используется плагин SyntaxHL от RichGuk. Скачиваем архив и помещаем папку syntaxhl в директорию плагинов редактора (tiny_mce/plugins/). Привызове редактора на веб-странице, внесём этот плагин в список загружаемых, и добавим иконку syntaxhl на панель интструментов:
tinyMCE.init({ // General options mode : "textareas", theme : "advanced", plugins : "safari,syntaxhl,pagebreak,style,...", // Theme options theme_advanced_buttons1 : "syntaxhl,|,italic,underline...", theme_advanced_buttons2 : "...", theme_advanced_buttons3 : "...", remove_linebreaks : false, extended_valid_elements : "textarea[cols|rows|disabled|name|readonly|class]", });
Теперь при запуске редактора, в верхней понеле инструментов появляется новая иконка (рис 2),
Рис 2
Иконка SyntaxHL
Рис 3
SyntaxHL в работе
Как видете, теперь библиотеку можно исполльзовать не вписывая каждый раз теги
<pre&qt; и т д.
Пробплемы возникают, когда мы пытаемся отредактировать уже сохранённый текст, содержащий html разметку. При инициализации редактора все сущности теги нашего кода преодразуются в теги и при повторном сохранении превращаются в обычную разметку. Выход простой - использовать php функцию htmlspecialchars, преобразующую теги в сущности, при выводе редактируемого текста в TinyMCE:
print '';
Если вы пишете на другом языке, используйте аналогичные функции из них ( Server.HTMLencode для ASP, escape в Perl).
Редактор FCKeditor, или в более новой и не режущий нежный американский слух, CKeditor так-же имеет плагин, аналогичный по функциональности. Это Highlight Plugin. Устанавливается он схожим образом - папка (
syntaxhighlight2
) с плагином помещается в fckeditor/plugins/. Далее в конфигурационном файле редактора (fckconfig.js) пишем следующее:FCKConfig.Plugins.Add( 'syntaxhighlight2', 'en');
И там-же добавляем иконку:
FCKConfig.ToolbarSets["Basic"] = [ ['SyntaxHighLight','-''Bold','Italic','-','OrderedList',...] ];Далее можно установить язык по умолчанию:
FCKConfig.SyntaxHighlight2LangDefault = 'xhtml' ;Псевдонимы языков следующие:
- c++ - C++
- csharp - C#
- css - CSS
- delphi - Delphi
- java - Java
- jscript - Java Script
- php - PHP
- python - Python
- ruby - Ruby
- sql - SQL
- vb - VB.NET
- xhtml - XML/HTML
Рис. 4
Highlight Plugin в работе
<link href='http://bitbucket.org/alexg/syntaxhighlighter/raw/8815b7f713eb/Styles/shCore.css' rel='stylesheet' type='text/css'/ &qt; <link href='http://bitbucket.org/alexg/syntaxhighlighter/raw/8815b7f713eb/Styles/shThemeDefault.css' rel='stylesheet' type='text/css'/ &qt;
Разумеется вы можете его модифицировать исходя из своиз потребностей, руководствуясь описаными выше настройками. Ну а принаписании статей, пользуйтесь вкладкой "Изменить HTML", добавляя тег pre с соответствующими атрибутами к блокам кода.
На этом всё. Осталось сказать спасибо Алексу Горбачеву за его замечательную библиотеку.
А в самом TinyMCE (после добавления кода посредством SyntaxHL) можно увидеть подсвеченный код?
ОтветитьУдалитьЕсли да, то как?