| 1 |
<?php
|
| 2 |
/*
|
| 3 |
Modules Name: Coolfilter
|
| 4 |
Modules URI: http://drupal.org/node/61357
|
| 5 |
Description: Adds syntax highlighting and line number to your code, base on Text_Highlighter.
|
| 6 |
Version: 2.9
|
| 7 |
Author: andot,liukan transplant to drupal
|
| 8 |
Author URI: http://www.kylinx.net/ & coolcode.cn
|
| 9 |
*/
|
| 10 |
//include_once 'coolfilter.module';
|
| 11 |
//================================================================================
|
| 12 |
// Download the code
|
| 13 |
//================================================================================
|
| 14 |
|
| 15 |
|
| 16 |
//================================================================================
|
| 17 |
// Get the PEAR path, and include the CoolCode
|
| 18 |
//================================================================================
|
| 19 |
$pear_dir = "/var/www/localhost/htdocs/drupal5/drupal/modules/coolfilter/pear";
|
| 20 |
|
| 21 |
if(is_dir($pear_dir))
|
| 22 |
ini_set("include_path", ini_get("include_path") . PATH_SEPARATOR . $pear_dir);
|
| 23 |
|
| 24 |
require_once 'Text/Highlighter.php';
|
| 25 |
|
| 26 |
//================================================================================
|
| 27 |
// Create our custom highlighter, then add the filters
|
| 28 |
// We have sets - before and after, which are performed before and
|
| 29 |
// after all of the other filters. This is to bypass any filters
|
| 30 |
// that do crazy text replacements. It's easier this way, instead of
|
| 31 |
// trying to undo what the other filters did.
|
| 32 |
//================================================================================
|
| 33 |
/*
|
| 34 |
$CoolCode = new CoolCode();
|
| 35 |
|
| 36 |
// Showing
|
| 37 |
add_filter('the_content', array(&$CoolCode, 'part_one'), -1000);
|
| 38 |
add_filter('the_content', array(&$CoolCode, 'part_two'), 1000);
|
| 39 |
|
| 40 |
add_filter('the_excerpt', array(&$CoolCode, 'part_one'), -1000);
|
| 41 |
add_filter('the_excerpt', array(&$CoolCode, 'part_two'), 1000);
|
| 42 |
|
| 43 |
add_filter('comment_text', array(&$CoolCode, 'part_one'), -1000);
|
| 44 |
add_filter('comment_text', array(&$CoolCode, 'part_two'), 1000);
|
| 45 |
|
| 46 |
add_action('wp_head', array(&$CoolCode, 'add_css'));
|
| 47 |
add_action('wp_head', array(&$CoolCode, 'add_js'));
|
| 48 |
|
| 49 |
unset($CoolCode);
|
| 50 |
*/
|
| 51 |
class CoolCode
|
| 52 |
{
|
| 53 |
// The languages the Text_Highlighter can accept
|
| 54 |
var $acceptable_lang = array('php', 'cpp', 'css', 'diff', 'dtd', 'javascript', 'html',
|
| 55 |
'mysql', 'perl', 'python', 'ruby', 'sql', 'xml', 'java', 'actionscript');
|
| 56 |
|
| 57 |
var $hl_class = array('class="hl-default"', 'class="hl-code"', 'class="hl-brackets"',
|
| 58 |
'class="hl-comment"', 'class="hl-quotes"', 'class="hl-string"',
|
| 59 |
'class="hl-identifier"', 'class="hl-builtin"', 'class="hl-reserved"',
|
| 60 |
'class="hl-inlinedoc"', 'class="hl-var"', 'class="hl-url"',
|
| 61 |
'class="hl-special"', 'class="hl-number"', 'class="hl-inlinetags"');
|
| 62 |
|
| 63 |
var $hl_style = array('style="color: Black;"', 'style="color: Gray;"', 'style="color: Olive;"',
|
| 64 |
'style="color: #ffa500;"', 'style="color: #8b0000;"', 'style="color: Red;"',
|
| 65 |
'style="color: Blue;"', 'style="color: Teal;"' ,'style="color: Green;"',
|
| 66 |
'style="color: Blue;"', 'style="color: #00008b;"', 'style="color: Blue;"',
|
| 67 |
'style="color: Navy;"', 'style="color: Maroon;"', 'style="color: Blue;"');
|
| 68 |
|
| 69 |
// The blocks array that holds the block ID's and their real code blocks
|
| 70 |
var $blocks = array();
|
| 71 |
|
| 72 |
/****************************************************************************
|
| 73 |
* part_one
|
| 74 |
* > Replace the code blocks with the block IDs
|
| 75 |
****************************************************************************/
|
| 76 |
function part_one($content)
|
| 77 |
{
|
| 78 |
$search = strtolower($content);
|
| 79 |
$pos = 0;
|
| 80 |
while (true) {
|
| 81 |
$count = 0;
|
| 82 |
$pos1 = strpos($search, "<coolcode", $pos);
|
| 83 |
$pos2 = strpos($search, "[coolcode", $pos);
|
| 84 |
if ($pos1 === false) {
|
| 85 |
if ($pos2 === false) {
|
| 86 |
return $content;
|
| 87 |
}
|
| 88 |
else {
|
| 89 |
$pos = $pos2;
|
| 90 |
$bracket = array('[', ']');
|
| 91 |
}
|
| 92 |
}
|
| 93 |
else {
|
| 94 |
if ($pos2 === false) {
|
| 95 |
$pos = $pos1;
|
| 96 |
$bracket = array('<', '>');
|
| 97 |
}
|
| 98 |
else if ($pos1 < $pos2) {
|
| 99 |
$pos = $pos1;
|
| 100 |
$bracket = array('<', '>');
|
| 101 |
}
|
| 102 |
else {
|
| 103 |
$pos = $pos2;
|
| 104 |
$bracket = array('[', ']');
|
| 105 |
}
|
| 106 |
}
|
| 107 |
$start = $pos++;
|
| 108 |
$count = 1;
|
| 109 |
while ($count > 0) {
|
| 110 |
$pos1 = strpos($search, $bracket[0] . "coolcode", $pos);
|
| 111 |
$pos2 = strpos($search, $bracket[0] . "/coolcode" . $bracket[1], $pos);
|
| 112 |
if ($pos1 === false) {
|
| 113 |
if ($pos2 === false) {
|
| 114 |
return $content;
|
| 115 |
}
|
| 116 |
else {
|
| 117 |
$pos = $pos2;
|
| 118 |
$count--;
|
| 119 |
}
|
| 120 |
}
|
| 121 |
else {
|
| 122 |
if ($pos2 === false) {
|
| 123 |
$pos = $pos1;
|
| 124 |
$count++;
|
| 125 |
}
|
| 126 |
else if ($pos1 < $pos2) {
|
| 127 |
$pos = $pos1;
|
| 128 |
$count++;
|
| 129 |
}
|
| 130 |
else {
|
| 131 |
$pos = $pos2;
|
| 132 |
$count--;
|
| 133 |
}
|
| 134 |
}
|
| 135 |
$pos++;
|
| 136 |
}
|
| 137 |
$end = $pos + 10;
|
| 138 |
$code = substr($content, $start, $end - $start);
|
| 139 |
$code = preg_replace('#^\<coolcode(.*?)\>(.*)\</coolcode\>$#sie', '$this->do_CoolCode($code, \'\\2\', \'\\1\');', $code);
|
| 140 |
$code = preg_replace('#^\[coolcode(.*?)\](.*)\[/coolcode\]$#sie', '$this->do_CoolCode($code, \'\\2\', \'\\1\');', $code);
|
| 141 |
$content = substr($content, 0, $start) . $code . substr($content, $end);
|
| 142 |
$search = strtolower($content);
|
| 143 |
$pos = $start + strlen($code);
|
| 144 |
}
|
| 145 |
return $content;
|
| 146 |
}
|
| 147 |
|
| 148 |
/****************************************************************************
|
| 149 |
* part_two
|
| 150 |
* > Replace the block ID's from part one with the actual code blocks
|
| 151 |
****************************************************************************/
|
| 152 |
function part_two($content)
|
| 153 |
{
|
| 154 |
if (count($this->blocks)) {
|
| 155 |
$content = str_replace(array_keys($this->blocks), array_values($this->blocks), $content);
|
| 156 |
$this->blocks = array();
|
| 157 |
}
|
| 158 |
|
| 159 |
return $content;
|
| 160 |
}
|
| 161 |
/****************************************************************************
|
| 162 |
* do_CoolCode
|
| 163 |
* > Perform the code highlighting that is to be replaced with a block ID
|
| 164 |
****************************************************************************/
|
| 165 |
function do_CoolCode($content, $txt, $options)
|
| 166 |
{
|
| 167 |
//global $post;
|
| 168 |
$options = str_replace(array("\\\"", "\\\'"), array("\"", "\'"), $options);
|
| 169 |
if (preg_match('/lang="(\w*?)"/i', $options, $match)) {
|
| 170 |
$lang = $match[1];
|
| 171 |
}
|
| 172 |
else {
|
| 173 |
$lang = "";
|
| 174 |
}
|
| 175 |
if (preg_match('/linenum="(\w*?)"/i', $options, $match)) {
|
| 176 |
$linenum = $match[1];
|
| 177 |
}
|
| 178 |
else {
|
| 179 |
$linenum = "on";
|
| 180 |
}
|
| 181 |
if (preg_match('/download="(.*?)"/i', $options, $match)) {
|
| 182 |
$download = $match[1];
|
| 183 |
}
|
| 184 |
else {
|
| 185 |
$download = "";
|
| 186 |
}
|
| 187 |
$txt = str_replace("\\\"", "\"", $txt);
|
| 188 |
$txt = trim($txt);
|
| 189 |
$txt = str_replace("\r\n", "\n", $txt);
|
| 190 |
$txt = str_replace("\r", "\n", $txt);
|
| 191 |
$blockID = $this->getBlockID($content);
|
| 192 |
if ($download == "") {
|
| 193 |
$this->blocks[$blockID] = '';
|
| 194 |
}
|
| 195 |
else {
|
| 196 |
//global $nid;
|
| 197 |
$this->blocks[$blockID] = '<div class="hl-title">Download Code: <a href="#coolcode_download">' . htmlspecialchars($download) . '</a></div>';
|
| 198 |
|
| 199 |
}
|
| 200 |
|
| 201 |
$hackphp = false;
|
| 202 |
|
| 203 |
if (strtolower($lang) == 'php') {
|
| 204 |
if (strpos($txt, '<' . '?') === false) {
|
| 205 |
$txt = '<' . "?php\n" . $txt . "\n?" . '>';
|
| 206 |
$hackphp = true;
|
| 207 |
}
|
| 208 |
}
|
| 209 |
|
| 210 |
if ((strtolower($linenum) == 'on') or (strtolower($linenum) == 'open')) {
|
| 211 |
if(!in_array(strtolower($lang), $this->acceptable_lang)) {
|
| 212 |
$this->blocks[$blockID] .= '<div class="hl-surround"><ol class="hl-main ln-show" '
|
| 213 |
. 'title="Double click to hide line number." '
|
| 214 |
. 'ondblclick = "linenumber(this)"><li class="hl-firstline">'
|
| 215 |
. str_replace("\n", "</li>\n<li>", htmlspecialchars($txt))
|
| 216 |
. '</li></ol></div>';
|
| 217 |
$this->blocks[$blockID] = str_replace("<li></li>", "<li> </li>", $this->blocks[$blockID]);
|
| 218 |
$this->blocks[$blockID] = str_replace('<li> ', '<li> ', $this->blocks[$blockID]);
|
| 219 |
}
|
| 220 |
else
|
| 221 |
{
|
| 222 |
$options = array(
|
| 223 |
'numbers' => HL_NUMBERS_LI,
|
| 224 |
);
|
| 225 |
$hl =& Text_Highlighter::factory($lang, $options);
|
| 226 |
$this->blocks[$blockID] .= '<div class="hl-surround">' . str_replace($this->hl_class, $this->hl_style, $hl->highlight($txt)) . '</div>';
|
| 227 |
$this->blocks[$blockID] = preg_replace('/<span style=\"[^\"]*?\"><\/span>/', '', $this->blocks[$blockID]);
|
| 228 |
$this->blocks[$blockID] = str_replace('<ol class="hl-main">',
|
| 229 |
'<ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)">',
|
| 230 |
$this->blocks[$blockID]);
|
| 231 |
$this->blocks[$blockID] = str_replace("\"> </span></li>", "\"> </span></li>", $this->blocks[$blockID]);
|
| 232 |
$this->blocks[$blockID] = preg_replace('/<li><span style=(.*?)> </si', '<li><span style=\\1> <', $this->blocks[$blockID]);
|
| 233 |
|
| 234 |
if ($hackphp) {
|
| 235 |
$this->blocks[$blockID] = str_replace("<span style=\"color: Blue;\"><?php</span></li>\n<li>", '', $this->blocks[$blockID]);
|
| 236 |
$this->blocks[$blockID] = str_replace('<li><span style="color: Blue;">?></span></li>', '', $this->blocks[$blockID]);
|
| 237 |
}
|
| 238 |
}
|
| 239 |
}
|
| 240 |
else {
|
| 241 |
if(!in_array(strtolower($lang), $this->acceptable_lang)) {
|
| 242 |
$this->blocks[$blockID] .= '<div class="hl-surround"><div class="hl-main">'
|
| 243 |
. str_replace("\n", "<br />", htmlspecialchars($txt))
|
| 244 |
. '</div></div>';
|
| 245 |
}
|
| 246 |
else
|
| 247 |
{
|
| 248 |
$hl =& Text_Highlighter::factory($lang);
|
| 249 |
$this->blocks[$blockID] .= '<div class="hl-surround">' . str_replace("\n", "<br />", str_replace("</pre>", "", str_replace("<pre>", "", str_replace($this->hl_class, $this->hl_style, $hl->highlight($txt))))) . '</div>';
|
| 250 |
|
| 251 |
if ($hackphp) {
|
| 252 |
$this->blocks[$blockID] = str_replace('<span style="color: Blue;"><?php</span><span style="color: Gray;"><br /></span>', '', $this->blocks[$blockID]);
|
| 253 |
$this->blocks[$blockID] = str_replace('<br /></span><span style="color: Blue;">?></span>', '</span>', $this->blocks[$blockID]);
|
| 254 |
}
|
| 255 |
}
|
| 256 |
$this->blocks[$blockID] = str_replace('<br /> ', '<br /> ', $this->blocks[$blockID]);
|
| 257 |
}
|
| 258 |
|
| 259 |
// correct the indent
|
| 260 |
$this->blocks[$blockID] = str_replace(" ", ' ', $this->blocks[$blockID]);
|
| 261 |
$this->blocks[$blockID] = str_replace(" ", ' ', $this->blocks[$blockID]);
|
| 262 |
|
| 263 |
return $blockID;
|
| 264 |
}
|
| 265 |
|
| 266 |
/****************************************************************************
|
| 267 |
* getBlockID
|
| 268 |
* > Generate a block ID that will be replaced at the end (after all that
|
| 269 |
* crazy WP text work!) with the right code
|
| 270 |
****************************************************************************/
|
| 271 |
function getBlockID($content)
|
| 272 |
{
|
| 273 |
static $num = 0;
|
| 274 |
|
| 275 |
// Just do a check to make sure the user
|
| 276 |
// hasn't (however unlikely) input block replacements
|
| 277 |
// as legit text
|
| 278 |
do
|
| 279 |
{
|
| 280 |
++$num;
|
| 281 |
$blockID = "<p>++CoolCode_BLOCK_$num++</p>";
|
| 282 |
}
|
| 283 |
while(strpos($content, $blockID) !== false);
|
| 284 |
|
| 285 |
return $blockID;
|
| 286 |
}
|
| 287 |
}
|
| 288 |
?>
|