on the line).
+ // So the source output looks like this:
+ //
+ //
+ //
+
+
+
GeSHi examples
+
+
+
+
GeSHi Example Script
+
To use this script, make sure that geshi.php is in the parent directory or in your
+include_path, and that the language files are in a subdirectory of GeSHi's directory called geshi/.
+
Enter your source and a language to highlight the source in and submit, or just choose a language to
+have that language file highlighted in PHP.
+parse_code();
+ echo '
';
+}
+?>
+
+
+
+
diff --git a/html/includes/geshi/contrib/langcheck.php b/html/includes/geshi/contrib/langcheck.php
new file mode 100755
index 000000000..0a2ca3282
--- /dev/null
+++ b/html/includes/geshi/contrib/langcheck.php
@@ -0,0 +1,666 @@
+Failed
";
+ echo "
\n";
+ foreach($error_cache as $error_msg) {
+ echo "- ";
+ switch($error_msg['t']) {
+ case TYPE_NOTICE:
+ echo "NOTICE:";
+ break;
+ case TYPE_WARNING:
+ echo "WARNING:";
+ break;
+ case TYPE_ERROR:
+ echo "ERROR:";
+ break;
+ }
+ echo " " . $error_msg['m'] . "
";
+ }
+ echo "
\n";
+ } else {
+ echo "
OK";
+ }
+ echo "\n";
+
+ $error_cache = array();
+}
+
+function report_error($type, $message) {
+ global $error_cache, $error_abort;
+
+ $error_cache[] = array('t' => $type, 'm' => $message);
+ if(TYPE_ERROR == $type) {
+ $error_abort = true;
+ }
+}
+
+?>
+
+
+
+
GeSHi Language File Validation Script
+
+
+
+
GeSHi Language File Validation Script
+
To use this script, make sure that geshi.php is in the
+parent directory or in your include_path, and that the language files are in a
+subdirectory of GeSHi's directory called geshi/.
+
Everything else will be done by this script automatically. After the script
+finished you should see messages of what could cause trouble with GeSHi or where
+your language files can be improved. Please be patient, as this might take some time.
+
+
+- Checking where to find GeSHi installation ... \n
- Listing available language files ... ";
+
+ if (!($dir = @opendir(GESHI_LANG_ROOT))) {
+ report_error(TYPE_ERROR, 'Error requesting listing for available language files!');
+ }
+
+ $languages = array();
+
+ if(!$error_abort) {
+ while ($file = readdir($dir)) {
+ if (!$file || $file[0] == '.' || strpos($file, '.') === false) {
+ continue;
+ }
+ $lang = substr($file, 0, strpos($file, '.'));
+ $languages[] = $lang;
+ }
+ closedir($dir);
+ }
+
+ $languages = array_unique($languages);
+ sort($languages);
+
+ if(!count($languages)) {
+ report_error(TYPE_WARNING, 'Unable to locate any usable language files in "'.GESHI_LANG_ROOT.'"!');
+ }
+
+ output_error_cache();
+}
+
+if (isset($_REQUEST['show']) && in_array($_REQUEST['show'], $languages)) {
+ $languages = array($_REQUEST['show']);
+}
+
+if(!$error_abort) {
+ foreach ($languages as $lang) {
+ echo "
\n- Validating language file for '$lang' ... ";
+
+ $langfile = GESHI_LANG_ROOT . $lang . '.php';
+
+ unset($language_data);
+
+ if(!is_file($langfile)) {
+ report_error(TYPE_ERROR, 'The path "' .$langfile. '" does not ressemble a regular file!');
+ } else if(!is_readable($langfile)) {
+ report_error(TYPE_ERROR, 'Cannot read file "' .$langfile. '"!');
+ } else {
+ $langfile_content = file_get_contents($langfile);
+ if(preg_match("/\?>(?:\r?\n|\r(?!\n)){2,}\Z/", $langfile_content)) {
+ report_error(TYPE_ERROR, 'Language file contains trailing empty lines at EOF!');
+ }
+ if(!preg_match("/\?>(?:\r?\n|\r(?!\n))?\Z/", $langfile_content)) {
+ report_error(TYPE_ERROR, 'Language file contains no PHP end marker at EOF!');
+ }
+ if(preg_match("/\t/", $langfile_content)) {
+ report_error(TYPE_NOTICE, 'Language file contains unescaped tabulator chars (probably for indentation)!');
+ }
+ if(preg_match('/^(?: )*(?! )(?! \*) /m', $langfile_content)) {
+ report_error(TYPE_NOTICE, 'Language file contains irregular indentation (other than 4 spaces per indentation level)!');
+ }
+
+ if(!preg_match("/\/\*\*((?!\*\/).)*?Author:((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not contain a specification of an author!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?Copyright:((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not contain a specification of the copyright!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?Release Version:((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not contain a specification of the release version!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?Date Started:((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not contain a specification of the date it was started!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?This file is part of GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not state that it belongs to GeSHi!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?language file for GeSHi\.((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not state that it is a language file for GeSHi!');
+ }
+ if(!preg_match("/\/\*\*((?!\*\/).)*?GNU General Public License((?!\*\/).)*?\*\//s", $langfile_content)) {
+ report_error(TYPE_WARNING, 'Language file does not state that it is provided under the terms of the GNU GPL!');
+ }
+
+ unset($langfile_content);
+
+ include $langfile;
+
+ if(!isset($language_data)) {
+ report_error(TYPE_ERROR, 'Language file does not contain a $language_data structure to check!');
+ } else if (!is_array($language_data)) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data structure which is not an array!');
+ }
+ }
+
+ if(!$error_abort) {
+ if(!isset($language_data['LANG_NAME'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'LANG_NAME\'] specification!');
+ } else if (!is_string($language_data['LANG_NAME'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'LANG_NAME\'] specification which is not a string!');
+ }
+
+ if(!isset($language_data['COMMENT_SINGLE'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_SIGNLE\'] structure to check!');
+ } else if (!is_array($language_data['COMMENT_SINGLE'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_SINGLE\'] structure which is not an array!');
+ }
+
+ if(!isset($language_data['COMMENT_MULTI'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'COMMENT_MULTI\'] structure to check!');
+ } else if (!is_array($language_data['COMMENT_MULTI'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_MULTI\'] structure which is not an array!');
+ }
+
+ if(isset($language_data['COMMENT_REGEXP'])) {
+ if (!is_array($language_data['COMMENT_REGEXP'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'COMMENT_REGEXP\'] structure which is not an array!');
+ }
+ }
+
+ if(!isset($language_data['QUOTEMARKS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'QUOTEMARKS\'] structure to check!');
+ } else if (!is_array($language_data['QUOTEMARKS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'QUOTEMARKS\'] structure which is not an array!');
+ }
+
+ if(isset($language_data['HARDQUOTE'])) {
+ if (!is_array($language_data['HARDQUOTE'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HARDQUOTE\'] structure which is not an array!');
+ }
+ }
+
+ if(!isset($language_data['ESCAPE_CHAR'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'ESCAPE_CHAR\'] specification to check!');
+ } else if (!is_string($language_data['ESCAPE_CHAR'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification which is not a string!');
+ } else if (1 < strlen($language_data['ESCAPE_CHAR'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'ESCAPE_CHAR\'] specification is not empty or exactly one char!');
+ }
+
+ if(!isset($language_data['CASE_KEYWORDS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_KEYWORDS\'] specification!');
+ } else if (!is_int($language_data['CASE_KEYWORDS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is not an integer!');
+ } else if (GESHI_CAPS_NO_CHANGE != $language_data['CASE_KEYWORDS'] &&
+ GESHI_CAPS_LOWER != $language_data['CASE_KEYWORDS'] &&
+ GESHI_CAPS_UPPER != $language_data['CASE_KEYWORDS']) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_KEYWORDS\'] specification which is neither of GESHI_CAPS_NO_CHANGE, GESHI_CAPS_LOWER nor GESHI_CAPS_UPPER!');
+ }
+
+ if(!isset($language_data['KEYWORDS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'KEYWORDS\'] structure to check!');
+ } else if (!is_array($language_data['KEYWORDS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'KEYWORDS\'] structure which is not an array!');
+ } else {
+ foreach($language_data['KEYWORDS'] as $kw_key => $kw_value) {
+ if(!is_integer($kw_key)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$kw_key' in \$language_data['KEYWORDS'] that is not integer!");
+ } else if (!is_array($kw_value)) {
+ report_error(TYPE_ERROR, "Language file contains a \$language_data['CASE_SENSITIVE']['$kw_value'] structure which is not an array!");
+ }
+ }
+ }
+
+ if(!isset($language_data['SYMBOLS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SYMBOLS\'] structure to check!');
+ } else if (!is_array($language_data['SYMBOLS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SYMBOLS\'] structure which is not an array!');
+ }
+
+ if(!isset($language_data['CASE_SENSITIVE'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'CASE_SENSITIVE\'] structure to check!');
+ } else if (!is_array($language_data['CASE_SENSITIVE'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'CASE_SENSITIVE\'] structure which is not an array!');
+ } else {
+ foreach($language_data['CASE_SENSITIVE'] as $cs_key => $cs_value) {
+ if(!is_integer($cs_key)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$cs_key' in \$language_data['CASE_SENSITIVE'] that is not integer!");
+ } else if (!is_bool($cs_value)) {
+ report_error(TYPE_ERROR, "Language file contains a Case Sensitivity specification for \$language_data['CASE_SENSITIVE']['$cs_value'] which is not a boolean!");
+ }
+ }
+ }
+
+ if(!isset($language_data['URLS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'URLS\'] structure to check!');
+ } else if (!is_array($language_data['URLS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'URLS\'] structure which is not an array!');
+ } else {
+ foreach($language_data['URLS'] as $url_key => $url_value) {
+ if(!is_integer($url_key)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$url_key' in \$language_data['URLS'] that is not integer!");
+ } else if (!is_string($url_value)) {
+ report_error(TYPE_ERROR, "Language file contains a Documentation URL specification for \$language_data['URLS']['$url_value'] which is not a string!");
+ } else if (preg_match('#&([^;]*(=|$))#U', $url_value)) {
+ report_error(TYPE_ERROR, "Language file contains unescaped ampersands (&) in \$language_data['URLS']!");
+ }
+ }
+ }
+
+ if(!isset($language_data['OOLANG'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OOLANG\'] specification!');
+ } else if (!is_int($language_data['OOLANG']) && !is_bool($language_data['OOLANG'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither boolean nor integer!');
+ } else if (false !== $language_data['OOLANG'] &&
+ true !== $language_data['OOLANG'] &&
+ 2 !== $language_data['OOLANG']) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OOLANG\'] specification which is neither of false, true or 2!');
+ }
+
+ if(!isset($language_data['OBJECT_SPLITTERS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'OBJECT_SPLITTERS\'] structure to check!');
+ } else if (!is_array($language_data['OBJECT_SPLITTERS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'OBJECT_SPLITTERS\'] structure which is not an array!');
+ }
+
+ if(!isset($language_data['REGEXPS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'REGEXPS\'] structure to check!');
+ } else if (!is_array($language_data['REGEXPS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'REGEXPS\'] structure which is not an array!');
+ }
+
+ if(!isset($language_data['STRICT_MODE_APPLIES'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STRICT_MODE_APPLIES\'] specification!');
+ } else if (!is_int($language_data['STRICT_MODE_APPLIES'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is not an integer!');
+ } else if (GESHI_MAYBE != $language_data['STRICT_MODE_APPLIES'] &&
+ GESHI_ALWAYS != $language_data['STRICT_MODE_APPLIES'] &&
+ GESHI_NEVER != $language_data['STRICT_MODE_APPLIES']) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STRICT_MODE_APPLIES\'] specification which is neither of GESHI_MAYBE, GESHI_ALWAYS nor GESHI_NEVER!');
+ }
+
+ if(!isset($language_data['SCRIPT_DELIMITERS'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'SCRIPT_DELIMITERS\'] structure to check!');
+ } else if (!is_array($language_data['SCRIPT_DELIMITERS'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'SCRIPT_DELIMITERS\'] structure which is not an array!');
+ }
+
+ if(!isset($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure to check!');
+ } else if (!is_array($language_data['HIGHLIGHT_STRICT_BLOCK'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'HIGHLIGHT_STRICT_BLOCK\'] structure which is not an array!');
+ }
+
+ if(isset($language_data['TAB_WIDTH'])) {
+ if (!is_int($language_data['TAB_WIDTH'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is not an integer!');
+ } else if (1 > $language_data['TAB_WIDTH']) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'TAB_WIDTH\'] specification which is less than 1!');
+ }
+ }
+
+ if(isset($language_data['PARSER_CONTROL'])) {
+ if (!is_array($language_data['PARSER_CONTROL'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'PARSER_CONTROL\'] structure which is not an array!');
+ }
+ }
+
+ if(!isset($language_data['STYLES'])) {
+ report_error(TYPE_ERROR, 'Language file contains no $language_data[\'STYLES\'] structure to check!');
+ } else if (!is_array($language_data['STYLES'])) {
+ report_error(TYPE_ERROR, 'Language file contains a $language_data[\'STYLES\'] structure which is not an array!');
+ } else {
+ $style_arrays = array('KEYWORDS', 'COMMENTS', 'ESCAPE_CHAR',
+ 'BRACKETS', 'STRINGS', 'NUMBERS', 'METHODS', 'SYMBOLS',
+ 'REGEXPS', 'SCRIPT');
+ foreach($style_arrays as $style_kind) {
+ if(!isset($language_data['STYLES'][$style_kind])) {
+ report_error(TYPE_ERROR, "Language file contains no \$language_data['STYLES']['$style_kind'] structure to check!");
+ } else if (!is_array($language_data['STYLES'][$style_kind])) {
+ report_error(TYPE_ERROR, "Language file contains a \$language_data['STYLES\']['$style_kind'] structure which is not an array!");
+ } else {
+ foreach($language_data['STYLES'][$style_kind] as $sk_key => $sk_value) {
+ if(!is_int($sk_key) && ('COMMENTS' != $style_kind && 'MULTI' != $sk_key)
+ && !(('STRINGS' == $style_kind || 'ESCAPE_CHAR' == $style_kind) && 'HARD' == $sk_key)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$sk_key' in \$language_data['STYLES']['$style_kind'] that is not integer!");
+ } else if (!is_string($sk_value)) {
+ report_error(TYPE_WARNING, "Language file contains a CSS specification for \$language_data['STYLES']['$style_kind'][$key] which is not a string!");
+ }
+ }
+ }
+ }
+
+ unset($style_arrays);
+ }
+ }
+
+ if(!$error_abort) {
+ //Initial sanity checks survived? --> Let's dig deeper!
+ foreach($language_data['KEYWORDS'] as $key => $keywords) {
+ if(!isset($language_data['CASE_SENSITIVE'][$key])) {
+ report_error(TYPE_ERROR, "Language file contains no \$language_data['CASE_SENSITIVE'] specification for keyword group $key!");
+ }
+ if(!isset($language_data['URLS'][$key])) {
+ report_error(TYPE_ERROR, "Language file contains no \$language_data['URLS'] specification for keyword group $key!");
+ }
+ if(empty($keywords)) {
+ report_error(TYPE_WARNING, "Language file contains an empty keyword list in \$language_data['KEYWORDS'] for group $key!");
+ }
+ foreach($keywords as $id => $kw) {
+ if(!is_string($kw)) {
+ report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['KEYWORDS'][$key][$id]!");
+ } else if (!strlen($kw)) {
+ report_error(TYPE_ERROR, "Language file contains an empty string entry at \$language_data['KEYWORDS'][$key][$id]!");
+ } else if (preg_match('/^([\(\)\{\}\[\]\^=.,:;\-+\*\/%\$\"\'\?]|&[\w#]\w*;)+$/i', $kw)) {
+ report_error(TYPE_NOTICE, "Language file contains an keyword ('$kw') at \$language_data['KEYWORDS'][$key][$id] which seems to be better suited for the symbols section!");
+ }
+ }
+ if(count($keywords) != count(array_unique($keywords))) {
+ $kw_diffs = array_count_values($keywords);
+ foreach($kw_diffs as $kw => $kw_count) {
+ if($kw_count > 1) {
+ report_error(TYPE_WARNING, "Language file contains per-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key]!");
+ }
+ }
+ }
+ }
+
+ $disallowed_before = "(?|^&";
+ $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
+
+ foreach($language_data['KEYWORDS'] as $key => $keywords) {
+ foreach($language_data['KEYWORDS'] as $key2 => $keywords2) {
+ if($key2 <= $key) {
+ continue;
+ }
+ $kw_diffs = array_intersect($keywords, $keywords2);
+ foreach($kw_diffs as $kw) {
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS'])) {
+ //Check the precondition\post-cindition for the involved keyword groups
+ $g1_pre = $disallowed_before;
+ $g2_pre = $disallowed_before;
+ $g1_post = $disallowed_after;
+ $g2_post = $disallowed_after;
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
+ $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+ $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+ }
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
+ $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+ $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+ }
+
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'])) {
+ $g1_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_BEFORE'];
+ }
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'])) {
+ $g1_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key]['DISALLOWED_AFTER'];
+ }
+
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'])) {
+ $g2_pre = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_BEFORE'];
+ }
+ if(isset($language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'])) {
+ $g2_post = $language_data['PARSER_CONTROL']['KEYWORDS'][$key2]['DISALLOWED_AFTER'];
+ }
+
+ if($g1_pre != $g2_pre || $g1_post != $g2_post) {
+ continue;
+ }
+ }
+ report_error(TYPE_WARNING, "Language file contains cross-group duplicate keyword '$kw' in \$language_data['KEYWORDS'][$key] and \$language_data['KEYWORDS'][$key2]!");
+ }
+ }
+ }
+ foreach($language_data['CASE_SENSITIVE'] as $key => $keywords) {
+ if(!isset($language_data['KEYWORDS'][$key]) && $key != GESHI_COMMENTS) {
+ report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['CASE_SENSITIVE'] specification for non-existing keyword group $key!");
+ }
+ }
+ foreach($language_data['URLS'] as $key => $keywords) {
+ if(!isset($language_data['KEYWORDS'][$key])) {
+ report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['URLS'] specification for non-existing keyword group $key!");
+ }
+ }
+ foreach($language_data['STYLES']['KEYWORDS'] as $key => $keywords) {
+ if(!isset($language_data['KEYWORDS'][$key])) {
+ report_error(TYPE_WARNING, "Language file contains an superfluous \$language_data['STYLES']['KEYWORDS'] specification for non-existing keyword group $key!");
+ }
+ }
+
+ foreach($language_data['COMMENT_SINGLE'] as $ck => $cv) {
+ if(!is_int($ck)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_SINGLE'] that is not integer!");
+ }
+ if(!is_string($cv)) {
+ report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_SINGLE'][$ck]!");
+ }
+ if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
+ report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
+ }
+ }
+ if(isset($language_data['COMMENT_REGEXP'])) {
+ foreach($language_data['COMMENT_REGEXP'] as $ck => $cv) {
+ if(!is_int($ck)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$ck' in \$language_data['COMMENT_REGEXP'] that is not integer!");
+ }
+ if(!is_string($cv)) {
+ report_error(TYPE_WARNING, "Language file contains an non-string entry at \$language_data['COMMENT_REGEXP'][$ck]!");
+ }
+ if(!isset($language_data['STYLES']['COMMENTS'][$ck])) {
+ report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['COMMENTS'] specification for comment group $ck!");
+ }
+ }
+ }
+ foreach($language_data['STYLES']['COMMENTS'] as $ck => $cv) {
+ if($ck != 'MULTI' && !isset($language_data['COMMENT_SINGLE'][$ck]) &&
+ !isset($language_data['COMMENT_REGEXP'][$ck])) {
+ report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['COMMENTS'] specification for Single Line or Regular-Expression Comment key $ck!");
+ }
+ }
+ if (isset($language_data['STYLES']['STRINGS']['HARD'])) {
+ if (empty($language_data['HARDQUOTE'])) {
+ report_error(TYPE_NOTICE, "Language file contains superfluous \$language_data['STYLES']['STRINGS'] specification for key 'HARD', but no 'HARDQUOTE's are defined!");
+ }
+ unset($language_data['STYLES']['STRINGS']['HARD']);
+ }
+ foreach($language_data['STYLES']['STRINGS'] as $sk => $sv) {
+ if($sk && !isset($language_data['QUOTEMARKS'][$sk])) {
+ report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['STRINGS'] specification for non-existing quotemark key $sk!");
+ }
+ }
+
+ foreach($language_data['REGEXPS'] as $rk => $rv) {
+ if(!is_int($rk)) {
+ report_error(TYPE_WARNING, "Language file contains an key '$rk' in \$language_data['REGEXPS'] that is not integer!");
+ }
+ if(is_string($rv)) {
+ //Check for unmasked / in regular expressions ...
+ if(empty($rv)) {
+ report_error(TYPE_WARNING, "Language file contains an empty regular expression at \$language_data['REGEXPS'][$rk]!");
+ } else {
+ if(preg_match("/(?)/s", $rv)) {
+ report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '<PIPE>' instead at \$language_data['REGEXPS'][$rk]!");
+ }
+ }
+ } elseif(is_array($rv)) {
+ if(!isset($rv[GESHI_SEARCH])) {
+ report_error(TYPE_ERROR, "Language file contains no GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+ } elseif(!is_string($rv[GESHI_SEARCH])) {
+ report_error(TYPE_ERROR, "Language file contains a GESHI_SEARCH entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+ } else {
+ if(preg_match("/(?)/s", $rv[GESHI_SEARCH])) {
+ report_error(TYPE_WARNING, "Language file contains a regular expression with an unescaped match for a pipe character '|' which needs escaping as '<PIPE>' instead at \$language_data['REGEXPS'][$rk]!");
+ }
+ }
+ if(!isset($rv[GESHI_REPLACE])) {
+ report_error(TYPE_WARNING, "Language file contains no GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+ } elseif(!is_string($rv[GESHI_REPLACE])) {
+ report_error(TYPE_ERROR, "Language file contains a GESHI_REPLACE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+ }
+ if(!isset($rv[GESHI_MODIFIERS])) {
+ report_error(TYPE_WARNING, "Language file contains no GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+ } elseif(!is_string($rv[GESHI_MODIFIERS])) {
+ report_error(TYPE_ERROR, "Language file contains a GESHI_MODIFIERS entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+ }
+ if(!isset($rv[GESHI_BEFORE])) {
+ report_error(TYPE_WARNING, "Language file contains no GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+ } elseif(!is_string($rv[GESHI_BEFORE])) {
+ report_error(TYPE_ERROR, "Language file contains a GESHI_BEFORE entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+ }
+ if(!isset($rv[GESHI_AFTER])) {
+ report_error(TYPE_WARNING, "Language file contains no GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk]!");
+ } elseif(!is_string($rv[GESHI_AFTER])) {
+ report_error(TYPE_ERROR, "Language file contains a GESHI_AFTER entry in extended regular expression at \$language_data['REGEXPS'][$rk] which is not a string!");
+ }
+ } else {
+ report_error(TYPE_WARNING, "Language file contains an non-string and non-array entry at \$language_data['REGEXPS'][$rk]!");
+ }
+ if(!isset($language_data['STYLES']['REGEXPS'][$rk])) {
+ report_error(TYPE_WARNING, "Language file contains no \$language_data['STYLES']['REGEXPS'] specification for regexp group $rk!");
+ }
+ }
+ foreach($language_data['STYLES']['REGEXPS'] as $rk => $rv) {
+ if(!isset($language_data['REGEXPS'][$rk])) {
+ report_error(TYPE_NOTICE, "Language file contains an superfluous \$language_data['STYLES']['REGEXPS'] specification for regexp key $rk!");
+ }
+ }
+
+
+ }
+
+ output_error_cache();
+
+ flush();
+
+ if($error_abort) {
+ break;
+ }
+ }
+}
+?>
+
+
+
Validation process completed in
+$time_end = explode(' ', microtime());
+$time_diff = $time_end[0] + $time_end[1] - $time_start[0] - $time_start[1];
+
+echo sprintf("%.2f", $time_diff);
+?> seconds.
+
+
+
+
diff --git a/html/includes/geshi/docs/BUGS b/html/includes/geshi/docs/BUGS
new file mode 100755
index 000000000..8a5cf0469
--- /dev/null
+++ b/html/includes/geshi/docs/BUGS
@@ -0,0 +1,29 @@
+
+ BUGS - list of known bugs in GeSHi
+ Version 1.0.8
+
+- Number highlighting is quite poor [possibly better now]
+- I'm not happy with URLS - there still could be extra bugs, and it's rather unflexible
+ (see TODO for a possible fix)
+- "Important" sections for some reason seem to have their spans added after every
+ newline up until the next lexic, instead of stopping at the
part. In fact,
+ context sensitiveness is quite poor...
+- Using the extra line number highlighting feature without actually using line numbers
+ will result in malformed XHTML (not sure about this one though...)
+- Slow!!! Especially for source with lots of strings in it. GeSHi will work acceptably
+ for sourcecode under 5K (for simple language files like SQL, a 100K file can be
+ highlighted in just 6 seconds), but above about 25K things get a little slow... If
+ you're using this as part of some larger software, you may want to think about
+ making some sort of "cache" effect to speed things up and reduce server load.
+- The result is built by string replacement instead of by building another string based
+ on the source, that would be much safer. The focus of releases beyond 1.0.7 will be on
+ changing this behaviour, which may well fix some of the other bugs mentioned above.
+- As of 1.0.7.1, dots (.) are allowed before keywords. This may change highlighting of some
+ things slightly, if you notice anything odd about the highlighting then please report
+ it to me.
+- Perl/Javascript /.../ regex syntax is only supported basically and there's no
+ guarantee it is working all the time.
+- The header output is not XHTML compliant. Please use the header instead.
+
+Send any bug reports to BenBE@omorphia.de, or submit them via the bug tracker at
+sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
diff --git a/html/includes/geshi/docs/CHANGES b/html/includes/geshi/docs/CHANGES
new file mode 100755
index 000000000..bab19b195
--- /dev/null
+++ b/html/includes/geshi/docs/CHANGES
@@ -0,0 +1,656 @@
+
+ CHANGES - Changelog for GeSHi (geshi.php only)
+
+Changes to the code are listed under the version they occured in, with who suggested
+it by each one (if there's nobody listed as suggesting it I dreamed it up :)). Users
+who suggested an idea often also provided the code that was used as a basis for the
+changes - thanks to all who suggested these ideas and gave me the code to show me how!
+
+Language files listed under each version were made by the author beside them, and then
+modified by me for consistency/bug fixing.
+
+Please send any bug reports to BenBE@omorphia.de, or use the bug report tracker
+at sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
+
+Version 1.0.8.2
+ - Added language files
+ * Brainfuck \ Brainfork (Benny Baumann)
+ * HQ9+ (Benny Baumann)
+ * INTERCAL (Benny Baumann)
+ * LOLcode (Benny Baumann)
+ * LScript (Beau McGuigan)
+ * Pixel Bender (Richard Olsson)
+ * ProvideX (Jeff Wilder)
+ * VIM Script (Swaroop C H)
+ * Visual Prolog (Thomas Linder Puls)
+ * Whitespace (Benny Baumann)
+ - Changed priority for COMMENT_REGEXP compared to String highlighting (BenBE)
+ - Fixed correct escaping of spaces inside of URLs (BenBE)
+ - Updated the list of common file extensions (BenBE)
+ - Updated the language file check script in contrib/ (BenBE)
+ - Fixed a problem with link targets resulting in unclickable links (SF#2379120, BenBE)
+ - Fixed an undefined variable issue in langcheck.php (BenBE)
+ - Improvements to language files (BenBE)
+ * eMail Header highlighting now uses the correct delimiters for keywords (BenBE)
+ * eMail (RFC822\mbox) highlighting now highlights IPs, MIME types and
+ subfield assignments correctly (BenBE)
+ * Minor style changes in COBOL to improve loading performance (BenBE)
+ * Added some missing keywords for D (BenBE)
+ * Removed duplicate keywords from Progres, SAS and TSQL (BenBE)
+ * Fixed Heredoc Syntax for Bash (SF#2185319, BenBE)
+ * Moved symbol-lookalike sequences from keyword groups to separate symbol group
+ for languages asp, klonec, klonecpp, php, php-brief (BenBE)
+ * Fixed a lot of duplicate keyword warnings (BenBE)
+ * Added missing keywords to the Python language file,
+ introducing support for Python 3.0. (SF#2441839, milian)
+ * Updated documentation links for TypoScript (SF#2014276, BenBE)
+ * Fixed a problem with tag and attribute names in XML highlighting (SF#2276119, BenBE)
+ * Improved MySQL language file (BenBE, JavaWoman)
+ * Some commentss accidentially mistaken for DocComments (SF#2454897, BenBE)
+ * Added improved Escape Char handling for c, c_mac, cpp and cpp_qt (SF#2458743, BenBE)
+Version 1.0.8.1
+ - Added language files
+ * AviSynth (Ryan Jones)
+ * eMail \ mbox (Benny Baumann)
+ * GNU Make (Neil Bird)
+ * Oracle 11i support (Simon Redhead)
+ * Prolog (Benny Baumann)
+ * SciLab (Christophe David)
+ * TeraTerm macro language (Boris Maisuradze)
+ - Added support for Escape Regular Expressions (BenBE)
+ * Implemented C-style Escapes in PHP (BenBE)
+ * Introduced support for \xAB and \007 style Char Escapes in PHP (BenBE)
+ * Implemented Variable Highlighting in PHP (BenBE)
+ * Implemented Variable Highlighting in Bash (milian)
+ - Fixed a problem with PCRE patterns for Keyword matching sometimes producing
+ very large strings, that could not be handled by some versions of PCRE lib,
+ causing broken highlighting an Regexp Compile errors (BenBE, milian)
+ - Fixed broken highlighting of bash commands like `dbus-send --dest=org.....`,
+ i.e. the dest was highlighted as variable declaration (milian)
+ - Fixed broken highlighting of some symbols in their escaped form (BenBE)
+ (
and were accidentially filtered even though they are valid)
+ - Fixed a "memory leak" in the *_regexp_caches (milian)
+ - Fixed broken Escape chars if classes were disabled
+ - start_line_numbers_at() was ignored when GESHI_HEADER_PRE_TABLE was set (revulo)
+ - Fixed a problem allowing Remote Code Inclusion under certain circumstances (BenBE)
+ - Changes to default CSS in order to make the GESHI_HEADER_PRE_TABLE align properly,
+ even on Windows / Mac systems with strange fonts (milian, revulo, ^RT)
+ - Minor style changes to the following languages:
+ * cpp-qt (milian)
+ * MySQL (BenBE)
+ * PHP (BenBE)
+ - Improvements to language files (BenBE, milian)
+ * Added MinSpareThread\MaxSpareThreads to Apache highlighter (BenBE)
+ * Added new Keyword group for APT sources.list highlighter (BenBE)
+ * Fixed highlighting in LaTeX for \begin{} and \end{}, i.e. the stuff inside
+ the curly braces. (milian, thanks for the report go to Matthias Pospiech)
+ * Improved String support for D (BenBE)
+ * MySQL was seriously broken (BenBE)
+ * Reworked Keyword groups for MySQL to allow for more configuration (BenBE)
+ * Improved Mirc script language file (milian)
+ * Improved C++ Qt language file (milian)
+ * Minor bug with Transpose Operator in Matlab (BenBE, Daniele de Rigo)
+ * Highlighting of Batch Files for Windows (BenBE)
+ * Updated AutoIt to include latest changes for AutoIt v3.2.12.1 (BenBE, Thierry)
+ * Fixed duplicate keyword warnings for Perl, Tcl and Typoscript (BenBE)
+ * Fixed Doc-URL getting reparsed by highlighted keywords of other groups (BenBE, Jordi Boggiano)
+Version 1.0.8
+ - Added language files
+ * APT sources.list (milian)
+ * Boo (Marcus Griep)
+ * CIL (Common Intermediate Language, .NET Assembly) (Marcus Griep)
+ * COBOL (Benny Baumann)
+ * Gnuplot (milian)
+ * KLoneC (Mickael Auger)
+ * KLoneC++ (Mickael Auger)
+ * PIC16xxx assembler (Phil Mattison)
+ * POV-Ray (Carl Fürstenberg)
+ * PowerShell (Frode Aarebrot)
+ * Progress (Marco Aurelio de Pasqual)
+ * TypoScript (Jan-Philipp Halle)
+ * Xorg configuration (milian)
+ - Make GeSHi's constructor arguments optional, so something like `$foo = new GeSHi;` is possible. (milian)
+ - Added an optimizer for lists to regular expressions. Using these cached lists results in a speedup of approx. 50%.
+ The slightly increased memory consumption (~150KB for PHP language file) is more than worth it! (milian)
+ - Some more memory & speed optimizations all over GeSHi (milian)
+ * Reduced memory overhead when highlighting keywords (BenBE)
+ * Keyword Linking now uses considerably less strtolower calls (milian)
+ * Cache Symbol Search Regexp and make Symbol Highlighting faster (milian)
+ * Use more native functions like substr_replace and strcasecmp to speed things up (milian)
+ * Use considerably less strlen() calls on various points by caching the results (milian)
+ * Properly set comments to be case insensitive where appropriate to increase performance (milian)
+ * Improve the performance of the strict mode tokenizer, making highlighting of languages like
+ HTML, ColdFusion or XML faster (milian)
+ * Setup caches for parsing on demand to make stylesheet generators fast (milian)
+ - Various improvements to Strict Block Handling (BenBE, milian)
+ * Added support for RegExp-based Strict Blocks (BenBE)
+ * Fixed highlighting incorrectly stopping at ?> in PHP (SF#1330968, BenBE)
+ * Languages with STRICT_MODE_APPLIES = GESHI_MAYBE default to strict mode now. When no highlightable
+ code is found in this mode, we fallback to the same setting as if GESHI_NEVER was set. That way it
+ should not be needed to call enable_strictmode() manually. (milian)
+ - Added new GESHI_HEADER_PRE_VALID type which uses the following markup: (milian)
+ * With line numbers:
+ * Without line numbers: header...CODE...
+ => valid HTML and no need for indentation
+ - Added new GESHI_HEADER_PRE_TABLE type which can be used to prevent linenumber-selection in Firefox
+ on copy'n'paste. (milian)
+ - set_language will not reset any language settings by default anymore.
+ * Added $force_reset param for to force full reload of a language. (milian)
+ * Make sure strict_mode is set properly when doing repeated set_language calls (milian)
+ - Fixed some problems with old PHP versions (SF#1975625, milian, BenBE)
+ - Fixed broken use with Suhosin Patch when /e modifier was disabled (SF#2021800, BenBE)
+ - Added support for external style information files to override language defaults without modifying language files (BenBE)
+ - The overall_class is now up to the user, and the language-code is _always_ added as a class (milian)
+ - Fixed Economy Mode for GeSHi::get_stylesheet() - now it just makes so much more sense! (milian)
+ - Fixed Economy Mode when COMMENT_REGEXP are used (BenBE)
+ - Changed the default encoding to use UTF-8, due to SF#2037598, BenBE)
+ - Improved overall string support:
+ * Added support for multichar string delimiters (SF#1932083, BenBE)
+ * Fixed problems of unfinished strings and comments producing invalid XHTML (SF#1996353, BenBE)
+ * Multichar Quotemarks sometimes had inconsistent behaviour (BenBE)
+ * Support for multiple styles of strings depending on the starter (BenBE)
+ * Properly handle escapes in strings, i.e. '\\' was not working properly before (milian)
+ * Fixed escape char support when an escape char is followed by multi-byte chars (SF#2037598, BenBE)
+ - Improved flexibility in language files (BenBE, milian)
+ * Added PARSER_CONTROL for OOLANG method highlighting (SF#1923060, BenBE)
+ * Added possibility to define strict blocks using an Regexp (BenBE)
+ * Removed explicit escaping of / in Regular Expressions (BenBE)
+ * Ignoring empty keyword groups when highlighting (milian)
+ * Make language_permissions configurable in language files via ['PARSER_CONTROL']['ENABLE_FLAGS']
+ this makes is_a calls unneeded and thus prevents PHP notices in PHP 5.x (milian)
+ * Extended support for number formats now covering the most common formats (SF#1923058, BenBE)
+ * Lifted a limitation that keywords had to have at least 2 subsequent letters (BenBE)
+ * Changed behaviour of PARSER_CONTROL now allowing to provide the full Lookahead and Lookbehind
+ expressions used as delimiters inside keywords instead of a simple char group (BenBE)
+ * Fixed improper handling of newlines in REGEXPS so this does not produce invalid html anylonger (milian)
+ - Some typos and mistakes in the documentation (BenBE)
+ - Added a script to contrib/ to verify language files are correct (BenBE)
+ - Fixed loads of compliancy warnings detected with that automated compliance testing script (BenBE)
+ - Many other improvements to various language files (BenBE, milian)
+ * Reduce strict errors & notices for language files (milian)
+ * Fixed symbol highlighting with C++ sometimes missing keywords after ; and comments (BenBE)
+ * Improved comment handling with TCL (Lars Hellström, BenBE)
+ * Fixed broken handling with XML comments (BenBE, SF#1849233)
+ * Fixed HTML comments spawning multiple lines producing invalid XHTML output (SF#1738173, BenBE)
+ * Added support for parameters beginning with dash in BASH language (BenBE)
+ * Support Apache's configuration sections, see http://httpd.apache.org/docs/2.2/sections.html (milian)
+ * Minor issue with PHP Heredoc and Nowdoc syntax sometimes not getting highlighted (BenBE)
+ * Updated Objective-C language file (SF#2013961, Quinn Taylor, BenBE)
+ * Added some keywords for VHDL (beshig, BenBE)
+ * Fixed severly broken ColdFusion language file (milian)
+ * Fixed some incorrectly highlighted things with the CSS language file (milian, BenBE)
+ * Improved Smarty language file (milian)
+ * Improved CSS language file (milian)
+ * Improved Pascal language file (milian)
+ * Improved LaTeX language file (Андрей Парамонов, BenBE)
+ * Fixed a regular expression in mIRC language file that caused a warning message to be issued (BenBE)
+ * Removed <, > and / from HTML names, now only containing the real tag names (BenBE)
+ * Use spaces instead of tabs for indendation in language files to have a consistent
+ coding standard accross geshi files (milian)
+ * Added some comment styles, keywords and added index highlighting (Chusslove Illich, Часлав Илић)
+ - Removed some private methods which were only called at exactly one place (milian)
+ * format_header_content
+ * format_footer_content
+ * get_attributes
+ - Second part of default style changes. Affected in this release:
+ * C++
+ * C++ (QT)
+ * CSS
+ * VHDL
+Version 1.0.7.22
+ - Added language files
+ * glSlang (BenBE)
+ * KiXtart (Riley McArdle)
+ * Lotus Notes @Formulas (Richard Civil)
+ * LotusScript (Richard Civil)
+ * MXML (David Spurr)
+ * Scala (Franco Lombardo)
+ * ActionScript 3 (Jordi Boggiano)
+ * GNU Gettext .po/.pot (Milian Wolff)
+ * Verilog (Günter Dannoritzer)
+ - Fixed a problem not yet addressed in 1.0.7.21 regarding highlighting of
+ symbols that caused some extra characters to be added in the output or
+ broke highlighting and standard compliance due to missing escaping of
+ internally used characters (SF#192320 and SF#1926259, BenBE)
+ - Fixed missing style information for ocaml language file (The_PHP_Jedi)
+ - Fixed a bug causing masses of warnings in rendered output if language file
+ miss style information (The_PHP_Jedi, BenBE)
+ - Missing tab width information could lead to warnings (BenBE)
+ - Missing symbol information for ASP (SF#1952038, nfsupport, BenBE)
+ - Empty delimiter message with OOoBasic (BenBE, Ccornell)
+ - Escaping of comments in LaTeX ignored (SF#1749806, BenBE)
+ - Modified Math environment $$ in LaTeX to be non-greedy (BenBE)
+ - Added possibility to match a regexp as comment (SF#1914640, SF#1945301, SF#1934832, BenBE)
+ - Introduced C-Style multiline continuation comments (SF#1914640, SF#1945301, BenBE)
+ - Introduced Fortran Comments (SF#1914640, SF#1934832, BenBE)
+ - Implemented Heredoc and Nowdoc Syntax for PHP and Perl (SF#1914640, BenBE)
+ - Implemented Compiler Directives for Delphi (SF#1914640, BenBE)
+ - Implemented minimalistic support for JavaScript \ Perl Regular Expressions (SF#1786665, SF#1754333, SF#1956631, BenBE)
+ - Fixed Strings in Matlab to be handled as comments instead of regexps, to prevent keywords being linked (BenBE)
+ - Applied PARSER_CONTROL fix of CPP for CPP-QT-Derivative (BenBE)
+ - Fixed incorrect treatment of unequally long multiline comment separators (related to SF #1891630, BenBE)
+ - Added PARSER_CONTROL settings for keywords in ASM language file (SF#1835148, BenBE)
+ - Fixed missing CASSE_SENSITIVE entry for DOS language file (SF#1956314, BenBE)
+ - Fixed accidential highlighting of keywords in argument names (SF#1956456, Milian Wolff, BenBE)
+ - Fixed yet again some #-related bash problem (SF#1956459, Milian Wolff, BenBE)
+ - Added backticks as symbols (Milian Wolff)
+ - Example script remembers selections and source submitted (Milian Wolff)
+ - Example script allows remembered source and preselected language to be cleared (Milian Wolff)
+ - Example script now properly includes geshi and doesn't suppress error messages anylonger. (Milian Wolff)
+ - Code cleanup by using direct string indexing instead of substr with length 1 (Milian Wolff)
+ - Optimized generation of code parts in strict mode (Milian Wolff)
+ - Optimized COMMENT_REGEXP by using an incremental regexp cache (Milian Wolff, BenBE)
+ - Fixed a problem that rarely skipped highlighting of escaped chars which usually should have gotten highlighted (BenBE)
+ - Optimized generation of highlighted strings to use fast skip forward while highlighting them (Milian Wolff, BenBE)
+ - Optimization using basic rework of indent function improving tab expansion performance (BenBE)
+ - Lots of other minor optimizations based on coding style improvements (Milian Wolff)
+ - Implemented setting to force spans to be closed before newlines, see SF#1727398 (Milian Wolff)
+ - Added missing credits for D language file to THANKS file (SF#1720899, BenBE)
+ - Optimization to prevent loading the current language file twice (Milian Wolff)
+ - Optimization: Use file_get_contents() to load sourcecode from files.
+ Even if GeSHi worked with PHP 4.1 before, it doesn't now. (Milian Wolff)
+ - Added description of extra language features (SF#1970248, BenBE)
+ - Added support for highlighting the C# using and namespace directives (SF #1395677, BenBE)
+ - Added support for highlighting the Java import and package directives (SF #1395677, BenBE)
+ - Fixed minor problem in Haskell cuasing accidential start of comment (SF#1987221, BenBE)
+ - Fixed minor issue causing loads of warnings if a language files defines no symbols (BenBE)
+ - Updated some aspects of the documentation and included further hints (BenBE)
+ - First of series of color scheme changes. Affected languages (sofar):
+ * Assembler (x86)
+ * Bash
+ * C
+ * C#
+ * Delphi
+ * Fortran77
+ * glSlang
+ * Java & Java 5
+ * JavaScript
+ * OCaml
+ * OpenOffice.org Basic
+ * Pascal
+ * Perl
+ * PHP and PHP-Brief
+Version 1.0.7.21
+ - Added language files
+ * Basic4GL (Matthew Webb)
+ - Fixed problem with mIRC language highlighting spaces only (BenBE)
+ - Language files can now specify a function to be called to decide the
+ colour of a regular expression match
+ - Added single quote to Lua (Darrin Roenfanz)
+ - Compare comments case insensitively (fixes AutoIT comments somewhat)
+ (Daniel Gordon)
+ - Fixed symbols not being highlighted at all (SF #1767953, BenBE)
+ - Fixed brackets not correctly managed (SF #1767954, BenBE)
+ - Changed default languages for some extensions
+ - Included color and character information for symbol highlighting in some languages (BenBE)
+ - Fixed a problem with extension detection if default was used (BenBE)
+ - Fixed a highlighting problem with the LaTeX language (SF #1776182, BenBE)
+ - Added a new parameter for enable_highlighting to reduce source duplication (SF #1786104, BenBE)
+ - Updated doxygen documentation to include since tags and some missing parameters
+ - Disabled symbol highlighting by default (doesn't affect brackets, cf. documentation) (BenBE)
+ - Added a check for set_case_keywords for the given param to be supported (BenBE)
+ - Minor rework of the HTML documentation layout \ W3C compliance (BenBE)
+ - Fixed highlighting error in bash language avoiding keywords in comments (SF #1786314, SF #1564839, BenBE)
+ - Fixed template params for C++ and C# not being highlighted (SF #1772919, BenBE)
+ - Fixed more reported problems about mirc highlighting
+ - Added some missing keywords for VB.NET
+ - Fixed some warnings in DOS language file (Florian Angehrn)
+ - Add possibility to handle more than one extra line style (SF #1698255, German Rumm, BenBE)
+ - Fixed handling of URLs when output case differs from URL case (SF #1815504, Tom Samstag, BenBE)
+ - Fixed POD (Plain Old Documentation) format problems breaking highlighting of Perl (SF #1891630, Shannon Wynter, BenBE)
+ - Fixed a problem with mIRC when & was used for identifiers (SF #1875552, BenBE)
+Version 1.0.7.20
+ - Added language files
+ * Genero (logic) and Per (forms) (FOURJ's Genero 4GL) (Lars Gersmann)
+ * Haskell (Dagit)
+ * ABAP (Andres Picazo)
+ * Motorola 68k Assembler (for MC68HC908GP32 Microcontroller) (BenBE)
+ * Dot (Adrien Friggeri)
+ - Fixed java documentation search for keywords to actually go to the
+ documentation (spaze)
+ - Applied fix for bug 1688864 (bad regexes) (Tim Starling)
+ - Fixed comment CSS rule in visualfoxpro
+ - ThinBASIC language update (Eros Olmi)
+ - mIRC language update (BenBE)
+ - Fixed outdated documentation URL of Perl language file (RuralMoon by BenBE)
+ - Fixed tab replacement code not generating the correct number of spaces in
+ some cases (Guillermo Calvo)
+ - Fixed two typos in Z80 language file
+ - Applied fix for bug 1730168 (Daniel Naber)
+ - Applied fix for bug 1705482 (Jason Frame)
+ * Configurable line endings (Replace \n by custom string)
+ * per-language tab-widths (Adjustable for width>=1)
+ * Included defaults for ASM (x86, m68k, z80), C, C (Mac), C++, C++ (QT), C#,
+ Delphi, CSS,, HTML, PHP, PHP (Brief), QBasic, Ruby, XML
+ - Added a possibility to force generation of a surrounding tag around
+ the highlighted source
+ - Applied fix for additional keywords for the bash language
+ (cf. http://bash.thefreebizhost.com/bash_geshi.php, BenBE / Jan G)
+ - Fix bad colour definition in GML language (Andreas Gohr)
+ - Fixed phpdoc comments not being indented one space if they should be (Andy
+ Hassall)
+Version 1.0.7.19
+ - Added language files
+ * X++ (Simon Butcher)
+ * Rails (Moises Deniz)
+ - Fixed invalid HTML being generated and doctypes not being highlighted over
+ multiple lines properly when line numbers are on (Validome)
+ - Improved the ruby syntax highlighting by basing it off the Rails file
+ - Changed some regular expressions to possibly help with badly performing
+ regex support in PHP (Tim Starling)
+ - Allow {TIME}, {LANGUAGE} and {VERSION} to be used in the header as well as
+ the normal