Location: PHPKode > projects > BusinessWiki > extensions/CodeSyntaxHighlight.php
<?php
 # Code syntax highlighting extension for MediaWiki using the GeSHi engine.
 # See http://qbnz.com/highlighter/ for more info about GeSHi.
 # Written by Clinton Woodward hide@address.com for SwinBrain
 #
 # Usage in mediawiki
 #  <code>[lang,line_no,start_at,range(1-4,6-7)]...</ code>
 # Examples
 #  <code>[lang]...</ code> // line_no default=Y, start_at default=1
 #  <code>[lang,N]...</ code> // no line numbers
 #  <code>[lang,5]...</ code> // start at line 5 (with line numbers
 #  <code>[lang,Y,5]...</ code> // deprecated - same as above
 #                             // ('Y' is implied by start_at)
 #  <code>[lang,1,(3-5,7)]...</ code> // mark lines 3,4,5 and 7
 #
 #  - lang is required, others are optional
 #  - line_no default is Y, start_at is default to 1
 #
 # version 1, started 25th August 2005
 # version 2, added 29th August, 2005
 # version 2.1, 19th October 2005
 #  - cleanup for SwinBrain release.
 #  - moved to the ByteClub wiki and added lots of languages
 # version 3, 2006-04-05
 #  - added changes from Jocelyn Fiat to allow single line code
 #  - altered args behaviour, deprecated implicit line_no='Y' when start_at given.
 #  - added support for the mark-range argument eg. (1,3,5-7)
 #  - removed case-sensitivity for 'Y'/'N' arg value
 # version 4, 2006-12-12
 #  - added attribute based parameters instead of old pre mediawiki 1.5 [...] method
 #  - <code lang="lang" numbers="Y|N" startat="#" range="1-3,6,9">...</ code>
 #  -       
 
$wgExtensionFunctions[] = 'wfCodeSyntaxHighlight';
 
$cshLanguages = array (
  'actionscript','ada','apache','asm','c','cpp','eiffel','ini','html','xhtml',
  'java','java5','css','js','javascript','vbnet','csharp','pascal','xml','php',
  'delphi','bash','perl','lisp','matlab','mpasm','objc','vb','smarty','vhdl',
  'ruby','sql','python','pseudocode','qbasic','scheme','oracle8','dos','text');
 
// See: http://qbnz.com/highlighter/geshi-doc.html
include_once('extensions/CodeSyntaxHighlight/geshi.php');
define('CSH_GESHI_PATH','extensions/CodeSyntaxHighlight/geshi');
 
 
function wfCodeSyntaxHighlight() {
  global $wgParser, $cshLanguages;
  # register the extension with the WikiText parser
  $wgParser->setHook('code', 'renderCodeSyntaxHighlight');
}
 
