I wanted to test the newly-released Prism.js since it promised clean markup and easy plugin development, but I found it was lacking a major feature for my own use: PHP Syntax Highlighting.
So, letting the code be my guide, I present an add-on to Prism.js less than 10 hours after it was released into the wild publicly.
Update: Instead of using the below code-blocks, you can just grab it from my forked repository. The repository has a few other updates and fixes.
The following code snippets can be added into an external .js file or the main prism.js file. The modifications are mainly for testing (read: kinda buggy) and released under the same license Prism itself is.
Add PHP Syntax Highlighting
Prism.languages.php = {
'comment': {
pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|\/\/.*?(\r?\n|$))/g,
lookbehind: true
},
'deliminator': /(\?>|\?>|<\?php|<\?php)/ig,
'variable': /(\$\w+)\b/ig,
'string': /("|')(\\?.)*?\1/g,
'regex': {
pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,
lookbehind: true
},
'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|extends|private|protected|throw)\b/g,
'function': /\b(abs|acos|acosh|addcslashes|addslashes|array_change_key_case|array_chunk|array_combine|array_count_values|array_diff|array_diff_assoc|array_diff_key|array_diff_uassoc|array_diff_ukey|array_fill|array_filter|array_flip|array_intersect|array_intersect_assoc|array_intersect_key|array_intersect_uassoc|array_intersect_ukey|array_key_exists|array_keys|array_map|array_merge|array_merge_recursive|array_multisort|array_pad|array_pop|array_product|array_push|array_rand|array_reduce|array_reverse|array_search|array_shift|array_slice|array_splice|array_sum|array_udiff|array_udiff_assoc|array_udiff_uassoc|array_uintersect|array_uintersect_assoc|array_uintersect_uassoc|array_unique|array_unshift|array_values|array_walk|array_walk_recursive|atan|atan2|atanh|base64_decode|base64_encode|base_convert|basename|bcadd|bccomp|bcdiv|bcmod|bcmul|bindec|bindtextdomain|bzclose|bzcompress|bzdecompress|bzerrno|bzerror|bzerrstr|bzflush|bzopen|bzread|bzwrite|ceil|chdir|checkdate|checkdnsrr|chgrp|chmod|chop|chown|chr|chroot|chunk_split|class_exists|closedir|closelog|copy|cos|cosh|count|count_chars|date|decbin|dechex|decoct|deg2rad|delete|ebcdic2ascii|echo|empty|end|ereg|ereg_replace|eregi|eregi_replace|error_log|error_reporting|escapeshellarg|escapeshellcmd|eval|exec|exit|exp|explode|extension_loaded|feof|fflush|fgetc|fgetcsv|fgets|fgetss|file_exists|file_get_contents|file_put_contents|fileatime|filectime|filegroup|fileinode|filemtime|fileowner|fileperms|filesize|filetype|floatval|flock|floor|flush|fmod|fnmatch|fopen|fpassthru|fprintf|fputcsv|fputs|fread|fscanf|fseek|fsockopen|fstat|ftell|ftok|getallheaders|getcwd|getdate|getenv|gethostbyaddr|gethostbyname|gethostbynamel|getimagesize|getlastmod|getmxrr|getmygid|getmyinode|getmypid|getmyuid|getopt|getprotobyname|getprotobynumber|getrandmax|getrusage|getservbyname|getservbyport|gettext|gettimeofday|gettype|glob|gmdate|gmmktime|ini_alter|ini_get|ini_get_all|ini_restore|ini_set|interface_exists|intval|ip2long|is_a|is_array|is_bool|is_callable|is_dir|is_double|is_executable|is_file|is_finite|is_float|is_infinite|is_int|is_integer|is_link|is_long|is_nan|is_null|is_numeric|is_object|is_readable|is_real|is_resource|is_scalar|is_soap_fault|is_string|is_subclass_of|is_uploaded_file|is_writable|is_writeable|mkdir|mktime|nl2br|parse_ini_file|parse_str|parse_url|passthru|pathinfo|readlink|realpath|rewind|rewinddir|rmdir|round|str_ireplace|str_pad|str_repeat|str_replace|str_rot13|str_shuffle|str_split|str_word_count|strcasecmp|strchr|strcmp|strcoll|strcspn|strftime|strip_tags|stripcslashes|stripos|stripslashes|stristr|strlen|strnatcasecmp|strnatcmp|strncasecmp|strncmp|strpbrk|strpos|strptime|strrchr|strrev|strripos|strrpos|strspn|strstr|strtok|strtolower|strtotime|strtoupper|strtr|strval|substr|substr_compare)\b/g,
'constant': /\b(__FILE__|__LINE__|__METHOD__|__FUNCTION__|__CLASS__)\b/g,
'boolean': /\b(true|false)\b/g,
'number': /\b-?(0x)?\d*\.?\d+\b/g,
'operator': /[-+]{1,2}|!|=?\<|=?\>;|={1,2}(?!>)|(\&){1,2}|\|?\||\?|\*|\//g,
'punctuation': /[{}[\];(),.:]/g
};
Allow embedded HTML in PHP
if (Prism.languages.markup) {
Prism.languages.insertBefore('php', 'comment', {
'markup': {
pattern: /(\?>|\?>)[\w\W]*?(?=(<\?php|<\?php))/ig,
lookbehind : true,
inside: {
'markup': {
pattern: /<\/?[\w:-]+\s*[\w\W]*?>/gi,
inside: Prism.languages.markup.tag.inside
},
rest: Prism.languages.php
}
}
});
}
NOTES / Warnings
This code adds several new language elements named: function, keyword, variable and constant that have no CSS attributed to them, so use this CSS somewhere.
.token.function, .token.constant {
color: #07a;
}
.token.variable {
color: #e90;
}
.token.deliminator {
font-weight:bold;
}
This code has NOT been heavily tested, but has been run successfully against the following block of code:
/**
Sample Block.
Author: Aaron Harun
URL: http://aaron.md, http://aahacreative.com
**/
if(__FILE__){
$explicitive = ($happyandyouknowit == false) ? ':(' : '! =D';
// Stick in some HTML.
?>
<strong>Why,</strong>
<?php
echo 'hello ' . "world" . addslashes($explicitive);
}
It doesn’t cover PHP embedded in HTML yet, but it seems very easy to do. The Repository version has it.
And finally, Prism.js is not running on this site, yet. I’ll have to integrate it into WP before that’s possible. Integrated with WP. Booyah.
Copied the code above and it worked perfectly. Awesome! thanks for this!
Thanks for the contribution. I have a couple suggestion/request if someone could add it. Would really like to add something to make vriable/names in DocComments get wrapped with a CSS class. Also would like to be able to highlight custom Function names with a CSS class
Hello.
I have a little problem with “=>”, try this:
Your escaping is broken. In the last section the HTML after “// Stick in some HTML. ” is double escaped, making it unreadable.
Also, the comments are colored brown which doesn’t go very well against the dark brown background of the code sections on this blog.
(Feel free to remove once taken care of).
It isn’t broken. If you download the github, you’ll see that code needs to be formatted in that way in the examples file.
One minor bug too:
add this
Prism.languages.php = { ‘ignore’: /&(lt|gt|amp);/gi,
and change operator ={1,2} to ={1,2}(?!>)
I second this – otherwise any code with logical AND “&&” is rewritten as “&&”.
Adding the ‘ignore’ line fixes it.
Nice; I just started using this. One minor bug: on line 18, your operator reg exp uses literal ‘<’ and ‘>’ characters rather than the < and > entities (and prism.js on line 93 replaces the characters automatically).
(and I’m still trying to figure out how how coded the cool spinning gears!)