1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Provides the Highlight JS filter.
|
6
|
*
|
7
|
* @author Juned Kazi
|
8
|
*/
|
9
|
|
10
|
/**
|
11
|
* Implement hook_filter_info().
|
12
|
*/
|
13
|
function highlight_js_filter_filter_info() {
|
14
|
$filters['highlight_js'] = array(
|
15
|
'title' => t('Highlight JS Filter'),
|
16
|
'description' => t('Allows users to post code verbatim using <code> and <?php ?> tags.'),
|
17
|
'prepare callback' => '_highlight_js_filter_prepare',
|
18
|
'process callback' => '_highlight_js_filter_process',
|
19
|
'tips callback' => '_highlight_js_filter_tips',
|
20
|
'cache' => TRUE,
|
21
|
);
|
22
|
return $filters;
|
23
|
}
|
24
|
|
25
|
|
26
|
/**
|
27
|
* Tips callback for Highlight JS filter.
|
28
|
*/
|
29
|
function _highlight_js_filter_tips($format, $long = FALSE) {
|
30
|
if ($long) {
|
31
|
return t('To post pieces of code, surround them with <code>...</code> tags.');
|
32
|
}
|
33
|
else {
|
34
|
return t('You may post code using <code>...</code> (generic) tags.');
|
35
|
}
|
36
|
}
|
37
|
|
38
|
/**
|
39
|
* Prepare callback for Highlight JS filter.
|
40
|
*/
|
41
|
function _highlight_js_filter_prepare($text) {
|
42
|
$text = preg_replace_callback('@^<\?php(.+?)\?>@sm', '_highlight_js_filter_escape_code_tag_callback', $text);
|
43
|
$text = preg_replace_callback('@^<code>(.+?)</code>@sm', '_highlight_js_filter_escape_code_tag_callback', $text);
|
44
|
$text = preg_replace_callback('@^<code class="(.+?)">(.+?)</code>@sm', '_highlight_js_filter_escape_code_tag_lang_callback', $text);
|
45
|
return $text;
|
46
|
}
|
47
|
|
48
|
/**
|
49
|
* Callback to escape content of <code> elements.
|
50
|
*/
|
51
|
function _highlight_js_filter_escape_code_tag_callback($matches) {
|
52
|
return highlight_js_filter_escape($matches[1], 'code');
|
53
|
}
|
54
|
|
55
|
/**
|
56
|
* Callback to escape content of <code lang="php"> elements.
|
57
|
*/
|
58
|
function _highlight_js_filter_escape_code_tag_lang_callback($matches) {
|
59
|
return highlight_js_filter_escape($matches[2], 'code', $matches[1]);
|
60
|
}
|
61
|
|
62
|
|
63
|
/**
|
64
|
* Escape code blocks during input filter 'prepare'.
|
65
|
*
|
66
|
* @param $text
|
67
|
* The string to escape.
|
68
|
* @param $type
|
69
|
* The type of code block, either 'code' or 'php'.
|
70
|
* @return
|
71
|
* The escaped string.
|
72
|
*/
|
73
|
function highlight_js_filter_escape($text, $type = 'code', $lang = '') {
|
74
|
// Note, pay attention to odd preg_replace-with-/e behaviour on slashes
|
75
|
$text = check_plain(str_replace('\"', '"', $text));
|
76
|
// Protect newlines from line break converter
|
77
|
$text = str_replace(array("\r", "\n"), array('', ' '), $text);
|
78
|
$lang = empty($lang) ? '' : ' class="' . $lang . '"';
|
79
|
// Add codefilter escape tags
|
80
|
$text = "[highlightjs_$type$lang]{$text}[/highlightjs_$type]";
|
81
|
return $text;
|
82
|
}
|
83
|
|
84
|
|
85
|
|
86
|
function _highlight_js_filter_process($text, $format) {
|
87
|
$text = preg_replace_callback('@\[highlightjs_code\](.+?)\[/highlightjs_code\]@s', '_highlight_js_filter_process_code_callback', $text);
|
88
|
$text = preg_replace_callback('@\[highlightjs_code class="(.+?)"\](.+?)\[/highlightjs_code\]@s', '_highlight_js_filter_process_code_lang_callback', $text);
|
89
|
return $text;
|
90
|
}
|
91
|
|
92
|
/**
|
93
|
* Callback to replace content of the <code> elements.
|
94
|
*/
|
95
|
function _highlight_js_filter_process_code_callback($matches) {
|
96
|
return highlight_js_filter_process_code($matches[1]);
|
97
|
}
|
98
|
|
99
|
/**
|
100
|
* Callback to replace content of the <code> elements.
|
101
|
*/
|
102
|
function _highlight_js_filter_process_code_lang_callback($matches) {
|
103
|
$lang = $matches[1];
|
104
|
$text = $matches[2];
|
105
|
return highlight_js_filter_process_code($text, $lang);
|
106
|
}
|
107
|
|
108
|
|
109
|
/**
|
110
|
* Processes chunks of escaped code into HTML.
|
111
|
*/
|
112
|
function highlight_js_filter_process_code($text, $lang = '') {
|
113
|
// Undo linebreak escaping
|
114
|
$text = str_replace(' ', "\n", $text);
|
115
|
// Inline or block level piece?
|
116
|
$multiline = strpos($text, "\n") !== FALSE;
|
117
|
// Note, pay attention to odd preg_replace-with-/e behaviour on slashes
|
118
|
$text = preg_replace("/^\n/", '', preg_replace('@</?(br|p)\s*/?>@', '', str_replace('\"', '"', $text)));
|
119
|
// Trim leading and trailing linebreaks
|
120
|
$text = trim($text, "\n");
|
121
|
$class = empty($lang) ? '' : ' class="' . $lang . '"';
|
122
|
$text = '<pre><code' . $class . '>' . highlight_js_filter_fix_spaces(str_replace(' ', ' ', $text)) . '</code></pre>';
|
123
|
return $text;
|
124
|
}
|
125
|
|
126
|
|
127
|
function highlight_js_filter_fix_spaces($text) {
|
128
|
return preg_replace('@ (?! )@', ' ', $text);
|
129
|
}
|