mode to maintain valid XHTML, see // http://sourceforge.net/tracker/index.php?func=detail&aid=1201963&group_id=114997&atid=670231 $enclose = GESHI_HEADER_DIV; $geshi->enable_line_numbers( GESHI_FANCY_LINE_NUMBERS ); } // Starting line number if( isset( $args['start'] ) ) $geshi->start_line_numbers_at( $args['start'] ); $geshi->set_header_type( $enclose ); // Strict mode if( isset( $args['strict'] ) ) $geshi->enable_strict_mode(); // Format $out = $geshi->parse_code(); $err = $geshi->error(); if( $err ) { // Error! return self::formatError( $err ); } else { // Armour for Parser::doBlockLevels() if( $enclose == GESHI_HEADER_DIV ) $out = str_replace( "\n", '', $out ); // Register CSS $parser->mOutput->addHeadItem( self::buildHeadItem( $geshi ), "source-{$lang}" ); return $out; } } /** * Hook into Article::view() to provide syntax highlighting for * custom CSS and JavaScript pages * * @param string $text * @param Title $title * @param OutputPage $output * @return bool */ public static function viewHook( &$text, $title, $output ) { // Determine the language preg_match( '!\.(css|js)$!u', $title->getText(), $matches ); $lang = $matches[1] == 'css' ? 'css' : 'javascript'; // Attempt to format $geshi = self::prepare( $text, $lang ); if( $geshi instanceof GeSHi ) { $out = $geshi->parse_code(); if( !$geshi->error() ) { // Done $output->addHeadItem( "source-$lang", self::buildHeadItem( $geshi ) ); $text = $out; return false; } } // Bottle out return true; } /** * Initialise a GeSHi object to format some code, performing * common setup for all our uses of it * * @param string $text * @param string $lang * @return GeSHi */ private static function prepare( $text, $lang ) { self::initialise(); $geshi = new GeSHi( $text, $lang ); if( $geshi->error() == GESHI_ERROR_NO_SUCH_LANG ) return null; $geshi->set_encoding( 'UTF-8' ); $geshi->enable_classes(); $geshi->set_overall_class( "source-$lang" ); $geshi->enable_keyword_links( false ); return $geshi; } /** * Prepare a CSS snippet suitable for use as a ParserOutput/OutputPage * head item * * @param GeSHi $geshi * @return string */ private static function buildHeadItem( $geshi ) { global $wgUseSiteCss, $wgSquidMaxage; $lang = $geshi->language; $css[] = ''; return implode( "\n", $css ); } /** * Format an error message * * @param string $error * @return string */ private static function formatError( $error = '' ) { $html = ''; if( $error ) $html .= "

{$error}

"; $html .= '

' . htmlspecialchars( wfMsgForContent( 'syntaxhighlight-specify' ) ) . ' <source lang="html">...</source>

' . '

' . htmlspecialchars( wfMsgForContent( 'syntaxhighlight-supported' ) ) . '

' . self::formatLanguages(); return "
{$html}
"; } /** * Format the list of supported languages * * @return string */ private static function formatLanguages() { $langs = self::getSupportedLanguages(); $list = array(); if( count( $langs ) > 0 ) { for( $i = 0; $i < count( $langs ); $i++ ) { if( preg_match( '!/([^\.]+)\.php$!u', $langs[$i], $m ) ) $list[] = '' . $m[1] . ''; } return '

' . implode( ', ', $list ) . '

'; } else { return '

' . htmlspecialchars( wfMsgForContent( 'syntaxhighlight-err-loading' ) ) . '

'; } } /** * Get the list of supported languages * * @return array */ private static function getSupportedLanguages() { if( !is_array( self::$languages ) ) { self::initialise(); self::$languages = glob( GESHI_LANG_ROOT . "/*.php" ); sort( self::$languages ); } return self::$languages; } /** * Initialise messages and ensure the GeSHi class is loaded */ private static function initialise() { global $wgMessageCache; if( !self::$initialised ) { require_once( dirname( __FILE__ ) . '/SyntaxHighlight_GeSHi.i18n.php' ); foreach( efSyntaxHighlight_GeSHiMessages() as $lang => $messages ) $wgMessageCache->addMessages( $messages, $lang ); if( !class_exists( 'GeSHi' ) ) require( 'geshi/geshi.php' ); self::$initialised = true; } } }