Rainbow

// ваш код великолепен — покажите его во всей красе

  1. Что это?

    Rainbow - библиотека JavaScript для подсветки синтаксиса кода.

    Оно маленькая(1.4kb), простая в использовании и легко модифицируется.

    Темы оформления определяются полностью через CSS.

  2. Как выглядит результат работы?

    /*
     * Запускаем jQuery при загрузке страницы
     */
    $(document).ready(function() {
        function showHiddenParagraphs() {
            $("p.hidden").fadeIn(500);
        }
        setTimeout(showHiddenParagraphs, 1000);
    });
  3. Как использовать?

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

    <!-- Можно использовать теги code или pre * -->
    <pre><code data-language="python">def openFile(path):
        file = open(path, "r")
        content = file.read()
        file.close()
        return content</code></pre>

    Затем надо включить файл CSS темы

    <!-- Надо включить в раздел <head> -->
    <link href="/assets/css/theme.css" rel="stylesheet" type="text/css">

    И включить файлы JavaScript Rainbow + того языка, который используется в подсвечиваемом коде

    <!-- Вы можете создать описание для любого языка программирования.
    Включения должны стоять перед закрывающим тегом </body> -->
    <script src="/assets/js/rainbow.min.js"></script>
    <script src="/assets/js/language/generic.js"></script>
    <script src="/assets/js/language/python.js"></script>
  4. Как работает?

    Rainbow - очень простой скрипт. Он проходит по блоку кода и перебирает шаблоны регулярных выражений, найденный комбинации оборачиваются в теги <span>. Все форматирование ложится на код CSS, используемой темы.

    Простой набор шаблонов для языка выглядит так:

    Rainbow.extend('css', [
        {
            'name': 'comment',
            'pattern': /\/\*[\s\S]*?\*\//gm
        },
        {
            'name': 'constant.hex-color',
            'pattern': /#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s)/gi
        },
        {
            'matches': {
                1: 'constant.numeric',
                2: 'keyword.unit'
            },
            'pattern': /(\d+)(px|cm|s|%)?/g
        }
    ], true);
  5. Документация

    Определение языка

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

    <pre><code data-language="javascript">var testing = true;</code></pre>

    На сайтах, где теги <code> обрезаются, атрибут можно устанавливать для тега <pre>.

    Методы API Rainbow

    Rainbow имеет четыре публичных метода:

    Rainbow.color

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

    Первый способ заключается в добавлении новых блоков с кодом в DOM и повторном вызове метода:

    // Простой вызов метода
    Rainbow.color();
    
    // Или с использованием возвратной функции
    Rainbow.color(function() {
        console.log('Новые блоки с кодом теперь подсвечены!');
    });

    Другой способ заключается в оборачивании блоков с кодом в элементы div и подсвечивании их перед добавлением в DOM:

    var div = document.createElement('div');
    div.innerHTML = '<p>code:</p><pre><code data-language="javascript">var foo = true;</code></pre>';
    Rainbow.color(div, function() {
        document.getElementById('other_div').appendChild(div);
    });

    Третий способ - непосредственная передача строки кода в метод:

    Rainbow.color('var foo = true;', 'javascript', function(highlighted_code) {
        console.log(highlighted_code);
    });
    Rainbow.addClass

    Данный метод позволяет определить глобальный класс CSS, который задается для каждого элемента span, создаваемого скриптом Rainbow:

    Rainbow.addClass('from-rainbow');
    Rainbow.onHighlight

    Данный метод служит для информирования о начале подсветки блока кода.

    Rainbow.onHighlight(function(block, language) {
        console.log(block, ' для языка ', language, ' подсвечивается');
    });

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

    Rainbow.extend

    Данный метод используется для определения пользовательских шаблонов.

    Rainbow.extend('language-name', [
        {
            'name': 'keyword',
            'pattern': /function|return|continue|break/g
        }
    ], true);

    Любой добавленный шаблон будет иметь преимущество над существующим шаблоном при совпадении на одном блоке кода.

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

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

    Rainbow.extend([
        {
            'name': '',
            'pattern': /true|false/g
        }
    ]);

    Когда имя языка не передается в качестве первого аргумента в метод Rainbow.extend(), шаблон используется как расширение для шаблона по умолчанию.

    Значение "name" определяет класс, который будет добавляться к тегу span. Например, если вы задали значение 'constant.hex-color', то код будет заключен в <span class="constant hex-color"></span>. Таким образом можно задавать особенное оформление отдельных блоков.

    Есть четыре разных способа задать шаблон:

    Соответствие по имени
    Rainbow.extend([
        {
            'name': 'constant.boolean',
            'pattern': /true|false/g
        }
    ]);
    Соответствие группе
    Rainbow.extend([
        {
            'matches': {
                1: 'constant.boolean.true',
                2: 'constant.boolean.false'
            },
            'pattern': /(true)|(false)/g
        }
    ]);
    Соответствие массиву подшаблоновы
    Rainbow.extend([
        {
            'matches': [
                {
                    'name': 'constant.boolean.true',
                    'pattern': /true/
                },
                {
                    'name': 'constant.boolean.false',
                    'pattern': /false/
                }
            ],
            'pattern': /true|false/g
        }
    ]);
    Соответствие другому языку

    Следующий код выделяет блок PHP, включенный в блок HTML:

    Rainbow.extend('html', [
        {
            'name': 'source.php.embedded',
            'matches': {
                2: {
                    'language': 'php'
                }
            },
            'pattern': /<\?(php)?([\s\S]*?)(\?>)/gm
        }
    ], true);

    Можно определять столько уровней подшаблонов, сколько нужно.

    Как Rainbow выбирает соответствие

    Самым лучшим методом является определние шаблона как можно более индивидуальным (например, указанием опеределенного ключевого слова).

    Когда вы создаете новый шаблон, он получает преимущество перед встроенным шаблоном. То есть расширенные правила всегда обарбатываются первыми.

    Rainbow выбирает первое соответствие для блока. Если другой шаблон перекрывает уже выбранный вариант, то он просто игнорируется.

    Есть одно исключение. Если соответствие, выявленное позже является более индивидуальным (начало и конец соответствия шабона лежат внутри выбранного шаблона), то новый шаблон получит преимущество.

    То есть, если у вас имеется шаблоны function test() и public function test(), то первый будет иметь преимущество.