# The callback function for converting the input text to HTML output
function renderCodeSyntaxHighlight($source, $args=array()) 
{
  global $cshLanguages;
  
  // defaults
  $source = trim($source);  // remove any unwanted whitespace 
  $lang = '';
  $line_no = 'Y';
  $line_start = 1;
  $line_range = '';
 
  // are there args? use them
  if (isset($args['lang'])) {
    
    // find the matching language
    $lang = (in_array($args['lang'],$cshLanguages)) ? $args['lang'] : '';
    // check for the special langlist request
    if ($args['lang']=='langlist') {
      sort($cshLanguages); // sort so its easy to read
      return 'Current enabled languages: <code class="csh">'.implode(', ',$cshLanguages).'.</ code>';
    }
    // show line numbers?
    $line_no = (isset($args['numbers']) && strtoupper($args['numbers'])=='Y') ? 'Y' : 'N';   
    // start at? implies numbers='Y'
    if (isset($args['startat']) && is_numeric($args['startat'])) {
      $line_no = 'Y';
      $line_start = $args['startat'] ;
    }
    // range? implies range="..."
    if (isset($args['range'])) {
      $line_no = 'Y';
      $line_range = getCSHMarkRange(trim('('.$args['range'].')'));
    }
        
  }
  // use the old [...] syntax for parameters
  else {
    
    // extract the required args [...]
    $lines = explode("\n",$source);
    $args = trim($lines[0]);
    
    // Is there a [..] section?
    if (strpos($args,'[')===0 && strpos($args,']')!==false) 
    {
      
      // extract the args values, trim off the [] characters.
      $eofargspos = strpos($args, ']');
      $args = explode(',', substr($args, 1, $eofargspos - 1));
      // Language? Is it one of the one we have enabled?
      if (in_array($args[0],$cshLanguages)) {
          $lang = $args[0];
      }
      // Is this the special "list the languages" command?
      elseif ($args[0] == 'langlist') {
          sort($cshLanguages); // sort so its easy to read
          return 'Current enabled languages: <code>'.implode(', ',$cshLanguages).'.</ code>';
      }
      else {
          $lang = '';
      }
      
      // Show line numbers/start line no?
      if (isset($args[1])) {
        if(is_numeric($args[1])) {
          $line_no = 'Y'; // implied by the presence of a start line number
          $line_start = intval($args[1]);
          if(isset($args[2])) {
              $line_range = getCSHMarkRange(trim($lines[0])); // give the whole arg string
          }
        }
        else {
          $line_no = (strtoupper($args[1]) == 'Y') ? 'Y' : 'N';
          // start line given? May be irrelevant if 'N' set :)
          if(isset($args[2]) && is_numeric($args[2])) {
              $line_start = intval($args[2]);
          }
        }
      }
 
      // Get rid of the now used first bit of [...] info, implode and trim
      $lines[0] = trim(substr($lines[0], $eofargspos + 1, strlen($lines[0])));
      $source = trim(implode("\n",$lines));
 
    }
  } // end old [...] syntax
  
  
  if ($lang !== '') 
  {
 
    // Remap any languages?
    if ($lang == 'pascal') { $lang = 'delphi'; } // looks better
    if ($lang == 'js') { $lang = 'javascript'; } // shortcut
    if ($lang == 'html') { $lang = 'html4strict'; } // shortcut
    if ($lang == 'xhtml') { $lang = 'html4strict'; } // remap
 
    // Create the GeSHi parser object, tell it what it needs...
    $geshi = new GeSHi($source, $lang, CSH_GESHI_PATH);
 
    // turn line numbers on?
    if ($line_no == 'Y') {
      // add to remove the extra line height we didn't like to see in mediawiki
      $norm = 'border: 0px solid green; margin: -1px; padding: 0;';
      $geshi->set_line_style($norm);
      $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS,0);
      if(is_array($line_range)) {
        $mark = 'background-color:#FFFFF0; color: red; font-weight: bold;';
        $geshi->set_highlight_lines_extra_style($mark);
        $geshi->highlight_lines_extra($line_range);
      }
    }
    // start line numbering at ...
    $geshi->start_line_numbers_at($line_start);
 
    // parse the output, hand it back.
    $output = $geshi->parse_code();
    return '<div class="csh">'.$output.'</div>';
 
  }
  else {
    // If it's not for us, catch and return with <code>...</ code> 
    return '<code>'.htmlentities($source).'</ code>';
  }
} // end renderCodeSyntaxHighlight()
 
function getCSHMarkRange($str)
{
  // get the (...) substring as an array of int values
  $start = strpos($str,'(')+1;
  $end = strpos($str,')');
  $str = substr($str,$start,$end-$start);
  // break into parts
  $tmp = explode(',',$str);
  foreach($tmp as $key=>$val) {
    // expand the 4-7 type ranges and replace in $tmp
    if(strpos($val,'-')) {
      list($start,$end) = explode('-',$val);
      for($i=$start; $i<=$end; $i++) $tmp[] = $i;
      unset($tmp[$key]);
    }
  }
  return $tmp;
}
Return current item: BusinessWiki