Делаем syntax highlighter plugin для TinyMCE

просмотров: 93134 августа 2011 года

Многие из нас сталкивались с проблемой подсветки программного кода в своем блоге. Наверно, одно из самых лучших на сегодняшний день решений - это highlight.js, разработан Иваном Сагалаевым.

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

Ставим задачу

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

Решение

Все оказалось достаточно простым, благодаря уже реализованному плагину для TinyMCE. Скачиваем SyntaxHL, он предоставит простую функциональность popup-a с выбором типа, а так же настройками вставляемого кода. Сохраняем его в tiny_mce/plugins/ и подключаем. В настройках инициализации TinyMCE делаем следующее:

tinyMCE.init({
 // подключаем плагин
 plugins : "... ,syntaxhl, ....",
 // определяем местоположение кнопки
 theme_advanced_buttons1 : "... , syntaxhl, ...",
....................................
 // Подключаем таблицу стилей подсветки
 content_css : "/_inc/highlighter/",	// стили можно перечислять через запятую

Если вы все сделали правильно, то в редакторе должна появится кнопка.

Теперь скачиваем последнюю версию Highlight.js с сайта разработчика и копируем ее в tiny_mce/plugins/syntaxhl/js/hljs. Подключаем движек подсветки синтаксиса. Для этого открываем файл tiny_mce/plugins/syntaxhl/dialog.htm, и добавляем перед закрывающим тегом </head>:

<script type="text/javascript" src="js/hljs/highlight.pack.js"></script>
 

 

Открываем файл tiny_mce/plugins/syntaxhl/js/dialog.js, ищем строки:

var SyntaxHLDialog = {
  init : function() {
  },

меняем на

var SyntaxHLDialog = {
  wrapper: document.createElement('div'),
  init : function() {
  },

 

В том же файле

    textarea_output = '<pre class="brush: ';
    textarea_output += f.syntaxhl_language.value + ';' + options + '">';
    textarea_output += tinyMCEPopup.editor.dom.encode(f.syntaxhl_code.value);
    textarea_output += '</pre> '; /* note space at the end, had a bug it was inserting twice? */
    tinyMCEPopup.editor.execCommand('mceInsertContent', false, textarea_output);
    tinyMCEPopup.close();

заменяем на:

    f.syntaxhl_code.value = f.syntaxhl_code.value.replace(/</g,'<'); 
    f.syntaxhl_code.value = f.syntaxhl_code.value.replace(/>/g,'>'); 
    textarea_output = '<pre><code '; 
    textarea_output += 'class="' + f.syntaxhl_language.value + '">'; 
    textarea_output += f.syntaxhl_code.value; 
    textarea_output += '</code></pre> ';

    /* делаем подсветку сразу и передаем полученный HTML в tinyMCE */
    this.wrapper.innerHTML = textarea_output;
    hljs.highlightBlock(this.wrapper.firstChild.firstChild, '    ');
    tinyMCEPopup.editor.execCommand('mceInsertContent', false, this.wrapper.innerHTML);
    tinyMCEPopup.close();

Теперь немного разберем, что мы сделали. Мы создали элемент-обертку и сперва вставляем в него код, далее при помощи метода hljs.highlightBlock подсвечиваем нужные символы и вставляем в tinyMCE уже подготовленный для отображения код.

Таким же образом, можно подключить и любой другой движек подсветки синтаксиса.

Теперь при нажатии на кнопочку syntaxHL у вас должно появиться окно, в которое вы можете вставить код, выбрать его тип, и он будет обрамлен в нужные нам теги.

Нюансы

Откроем файл tiny_mce/plugins/syntaxhl/dialog.html и вносим небольшие поправки в названия языков (например, в SyntaxHL по умолчанию JavaScript обозван value="jscript", и Highlight.js такой класс не поймет, поэтому его надо переименовать в value="javascript"), а так же сортируем их в удобной нам последовательности. У меня выглядит так:

        <select name="syntaxhl_language" id="syntaxhl_language">
            <option value="php">PHP</option>
            <option value="javascript">Javascript</option>
            <option value="css">CSS</option>
            <option value="html">XML/XHTML</option>
            <option value="sql">SQL</option>
            <option value="cpp">C++</option>
            <option value="bash">Bash(Shell)</option>
            <option value="perl">Perl</option>
            <option value="ruby">Ruby</option>
            <option value="plain">Plain(Text)</option>
            <option value="diff">Diff</option>
            <option value="delphi">Delphi</option>
            <option value="groovy">Groovy</option>
            <option value="java">Java</option>
            <option value="python">Python</option>
            <option value="scala">Scala</option>
            <option value="vb">VB</option>
            <option value="csharp">C#</option>
        </select>

ВНИМАНИЕ! Если у вас стоит русифицированный tinyMCE, то вам необходимо перейти в папку tiny_mce/plugins/syntaxhl/langs/ и сделать копии имеющихся там файлов en.js и en_dlg.js, и переименовать в ru.js и ru_dlg.js соответственно.

Чтобы видеть подсветку в tinyMCE, нужно в его инициализации добавить одну из тем highlight.js

Результат

Готовое решение можно скачать ЗДЕСЬ

 

Если Вас заинтерисовала эта статья, то так же полезно будет почитать это: Вырезается вводимый HTML-код в TinyMCE?

Поделиться

Что скажем?