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; } }