Extension talk:GeSHiHighlight

The instructions state

Don't forget to include GeSHi also: include_once("geshi.php"); 

But it doesn't say WHERE to include this. Any ideas? Geshi seems to be working even though I skipped that particular instruction, except for some problems with the display of the text below the text entry area (where it says DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!)

bad displayed page
I changed the code a bit, with this you don't need to rename anything.


 * 1) you want to change the below three lines

define("GESHI_PATH","../../include/geshi/geshi");// definition where are stored geshi language parsing files require_once(GESHI_PATH."/../geshi.php"); // i assume geshi.php is in the parent directory of the language files define("_LANG_DEFAULT", "java");


 * ok, end of editing :)

function wfSyntaxExtension { global $wgParser, $lang_default; $langArray = geshi_list_languages(GESHI_PATH); foreach ( $langArray as $lang ){ if ($lang == "") continue; $wgParser->setHook('code='.$lang,                       create_function( '$text', '$geshi = new GeSHi(rtrim(ltrim($text,"\n\r")), ' ."$lang". ', GESHI_PATH); return $geshi->parse_code;' )               );        }        $wgParser->setHook('code',		create_function( '$text', '$geshi = new GeSHi(rtrim(ltrim($text,"\n\r")), _LANG_DEFAULT, GESHI_PATH); return $geshi->parse_code;' )       ); }

With this, you can either use &lt;code&gt;&lt;/code&gt; for the default language or &lt;code=language&gt;&lt;/code=language&gt; to specify a language.

Camel Case Option
For languages that are not case sensitive it is nevertheless nice to grant a uniform way of casing keywords through a whole wiki. A GeSHi language file could define a number of keywords written in camel case: for example GetType, SetRecord....

Users often do not comply to the standards and write with mixed case: gETtype, setrEcord.... It doesn't look nice, even if the code might be nevertheless valid.

The patch below defines a new constant in geshi.php: GESHI_CAPS_REPLACE and implements it for replacing the keywords with the corresponding word found in the stored array.

In the geshi.php file find the declaration of the capitalization constants:

// Capatalisation constants /** Lowercase keywords found */ define('GESHI_CAPS_NO_CHANGE', 0); /** Uppercase keywords found */ define('GESHI_CAPS_UPPER', 1); /** Leave keywords found as the case that they are */ define('GESHI_CAPS_LOWER', 2);

add the following line:

define('GESHI_CAPS_REPLACE', 3);

Find the function   and replace it with the following:

function change_case ($instr) {		if ($this->language_data['CASE_KEYWORDS'] == GESHI_CAPS_UPPER) { return strtoupper($instr); } elseif ($this->language_data['CASE_KEYWORDS'] == GESHI_CAPS_LOWER) { return strtolower($instr); /************************		* Orso B. Schmid 01 Jan 2007 * added support for camelCase keywords: * the found keywords will be replaced with the items of the array */		} elseif ($this->language_data['CASE_KEYWORDS'] == GESHI_CAPS_REPLACE) { foreach ($this->language_data['KEYWORDS'] as $nr => $wordset) { $allwords = explode(' ', strtolower(implode(' ', $wordset))); if (in_array(strtolower($instr), $allwords)) { return $wordset[array_search(strtolower($instr), $allwords)]; }			}		}		/************************ */		return $instr; }

The new option should be called in the language file(s):

$language_data = array (	...	'CASE_KEYWORDS' => GESHI_CAPS_REPLACE,	.... )

Real code tag support
The code tag is not truly supported under the last stable version of GeSHi, currently 1.0.7.16. Whatever you do, the code tag converts into block (turns into pre in the html), upsetting a whole wiki content, moreover the classes are not applied to it. It is probably useless, since GeSHi will be updated soon, but there is a fast fix for displaying code tags correctly as inline elements and classes be applied.

In order to achieve this you can modify geshi.php 1.0.7.16:
 * 1) add a new html container: new constant: GESHI_HEADER_CODE
 * 2) update the function  
 * 3) Implement the constant in the function  
 * 4) Implement the constant in the function  


 * Note: this patch in only tested for the version 1.0.7.16!

