summaryrefslogtreecommitdiff
path: root/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php')
-rw-r--r--extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php220
1 files changed, 101 insertions, 119 deletions
diff --git a/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php b/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
index 7318574d..6d1f73c7 100644
--- a/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
+++ b/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php
@@ -1,5 +1,22 @@
<?php
+/**
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
class SyntaxHighlight_GeSHi {
/**
* Has GeSHi been initialised this session?
@@ -28,12 +45,6 @@ class SyntaxHighlight_GeSHi {
// Don't trim leading spaces away, just the linefeeds
$text = preg_replace( '/^\n+/', '', $text );
- if( $wgUseTidy ) {
- // HTML Tidy will convert tabs to spaces incorrectly (bug 30930).
- // Preemptively replace the spaces in a more controlled fashion.
- $text = self::tabsToSpaces( $text );
- }
-
// Validate language
if( isset( $args['lang'] ) && $args['lang'] ) {
$lang = $args['lang'];
@@ -101,8 +112,14 @@ class SyntaxHighlight_GeSHi {
if( $enclose === GESHI_HEADER_DIV ) {
$out = str_replace( "\n", '', $out );
}
+ // HTML Tidy will convert tabs to spaces incorrectly (bug 30930).
+ // But the conversion from tab to space occurs while reading the input,
+ // before the conversion from &#9; to tab, so we can armor it that way.
+ if( $wgUseTidy ) {
+ $out = str_replace( "\t", '&#9;', $out );
+ }
// Register CSS
- $parser->getOutput()->addHeadItem( self::buildHeadItem( $geshi ), "source-{$lang}" );
+ $parser->getOutput()->addModuleStyles( "ext.geshi.language.$lang" );
if ( $wgUseSiteCss ) {
$parser->getOutput()->addModuleStyles( 'ext.geshi.local' );
@@ -199,15 +216,8 @@ class SyntaxHighlight_GeSHi {
* @return int
*/
static function getEncloseType( $args ) {
- // Since version 1.0.8 geshi can produce valid pre, but we need to check for it
- if ( defined('GESHI_HEADER_PRE_VALID') ) {
- $pre = GESHI_HEADER_PRE_VALID;
- } else {
- $pre = GESHI_HEADER_PRE;
- }
-
// "Enclose" parameter
- $enclose = $pre;
+ $enclose = GESHI_HEADER_PRE_VALID;
if ( isset( $args['enclose'] ) ) {
if ( $args['enclose'] === 'div' ) {
$enclose = GESHI_HEADER_DIV;
@@ -216,51 +226,10 @@ class SyntaxHighlight_GeSHi {
}
}
- if( isset( $args['line'] ) && $pre === GESHI_HEADER_PRE ) {
- // Force <div> 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;
- }
-
return $enclose;
}
/**
- * Hook into Article::view() to provide syntax highlighting for
- * custom CSS and JavaScript pages.
- *
- * B/C for MW 1.20 and before. 1.21 and later use renderHook() instead.
- *
- * @param string $text
- * @param Title $title
- * @param OutputPage $output
- * @return bool
- */
- public static function viewHook( $text, $title, $output ) {
- global $wgUseSiteCss;
- // Determine the language
- $matches = array();
- preg_match( '!\.(css|js)$!u', $title->getText(), $matches );
- $lang = isset( $matches[1] ) && $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 ) );
- $output->addHTML( "<div dir=\"ltr\">{$out}</div>" );
- if( $wgUseSiteCss ) {
- $output->addModuleStyles( 'ext.geshi.local' );
- }
- return false;
- }
- }
- // Bottle out
- return true;
- }
-
- /**
* Hook into Content::getParserOutput to provide syntax highlighting for
* script content.
*
@@ -268,10 +237,11 @@ class SyntaxHighlight_GeSHi {
* @since MW 1.21
*/
public static function renderHook( Content $content, Title $title,
- ParserOptions $options, $generateHtml, ParserOutput &$output
+ $revId, ParserOptions $options, $generateHtml, ParserOutput &$output
) {
- global $wgSyntaxHighlightModels, $wgUseSiteCss;
+ global $wgSyntaxHighlightModels, $wgUseSiteCss,
+ $wgParser, $wgTextModelsToParse;
// Determine the language
$model = $content->getModel();
@@ -281,16 +251,22 @@ class SyntaxHighlight_GeSHi {
}
if ( !$generateHtml ) {
- // Nothing to do.
- return false;
+ // Nothing special for us to do, let MediaWiki handle this.
+ return true;
}
// Hope that $wgSyntaxHighlightModels does not contain silly types.
- $text = Contenthandler::getContentText( $content );
+ $text = ContentHandler::getContentText( $content );
if ( $text === null || $text === false ) {
- // Oops! Non-text content?
- return false;
+ // Oops! Non-text content? Let MediaWiki handle this.
+ return true;
+ }
+
+ // Parse using the standard parser to get links etc. into the database, HTML is replaced below.
+ // We could do this using $content->fillParserOutput(), but alas it is 'protected'.
+ if ( $content instanceof TextContent && in_array( $model, $wgTextModelsToParse ) ) {
+ $output = $wgParser->parse( $text, $title, $options, true, true, $revId );
}
$lang = $wgSyntaxHighlightModels[$model];
@@ -302,12 +278,14 @@ class SyntaxHighlight_GeSHi {
$out = $geshi->parse_code();
if( !$geshi->error() ) {
// Done
- $output->addHeadItem( self::buildHeadItem( $geshi ), "source-$lang" );
+ $output->addModuleStyles( "ext.geshi.language.$lang" );
$output->setText( "<div dir=\"ltr\">{$out}</div>" );
if( $wgUseSiteCss ) {
$output->addModuleStyles( 'ext.geshi.local' );
}
+
+ // Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
return false;
}
}
@@ -320,8 +298,6 @@ class SyntaxHighlight_GeSHi {
* Initialise a GeSHi object to format some code, performing
* common setup for all our uses of it
*
- * @note Used only until MW 1.20
- *
* @param string $text
* @param string $lang
* @return GeSHi
@@ -350,40 +326,66 @@ class SyntaxHighlight_GeSHi {
}
}
+ /**
+ * GeSHi comes by default with a font-family set to monospace, which
+ * causes the font-size to be smaller than one would expect.
+ * We append a CSS hack to the default GeSHi styles: specifying 'monospace'
+ * twice "resets" the browser font-size specified for monospace.
+ *
+ * The hack is documented in MediaWiki core under
+ * docs/uidesign/monospace.html and in bug 33496.
+ */
+ // Preserve default since we don't want to override the other style
+ // properties set by geshi (padding, font-size, vertical-align etc.)
+ $geshi->set_code_style(
+ 'font-family: monospace, monospace;',
+ /* preserve defaults = */ true
+ );
+
+ // No need to preserve default (which is just "font-family: monospace;")
+ // outputting both is unnecessary
+ $geshi->set_overall_style(
+ 'font-family: monospace, monospace;',
+ /* preserve defaults = */ false
+ );
+
return $geshi;
}
/**
* Prepare a CSS snippet suitable for use as a ParserOutput/OutputPage
- * head item
+ * head item.
+ *
+ * Not used anymore, kept for backwards-compatibility with other extensions.
*
+ * @deprecated
* @param GeSHi $geshi
* @return string
*/
public static function buildHeadItem( $geshi ) {
- /**
- * Geshi comes by default with a font-family set to monospace which
- * ends ultimately ends up causing the font-size to be smaller than
- * one would expect (causing bug 26204).
- * We append to the default geshi style a CSS hack which is to specify
- * monospace twice which "reset" the browser font-size specified for monospace.
- *
- * The hack is documented in MediaWiki core under
- * docs/uidesign/monospace.html and in bug 33496.
- */
- $geshi->set_code_style( 'font-family: monospace, monospace;',
- /** preserve defaults */ true );
+ wfDeprecated( __METHOD__ );
+ $css = array();
+ $css[] = '<style type="text/css">/*<![CDATA[*/';
+ $css[] = self::getCSS( $geshi );
+ $css[] = '/*]]>*/';
+ $css[] = '</style>';
+ return implode( "\n", $css );
+ }
+ /**
+ * Get the complete CSS code necessary to display styles for given GeSHi instance.
+ *
+ * @param GeSHi $geshi
+ * @return string
+ */
+ public static function getCSS( $geshi ) {
$lang = $geshi->language;
$css = array();
- $css[] = '<style type="text/css">/*<![CDATA[*/';
$css[] = ".source-$lang {line-height: normal;}";
$css[] = ".source-$lang li, .source-$lang pre {";
$css[] = "\tline-height: normal; border: 0px none white;";
$css[] = "}";
- $css[] = $geshi->get_stylesheet( false );
- $css[] = '/*]]>*/';
- $css[] = '</style>';
+ $css[] = $geshi->get_stylesheet( /*$economy_mode*/ false );
return implode( "\n", $css );
}
@@ -472,7 +474,7 @@ class SyntaxHighlight_GeSHi {
* @param $extensionTypes
* @return bool
*/
- public static function hSpecialVersion_GeSHi( &$extensionTypes ) {
+ public static function extensionTypes( &$extensionTypes ) {
global $wgExtensionCredits;
self::initialise();
$wgExtensionCredits['parserhook']['SyntaxHighlight_GeSHi']['version'] = GESHI_VERSION;
@@ -480,43 +482,23 @@ class SyntaxHighlight_GeSHi {
}
/**
- * @see SyntaxHighlight_GeSHi::hSpecialVersion_GeSHi
- * @param $sp
- * @param $extensionTypes
- * @return bool
- */
- public static function hOldSpecialVersion_GeSHi( &$sp, &$extensionTypes ) {
- return self::hSpecialVersion_GeSHi( $extensionTypes );
- }
-
- /**
- * Convert tabs to spaces
+ * Register a ResourceLoader module providing styles for each supported language.
*
- * @param string $text
- * @return string
+ * @param ResourceLoader $resourceLoader
+ * @return bool true
*/
- private static function tabsToSpaces( $text ) {
- $lines = explode( "\n", $text );
- $lines = array_map( array( __CLASS__, 'tabsToSpacesLine' ), $lines );
- return implode( "\n", $lines );
- }
-
- /**
- * Convert tabs to spaces for a single line
- *
- * @param $line
- * @internal param string $text
- * @return string
- */
- private static function tabsToSpacesLine( $line ) {
- $parts = explode( "\t", $line );
- $width = 8; // To match tidy's config & typical browser defaults
- $out = $parts[0];
- foreach( array_slice( $parts, 1 ) as $chunk ) {
- $spaces = $width - (strlen( $out ) % $width);
- $out .= str_repeat( ' ', $spaces );
- $out .= $chunk;
+ public static function resourceLoaderRegisterModules( &$resourceLoader ) {
+ $modules = array();
+
+ foreach ( self::getSupportedLanguages() as $lang ) {
+ $modules["ext.geshi.language.$lang" ] = array(
+ 'class' => 'ResourceLoaderGeSHiModule',
+ 'lang' => $lang,
+ );
}
- return $out;
+
+ $resourceLoader->register( $modules );
+
+ return true;
}
}