This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
class CodeColorer {
var $blocks = array();
var $comments = array();
var $geshiPath = '';
var $samplePhpCode = '
[cc_php]
/**
* Comment
*/
function hello() {
echo "Hello!";
return null;
}
exit();
[/cc_php]
';
/** Search content for code tags and replace it */
function BeforeHighlightCodeBlock($content) {
$content = preg_replace('#(\s*)\[cc([^\s\]_]*(?:_[^\s\]]*)?)([^\]]*)\](.*?)\[/cc\2\](\s*)#sie', '$this->PerformHighlightCodeBlock(\'\\4\', \'\\3\', $content, \'\\2\', \'\\1\', \'\\5\');', $content);
$content = preg_replace('#(\s*)\(.*?)\(\s*)#sie', '$this->PerformHighlightCodeBlock(\'\\3\', \'\\2\', $content, \'\', \'\\1\', \'\\4\');', $content);
return $content;
}
function AfterHighlightCodeBlock($content) {
$content = str_replace(array_keys($this->blocks), array_values($this->blocks), $content);
$this->blocks = array();
return $content;
}
function BeforeProtectComment($content) {
$content = preg_replace('#\s*(\[cc[^\s\]_]*(?:_[^\s\]]*)?[^\]]*\].*?\[/cc\1\])\s*#sie', '$this->PerformHighlightCodeBlock(\'\\3\', \'\\2\', $content, \'\\1\');', $content);
$content = preg_replace('#\s*(\.*?\)\s*#sie', '$this->PerformProtectComment(\'\\1\', $content);', $content);
return $content;
}
function AfterProtectComment($content) {
$content = str_replace(array_keys($this->comments), array_values($this->comments), $content);
$this->comments = array();
return $content;
}
/**
* Perform code highlightning
*/
function PerformHighlightCodeBlock($text, $opts, $content, $suffix = '', $before = '', $after = '') {
// Preprocess source text
$text = str_replace(array("\\\"", "\\\'"), array ("\"", "\'"), $text);
$text = preg_replace('/(< \?php)/i', '' . $text . '';
} else {
// See if we should force a height
$num_lines = count(explode("\n", $text));
$result = $this->PerformHighlightGeshi($text, $options);
$result = $this->AddContainer($result, $options, $num_lines);
}
if ($options['inline']) {
$blockID = $this->GetBlockID($content, false, '', '');
} else {
$blockID = $this->GetBlockID($content);
}
$this->blocks[$blockID] = $result;
if ($options['inline']) {
$result = $before . $blockID . $after;
} else {
$result = "\n\n$blockID\n\n";
}
return $result;
}
/**
* Perform code protecting from mangling by Wordpress (used in Comments)
*/
function PerformProtectComment($text, $content) {
$text = str_replace(array("\\\"", "\\\'"), array ("\"", "\'"), $text);
$blockID = $this->GetBlockID($content, true, '', '');
$this->comments[$blockID] = $text;
return "\n\n" . $blockID . "\n\n";
}
/**
* Perform code highlighting using GESHi engine
*/
function PerformHighlightGeshi($content, $options) {
/* Geshi configuration */
if (!$this->geshi) {
$this->geshi = new GeSHi();
$this->geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS, 1);
if (is_feed()) {
$this->geshi->set_overall_style('padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap');
}
}
$geshi = $this->geshi;
$geshi->set_source($content);
$geshi->set_language($options['lang']);
$geshi->set_overall_class('codecolorer');
$geshi->set_tab_width($options['tab_size']);
if (!is_feed()) {
$geshi->enable_classes();
if ($options['nowrap']) {
$geshi->set_overall_style('white-space:nowrap');
} else {
$geshi->set_overall_style('');
}
}
if (!is_null($options['strict'])) $geshi->enable_strict_mode($options['strict']);
if ($options['no_links']) $geshi->enable_keyword_links(false);
if ($options['inline']) {
$geshi->set_header_type(GESHI_HEADER_NONE);
} else {
$geshi->set_header_type(GESHI_HEADER_DIV);
}
$result = $geshi->parse_code();
if ($geshi->error()) {
return $geshi->error();
}
if ($options['line_numbers'] && !$options['inline']) {
$table = ' | ') + 1; $i < $count; $i++) {
$table .= ($i + $options['first_line']) . '
';
}
$result = $table . '' . $result . ' |
';
}
return $result;
}
function AddContainer($html, $options, $num_lines) {
if ($options['inline']) {
$theme = empty($options['inline_theme']) ? 'default' : $options['inline_theme'];
$result = '';
$result .= '' . $html . '';
$result .= '';
} else {
$theme = empty($options['theme']) ? 'default' : $options['theme'];
$style = 'style="';
if ($options['nowrap']) $style .= 'overflow:auto;white-space:nowrap;';
if (is_feed()) $style .= 'border: 1px solid #9F9F9F;';
$style .= $this->GetDimensionRule('width', is_feed() ? $options['rss_width'] : $options['width']);
if($num_lines > $options['lines'] && $options['lines'] > 0) {
$style .= $this->GetDimensionRule('height', $options['height']);
}
$style .= '"';
$css_class = 'codecolorer-container ' . $options['lang'] . ' ' . $theme;
if ($options['noborder']) $css_class .= ' codecolorer-noborder';
$result = '' . $html . '
';
}
return $result;
}
/**
* Generate a block ID that will be replaced at the end (after all that
* crazy WP text work!) with the right code
*/
function GetBlockID($content, $comment = false, $before = '', $after = '
') {
static $num = 0;
$block = $comment ? 'COMMENT' : 'BLOCK';
$before = $before . '::CODECOLORER_' . $block . '_';
$after = '::' . $after;
// Just do a check to make sure the user
// hasn't (however unlikely) input block replacements
// as legit text
do {
++$num;
$blockID = $before . $num . $after;
} while (strpos($content, $blockID) !== false);
return $blockID;
}
function GetDimensionRule($dimension, $value) {
$rule = '';
if (!empty($value)) $rule = "$dimension:$value" . (is_numeric($value) ? 'px;' : ';');
return $rule;
}
function ShowOptionsPage() {
$page = $this->GetOptionsPage();
$page->Show();
}
function GetOptionsPage() {
if (!$this->optionsPage) {
if (!class_exists('CodeColorerAdmin')) {
$path = dirname(__FILE__);
if (!file_exists("$path/codecolorer-admin.php")) return false;
require_once("$path/codecolorer-admin.php");
}
$this->optionsPage = new CodeColorerAdmin($this);
}
return $this->optionsPage;
}
function GetSampleCodeHighlighted() {
$content = $this->BeforeHighlightCodeBlock($this->samplePhpCode);
return $this->AfterHighlightCodeBlock($content);
}
/**
* Returns the instance of the Sitemap Generator
*/
function &GetInstance() {
if (isset($GLOBALS['codecolorer_instance'])) {
return $GLOBALS['codecolorer_instance'];
}
return null;
}
/**
* Enables the Google Sitemap Generator and registers the WordPress hooks
*
* @since 3.0
* @access public
* @author Arne Brachhold
*/
function Enable() {
if (!isset($GLOBALS['codecolorer_instance'])) {
if (class_exists('GeSHi')) return false;
$path = dirname(__FILE__);
if (!class_exists('CodeColorerOptions')) {
if (!file_exists("$path/codecolorer-options.php")) return false;
require_once("$path/codecolorer-options.php");
}
if (!file_exists("$path/lib/geshi.php")) return false;
require_once("$path/lib/geshi.php");
$GLOBALS['codecolorer_instance'] = new CodeColorer();
}
return true;
}
}