Підсвічування синтаксису стало своєрідним стандартним питанням для обговорення та написання практичних посібників на цілій низці сайтів. Доступно безліч способів для включення підсвічування синтаксису залежно від того, які мови ви використовуєте та як хочете відображати свій код.
Довгий час автор цього посібника використав для цієї мети Google Prettify, оскільки він простий у налаштуванні. Єдиний недолік у його застосуванні полягає в тому, що він не завжди створює виділення кольором для всіх елементів коду, які ви використовуєте. Спроби переробити його на свій лад не увінчалися успіхом, оскільки з цим інструментом не так просто розібратися самостійно в плані внесення авторських правок у вихідний код.
Завантажити вихідні | демонстрація
На щастя, нещодавно було знайдено інший інструмент для підсвічування синтаксису під назвою Prism.js, що дозволяє розширювати можливості підсвічування синтаксису та виділення блоків розмітки коду в HTML и CSS силами досить простого плагіна.
Взявши за основу цей інструмент і додавши до нього підтримку нумерації рядків та підсвічування коду PHP, а також змінивши кілька патернів по роботі з різними елементами різних мов, автор зміг отримати плагін, про створення і використання якого і піде в цій статті.
Збираємо плагін
Нам треба лише додати функцію і шорт-код у WordPress, щоб ми могли легко включати підсвічування коду у своїх сніппетах, використовуючи для цієї мети злегка модифікований скрипт Prism.js. Найпростіший спосіб вирішити всі завдання – це зробити окремий плагін. У підсумковому вигляді виглядатиме це якось так:
Почнемо писати наш плагін з обов'язкових полів:
/* Plugin Name: Syntax Highlighter Plugin URI: http://wp.tutsplus.com/tutorials/plugins/adding-a-syntax-highlighter-shortcode-using-prism-js Description: Highlight your code snippets with an easy to use shortcode based on Lea Verou's Prism.js. Version: 1.0.0 Author: c.bavota Author URI: http://bavotasan.com */
Далі додамо наш шорт-код і обробимо цей код, щоб бути впевненими в тому, що він спрацює в потрібний нам час:
add_filter( 'the_content', 'sh_pre_process_shortcode', 7 ); /** * Functionality to set up highlighter shortcode correctly. * * This function is attached to the 'the_content' filter hook. * * @since 1.0.0 */ function sh_pre_process_shortcode( $content ) { global $shortcode_tags; $orig_shortcode_tags = $shortcode_tags; $shortcode_tags = array(); // New shortcodes add_shortcode( 'code', 'sh_syntax_highlighter' ); $content = do_shortcode( $content ); $shortcode_tags = $orig_shortcode_tags; return $content; } /** * Code shortcode function * * This function is attached to the 'code' shortcode hook. * * @since 1.0.0 */ function sh_syntax_highlighter( $atts, $content = null ) { extract( shortcode_atts( array( 'type' => 'markup', 'title' => '', 'linenums' => '', ), $atts ) ); $title = ( $title ) ? ' rel="' . $title . '"' : ''; $linenums = ( $linenums ) ? ' data-linenums="' . $linenums . '"' : ''; $find_array = array( '[', ']' ); $replace_array = array( '[', ']' ); return '</pre> <div class="syntax-highlighter" title=""> <pre><code class="language-' . $type . '">' . preg_replace_callback( '|(.*)|isU', 'sh_pre_entities', trim( str_replace( $find_array, $replace_array, $content ) ) ) . '</code></pre> </div> <pre> '; } /** * Helper function for 'sh_syntax_highlighter' * * @since 1.0.0 */ function sh_pre_entities( $matches ) { return str_replace( $matches[1], htmlentities( $matches[1]), $matches[0] ); }
Функція sh_pre_process_shortcode() потрібна для того, щоб синтаксис нашого шорт-коду був оброблений до того, як усі фільтри контенту приберуть текст, запропонований WordPress за замовчуванням. Допоміжна функція відфільтрує наш код та замінить значення HTML-коду нашими відповідними значеннями та параметрами.
Робимо запити до скриптів та стилів
Щоб наш плагін працював як слід, нам треба додати кілька функцій у наші файли CSS и JS:
add_action( 'wp_enqueue_scripts', 'sh_add_js' ); /** * Load all JavaScript to header * * This function is attached to the 'wp_enqueue_scripts' action hook. * * @uses is_admin() * @uses is_singular() * @uses wp_enqueue_script() * @uses plugins_url() * * @since 1.0.0 */ function sh_add_js() { if ( sh_has_shortcode( 'code' ) ) { wp_enqueue_script( 'sh_js', plugins_url( 'js/sh.js', __FILE__ ), '', '', true ); wp_enqueue_style( 'sh_css', plugins_url( 'css/sh.css', __FILE__ ) ); } } /** * Check posts to see if shortcode has been used * * @since 1.0.0 */function sh_has_shortcode( $shortcode = '' ) { global $wp_query; foreach( $wp_query->posts as $post ) { if ( ! empty( $shortcode ) && stripos($post->post_content, '[' . $shortcode) !== false ) { return true; } } return false; }
До них також потрібно зробити запити, але тільки в тому випадку, якщо наш шорт-код використовується у структурі контенту конкретного посту. Тому нам треба запровадити додаткову функцію, яка перевірятиме, чи є у пості необхідний шорт-код.
Швидка розмітка тегами
Додаємо швидкий тег до нашого шорт-коду, це досить просто:
add_action( 'admin_enqueue_scripts', 'sh_add_quicktags' ); /** * Adds a syntax highlighter quicktag to the post editor * * This function is attached to the 'admin_print_footer_scripts' action hook. * * @since 1.0.0 */ function sh_add_quicktags( $hook ) { if( 'post.php' == $hook || 'post-new.php' == $hook ) wp_enqueue_script( 'sh_quicktag_js', plugins_url( 'js/quicktag.js', __FILE__ ), array( 'quicktags' ), '', true ); }
Ось що нам знадобиться у файлі quicktag.js:
QTags.SyntaxButton = function() { QTags.TagButton.call( this, 'syntax_highlighter', 'syntax highlighter', '', '[/code]' ); }; QTags.SyntaxButton.prototype = new QTags.TagButton(); QTags.SyntaxButton.prototype.callback = function( e, c, ed ) { var type, linenums, title, t = this; if ( t.isOpen( ed ) === false ) { type = prompt( 'Type (markup, php, css, javascript)', 'markup' ), title = prompt( 'Title (optional)' ), linenums = prompt( 'Line number (optional)' ); type = ( type ) ? ' type="' + type + '"' : ''; title = ( title ) ? ' title="' + title + '"' : ''; linenums = ( linenums ) ? ' linenums="' + linenums + '"' : ''; if ( type ) { t.tagStart = '1'; QTags.TagButton.prototype.callback.call( t, e, c, ed ); } } else { QTags.TagButton.prototype.callback.call( t, e, c, ed ); } }; edButtons[150] = new QTags.SyntaxButton();
Оформлення CSS
Для виділення синтаксису я віддаю перевагу темній темі, тому використовую наступні параметри для CSS:
code[class*="language-"], pre[class*="language-"] { color: #fff; text-shadow: 0 1px 1px #000; font-family: Menlo, Monaco, "Courier New", monospace; direction: ltr; text-align: left; word-spacing: normal; white-space: pre; word-wrap: normal; line-height: 1.4; background: none; border: 0; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; -webkit-hyphens: none; -moz-hyphens: none; -ms-hyphens: none; hyphens: none; } pre[class*="language-"] code { float: left; padding: 0 15px 0 0; } pre[class*="language-"], :not(pre) > code[class*="language-"] { background: #222; } .syntax-highlighter[rel] { position: relative; } .syntax-highlighter[rel] pre[class*="language-"] { padding-top: 44px; } .syntax-highlighter[rel]:before { content: attr(rel); text-align: center; text-shadow: 1px 1px 2px rgba(0,0,0,0.6); position: absolute; top: -1px; background: #3A87AD; padding: 5px 10px; left: 0; right: 0; font: bold 16px/20px "myriad-pro-1","myriad-pro-2","Lucida Grande",Sans-Serif; color: #fff; -moz-border-radius: 7px 7px 0 0; -webkit-border-radius: 7px 7px 0 0; border-radius: 7px 7px 0 0; } /* Code blocks */ pre[class*="language-"] { padding: 15px; margin: 1em 0; overflow: auto; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } /* Inline code */ :not(pre) > code[class*="language-"] { padding: 5px 10px; line-height: 1; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } .token.comment, .token.line-comment, .token.prolog, .token.doctype, .token.cdata { color: #797979; } .token.selector, .token.operator, .token.punctuation { color: #fff; } .namespace { opacity: .7; } .token.tag, .token.boolean { color: #ffd893; } .token.atrule, .token.attr-value, .token.hex, .token.string { color: #B0C975; } .token.property, .token.entity, .token.url, .token.attr-name, .token.keyword { color: #c27628; } .token.regex { color: #9B71C6; } .token.entity { cursor: help; } .token.function, .token.constant { color: #e5a638; } .token.variable { color: #fdfba8; } .token.number { color: #8799B0; } .token.important, .token.deliminator { color: #E45734; } pre[data-line] { position: relative; padding: 1em 0 1em 3em; } .line-highlight { position: absolute; left: 0; right: 0; padding: inherit 0; margin-top: 1em; /* Same as .prism’s padding-top */ background: rgba(255,255,255,.2); pointer-events: none; line-height: inherit; white-space: pre; } .line-highlight:before, .line-highlight[data-end]:after { content: attr(data-start); position: absolute; top: .3em; left: .6em; min-width: 1em; padding: 0 .5em; background-color: rgba(255,255,255,.3); color: #fff; font: bold 65%/1.5 sans-serif; text-align: center; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; text-shadow: none; } .line-highlight[data-end]:after { content: attr(data-end); top: auto; bottom: .4em; } /* for line numbers */ ol.linenums { margin: 0; padding: 0 0 0 35px; } .linenums li { padding-left: 10px; border-left: 3px #d9d336 solid; }
Використання шорт-коду
Код нашого "розмітника" містить три атрибути: тип, назву и linenums. Розшифруємо, що вони означають:
- тип: 4 типи мови, які працюють з нашим "розмічувачем": розмітка, CSS, PHP, наявність.
- назву: необов'язковий заголовок, який можна увімкнути під час запуску підсвічування синтаксису.
- linenums: додає номери рядків до коду, починаючи з будь-якого заданого вами числа (теж необов'язково).
Єдиний обов'язковий атрибут - це "тип", за умовчанням його значення виставлено як "розмітка".
Висновок
Складання плагіна для візуального "підсвічування" коду - справа всього декількох кліків і послідовних кроків; але завдяки цьому у вас з'явиться плагін, який завжди можна завантажити та встановити на новий сайт без необхідності розбиратися, як він працює, і як усе це було зібрано докупи. Хоча часом досить цікаво розумітися на тому, як все влаштовано в роботі WordPress і як змінити ті чи інші налаштування. Якщо темна тема оформлення та виділення вам не до смаку, то можете внести власні налаштування в CSS для впровадження нових стилів "підсвічування", що більше підійде дизайну вашого сайту.
Коментарі до запису: 2
А чому цей плагін не підтримує кирилицю, він її кракозябрами виводить
Напевно, тому, що цей плагін не розрахований на підтримку кирилиці. Спробуйте Syntax Highlighter.