forked from moodlehq/moodle-filter_geshi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.php
182 lines (158 loc) · 6.41 KB
/
filter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
// This file is part of Moodle - http://moodle.org/
//
// GeSHi syntax highlight filter for Moodle
// Based on work by Grigory Rubtsov <[email protected]>, 2005
//
// Uses GeSHi syntax highlighter 1.0.7.5
// http://qbnz.com/highlighter/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package filter_geshi
* @copyright 2005 Nigel McNie <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/filter/geshi/geshi/geshi.php');
//
// DEFAULT CONFIGURATION
//
// Configure the GeSHi filter here
//
// Line numbers: set to true to have them on by default
$CFG->geshifilter_linenumbers = false;
// Keyword to URL conversion: set to true to have this conversion made
$CFG->geshifilter_urls = true;
// Indent Size: controls the number of spaces that are substituted for a tab
$CFG->geshifilter_indentsize = 4;
class filter_geshi extends moodle_text_filter {
// Highlight code enclosed by <span syntax="langname"> </span>, with options:
// linenumbers="yes": Enable line numbers
// urls="yes": Enable keyword-to-URL conversion
// indentsize="num": Switch tabs for this many spaces. Be warned! Only TABS are replaced.
public function filter($text, array $options = array()) {
if (stripos($text, '<code>') !== false) {
$search = '/<code(.*?)>(.*?)<\/code>\s*/is';
} else if (stripos($text, '<php>') !== false) {
$search = '/<php(.*?)>(.*?)<\/php>\s*/is';
} else if (stripos($text, 'syntax=') !== false) {
$search = '/<span (.*?)>(.*?)<\/span>\s*/is';
} else {
return $text;
}
return preg_replace_callback($search, 'self::geshi_filter_callback', $text);
}
protected function geshi_filter_callback($data) {
global $CFG;
//echo 'data as inputted:';
//geshi_dbg($data);
$options = array(
'syntax' => 'php',
'linenumbers' => $CFG->geshifilter_linenumbers,
'urls' => $CFG->geshifilter_urls,
'indentsize' => $CFG->geshifilter_indentsize,
'inline' => 'no'
);
if (isset($data[2])) {
// Get the options that the user set in the <span> tag
$chosen_options = explode(' ', $data[1]);
//echo 'chosen options RAW:';
//geshi_dbg($chosen_options);
foreach ($chosen_options as $key => $option) {
unset($chosen_options[$key]);
$parts = explode('=', $option);
if (!isset($parts[1])) { // MD to avoid notice
continue; // MD
} // MD
$parts[1] = (($parts[1] && '"' == $parts[1][0])) ? substr($parts[1], 1) : $parts[1];
$parts[1] = (($parts[1] && '"' == $parts[1][strlen($parts[1]) - 1])) ? substr($parts[1], 0, -1) : $parts[1];
//echo 'parts:';
//geshi_dbg($parts);
//if ($parts[1]) {
$chosen_options[$parts[0]] = $parts[1];
//}
}
$chosen_options_keys = array_keys($chosen_options);
//echo 'chosen options processed';
//geshi_dbg($chosen_options);
// Set options
foreach (array_keys($options) as $key) {
if (in_array($key, $chosen_options_keys)) {
$options[$key] = $chosen_options[$key];
}
}
//echo 'options as set:';
//var_dump($options);
if (is_null($options['syntax'])) {
return $data[0];
}
if ('' == $options['syntax']) {
return '<pre>' . $data[2] . '</pre>';
}
// BC for original plugin
if ('_' == $options['syntax'][0]) {
$options['linenumbers'] = true;
$options['syntax'] = substr($options['syntax'], 1);
}
// Because GeSHi uses html4strict as language name for
// HTML, we should convert the more common "HTML" here.
if ('html' == $options['syntax']) {
$options['syntax'] = 'html4strict';
}
$code = self::geshi_filter_decode_special_chars(self::geshi_filter_br2nl($data[2]));
$geshi = new GeSHi($code, $options['syntax']);
$geshi->enable_classes(false);
$geshi->set_overall_style('font-family: monospace;');
$header = $footer = '';
if (self::geshi_is_yes($options['inline'])) {
$geshi->set_header_type(GESHI_HEADER_NONE);
$header = '<span style="font-family:monospace;" class="' . $options['syntax'] . '">';
$footer = '</span>';
} else {
if (self::geshi_is_yes($options['linenumbers'])) {
$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, 5);
$geshi->set_line_style('color:#222;', 'color:#888;');
$geshi->set_header_type(GESHI_HEADER_DIV);
$geshi->set_overall_style('font-size: 14px;font-family: monospace;', true);
}
if ($options['indentsize']) {
$geshi->set_tab_width($options['indentsize']);
$geshi->set_header_type(GESHI_HEADER_DIV);
}
}
if (!self::geshi_is_yes($options['urls'])) {
for ($i = 0; $i < 5; $i++) {
$geshi->set_url_for_keyword_group($i, '');
}
}
return $header . $geshi->parse_code() . $footer;
}
}
static public function geshi_filter_br2nl($str) {
return preg_replace("'<br\s*\/?>\r?\n?'","\n",$str);
}
static public function geshi_filter_decode_special_chars($str) {
// analog of htmlspecialchars_decode in PHP 5
$search = array("&",""", "<", ">","\","'");
$replace = array("&","\"", "<", ">","\\","\'");
return str_replace($search, $replace, $str);
}
static public function geshi_is_yes ($str) {
return ('yes' == $str || '1' == $str);
}
static public function geshi_dbg($input) {
echo '<pre>' . htmlspecialchars(print_r($input, true)) . '</pre>';
}
}