Add a new constant GESHI_HEADER_CODE
Find the line where the html containers are defined:   and add the following line:

define('GESHI_HEADER_CODE', 3);

Update header type
Find the function   and replace the line

if (GESHI_HEADER_DIV != $type && GESHI_HEADER_PRE != $type && GESHI_HEADER_NONE != $type) {

with the line:

if (GESHI_HEADER_DIV != $type && GESHI_HEADER_PRE != $type && GESHI_HEADER_NONE != $type && GESHI_HEADER_CODE != $type) {

Implement in the function 'header'
Find the function   and replace the block:

// Work out what to return and do it		if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { if ($this->header_type == GESHI_HEADER_PRE) { return "$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "$header"; }		} else { if ($this->header_type == GESHI_HEADER_PRE) { return "$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "$header"; }		} With the block:

// Work out what to return and do it		if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { if ($this->header_type == GESHI_HEADER_PRE) { return "$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "$header"; } 		} else { if ($this->header_type == GESHI_HEADER_PRE) { return "$header"; } elseif ($this->header_type == GESHI_HEADER_DIV) { return "$header"; }			# Orso B. Schmid 01 Jan 2007: fast fix for ''' and replace the block:

if ($this->header_type == GESHI_HEADER_DIV) { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "$footer_content "; }			return "$footer_content "; } else { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "$footer_content"; }			return "$footer_content"; } with the block:

if ($this->header_type == GESHI_HEADER_DIV) { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "</ol>$footer_content "; }			return "$footer_content "; } elseif ($this->header_type == GESHI_HEADER_PRE) { if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) { return "</ol>$footer_content <//pre> "; }			return "$footer_content<//pre>"; } 		# Orso B. Schmid 01 Jan 2007: fast fix for ";		} Please replace the //	with / in the pre tag! It seems that it is not possible to escape an ending pre tag within a pre tag!!!!!

Use the constant GESHI_HEADER_CODE
Now you can call your GeSHi objects in GeSHihiglight as follows, specifying GESHI_HEADER_CODE for code tags elements. In the example below two new tags are created for every installed language file: a code=... and a pre=... tag. For all created geshi objects classes are enabled. Remove what you don't need. Or add other options as explained in the official GeSHi documentation

You can use pre or div or now code according to your needs. If you specify a default for code it remains now inline.

It is advisable to remove unused language files.

function wfSyntaxExtension { global $wgParser, $lang_default; $langArray = geshi_list_languages(GESHI_PATH); foreach ( $langArray as $lang ){ if ($lang == "") continue; # use GESHI_HEADER_CODE to preserve inline code. $wgParser->setHook('code='.$lang,			create_function( '$text', '$geshi = new GeSHi(rtrim(ltrim($text,"\n\r")), ' ."$lang". ', GESHI_PATH); $geshi->set_header_type(GESHI_HEADER_CODE); $geshi->enable_classes(true); return $geshi->parse_code;' )		);		# use GESHI_HEADER_PRE or GESHI_HEADER_DIV for block elements. $wgParser->setHook('pre='.$lang,			create_function( '$text', '$geshi = new GeSHi(rtrim(ltrim($text,"\n\r")), ' ."$lang". ', GESHI_PATH); $geshi->set_header_type(GESHI_HEADER_PRE); $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS, 1); $geshi->enable_classes(true); return $geshi->parse_code;' )		);	}	$wgParser->setHook('code',		create_function( '$text', '$geshi = new GeSHi(rtrim(ltrim($text,"\n\r")), _LANG_DEFAULT, GESHI_PATH); $geshi->set_header_type(GESHI_HEADER_CODE); $geshi->enable_classes(true); return $geshi->parse_code;' )	);

}

I'm no PHP programmer, so the patch most likely can be optimized. It works fine under MediaWiki 1.8.2.

--Orso B. Schmid 06:50, 3 January 2007 (UTC)