44 define(
'GESHI_VERSION',
'1.0.8.12');
49 define(
'GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
53 define(
'GESHI_LANG_ROOT', GESHI_ROOT .
'geshi' . DIRECTORY_SEPARATOR);
56 if (!
defined(
'GESHI_SECURITY_PARANOID')) {
58 define(
'GESHI_SECURITY_PARANOID',
false);
63 define(
'GESHI_NO_LINE_NUMBERS', 0);
65 define(
'GESHI_NORMAL_LINE_NUMBERS', 1);
67 define(
'GESHI_FANCY_LINE_NUMBERS', 2);
71 define(
'GESHI_HEADER_NONE', 0);
73 define(
'GESHI_HEADER_DIV', 1);
75 define(
'GESHI_HEADER_PRE', 2);
77 define(
'GESHI_HEADER_PRE_VALID', 3);
91 define(
'GESHI_HEADER_PRE_TABLE', 4);
95 define(
'GESHI_CAPS_NO_CHANGE', 0);
97 define(
'GESHI_CAPS_UPPER', 1);
99 define(
'GESHI_CAPS_LOWER', 2);
103 define(
'GESHI_LINK', 0);
105 define(
'GESHI_HOVER', 1);
107 define(
'GESHI_ACTIVE', 2);
109 define(
'GESHI_VISITED', 3);
115 define(
'GESHI_START_IMPORTANT',
'<BEGIN GeSHi>');
117 define(
'GESHI_END_IMPORTANT',
'<END GeSHi>');
124 define(
'GESHI_NEVER', 0);
127 define(
'GESHI_MAYBE', 1);
129 define(
'GESHI_ALWAYS', 2);
133 define(
'GESHI_SEARCH', 0);
136 define(
'GESHI_REPLACE', 1);
138 define(
'GESHI_MODIFIERS', 2);
141 define(
'GESHI_BEFORE', 3);
144 define(
'GESHI_AFTER', 4);
147 define(
'GESHI_CLASS', 5);
150 define(
'GESHI_COMMENTS', 0);
153 define(
'GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION,
'4.3.3') === 1));
156 if (!function_exists(
'stripos')) {
162 function stripos($haystack, $needle, $offset = null) {
163 if (!is_null($offset)) {
164 $haystack = substr($haystack, $offset);
166 if (preg_match(
'/'. preg_quote($needle,
'/') .
'/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
176 function stripos($haystack, $needle, $offset = null) {
177 if (preg_match(
'/'. preg_quote($needle,
'/') .
'/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
189 define(
'GESHI_MAX_PCRE_SUBPATTERNS', 500);
195 define(
'GESHI_MAX_PCRE_LENGTH', 12288);
199 define(
'GESHI_NUMBER_INT_BASIC', 1);
201 define(
'GESHI_NUMBER_INT_CSTYLE', 2);
203 define(
'GESHI_NUMBER_BIN_SUFFIX', 16);
205 define(
'GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);
207 define(
'GESHI_NUMBER_BIN_PREFIX_0B', 64);
209 define(
'GESHI_NUMBER_OCT_PREFIX', 256);
211 define(
'GESHI_NUMBER_OCT_PREFIX_0O', 512);
213 define(
'GESHI_NUMBER_OCT_PREFIX_AT', 1024);
215 define(
'GESHI_NUMBER_OCT_SUFFIX', 2048);
217 define(
'GESHI_NUMBER_HEX_PREFIX', 4096);
219 define(
'GESHI_NUMBER_HEX_PREFIX_DOLLAR', 8192);
221 define(
'GESHI_NUMBER_HEX_SUFFIX', 16384);
223 define(
'GESHI_NUMBER_FLT_NONSCI', 65536);
225 define(
'GESHI_NUMBER_FLT_NONSCI_F', 131072);
227 define(
'GESHI_NUMBER_FLT_SCI_SHORT', 262144);
229 define(
'GESHI_NUMBER_FLT_SCI_ZERO', 524288);
236 define(
'GESHI_ERROR_NO_INPUT', 1);
238 define(
'GESHI_ERROR_NO_SUCH_LANG', 2);
240 define(
'GESHI_ERROR_FILE_NOT_READABLE', 3);
242 define(
'GESHI_ERROR_INVALID_HEADER_TYPE', 4);
244 define(
'GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
334 'KEYWORDS' =>
array(),
335 'COMMENTS' =>
array(
'MULTI' =>
true),
336 'REGEXPS' =>
array(),
337 'ESCAPE_CHAR' =>
true,
454 var
$code_style =
'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
598 if ( is_string($source) && ($source !==
'') ) {
601 if ( is_string($language) && ($language !==
'') ) {
628 $debug_tpl_vars =
array(
630 '{PATH}' => $this->language_path
633 array_keys($debug_tpl_vars),
634 array_values($debug_tpl_vars),
635 $this->error_messages[$this->
error]);
637 return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
651 return $this->language_data[
'LANG_NAME'] .
' (Unknown Language)';
653 return $this->language_data[
'LANG_NAME'];
664 $this->highlight_extra_lines =
array();
678 $this->loaded_language =
false;
682 $language = preg_replace(
'#[^a-zA-Z0-9\-_]#',
'', $language);
684 $language = strtolower($language);
687 $file_name = $this->language_path . $language .
'.php';
688 if ($file_name == $this->loaded_language) {
695 $this->
error =
false;
699 if (!is_readable($file_name)) {
721 if(strpos(
$path,
':')) {
723 if(DIRECTORY_SEPARATOR ==
"\\") {
724 if(!preg_match(
'#^[a-zA-Z]:#',
$path) ||
false !== strpos(
$path,
':', 2)) {
731 if(preg_match(
'#[^/a-zA-Z0-9_\.\-\\\s:]#',
$path)) {
735 if(GESHI_SECURITY_PARANOID &&
false !== strpos(
$path,
'/.')) {
739 if(GESHI_SECURITY_PARANOID &&
false !== strpos(
$path,
'..')) {
760 $dir = dir($this->language_path);
763 while (
false !== ($entry = $dir->read()))
765 $full_path = $this->language_path.$entry;
768 if (is_dir($full_path)) {
773 if (!preg_match(
'/^([^.]+)\.php$/', $entry, $matches)) {
778 $langname = $matches[1];
781 if ($full_names ===
true)
785 $back[$langname] = $fullname;
808 $language = preg_replace(
'#[^a-zA-Z0-9\-_]#',
'', $language);
810 $language = strtolower($language);
813 $fullpath = $this->language_path.$language.
'.php';
816 if (
false === (
$data = file_get_contents($fullpath))) {
817 $this->
error = sprintf(
'Geshi::get_lang_fullname() Unknown Language: %s', $language);
822 if (!preg_match(
'/\'LANG_NAME\'\s*=>\s*\'((?:[^\']|\\\')+?)\'/',
$data, $matches)) {
823 $this->
error = sprintf(
'Geshi::get_lang_fullname(%s): Regex can not detect language', $language);
828 return stripcslashes($matches[1]);
854 $this->header_type = $type;
867 if (!$preserve_defaults) {
868 $this->overall_style =
$style;
870 $this->overall_style .=
$style;
883 $this->overall_class = $class;
894 $this->overall_id = $id;
905 $this->use_classes = ($flag) ?
true :
false;
924 if (!$preserve_defaults) {
925 $this->code_style =
$style;
927 $this->code_style .=
$style;
951 if (!$preserve_defaults) {
952 $this->line_style1 = $style1;
955 $this->line_style1 .= $style1;
982 $this->line_numbers = $flag;
983 $this->line_nth_row = $nth_row;
996 $this->allow_multiline_span = (bool) $flag;
1023 foreach($this->language_data[
'STYLES'][
'KEYWORDS'] as $_key => $_value) {
1024 if (!$preserve_defaults) {
1025 $this->language_data[
'STYLES'][
'KEYWORDS'][$_key] =
$style;
1027 $this->language_data[
'STYLES'][
'KEYWORDS'][$_key] .=
$style;
1031 if (!$preserve_defaults) {
1032 $this->language_data[
'STYLES'][
'KEYWORDS'][$key] =
$style;
1034 $this->language_data[
'STYLES'][
'KEYWORDS'][$key] .=
$style;
1039 if (!isset($this->lexic_permissions[
'KEYWORDS'][$key])) {
1040 $this->lexic_permissions[
'KEYWORDS'][$key] =
true;
1052 $this->lexic_permissions[
'KEYWORDS'][$key] = ($flag) ?
true :
false;
1068 foreach($this->language_data[
'STYLES'][
'COMMENTS'] as $_key => $_value) {
1069 if (!$preserve_defaults) {
1070 $this->language_data[
'STYLES'][
'COMMENTS'][$_key] =
$style;
1072 $this->language_data[
'STYLES'][
'COMMENTS'][$_key] .=
$style;
1076 if (!$preserve_defaults) {
1077 $this->language_data[
'STYLES'][
'COMMENTS'][$key] =
$style;
1079 $this->language_data[
'STYLES'][
'COMMENTS'][$key] .=
$style;
1092 $this->lexic_permissions[
'COMMENTS'][$key] = ($flag) ?
true :
false;
1106 if (!$preserve_defaults) {
1107 $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$group] =
$style;
1109 $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$group] .=
$style;
1120 $this->lexic_permissions[
'ESCAPE_CHAR'] = ($flag) ?
true :
false;
1138 if (!$preserve_defaults) {
1139 $this->language_data[
'STYLES'][
'BRACKETS'][0] =
$style;
1141 $this->language_data[
'STYLES'][
'BRACKETS'][0] .=
$style;
1156 $this->lexic_permissions[
'BRACKETS'] = ($flag) ?
true :
false;
1172 if (!$preserve_defaults) {
1173 $this->language_data[
'STYLES'][
'SYMBOLS'][$group] =
$style;
1175 $this->language_data[
'STYLES'][
'SYMBOLS'][$group] .=
$style;
1192 $this->lexic_permissions[
'SYMBOLS'] = ($flag) ?
true :
false;
1210 if (!$preserve_defaults) {
1211 $this->language_data[
'STYLES'][
'STRINGS'][$group] =
$style;
1213 $this->language_data[
'STYLES'][
'STRINGS'][$group] .=
$style;
1224 $this->lexic_permissions[
'STRINGS'] = ($flag) ?
true :
false;
1240 if (!$preserve_defaults) {
1241 $this->language_data[
'STYLES'][
'SCRIPT'][$group] =
$style;
1243 $this->language_data[
'STYLES'][
'SCRIPT'][$group] .=
$style;
1259 if (!$preserve_defaults) {
1260 $this->language_data[
'STYLES'][
'NUMBERS'][$group] =
$style;
1262 $this->language_data[
'STYLES'][
'NUMBERS'][$group] .=
$style;
1273 $this->lexic_permissions[
'NUMBERS'] = ($flag) ?
true :
false;
1290 if (!$preserve_defaults) {
1291 $this->language_data[
'STYLES'][
'METHODS'][$key] =
$style;
1293 $this->language_data[
'STYLES'][
'METHODS'][$key] .=
$style;
1304 $this->lexic_permissions[
'METHODS'] = ($flag) ?
true :
false;
1318 if (!$preserve_defaults) {
1319 $this->language_data[
'STYLES'][
'REGEXPS'][$key] =
$style;
1321 $this->language_data[
'STYLES'][
'REGEXPS'][$key] .=
$style;
1333 $this->lexic_permissions[
'REGEXPS'][$key] = ($flag) ?
true :
false;
1344 $this->language_data[
'CASE_SENSITIVE'][$key] = ($case) ?
true :
false;
1358 if (in_array($case,
array(
1360 $this->language_data[
'CASE_KEYWORDS'] = $case;
1373 $this->tab_width = intval($width);
1376 if ($this->tab_width < 1) {
1378 $this->tab_width = 8;
1389 $this->use_language_tab_width = (bool) $use;
1400 if (!$this->use_language_tab_width ||
1401 !isset($this->language_data[
'TAB_WIDTH'])) {
1404 return $this->language_data[
'TAB_WIDTH'];
1417 if (
GESHI_MAYBE == $this->language_data[
'STRICT_MODE_APPLIES']) {
1444 $flag = $flag ? true :
false;
1445 foreach ($this->lexic_permissions as $key => $value) {
1446 if (is_array($value)) {
1447 foreach ($value as $k => $v) {
1448 $this->lexic_permissions[$key][$k] = $flag;
1451 $this->lexic_permissions[$key] = $flag;
1470 $extension = strtolower($extension);
1472 if ( !is_array($lookup) || empty($lookup)) {
1474 '6502acme' =>
array(
'a',
's',
'asm',
'inc' ),
1475 '6502tasm' =>
array(
'a',
's',
'asm',
'inc' ),
1476 '6502kickass' =>
array(
'a',
's',
'asm',
'inc' ),
1477 '68000devpac' =>
array(
'a',
's',
'asm',
'inc' ),
1478 'abap' =>
array(
'abap'),
1479 'actionscript' =>
array(
'as'),
1480 'ada' =>
array(
'a',
'ada',
'adb',
'ads'),
1481 'apache' =>
array(
'conf'),
1482 'asm' =>
array(
'ash',
'asm',
'inc'),
1483 'asp' =>
array(
'asp'),
1484 'bash' =>
array(
'sh'),
1485 'bf' =>
array(
'bf'),
1486 'c' =>
array(
'c',
'h'),
1487 'c_mac' =>
array(
'c',
'h'),
1488 'caddcl' =>
array(),
1489 'cadlisp' =>
array(),
1490 'cdfg' =>
array(
'cdfg'),
1491 'cobol' =>
array(
'cbl'),
1492 'cpp' =>
array(
'cpp',
'hpp',
'C',
'H',
'CPP',
'HPP'),
1493 'csharp' =>
array(
'cs'),
1494 'css' =>
array(
'css'),
1496 'delphi' =>
array(
'dpk',
'dpr',
'pp',
'pas'),
1497 'diff' =>
array(
'diff',
'patch'),
1498 'dos' =>
array(
'bat',
'cmd'),
1499 'gdb' =>
array(
'kcrash',
'crash',
'bt'),
1500 'gettext' =>
array(
'po',
'pot'),
1501 'gml' =>
array(
'gml'),
1502 'gnuplot' =>
array(
'plt'),
1503 'groovy' =>
array(
'groovy'),
1504 'haskell' =>
array(
'hs'),
1505 'haxe' =>
array(
'hx'),
1506 'html4strict' =>
array(
'html',
'htm'),
1507 'ini' =>
array(
'ini',
'desktop'),
1508 'java' =>
array(
'java'),
1509 'javascript' =>
array(
'js'),
1510 'klonec' =>
array(
'kl1'),
1511 'klonecpp' =>
array(
'klx'),
1512 'latex' =>
array(
'tex'),
1513 'lisp' =>
array(
'lisp'),
1514 'lua' =>
array(
'lua'),
1515 'matlab' =>
array(
'm'),
1517 'mysql' =>
array(
'sql'),
1521 'oracle8' =>
array(),
1522 'oracle10' =>
array(),
1523 'pascal' =>
array(
'pas'),
1524 'perl' =>
array(
'pl',
'pm'),
1525 'php' =>
array(
'php',
'php5',
'phtml',
'phps'),
1526 'povray' =>
array(
'pov'),
1527 'providex' =>
array(
'pvc',
'pvx'),
1528 'prolog' =>
array(
'pl'),
1529 'python' =>
array(
'py'),
1530 'qbasic' =>
array(
'bi'),
1531 'reg' =>
array(
'reg'),
1532 'ruby' =>
array(
'rb'),
1533 'sas' =>
array(
'sas'),
1534 'scala' =>
array(
'scala'),
1535 'scheme' =>
array(
'scm'),
1536 'scilab' =>
array(
'sci'),
1537 'smalltalk' =>
array(
'st'),
1538 'smarty' =>
array(),
1539 'tcl' =>
array(
'tcl'),
1540 'text' =>
array(
'txt'),
1541 'vb' =>
array(
'bas'),
1543 'visualfoxpro' =>
array(),
1544 'whitespace' =>
array(
'ws'),
1545 'xml' =>
array(
'xml',
'svg',
'xrc'),
1546 'z80' =>
array(
'z80',
'asm',
'inc')
1550 foreach ($lookup as
$lang => $extensions) {
1551 if (in_array($extension, $extensions)) {
1577 if (is_readable($file_name)) {
1578 $this->
set_source(file_get_contents($file_name));
1579 $this->
set_language(self::get_language_name_from_extension(substr(strrchr($file_name,
'.'), 1), $lookup));
1593 if (!is_array($this->language_data[
'KEYWORDS'][$key])) {
1594 $this->language_data[
'KEYWORDS'][$key] =
array();
1596 if (!in_array($word, $this->language_data[
'KEYWORDS'][$key])) {
1597 $this->language_data[
'KEYWORDS'][$key][] = $word;
1600 if ($this->parse_cache_built) {
1601 $subkey = count($this->language_data[
'CACHED_KEYWORD_LISTS'][$key]) - 1;
1602 $this->language_data[
'CACHED_KEYWORD_LISTS'][$key][$subkey] .=
'|' . preg_quote($word,
'/');
1621 $key_to_remove = array_search($word, $this->language_data[
'KEYWORDS'][$key]);
1622 if ($key_to_remove !==
false) {
1623 unset($this->language_data[
'KEYWORDS'][$key][$key_to_remove]);
1626 if ($recompile && $this->parse_cache_built) {
1642 $words = (
array) $words;
1643 if (empty($words)) {
1649 $this->language_data[
'KEYWORDS'][$key] = $words;
1650 $this->lexic_permissions[
'KEYWORDS'][$key] =
true;
1651 $this->language_data[
'CASE_SENSITIVE'][$key] = $case_sensitive;
1652 $this->language_data[
'STYLES'][
'KEYWORDS'][$key] =
$styles;
1655 if ($this->parse_cache_built) {
1668 unset($this->language_data[
'KEYWORDS'][$key]);
1669 unset($this->lexic_permissions[
'KEYWORDS'][$key]);
1670 unset($this->language_data[
'CASE_SENSITIVE'][$key]);
1671 unset($this->language_data[
'STYLES'][
'KEYWORDS'][$key]);
1674 unset($this->language_data[
'CACHED_KEYWORD_LISTS'][$key]);
1684 $this->language_data[
'CACHED_KEYWORD_LISTS'][$key] =
1686 $space_as_whitespace =
false;
1687 if(isset($this->language_data[
'PARSER_CONTROL'])) {
1688 if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'])) {
1689 if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'SPACE_AS_WHITESPACE'])) {
1690 $space_as_whitespace = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'SPACE_AS_WHITESPACE'];
1692 if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$key][
'SPACE_AS_WHITESPACE'])) {
1693 if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$key][
'SPACE_AS_WHITESPACE'])) {
1694 $space_as_whitespace = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$key][
'SPACE_AS_WHITESPACE'];
1699 if($space_as_whitespace) {
1700 foreach($this->language_data[
'CACHED_KEYWORD_LISTS'][$key] as $rxk => $rxv) {
1701 $this->language_data[
'CACHED_KEYWORD_LISTS'][$key][$rxk] =
1702 str_replace(
" ",
"\\s+", $rxv);
1714 $this->header_content = $content;
1724 $this->footer_content = $content;
1734 $this->header_content_style =
$style;
1744 $this->footer_content_style =
$style;
1755 $this->force_code_block = (bool)$flag;
1768 $this->language_data[
'URLS'][$group] =
$url;
1780 $this->link_styles[$type] =
$styles;
1791 $this->link_target =
'';
1793 $this->link_target =
' target="' .
$target .
'"';
1804 $this->important_styles =
$styles;
1826 $this->add_ids = ($flag) ?
true :
false;
1844 if (is_array($lines)) {
1846 foreach ($lines as $line) {
1851 $lines = intval($lines);
1852 $this->highlight_extra_lines[$lines] = $lines;
1856 unset($this->highlight_extra_lines_styles[$lines]);
1857 } elseif (
$style ===
false) {
1858 unset($this->highlight_extra_lines[$lines]);
1859 unset($this->highlight_extra_lines_styles[$lines]);
1861 $this->highlight_extra_lines_styles[$lines] =
$style;
1873 $this->highlight_extra_lines_style =
$styles;
1883 $this->line_ending = (
string)$line_ending;
1902 $this->line_numbers_start = abs(intval($number));
1919 $this->encoding = strtolower($encoding);
1930 $this->keyword_links = (bool) $enable;
1944 if($this->lexic_permissions[
'NUMBERS']) {
1946 if(!isset($this->language_data[
'NUMBERS'])) {
1947 $this->language_data[
'NUMBERS'] = 0;
1950 if(is_array($this->language_data[
'NUMBERS'])) {
1951 $this->language_data[
'NUMBERS_CACHE'] = $this->language_data[
'NUMBERS'];
1953 $this->language_data[
'NUMBERS_CACHE'] =
array();
1954 if(!$this->language_data[
'NUMBERS']) {
1955 $this->language_data[
'NUMBERS'] =
1960 for($i = 0, $j = $this->language_data[
'NUMBERS']; $j > 0; ++$i, $j>>=1) {
1962 if(isset($this->language_data[
'STYLES'][
'NUMBERS'][1<<$i])) {
1963 $this->language_data[
'STYLES'][
'NUMBERS'][$i] =
1964 $this->language_data[
'STYLES'][
'NUMBERS'][1<<$i];
1965 unset($this->language_data[
'STYLES'][
'NUMBERS'][1<<$i]);
1972 if(isset($this->language_data[
'STYLES'][
'NUMBERS'][$i])) {
1973 $this->language_data[
'NUMBERS_CACHE'][$i] = 1 << $i;
1975 if(!isset($this->language_data[
'NUMBERS_CACHE'][0])) {
1976 $this->language_data[
'NUMBERS_CACHE'][0] = 0;
1978 $this->language_data[
'NUMBERS_CACHE'][0] |= 1 << $i;
1999 if ($this->lexic_permissions[
'SYMBOLS'] && !empty($this->language_data[
'SYMBOLS'])) {
2000 $this->language_data[
'MULTIPLE_SYMBOL_GROUPS'] = count($this->language_data[
'STYLES'][
'SYMBOLS']) > 1;
2002 $this->language_data[
'SYMBOL_DATA'] =
array();
2003 $symbol_preg_multi =
array();
2004 $symbol_preg_single =
array();
2005 foreach ($this->language_data[
'SYMBOLS'] as $key => $symbols) {
2006 if (is_array($symbols)) {
2007 foreach ($symbols as $sym) {
2008 $sym = $this->
hsc($sym);
2009 if (!isset($this->language_data[
'SYMBOL_DATA'][$sym])) {
2010 $this->language_data[
'SYMBOL_DATA'][$sym] = $key;
2011 if (isset($sym[1])) {
2012 $symbol_preg_multi[] = preg_quote($sym,
'/');
2016 $symbol_preg_single[] =
'\-';
2018 $symbol_preg_single[] = preg_quote($sym,
'/');
2024 $symbols = $this->
hsc($symbols);
2025 if (!isset($this->language_data[
'SYMBOL_DATA'][$symbols])) {
2026 $this->language_data[
'SYMBOL_DATA'][$symbols] = 0;
2027 if (isset($symbols[1])) {
2028 $symbol_preg_multi[] = preg_quote($symbols,
'/');
2029 } elseif ($symbols ==
'-') {
2031 $symbol_preg_single[] =
'\-';
2033 $symbol_preg_single[] = preg_quote($symbols,
'/');
2043 $symbol_preg =
array();
2044 if (!empty($symbol_preg_multi)) {
2045 rsort($symbol_preg_multi);
2046 $symbol_preg[] = implode(
'|', $symbol_preg_multi);
2048 if (!empty($symbol_preg_single)) {
2049 rsort($symbol_preg_single);
2050 $symbol_preg[] =
'[' . implode(
'', $symbol_preg_single) .
']';
2052 $this->language_data[
'SYMBOL_SEARCH'] = implode(
"|", $symbol_preg);
2057 $this->language_data[
'CACHED_KEYWORD_LISTS'] =
array();
2058 foreach (array_keys($this->language_data[
'KEYWORDS']) as $key) {
2059 if (!isset($this->lexic_permissions[
'KEYWORDS'][$key]) ||
2060 $this->lexic_permissions[
'KEYWORDS'][$key]) {
2066 if ($this->lexic_permissions[
'BRACKETS']) {
2067 $this->language_data[
'CACHE_BRACKET_MATCH'] =
array(
'[',
']',
'(',
')',
'{',
'}');
2068 if (!$this->use_classes && isset($this->language_data[
'STYLES'][
'BRACKETS'][0])) {
2069 $this->language_data[
'CACHE_BRACKET_REPLACE'] =
array(
2070 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">[|>',
2071 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">]|>',
2072 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">(|>',
2073 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">)|>',
2074 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">{|>',
2075 '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] .
'">}|>',
2079 $this->language_data[
'CACHE_BRACKET_REPLACE'] =
array(
2080 '<| class="br0">[|>',
2081 '<| class="br0">]|>',
2082 '<| class="br0">(|>',
2083 '<| class="br0">)|>',
2084 '<| class="br0">{|>',
2085 '<| class="br0">}|>',
2091 if($this->lexic_permissions[
'NUMBERS']) {
2094 if(!isset($this->language_data[
'NUMBERS_CACHE'])) {
2100 static $numbers_format =
array(
2102 '(?:(?<![0-9a-z_\.%$@])|(?<=\.\.))(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2104 '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2106 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[01]+?[bB](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2108 '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])%[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2110 '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0b[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2112 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2114 '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0o[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2116 '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])\@[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2118 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[0-7]+?o(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2120 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0x[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2122 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\$[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2124 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d[0-9a-fA-F]*?[hH](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2126 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2128 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2130 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
2132 '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)' 2137 $this->language_data[
'NUMBERS_RXCACHE'] =
array();
2138 foreach($this->language_data[
'NUMBERS_CACHE'] as $key => $rxdata) {
2139 if(is_string($rxdata)) {
2145 for($i = 1; $i <= $rxdata; $i<<=1) {
2147 $rxuse[] = $numbers_format[$i];
2150 $regexp = implode(
"|", $rxuse);
2153 $this->language_data[
'NUMBERS_RXCACHE'][$key] =
2154 "/(?<!<\|\/)(?<!<\|!REG3XP)(?<!<\|\/NUM!)(?<!\d\/>)($regexp)(?!(?:<DOT>|(?>[^<]))+>)(?![^<]*>)(?!\|>)(?!\/>)/i";
2157 if(!isset($this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'])) {
2158 $this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'] =
'#\d#';
2162 $this->parse_cache_built =
true;
2177 $start_time = microtime();
2180 $code = str_replace(
"\r\n",
"\n", $this->source);
2193 $this->
set_time($start_time, $start_time);
2199 if (!$this->parse_cache_built) {
2204 $length = strlen(
$code);
2205 $COMMENT_MATCHED =
false;
2206 $stuff_to_parse =
'';
2215 if ($this->strict_mode) {
2221 $next_match_pointer = null;
2223 $delim_copy = $this->language_data[
'SCRIPT_DELIMITERS'];
2225 while ($i < $length) {
2226 $next_match_pos = $length + 1;
2227 foreach ($delim_copy as $dk => $delimiters) {
2228 if(is_array($delimiters)) {
2229 foreach ($delimiters as $open => $close) {
2231 if (!isset($matches[$dk][$open])) {
2232 $matches[$dk][$open] =
array(
2237 'open_strlen' => strlen($open),
2240 'close_strlen' => strlen($close),
2244 if ($matches[$dk][$open][
'next_match'] < $i) {
2246 $open_pos = strpos(
$code, $open, $i);
2247 if ($open_pos ===
false) {
2249 unset($delim_copy[$dk][$open]);
2252 $matches[$dk][$open][
'next_match'] = $open_pos;
2254 if ($matches[$dk][$open][
'next_match'] < $next_match_pos) {
2256 $matches[$dk][$open][
'close_pos'] =
2257 strpos(
$code, $close, $matches[$dk][$open][
'next_match']+1);
2259 $next_match_pointer =& $matches[$dk][$open];
2260 $next_match_pos = $matches[$dk][$open][
'next_match'];
2272 preg_match($delimiters,
$code, $matches_rx, PREG_OFFSET_CAPTURE, $i)) {
2274 if(isset($matches_rx[
'start']) && isset($matches_rx[
'end']))
2276 $matches[$dk] =
array(
2277 'next_match' => $matches_rx[
'start'][1],
2280 'close_strlen' => strlen($matches_rx[
'end'][0]),
2281 'close_pos' => $matches_rx[
'end'][1],
2284 $matches[$dk] =
array(
2285 'next_match' => $matches_rx[1][1],
2288 'close_strlen' => strlen($matches_rx[2][0]),
2289 'close_pos' => $matches_rx[2][1],
2294 unset($delim_copy[$dk]);
2298 if ($matches[$dk][
'next_match'] <= $next_match_pos) {
2299 $next_match_pointer =& $matches[$dk];
2300 $next_match_pos = $matches[$dk][
'next_match'];
2307 1 => substr(
$code, $i, $next_match_pos - $i)
2311 if ($next_match_pos > $length) {
2317 $parts[$k][0] = $next_match_pointer[
'dk'];
2320 if(is_array($delim_copy[$next_match_pointer[
'dk']])) {
2322 $i = $next_match_pos + $next_match_pointer[
'open_strlen'];
2324 $close_pos = strpos(
$code, $next_match_pointer[
'close'], $i);
2325 if ($close_pos ==
false) {
2328 $i = $close_pos + $next_match_pointer[
'close_strlen'];
2329 if ($i == $length) {
2332 if (
$code[$i] == $next_match_pointer[
'open'][0] && ($next_match_pointer[
'open_strlen'] == 1 ||
2333 substr(
$code, $i, $next_match_pointer[
'open_strlen']) == $next_match_pointer[
'open'])) {
2335 foreach ($matches as $submatches) {
2336 foreach ($submatches as $match) {
2337 if ($match[
'next_match'] == $i) {
2348 $close_pos = $next_match_pointer[
'close_pos'] + $next_match_pointer[
'close_strlen'];
2352 if ($close_pos ===
false) {
2354 $parts[$k][1] = substr(
$code, $next_match_pos);
2358 $parts[$k][1] = substr(
$code, $next_match_pos, $i - $next_match_pos);
2362 unset($delim_copy, $next_match_pointer, $next_match_pos, $matches);
2365 if ($num_parts == 1 && $this->strict_mode ==
GESHI_MAYBE) {
2401 $hq = isset($this->language_data[
'HARDQUOTE']) ? $this->language_data[
'HARDQUOTE'][0] :
false;
2402 $hq_strlen = strlen($hq);
2410 $escaped_escape_char = $this->
hsc($this->language_data[
'ESCAPE_CHAR']);
2413 $sc_disallowed_before =
"";
2414 $sc_disallowed_after =
"";
2416 if (isset($this->language_data[
'PARSER_CONTROL'])) {
2417 if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'])) {
2418 if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_BEFORE'])) {
2419 $sc_disallowed_before = $this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_BEFORE'];
2421 if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_AFTER'])) {
2422 $sc_disallowed_after = $this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_AFTER'];
2428 $is_string_starter =
array();
2429 if ($this->lexic_permissions[
'STRINGS']) {
2430 foreach ($this->language_data[
'QUOTEMARKS'] as $quotemark) {
2431 if (!isset($is_string_starter[$quotemark[0]])) {
2432 $is_string_starter[$quotemark[0]] = (
string)$quotemark;
2433 } elseif (is_string($is_string_starter[$quotemark[0]])) {
2434 $is_string_starter[$quotemark[0]] =
array(
2435 $is_string_starter[$quotemark[0]],
2438 $is_string_starter[$quotemark[0]][] = $quotemark;
2446 for ($key = 0; $key < $num_parts; ++$key) {
2452 $endresult .= $this->
hsc($parts[$key][1]);
2453 unset($parts[$key]);
2458 $part = $parts[$key][1];
2460 $highlight_part =
true;
2461 if ($this->strict_mode && !is_null($parts[$key][0])) {
2463 $script_key = $parts[$key][0];
2464 $highlight_part = $this->language_data[
'HIGHLIGHT_STRICT_BLOCK'][$script_key];
2465 if ($this->language_data[
'STYLES'][
'SCRIPT'][$script_key] !=
'' &&
2466 $this->lexic_permissions[
'SCRIPT']) {
2469 if (!$this->use_classes &&
2470 $this->language_data[
'STYLES'][
'SCRIPT'][$script_key] !=
'') {
2471 $attributes =
' style="' . $this->language_data[
'STYLES'][
'SCRIPT'][$script_key] .
'"';
2473 $attributes =
' class="sc' . $script_key .
'"';
2475 $result .=
"<span$attributes>";
2476 $STRICTATTRS = $attributes;
2480 if ($highlight_part) {
2486 $next_comment_regexp_key =
'';
2487 $next_comment_regexp_pos = -1;
2488 $next_comment_multi_pos = -1;
2489 $next_comment_single_pos = -1;
2490 $comment_regexp_cache_per_key =
array();
2491 $comment_multi_cache_per_key =
array();
2492 $comment_single_cache_per_key =
array();
2493 $next_open_comment_multi =
'';
2494 $next_comment_single_key =
'';
2495 $escape_regexp_cache_per_key =
array();
2496 $next_escape_regexp_key =
'';
2497 $next_escape_regexp_pos = -1;
2499 $length = strlen($part);
2500 for ($i = 0; $i < $length; ++$i) {
2506 if (isset($this->language_data[
'COMMENT_REGEXP']) && $next_comment_regexp_pos < $i) {
2507 $next_comment_regexp_pos = $length;
2508 foreach ($this->language_data[
'COMMENT_REGEXP'] as $comment_key => $regexp) {
2510 if (isset($comment_regexp_cache_per_key[$comment_key]) &&
2511 ($comment_regexp_cache_per_key[$comment_key][
'pos'] >= $i ||
2512 $comment_regexp_cache_per_key[$comment_key][
'pos'] ===
false)) {
2514 if ($comment_regexp_cache_per_key[$comment_key][
'pos'] ===
false) {
2518 $match_i = $comment_regexp_cache_per_key[$comment_key][
'pos'];
2521 (
GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $i), $match, PREG_OFFSET_CAPTURE)) ||
2522 (!
GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $i))
2524 $match_i = $match[0][1];
2529 $comment_regexp_cache_per_key[$comment_key] =
array(
2530 'key' => $comment_key,
2531 'length' => strlen($match[0][0]),
2535 $comment_regexp_cache_per_key[$comment_key][
'pos'] =
false;
2539 if ($match_i !==
false && $match_i < $next_comment_regexp_pos) {
2540 $next_comment_regexp_pos = $match_i;
2541 $next_comment_regexp_key = $comment_key;
2542 if ($match_i === $i) {
2549 $string_started =
false;
2551 if (isset($is_string_starter[$char])) {
2556 if (is_array($is_string_starter[$char])) {
2558 foreach ($is_string_starter[$char] as $testchar) {
2559 if ($testchar === substr($part, $i, strlen($testchar)) &&
2560 strlen($testchar) > strlen($char_new)) {
2561 $char_new = $testchar;
2562 $string_started =
true;
2565 if ($string_started) {
2569 $testchar = $is_string_starter[$char];
2570 if ($testchar === substr($part, $i, strlen($testchar))) {
2572 $string_started =
true;
2575 $char_len = strlen($char);
2578 if ($string_started && ($i != $next_comment_regexp_pos)) {
2580 $string_key = array_search($char, $this->language_data[
'QUOTEMARKS']);
2581 if (!isset($this->language_data[
'STYLES'][
'STRINGS'][$string_key]) ||
2582 !isset($this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$string_key])) {
2588 $stuff_to_parse =
'';
2590 if (!$this->use_classes) {
2591 $string_attributes =
' style="' . $this->language_data[
'STYLES'][
'STRINGS'][$string_key] .
'"';
2593 $string_attributes =
' class="st'.$string_key.
'"';
2597 $string =
"<span$string_attributes>" .
GeSHi::hsc($char);
2599 $string_open =
true;
2601 if(empty($this->language_data[
'ESCAPE_REGEXP'])) {
2602 $next_escape_regexp_pos = $length;
2607 $close_pos = strpos($part, $char,
$start);
2608 if(
false === $close_pos) {
2609 $close_pos = $length;
2612 if($this->lexic_permissions[
'ESCAPE_CHAR']) {
2614 if (isset($this->language_data[
'ESCAPE_REGEXP']) && $next_escape_regexp_pos <
$start) {
2615 $next_escape_regexp_pos = $length;
2616 foreach ($this->language_data[
'ESCAPE_REGEXP'] as $escape_key => $regexp) {
2618 if (isset($escape_regexp_cache_per_key[$escape_key]) &&
2619 ($escape_regexp_cache_per_key[$escape_key][
'pos'] >=
$start ||
2620 $escape_regexp_cache_per_key[$escape_key][
'pos'] ===
false)) {
2622 if ($escape_regexp_cache_per_key[$escape_key][
'pos'] ===
false) {
2626 $match_i = $escape_regexp_cache_per_key[$escape_key][
'pos'];
2632 $match_i = $match[0][1];
2637 $escape_regexp_cache_per_key[$escape_key] =
array(
2638 'key' => $escape_key,
2639 'length' => strlen($match[0][0]),
2643 $escape_regexp_cache_per_key[$escape_key][
'pos'] =
false;
2647 if ($match_i !==
false && $match_i < $next_escape_regexp_pos) {
2648 $next_escape_regexp_pos = $match_i;
2649 $next_escape_regexp_key = $escape_key;
2650 if ($match_i ===
$start) {
2658 if(
'' != $this->language_data[
'ESCAPE_CHAR']) {
2659 $simple_escape = strpos($part, $this->language_data[
'ESCAPE_CHAR'],
$start);
2660 if(
false === $simple_escape) {
2661 $simple_escape = $length;
2664 $simple_escape = $length;
2667 $next_escape_regexp_pos = $length;
2668 $simple_escape = $length;
2671 if($simple_escape < $next_escape_regexp_pos &&
2672 $simple_escape < $length &&
2673 $simple_escape < $close_pos) {
2675 $es_pos = $simple_escape;
2681 if (!$this->use_classes) {
2682 $escape_char_attributes =
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][0] .
'"';
2684 $escape_char_attributes =
' class="es0"';
2688 $string .=
"<span$escape_char_attributes>" .
2689 GeSHi::hsc($this->language_data[
'ESCAPE_CHAR']);
2692 $es_char = $part[$es_pos + 1];
2693 if ($es_char ==
"\n") {
2695 $string .=
"</span>\n";
2697 } elseif (ord($es_char) >= 128) {
2700 if(function_exists(
'mb_substr')) {
2701 $es_char_m = mb_substr(substr($part, $es_pos+1, 16), 0, 1, $this->encoding);
2702 $string .= $es_char_m .
'</span>';
2704 if(preg_match(
"/[\xC2-\xDF][\x80-\xBF]".
2705 "|\xE0[\xA0-\xBF][\x80-\xBF]".
2706 "|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}".
2707 "|\xED[\x80-\x9F][\x80-\xBF]".
2708 "|\xF0[\x90-\xBF][\x80-\xBF]{2}".
2709 "|[\xF1-\xF3][\x80-\xBF]{3}".
2710 "|\xF4[\x80-\x8F][\x80-\xBF]{2}/s",
2711 $part, $es_char_m, null, $es_pos + 1)) {
2712 $es_char_m = $es_char_m[0];
2714 $es_char_m = $es_char;
2716 $string .= $this->
hsc($es_char_m) .
'</span>';
2718 $es_char_m = $this->
hsc($es_char);
2720 $start = $es_pos + strlen($es_char_m) + 1;
2722 $string .= $this->
hsc($es_char) .
'</span>';
2725 } elseif ($next_escape_regexp_pos < $length &&
2726 $next_escape_regexp_pos < $close_pos) {
2727 $es_pos = $next_escape_regexp_pos;
2732 $escape = $escape_regexp_cache_per_key[$next_escape_regexp_key];
2733 $escape_str = substr($part, $es_pos, $escape[
'length']);
2734 $escape_key = $escape[
'key'];
2737 if (!$this->use_classes) {
2738 $escape_char_attributes =
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$escape_key] .
'"';
2740 $escape_char_attributes =
' class="es' . $escape_key .
'"';
2744 $string .=
"<span$escape_char_attributes>" .
2745 $this->
hsc($escape_str) .
'</span>';
2747 $start = $es_pos + $escape[
'length'];
2750 $string .= $this->
hsc(substr($part,
$start, $close_pos -
$start + $char_len)) .
'</span>';
2751 $start = $close_pos + $char_len;
2752 $string_open =
false;
2754 }
while($string_open);
2756 if ($check_linenumbers) {
2762 $string = str_replace(
"\n",
"</span>\n<span$string_attributes>", $string);
2769 } elseif ($this->lexic_permissions[
'STRINGS'] && $hq && $hq[0] == $char &&
2770 substr($part, $i, $hq_strlen) == $hq && ($i != $next_comment_regexp_pos)) {
2772 if (!$this->use_classes) {
2773 $string_attributes =
' style="' . $this->language_data[
'STYLES'][
'STRINGS'][
'HARD'] .
'"';
2774 $escape_char_attributes =
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][
'HARD'] .
'"';
2776 $string_attributes =
' class="st_h"';
2777 $escape_char_attributes =
' class="es_h"';
2781 $stuff_to_parse =
'';
2787 $start = $i + $hq_strlen;
2788 while ($close_pos = strpos($part, $this->language_data[
'HARDQUOTE'][1],
$start)) {
2790 if ($this->lexic_permissions[
'ESCAPE_CHAR'] && $part[$close_pos - 1] == $this->language_data[
'HARDCHAR'] &&
2791 (($i + $hq_strlen) != ($close_pos))) {
2793 foreach ($this->language_data[
'HARDESCAPE'] as $hardescape) {
2794 if (substr($part, $close_pos - 1, strlen($hardescape)) == $hardescape) {
2796 $escape_char_pos = $close_pos - 1;
2797 while ($escape_char_pos > 0
2798 && $part[$escape_char_pos - 1] == $this->language_data[
'HARDCHAR']) {
2801 if (($close_pos - $escape_char_pos) & 1) {
2816 $close_pos = $length;
2820 $string = substr($part, $i, $close_pos - $i + 1);
2825 if ($this->lexic_permissions[
'ESCAPE_CHAR'] && $this->language_data[
'ESCAPE_CHAR']) {
2828 while ($es_pos = strpos($string, $this->language_data[
'ESCAPE_CHAR'],
$start)) {
2832 foreach ($this->language_data[
'HARDESCAPE'] as $hardescape) {
2833 if (substr($string, $es_pos, strlen($hardescape)) == $hardescape) {
2835 $new_string .=
"<span$escape_char_attributes>" .
2836 $this->
hsc($hardescape) .
'</span>';
2837 $start = $es_pos + strlen($hardescape);
2844 while (isset($string[$es_pos + $c]) && isset($string[$es_pos + $c + 1])
2845 && $string[$es_pos + $c] == $this->language_data[
'ESCAPE_CHAR']
2846 && $string[$es_pos + $c + 1] == $this->language_data[
'ESCAPE_CHAR']) {
2850 $new_string .=
"<span$escape_char_attributes>" .
2851 str_repeat($escaped_escape_char, $c) .
2856 $new_string .= $escaped_escape_char;
2860 $string = $new_string . $this->
hsc(substr($string,
$start));
2862 $string = $this->
hsc($string);
2865 if ($check_linenumbers) {
2871 $string = str_replace(
"\n",
"</span>\n<span$string_attributes>", $string);
2874 $result .=
"<span$string_attributes>" . $string .
'</span>';
2879 if ($i == $next_comment_regexp_pos) {
2880 $COMMENT_MATCHED =
true;
2881 $comment = $comment_regexp_cache_per_key[$next_comment_regexp_key];
2882 $test_str = $this->
hsc(substr($part, $i,
$comment[
'length']));
2885 if ($this->lexic_permissions[
'COMMENTS'][
'MULTI']) {
2886 if (!$this->use_classes) {
2887 $attributes =
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][
$comment[
'key']] .
'"';
2889 $attributes =
' class="co' .
$comment[
'key'] .
'"';
2892 $test_str =
"<span$attributes>" . $test_str .
"</span>";
2895 if ($check_linenumbers) {
2897 $test_str = str_replace(
2898 "\n",
"</span>\n<span$attributes>",
2899 str_replace(
"\n ",
"\n ", $test_str)
2908 $stuff_to_parse =
'';
2912 if (!$COMMENT_MATCHED) {
2914 if (!empty($this->language_data[
'COMMENT_MULTI']) && $next_comment_multi_pos < $i) {
2915 $next_comment_multi_pos = $length;
2916 foreach ($this->language_data[
'COMMENT_MULTI'] as $open => $close) {
2918 if (isset($comment_multi_cache_per_key[$open]) &&
2919 ($comment_multi_cache_per_key[$open] >= $i ||
2920 $comment_multi_cache_per_key[$open] ===
false)) {
2922 if ($comment_multi_cache_per_key[$open] ===
false) {
2926 $match_i = $comment_multi_cache_per_key[$open];
2927 } elseif (($match_i = stripos($part, $open, $i)) !==
false) {
2928 $comment_multi_cache_per_key[$open] = $match_i;
2930 $comment_multi_cache_per_key[$open] =
false;
2933 if ($match_i !==
false && $match_i < $next_comment_multi_pos) {
2934 $next_comment_multi_pos = $match_i;
2935 $next_open_comment_multi = $open;
2936 if ($match_i === $i) {
2942 if ($i == $next_comment_multi_pos) {
2943 $open = $next_open_comment_multi;
2944 $close = $this->language_data[
'COMMENT_MULTI'][$open];
2945 $open_strlen = strlen($open);
2946 $close_strlen = strlen($close);
2947 $COMMENT_MATCHED =
true;
2948 $test_str_match = $open;
2950 if ($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
2953 if (!$this->use_classes) {
2954 $attributes =
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][
'MULTI'] .
'"';
2956 $attributes =
' class="coMULTI"';
2958 $test_str =
"<span$attributes>" . $this->
hsc($open);
2960 if (!$this->use_classes) {
2961 $attributes =
' style="' . $this->important_styles .
'"';
2963 $attributes =
' class="imp"';
2968 $test_str =
"<span$attributes>";
2971 $test_str = $this->
hsc($open);
2974 $close_pos = strpos( $part, $close, $i + $open_strlen );
2976 if ($close_pos ===
false) {
2977 $close_pos = $length;
2981 $rest_of_comment = $this->
hsc(substr($part, $i + $open_strlen, $close_pos - $i - $open_strlen + $close_strlen));
2982 if (($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
2984 $check_linenumbers) {
2987 $test_str .= str_replace(
2988 "\n",
"</span>\n<span$attributes>",
2989 str_replace(
"\n ",
"\n ", $rest_of_comment)
2992 $test_str .= $rest_of_comment;
2995 if ($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
2997 $test_str .=
'</span>';
3000 $i = $close_pos + $close_strlen - 1;
3004 $stuff_to_parse =
'';
3009 if (!$COMMENT_MATCHED) {
3011 if (!empty($this->language_data[
'COMMENT_SINGLE']) && $next_comment_single_pos < $i) {
3012 $next_comment_single_pos = $length;
3013 foreach ($this->language_data[
'COMMENT_SINGLE'] as $comment_key => $comment_mark) {
3015 if (isset($comment_single_cache_per_key[$comment_key]) &&
3016 ($comment_single_cache_per_key[$comment_key] >= $i ||
3017 $comment_single_cache_per_key[$comment_key] ===
false)) {
3019 if ($comment_single_cache_per_key[$comment_key] ===
false) {
3023 $match_i = $comment_single_cache_per_key[$comment_key];
3027 ($match_i = stripos($part, $comment_mark, $i)) !==
false) ||
3030 (($match_i = strpos($part, $comment_mark, $i)) !==
false))) {
3031 $comment_single_cache_per_key[$comment_key] = $match_i;
3033 $comment_single_cache_per_key[$comment_key] =
false;
3036 if ($match_i !==
false && $match_i < $next_comment_single_pos) {
3037 $next_comment_single_pos = $match_i;
3038 $next_comment_single_key = $comment_key;
3039 if ($match_i === $i) {
3045 if ($next_comment_single_pos == $i) {
3046 $comment_key = $next_comment_single_key;
3047 $comment_mark = $this->language_data[
'COMMENT_SINGLE'][$comment_key];
3048 $com_len = strlen($comment_mark);
3052 if ((empty($sc_disallowed_before) || ($i == 0) ||
3053 (
false === strpos($sc_disallowed_before, $part[$i-1]))) &&
3054 (empty($sc_disallowed_after) || ($length <= $i + $com_len) ||
3055 (
false === strpos($sc_disallowed_after, $part[$i + $com_len]))))
3058 $COMMENT_MATCHED =
true;
3059 if ($this->lexic_permissions[
'COMMENTS'][$comment_key]) {
3060 if (!$this->use_classes) {
3061 $attributes =
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][$comment_key] .
'"';
3063 $attributes =
' class="co' . $comment_key .
'"';
3065 $test_str =
"<span$attributes>" . $this->
hsc($this->
change_case($comment_mark));
3067 $test_str = $this->
hsc($comment_mark);
3071 $close_pos = strpos($part,
"\n", $i);
3073 if ($close_pos ===
false) {
3074 $close_pos = $length;
3077 $test_str .= $this->
hsc(substr($part, $i + $com_len, $close_pos - $i - $com_len));
3078 if ($this->lexic_permissions[
'COMMENTS'][$comment_key]) {
3079 $test_str .=
"</span>";
3091 $stuff_to_parse =
'';
3098 if (!$COMMENT_MATCHED) {
3099 $stuff_to_parse .= $char;
3103 $COMMENT_MATCHED =
false;
3108 $stuff_to_parse =
'';
3113 if ($STRICTATTRS !=
'') {
3114 $result = str_replace(
"\n",
"</span>\n<span$STRICTATTRS>",
$result);
3119 unset($part, $parts[$key],
$result);
3125 $endresult = str_replace(
array(
'<SEMI>',
'<PIPE>'),
array(
';',
'|'), $endresult);
3134 $this->
set_time($start_time, microtime());
3150 if (
false !== strpos(
$result,
"\t")) {
3151 $lines = explode(
"\n",
$result);
3154 $tab_string =
' ' . str_repeat(
' ', $tab_width);
3156 for ($key = 0,
$n = count($lines); $key <
$n; $key++) {
3157 $line = $lines[$key];
3158 if (
false === strpos($line,
"\t")) {
3163 $length = strlen($line);
3167 for ($i = 0; $i < $length; ++$i) {
3180 $lines[$key] .= $char;
3181 } elseif (
'<' == $char) {
3183 $lines[$key] .=
'<';
3184 } elseif (
'&' == $char) {
3185 $substr = substr($line, $i + 3, 5);
3186 $posi = strpos($substr,
';');
3187 if (
false === $posi) {
3192 $lines[$key] .= $char;
3193 } elseif (
"\t" == $char) {
3201 $tab_end_width = $tab_width - ($pos %
$tab_width);
3202 if (($pos & 1) || 1 == $tab_end_width) {
3203 $str .= substr($tab_string, 6, $tab_end_width);
3205 $str .= substr($tab_string, 0, $tab_end_width+5);
3207 $lines[$key] .= $str;
3208 $pos += $tab_end_width;
3210 if (
false === strpos($line,
"\t", $i + 1)) {
3211 $lines[$key] .= substr($line, $i + 1);
3214 } elseif (0 == $pos &&
' ' == $char) {
3215 $lines[$key] .=
' ';
3218 $lines[$key] .= $char;
3223 $result = implode(
"\n", $lines);
3232 if ($this->line_ending === null) {
3249 switch ($this->language_data[
'CASE_KEYWORDS']) {
3251 return strtoupper($instr);
3253 return strtolower($instr);
3271 $keyword = $match[0];
3272 $keyword_match = $match[1];
3277 if ($this->keyword_links) {
3280 if (isset($this->language_data[
'URLS'][$k]) &&
3281 $this->language_data[
'URLS'][$k] !=
'') {
3287 if (!$this->language_data[
'CASE_SENSITIVE'][$k] &&
3288 strpos($this->language_data[
'URLS'][$k],
'{FNAME}') !==
false) {
3289 foreach ($this->language_data[
'KEYWORDS'][$k] as $word) {
3290 if (strcasecmp($word, $keyword_match) == 0) {
3295 $word = $keyword_match;
3298 $before =
'<|UR1|"' .
3306 str_replace(
'+',
'%20', urlencode($this->
hsc($word))),
3307 str_replace(
'+',
'%20', urlencode($this->
hsc(strtolower($word)))),
3308 str_replace(
'+',
'%20', urlencode($this->
hsc(strtoupper($word)))),
3310 $this->language_data[
'URLS'][$k]
3316 return $before .
'<|/'. $k .
'/>' . $this->
change_case($keyword) .
'|>' . $after;
3331 return ' style="' . call_user_func($this->language_data[
'STYLES'][
'REGEXPS'][$this->_rx_key], $matches[1]) .
'"'. $matches[1] .
'|>';
3347 if ($this->_hmr_replace) {
3351 foreach (array_keys($matches) as $k) {
3352 $search[] =
'\\' . $k;
3355 $before = str_replace($search, $matches, $before);
3356 $after = str_replace($search, $matches, $after);
3357 $replace = str_replace($search, $matches, $replace);
3359 $replace = $matches[0];
3362 .
'<|!REG3XP' . $this->_hmr_key .
'!>' 3363 . str_replace(
"\n",
"|>\n<|!REG3XP" . $this->_hmr_key .
'!>', $replace)
3378 $stuff_to_parse =
' ' . $this->
hsc($stuff_to_parse);
3381 $disallowed_before =
"(?<![a-zA-Z0-9\$_\|\#|^&";
3382 $disallowed_after =
"(?![a-zA-Z0-9_\|%\\-&;";
3383 if ($this->lexic_permissions[
'STRINGS']) {
3384 $quotemarks = preg_quote(implode($this->language_data[
'QUOTEMARKS']),
'/');
3385 $disallowed_before .= $quotemarks;
3386 $disallowed_after .= $quotemarks;
3388 $disallowed_before .=
"])";
3389 $disallowed_after .=
"])";
3391 $parser_control_pergroup =
false;
3392 if (isset($this->language_data[
'PARSER_CONTROL'])) {
3393 if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'])) {
3395 if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_BEFORE'])) {
3396 $disallowed_before = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_BEFORE'];
3399 if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_AFTER'])) {
3400 $disallowed_after = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_AFTER'];
3403 $parser_control_pergroup = (count($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS']) -
$x) > 0;
3407 foreach (array_keys($this->language_data[
'KEYWORDS']) as $k) {
3408 if (!isset($this->lexic_permissions[
'KEYWORDS'][$k]) ||
3409 $this->lexic_permissions[
'KEYWORDS'][$k]) {
3411 $case_sensitive = $this->language_data[
'CASE_SENSITIVE'][$k];
3412 $modifiers = $case_sensitive ?
'' :
'i';
3415 $disallowed_before_local = $disallowed_before;
3416 $disallowed_after_local = $disallowed_after;
3417 if ($parser_control_pergroup && isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k])) {
3418 if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_BEFORE'])) {
3419 $disallowed_before_local =
3420 $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_BEFORE'];
3423 if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_AFTER'])) {
3424 $disallowed_after_local =
3425 $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_AFTER'];
3429 $this->_kw_replace_group = $k;
3433 for ($set = 0, $set_length = count($this->language_data[
'CACHED_KEYWORD_LISTS'][$k]); $set < $set_length; ++$set) {
3434 $keywordset =& $this->language_data[
'CACHED_KEYWORD_LISTS'][$k][$set];
3438 $stuff_to_parse = preg_replace_callback(
3439 "/$disallowed_before_local({$keywordset})(?!<DOT>(?:htm|php|aspx?))$disallowed_after_local/$modifiers",
3440 array($this,
'handle_keyword_replace'),
3448 foreach ($this->language_data[
'REGEXPS'] as $key => $regexp) {
3449 if ($this->lexic_permissions[
'REGEXPS'][$key]) {
3450 if (is_array($regexp)) {
3455 $this->_hmr_key = $key;
3457 $stuff_to_parse = preg_replace_callback(
3458 "/" . $regexp[
GESHI_SEARCH] .
"/{$regexp[GESHI_MODIFIERS]}",
3459 array($this,
'handle_multiline_regexps'),
3461 $this->_hmr_replace =
false;
3462 $this->_hmr_before =
'';
3463 $this->_hmr_after =
'';
3465 $stuff_to_parse = preg_replace(
3473 $this->_hmr_key = $key;
3474 $stuff_to_parse = preg_replace_callback(
"/(" . $regexp .
")/",
3475 array($this,
'handle_multiline_regexps'), $stuff_to_parse);
3476 $this->_hmr_key =
'';
3478 $stuff_to_parse = preg_replace(
"/(" . $regexp .
")/",
"<|!REG3XP$key!>\\1|>", $stuff_to_parse);
3485 $numbers_found =
false;
3487 if ($this->lexic_permissions[
'NUMBERS'] && preg_match($this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'], $stuff_to_parse )) {
3488 $numbers_found =
true;
3491 foreach($this->language_data[
'NUMBERS_RXCACHE'] as $id => $regexp) {
3493 $stuff_to_parse = preg_replace($regexp,
"<|/NUM!$id/>\\1|>", $stuff_to_parse);
3500 foreach (array_keys($this->language_data[
'KEYWORDS']) as $k) {
3501 if (!$this->use_classes) {
3502 $attributes =
' style="' .
3503 (isset($this->language_data[
'STYLES'][
'KEYWORDS'][$k]) ?
3504 $this->language_data[
'STYLES'][
'KEYWORDS'][$k] :
"") .
'"';
3506 $attributes =
' class="kw' . $k .
'"';
3508 $stuff_to_parse = str_replace(
"<|/$k/>",
"<|$attributes>", $stuff_to_parse);
3511 if ($numbers_found) {
3513 foreach($this->language_data[
'NUMBERS_RXCACHE'] as $id => $regexp) {
3518 if (!$this->use_classes) {
3519 $attributes =
' style="' . $this->language_data[
'STYLES'][
'NUMBERS'][$id] .
'"';
3521 $attributes =
' class="nu'.$id.
'"';
3525 $stuff_to_parse = str_replace(
"/NUM!$id/", $attributes, $stuff_to_parse);
3531 if ($this->lexic_permissions[
'METHODS'] && $this->language_data[
'OOLANG']) {
3532 $oolang_spaces =
"[\s]*";
3533 $oolang_before =
"";
3534 $oolang_after =
"[a-zA-Z][a-zA-Z0-9_]*";
3535 if (isset($this->language_data[
'PARSER_CONTROL'])) {
3536 if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'])) {
3537 if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_BEFORE'])) {
3538 $oolang_before = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_BEFORE'];
3540 if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_AFTER'])) {
3541 $oolang_after = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_AFTER'];
3543 if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_SPACES'])) {
3544 $oolang_spaces = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_SPACES'];
3549 foreach ($this->language_data[
'OBJECT_SPLITTERS'] as $key => $splitter) {
3550 if (
false !== strpos($stuff_to_parse, $splitter)) {
3551 if (!$this->use_classes) {
3552 $attributes =
' style="' . $this->language_data[
'STYLES'][
'METHODS'][$key] .
'"';
3554 $attributes =
' class="me' . $key .
'"';
3556 $stuff_to_parse = preg_replace(
"/($oolang_before)(" . preg_quote($this->language_data[
'OBJECT_SPLITTERS'][$key],
'/') .
")($oolang_spaces)($oolang_after)/",
"\\1\\2\\3<|$attributes>\\4|>", $stuff_to_parse);
3567 if ($this->lexic_permissions[
'BRACKETS']) {
3568 $stuff_to_parse = str_replace( $this->language_data[
'CACHE_BRACKET_MATCH'],
3569 $this->language_data[
'CACHE_BRACKET_REPLACE'], $stuff_to_parse );
3574 if ($this->lexic_permissions[
'SYMBOLS'] && !empty($this->language_data[
'SYMBOLS'])) {
3576 $n_symbols = preg_match_all(
"/<\|(?:<DOT>|[^>])+>(?:(?!\|>).*?)\|>|<\/a>|(?:" . $this->language_data[
'SYMBOL_SEARCH'] .
")+(?![^<]+?>)/", $stuff_to_parse, $pot_symbols, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
3578 for ($s_id = 0; $s_id < $n_symbols; ++$s_id) {
3579 $symbol_match = $pot_symbols[$s_id][0][0];
3580 if (strpos($symbol_match,
'<') !==
false || strpos($symbol_match,
'>') !==
false) {
3584 if(strpos($symbol_match,
'<SEMI>') ===
false &&
3585 strpos($symbol_match,
'<PIPE>') ===
false) {
3592 $symbol_length = strlen($symbol_match);
3593 $symbol_offset = $pot_symbols[$s_id][0][1];
3594 unset($pot_symbols[$s_id]);
3598 if ($this->language_data[
'MULTIPLE_SYMBOL_GROUPS']) {
3601 preg_match_all(
"/" . $this->language_data[
'SYMBOL_SEARCH'] .
"/", $symbol_match, $sym_match_syms, PREG_PATTERN_ORDER);
3602 foreach ($sym_match_syms[0] as $sym_ms) {
3604 if (isset($this->language_data[
'SYMBOL_DATA'][$sym_ms])
3605 && ($this->language_data[
'SYMBOL_DATA'][$sym_ms] != $old_sym)) {
3606 if (-1 != $old_sym) {
3609 $old_sym = $this->language_data[
'SYMBOL_DATA'][$sym_ms];
3610 if (!$this->use_classes) {
3611 $symbol_hl .=
'<| style="' . $this->language_data[
'STYLES'][
'SYMBOLS'][$old_sym] .
'">';
3613 $symbol_hl .=
'<| class="sy' . $old_sym .
'">';
3616 $symbol_hl .= $sym_ms;
3618 unset($sym_match_syms);
3622 if (-1 != $old_sym) {
3626 if (!$this->use_classes) {
3627 $symbol_hl =
'<| style="' . $this->language_data[
'STYLES'][
'SYMBOLS'][0] .
'">';
3629 $symbol_hl =
'<| class="sy0">';
3631 $symbol_hl .= $symbol_match .
'|>';
3634 $stuff_to_parse = substr_replace($stuff_to_parse, $symbol_hl, $symbol_offset + $global_offset, $symbol_length);
3638 $global_offset += strlen($symbol_hl) - $symbol_length;
3644 foreach (array_keys($this->language_data[
'REGEXPS']) as $key) {
3645 if ($this->lexic_permissions[
'REGEXPS'][$key]) {
3646 if (is_callable($this->language_data[
'STYLES'][
'REGEXPS'][$key])) {
3647 $this->_rx_key = $key;
3648 $stuff_to_parse = preg_replace_callback(
"/!REG3XP$key!(.*)\|>/U",
3649 array($this,
'handle_regexps_callback'),
3652 if (!$this->use_classes) {
3653 $attributes =
' style="' . $this->language_data[
'STYLES'][
'REGEXPS'][$key] .
'"';
3655 if (is_array($this->language_data[
'REGEXPS'][$key]) &&
3656 array_key_exists(
GESHI_CLASS, $this->language_data[
'REGEXPS'][$key])) {
3657 $attributes =
' class="' .
3658 $this->language_data[
'REGEXPS'][$key][
GESHI_CLASS] .
'"';
3660 $attributes =
' class="re' . $key .
'"';
3663 $stuff_to_parse = str_replace(
"!REG3XP$key!",
"$attributes", $stuff_to_parse);
3669 $stuff_to_parse = str_replace(
'<DOT>',
'.', $stuff_to_parse);
3672 if ($this->use_classes) {
3673 $stuff_to_parse = str_replace(
'<|UR1|',
'<a' . $this->link_target .
' href=', $stuff_to_parse);
3675 $stuff_to_parse = str_replace(
'<|UR1|',
'<a' . $this->link_target .
' style="' . $this->link_styles[GESHI_LINK] .
'" href=', $stuff_to_parse);
3678 $stuff_to_parse = str_replace(
'<|UR1|',
'<a' . $this->link_target .
' href=', $stuff_to_parse);
3685 $stuff_to_parse = str_replace(
'<|',
'<span', $stuff_to_parse);
3686 $stuff_to_parse = str_replace (
'|>',
'</span>', $stuff_to_parse );
3687 return substr($stuff_to_parse, 1);
3699 $start = explode(
' ', $start_time);
3700 $end = explode(
' ', $end_time);
3721 $arrays = func_get_args();
3722 $narrays = count($arrays);
3726 for ($i = 0; $i < $narrays; $i ++) {
3727 if (!is_array($arrays[$i])) {
3729 trigger_error(
'Argument #' . ($i+1) .
' is not an array - trying to merge array with scalar! Returning false!', E_USER_WARNING);
3738 for ($i = 1; $i < $narrays; $i ++) {
3739 foreach ($arrays[$i] as $key => $value) {
3740 if (is_array($value) && isset(
$ret[$key])) {
3745 $ret[$key] = $value;
3762 if ($file_name == $this->loaded_language) {
3768 $this->loaded_language = $file_name;
3769 $this->parse_cache_built =
false;
3771 $language_data =
array();
3781 $this->strict_mode = $this->language_data[
'STRICT_MODE_APPLIES'];
3785 foreach (array_keys($this->language_data[
'KEYWORDS']) as $key) {
3786 if (!empty($this->language_data[
'KEYWORDS'][$key])) {
3787 $this->lexic_permissions[
'KEYWORDS'][$key] =
true;
3789 $this->lexic_permissions[
'KEYWORDS'][$key] =
false;
3793 foreach (array_keys($this->language_data[
'COMMENT_SINGLE']) as $key) {
3794 $this->lexic_permissions[
'COMMENTS'][$key] =
true;
3796 foreach (array_keys($this->language_data[
'REGEXPS']) as $key) {
3797 $this->lexic_permissions[
'REGEXPS'][$key] =
true;
3804 if (!empty($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS'])) {
3805 foreach ($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS'] as $flag => $value) {
3808 if ($flag ==
'ALL') {
3812 if (!isset($this->lexic_permissions[$flag])) {
3816 if (is_array($this->lexic_permissions[$flag])) {
3817 foreach ($this->lexic_permissions[$flag] as $key => $val) {
3818 $this->lexic_permissions[$flag][$key] = $perm;
3821 $this->lexic_permissions[$flag] = $perm;
3824 unset($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS']);
3829 if(!isset($this->language_data[
'HARDCHAR'])) {
3830 $this->language_data[
'HARDCHAR'] = $this->language_data[
'ESCAPE_CHAR'];
3834 $style_filename = substr($file_name, 0, -4) .
'.style.php';
3835 if (is_readable($style_filename)) {
3837 if (isset($style_data)) {
3842 include $style_filename;
3845 if (isset($style_data) && is_array($style_data)) {
3846 $this->language_data[
'STYLES'] =
3847 $this->
merge_arrays($this->language_data[
'STYLES'], $style_data);
3871 $this->
indent($parsed_code);
3876 $parsed_code = preg_replace(
'#<span[^>]+>(\s*)</span>#',
'\\1', $parsed_code);
3880 if ($this->add_ids && !$this->overall_id) {
3881 $this->overall_id =
'geshi-' . substr(md5(microtime()), 0, 4);
3886 $code = explode(
"\n", $parsed_code);
3887 $parsed_code = $this->
header();
3897 for ($i = 0,
$n = count(
$code); $i <
$n;) {
3903 if (
'' == trim(
$code[$i])) {
3904 $code[$i] =
' ';
3909 $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
3911 if ($this->use_classes) {
3913 $attrs[
'class'][] =
'li2';
3914 $def_attr =
' class="de2"';
3921 $def_attr =
' style="' . $this->code_style .
'"';
3924 if ($this->use_classes) {
3926 $attrs[
'class'][] =
'li1';
3927 $def_attr =
' class="de1"';
3931 $def_attr =
' style="' . $this->code_style .
'"';
3937 $start =
"<pre$def_attr>";
3941 $start =
"<div$def_attr>";
3948 if ($this->add_ids) {
3949 $attrs[
'id'][] =
"$this->overall_id-$i";
3953 if (in_array($i, $this->highlight_extra_lines)) {
3954 if ($this->use_classes) {
3955 if (isset($this->highlight_extra_lines_styles[$i])) {
3956 $attrs[
'class'][] =
"lx$i";
3958 $attrs[
'class'][] =
"ln-xtra";
3967 foreach ($attrs as $key => $attr) {
3968 $attr_string .=
' ' . $key .
'="' . implode(
' ', $attr) .
'"';
3971 $parsed_code .=
"<li$attr_string>$start{$code[$i-1]}$end</li>$ls";
3972 unset(
$code[$i - 1]);
3976 if ($this->use_classes) {
3977 $attributes =
' class="de1"';
3979 $attributes =
' style="'. $this->code_style .
'"';
3982 $parsed_code .=
'<pre'. $attributes .
'>';
3985 if ($this->use_classes) {
3986 $attrs =
' class="ln"';
3988 $attrs =
' style="'. $this->table_linenumber_style .
'"';
3990 $parsed_code .=
'<td'.$attrs.
'><pre'.$attributes.
'>';
3996 for ($i = 0; $i <
$n; ++$i) {
4000 $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
4002 if ($this->use_classes) {
4003 $parsed_code .=
'<span class="xtra li2"><span class="de2">';
4008 $parsed_code .=
'<span style="display:block;' . $this->line_style2 .
'">' 4009 .
'<span style="' . $this->code_style .
'">';
4014 if (in_array($i + 1, $this->highlight_extra_lines)) {
4015 if ($this->use_classes) {
4016 if (isset($this->highlight_extra_lines_styles[$i])) {
4017 $parsed_code .=
"<span class=\"xtra lx$i\">";
4019 $parsed_code .=
"<span class=\"xtra ln-xtra\">";
4022 $parsed_code .=
"<span style=\"display:block;" . $this->
get_line_style($i) .
"\">";
4026 $parsed_code .= $this->line_numbers_start + $i;
4028 $parsed_code .= str_repeat(
'</span>', $close);
4029 } elseif ($i != $n) {
4030 $parsed_code .=
"\n";
4033 $parsed_code .=
'</pre></td><td'.$attributes.
'>';
4035 $parsed_code .=
'<pre'. $attributes .
'>';
4040 for ($i = 0; $i <
$n; ++$i) {
4043 if (
'' == trim(
$code[$i])) {
4044 $code[$i] =
' ';
4048 $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
4050 if ($this->use_classes) {
4051 $parsed_code .=
'<span class="xtra li2"><span class="de2">';
4056 $parsed_code .=
'<span style="display:block;' . $this->line_style2 .
'">' 4057 .
'<span style="' . $this->code_style .
'">';
4062 if (in_array($i + 1, $this->highlight_extra_lines)) {
4063 if ($this->use_classes) {
4064 if (isset($this->highlight_extra_lines_styles[$i])) {
4065 $parsed_code .=
"<span class=\"xtra lx$i\">";
4067 $parsed_code .=
"<span class=\"xtra ln-xtra\">";
4070 $parsed_code .=
"<span style=\"display:block;" . $this->
get_line_style($i) .
"\">";
4075 $parsed_code .=
$code[$i];
4078 $parsed_code .= str_repeat(
'</span>', $close);
4081 elseif ($i + 1 < $n) {
4082 $parsed_code .=
"\n";
4088 $parsed_code .=
'</pre>';
4091 $parsed_code .=
'</td>';
4095 $parsed_code .= $this->
footer();
4112 if ($this->overall_class !=
'') {
4113 $attributes .=
" ".$this->_genCSSName($this->overall_class);
4117 if ($this->overall_id !=
'') {
4118 $attributes .=
" id=\"{$this->overall_id}\"";
4120 if ($this->overall_style !=
'' && !$this->use_classes) {
4121 $attributes .=
' style="' . $this->overall_style .
'"';
4124 $ol_attributes =
'';
4126 if ($this->line_numbers_start != 1) {
4127 $ol_attributes .=
' start="' . $this->line_numbers_start .
'"';
4138 if ($this->use_classes) {
4139 $attr =
' class="head"';
4141 $attr =
" style=\"{$this->header_content_style}\"";
4144 $header =
"<thead><tr><td colspan=\"2\" $attr>$header</td></tr></thead>";
4146 $header =
"<div$attr>$header</div>";
4152 return "$header<ol$attributes$ol_attributes>";
4154 return $header . ($this->force_code_block ?
'<div>' :
'');
4160 return "<pre$attributes>$header<ol$ol_attributes>";
4163 return "<div$attributes>$header<ol$ol_attributes>";
4165 return "<table$attributes>$header<tbody><tr class=\"li1\">";
4169 return "<pre$attributes>$header" .
4170 ($this->force_code_block ?
'<div>' :
'');
4172 return "<div$attributes>$header" .
4173 ($this->force_code_block ?
'<div>' :
'');
4189 $footer = str_replace(
"\n",
'', $footer);;
4193 if ($this->use_classes) {
4194 $attr =
' class="foot"';
4196 $attr =
" style=\"{$this->footer_content_style}\"";
4199 $footer =
"<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
4201 $footer =
"<div$attr>$footer</div>";
4211 return "</ol>$footer</div>";
4213 return ($this->force_code_block ?
'</div>' :
'') .
4218 return "</tr></tbody>$footer</table>";
4220 return ($this->force_code_block ?
'</div>' :
'') .
4225 return "</ol>$footer</pre>";
4227 return ($this->force_code_block ?
'</div>' :
'') .
4242 $keywords = $replacements =
array();
4244 $keywords[] =
'<TIME>';
4245 $keywords[] =
'{TIME}';
4246 $replacements[] = $replacements[] = number_format($time = $this->
get_time(), 3);
4248 $keywords[] =
'<LANGUAGE>';
4249 $keywords[] =
'{LANGUAGE}';
4250 $replacements[] = $replacements[] = $this->language_data[
'LANG_NAME'];
4252 $keywords[] =
'<VERSION>';
4253 $keywords[] =
'{VERSION}';
4256 $keywords[] =
'<SPEED>';
4257 $keywords[] =
'{SPEED}';
4261 $speed = strlen($this->source) /
$time;
4262 if ($speed >= 1024) {
4263 $speed = sprintf(
"%.2f KB/s", $speed / 1024.0);
4265 $speed = sprintf(
"%.0f B/s", $speed);
4268 $replacements[] = $replacements[] = $speed;
4270 return str_replace($keywords, $replacements, $instr);
4326 function hsc($string, $quote_style = ENT_COMPAT) {
4328 static $aTransSpecchar =
array(
4344 switch ($quote_style) {
4346 unset($aTransSpecchar[
'"']);
4349 $aTransSpecchar[
"'"] =
''';
4354 return strtr($string, $aTransSpecchar);
4358 return (is_numeric($name[0]) ?
'_' :
'') . $name;
4380 if(!isset($this->language_data[
'NUMBERS_CACHE'])) {
4387 if ($this->overall_id) {
4388 $selector =
'#' . $this->
_genCSSName($this->overall_id);
4391 if ($this->overall_class) {
4392 $selector .=
'.' . $this->
_genCSSName($this->overall_class);
4398 if (!$economy_mode) {
4399 $stylesheet =
"/**\n".
4400 " * GeSHi Dynamically Generated Stylesheet\n".
4401 " * --------------------------------------\n".
4402 " * Dynamically generated stylesheet for {$this->language}\n".
4403 " * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n".
4404 " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
4405 " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
4406 " * --------------------------------------\n".
4409 $stylesheet =
"/**\n".
4410 " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
4411 " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
4421 $stylesheet .=
"$selector.de1, $selector.de2 {{$this->code_style}}\n";
4426 if ($this->overall_style !=
'') {
4427 $stylesheet .=
"$selector {{$this->overall_style}}\n";
4434 foreach ($this->link_styles as $key =>
$style) {
4438 $stylesheet .=
"{$selector}a:link {{$style}}\n";
4441 $stylesheet .=
"{$selector}a:hover {{$style}}\n";
4444 $stylesheet .=
"{$selector}a:active {{$style}}\n";
4447 $stylesheet .=
"{$selector}a:visited {{$style}}\n";
4455 if ($this->header_content_style !=
'') {
4456 $stylesheet .=
"$selector.head {{$this->header_content_style}}\n";
4458 if ($this->footer_content_style !=
'') {
4459 $stylesheet .=
"$selector.foot {{$this->footer_content_style}}\n";
4464 if ($this->important_styles !=
'') {
4465 $stylesheet .=
"$selector.imp {{$this->important_styles}}\n";
4470 $stylesheet .=
"{$selector}li, {$selector}.li1 {{$this->line_style1}}\n";
4472 if ((!$economy_mode || $this->line_numbers !=
GESHI_NO_LINE_NUMBERS) && $this->table_linenumber_style !=
'') {
4473 $stylesheet .=
"{$selector}.ln {{$this->table_linenumber_style}}\n";
4477 $stylesheet .=
"{$selector}.li2 {{$this->line_style2}}\n";
4481 foreach ($this->language_data[
'STYLES'][
'KEYWORDS'] as $group =>
$styles) {
4482 if (
$styles !=
'' && (!$economy_mode ||
4483 (isset($this->lexic_permissions[
'KEYWORDS'][$group]) &&
4484 $this->lexic_permissions[
'KEYWORDS'][$group]))) {
4485 $stylesheet .=
"$selector.kw$group {{$styles}}\n";
4488 foreach ($this->language_data[
'STYLES'][
'COMMENTS'] as $group =>
$styles) {
4489 if (
$styles !=
'' && (!$economy_mode ||
4490 (isset($this->lexic_permissions[
'COMMENTS'][$group]) &&
4491 $this->lexic_permissions[
'COMMENTS'][$group]) ||
4492 (!empty($this->language_data[
'COMMENT_REGEXP']) &&
4493 !empty($this->language_data[
'COMMENT_REGEXP'][$group])))) {
4494 $stylesheet .=
"$selector.co$group {{$styles}}\n";
4497 foreach ($this->language_data[
'STYLES'][
'ESCAPE_CHAR'] as $group =>
$styles) {
4498 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'ESCAPE_CHAR'])) {
4500 if ($group ===
'HARD') {
4503 $stylesheet .=
"$selector.es$group {{$styles}}\n";
4506 foreach ($this->language_data[
'STYLES'][
'BRACKETS'] as $group =>
$styles) {
4507 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'BRACKETS'])) {
4508 $stylesheet .=
"$selector.br$group {{$styles}}\n";
4511 foreach ($this->language_data[
'STYLES'][
'SYMBOLS'] as $group =>
$styles) {
4512 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'SYMBOLS'])) {
4513 $stylesheet .=
"$selector.sy$group {{$styles}}\n";
4516 foreach ($this->language_data[
'STYLES'][
'STRINGS'] as $group =>
$styles) {
4517 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'STRINGS'])) {
4519 if ($group ===
'HARD') {
4522 $stylesheet .=
"$selector.st$group {{$styles}}\n";
4525 foreach ($this->language_data[
'STYLES'][
'NUMBERS'] as $group =>
$styles) {
4526 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'NUMBERS'])) {
4527 $stylesheet .=
"$selector.nu$group {{$styles}}\n";
4530 foreach ($this->language_data[
'STYLES'][
'METHODS'] as $group =>
$styles) {
4531 if (
$styles !=
'' && (!$economy_mode || $this->lexic_permissions[
'METHODS'])) {
4532 $stylesheet .=
"$selector.me$group {{$styles}}\n";
4536 foreach ($this->language_data[
'STYLES'][
'SCRIPT'] as $group =>
$styles) {
4538 $stylesheet .=
"$selector.sc$group {{$styles}}\n";
4541 foreach ($this->language_data[
'STYLES'][
'REGEXPS'] as $group =>
$styles) {
4542 if (
$styles !=
'' && (!$economy_mode ||
4543 (isset($this->lexic_permissions[
'REGEXPS'][$group]) &&
4544 $this->lexic_permissions[
'REGEXPS'][$group]))) {
4545 if (is_array($this->language_data[
'REGEXPS'][$group]) &&
4546 array_key_exists(
GESHI_CLASS, $this->language_data[
'REGEXPS'][$group])) {
4547 $stylesheet .=
"$selector.";
4548 $stylesheet .= $this->language_data[
'REGEXPS'][$group][
GESHI_CLASS];
4549 $stylesheet .=
" {{$styles}}\n";
4551 $stylesheet .=
"$selector.re$group {{$styles}}\n";
4556 if (!$economy_mode || (count($this->highlight_extra_lines)!=count($this->highlight_extra_lines_styles))) {
4557 $stylesheet .=
"{$selector}.ln-xtra, {$selector}li.ln-xtra, {$selector}div.ln-xtra {{$this->highlight_extra_lines_style}}\n";
4559 $stylesheet .=
"{$selector}span.xtra { display:block; }\n";
4560 foreach ($this->highlight_extra_lines_styles as $lineid =>
$linestyle) {
4561 $stylesheet .=
"{$selector}.lx$lineid, {$selector}li.lx$lineid, {$selector}div.lx$lineid {{$linestyle}}\n";
4577 if (isset($this->highlight_extra_lines_styles[$line])) {
4578 $style = $this->highlight_extra_lines_styles[$line];
4602 $regex_chars =
array(
'.',
'\\',
'+',
'-',
'*',
'?',
'[',
'^',
']',
'$',
4603 '(',
')',
'{',
'}',
'=',
'!',
'<',
'>',
'|',
':', $regexp_delimiter);
4605 $regexp_list =
array(
'');
4606 $num_subpatterns = 0;
4611 $prev_keys =
array();
4614 for ($i = 0, $i_max = count($list); $i < $i_max; ++$i) {
4618 $num_subpatterns = substr_count($regexp_list[$list_key],
'(?:');
4623 $entry = preg_quote((
string) $list[$i], $regexp_delimiter);
4624 $pointer = &$tokens;
4629 if (isset($prev_keys[$level])) {
4630 if ($prev_keys[$level] == $entry) {
4635 while (isset($entry[$char]) && isset($prev_keys[$level][$char])
4636 && $entry[$char] == $prev_keys[$level][$char]) {
4641 if ($char == strlen($prev_keys[$level])) {
4643 $pointer = &$pointer[$prev_keys[$level]];
4646 $new_key_part1 = substr($prev_keys[$level], 0, $char);
4647 $new_key_part2 = substr($prev_keys[$level], $char);
4649 if (in_array($new_key_part1[0], $regex_chars)
4650 || in_array($new_key_part2[0], $regex_chars)) {
4652 $pointer[$entry] =
array(
'' =>
true);
4653 array_splice($prev_keys, $level, count($prev_keys), $entry);
4654 $cur_len += strlen($entry);
4658 $pointer[$new_key_part1] =
array($new_key_part2 => $pointer[$prev_keys[$level]]);
4659 unset($pointer[$prev_keys[$level]]);
4660 $pointer = &$pointer[$new_key_part1];
4662 array_splice($prev_keys, $level, count($prev_keys),
array($new_key_part1, $new_key_part2));
4663 $cur_len += strlen($new_key_part2);
4667 $entry = substr($entry, $char);
4672 if ($level == 0 && !empty($tokens)) {
4675 $new_subpatterns = substr_count($new_entry,
'(?:');
4677 $regexp_list[++$list_key] = $new_entry;
4678 $num_subpatterns = $new_subpatterns;
4680 if (!empty($regexp_list[$list_key])) {
4681 $new_entry =
'|' . $new_entry;
4683 $regexp_list[$list_key] .= $new_entry;
4684 $num_subpatterns += $new_subpatterns;
4690 $pointer[$entry] =
array(
'' =>
true);
4691 array_splice($prev_keys, $level, count($prev_keys), $entry);
4693 $cur_len += strlen($entry);
4701 if ( !empty($regexp_list[$list_key]) ) {
4704 $regexp_list[$list_key] = $new_entry;
4706 if (!empty($regexp_list[$list_key])) {
4707 $new_entry =
'|' . $new_entry;
4709 $regexp_list[$list_key] .= $new_entry;
4711 return $regexp_list;
4726 foreach ($tokens as $token => $sub_tokens) {
4728 $close_entry = isset($sub_tokens[
'']);
4729 unset($sub_tokens[
'']);
4730 if (!empty($sub_tokens)) {
4746 $list = preg_replace(
'#\(\?\:(.)\)\?#',
'\1?', $list);
4750 if (!isset($callback_2)) {
4751 $callback_2 = create_function(
'$matches',
'return "[" . str_replace("|", "", $matches[1]) . "]";');
4753 $list = preg_replace_callback(
'#\(\?\:((?:.\|)+.)\)#', $callback_2, $list);
4756 return substr($list, 0, -1);
4761 if (!function_exists(
'geshi_highlight')) {
4773 function geshi_highlight($string, $language,
$path = null, $return =
false) {
4778 return '<code>' .
$geshi->parse_code() .
'</code>';
4781 echo '<code>' .
$geshi->parse_code() .
'</code>';
replace_keywords($instr)
Replaces certain keywords in the header and footer with certain configuration values.
$highlight_extra_lines_style
set_keyword_group_highlighting($key, $flag=true)
Turns highlighting on/off for a keyword group.
finalise(&$parsed_code)
Takes the parsed code and various options, and creates the HTML surrounding it to make it look nice...
set_header_content_style($style)
Sets the style for the header content.
enable_keyword_links($enable=true)
Turns linking of keywords on or off.
enable_highlighting($flag=true)
Enables all highlighting.
set_regexps_highlighting($key, $flag)
Turns highlighting on/off for regexps.
set_escape_characters_style($style, $preserve_defaults=false, $group=0)
Sets the styles for escaped characters.
const GESHI_ACTIVE
Links in the source in the :active state.
set_strings_style($style, $preserve_defaults=false, $group=0)
Sets the styles for strings.
const GESHI_NUMBER_INT_CSTYLE
Enhanced number format for integers like seen in C.
const GESHI_ERROR_INVALID_LINE_NUMBER_TYPE
The line number type passed to GeSHi->enable_line_numbers() was invalid.
const GESHI_MAX_PCRE_LENGTH
it's also important not to generate too long regular expressions be generous here...
set_time($start_time, $end_time)
Sets the time taken to parse the code.
set_source($source)
Sets the source code for this object.
footer()
Returns the footer for the code block.
const GESHI_MODIFIERS
The key of the regex array defining any modifiers to the regular expression.
const GESHI_LANG_ROOT(!defined('GESHI_ROOT'))
The language file directory for GeSHi private.
const GESHI_PHP_PRE_433
Used to work around missing PHP features.
const GESHI_START_IMPORTANT
The starter for important parts of the source.
hsc($string, $quote_style=ENT_COMPAT)
Secure replacement for PHP built-in function htmlspecialchars().
set_overall_style($style, $preserve_defaults=false)
Sets the styles for the code that will be outputted when this object is parsed.
const GESHI_NORMAL_LINE_NUMBERS
Use normal line numbers when building the result.
const GESHI_NUMBER_FLT_SCI_ZERO
Number format to highlight floating-point numbers with support for scientific notation (E) and requir...
set_case_sensitivity($key, $case)
Sets whether a set of keywords are checked for in a case sensitive manner.
load_language($file_name)
Gets language information and stores it for later use.
if(strncmp($real_path, SOURCE_ROOT, $base_path_len)) if(!file_exists($path)) $geshi
highlight_lines_extra($lines, $style=null)
Specifies which lines to highlight extra.
build_style_cache()
Setup caches needed for styling.
disable_highlighting()
Disables all highlighting.
const GESHI_NUMBER_HEX_SUFFIX
Number format to highlight hex numbers with a suffix of h.
set_symbols_style($style, $preserve_defaults=false, $group=0)
Sets the styles for symbols.
get_version()
Returns the version of GeSHi.
const GESHI_HEADER_PRE_VALID
Use a pre to wrap lines when line numbers are enabled or to wrap the whole code.
set_footer_content_style($style)
Sets the style for the footer content.
set_header_content($content)
Sets the content of the header block.
set_link_target($target)
Sets the target for links in code.
const GESHI_BEFORE
The key of the regex array defining what bracket group in a matched search to put before the replacem...
enable_line_numbers($flag, $nth_row=5)
Sets whether line numbers should be displayed.
const GESHI_CLASS
The key of the regex array defining a custom keyword to use for this regexp's html tag class...
const GESHI_HOVER
Links in the source in the :hover state.
get_language_fullname($language)
Get full_name for a lang or false.
get_real_tab_width()
Returns the tab width to use, based on the current language and user preference.
Add rich text string
The name of the decorator.
set_line_ending($line_ending)
Sets the line-ending.
set_highlight_lines_extra_style($styles)
Sets the style for extra-highlighted lines.
enable_classes($flag=true)
Sets whether CSS classes should be used to highlight the source.
error()
Returns an error message associated with the last GeSHi operation, or false if no error has occurred...
set_code_style($style, $preserve_defaults=false)
Sets the style for the actual code.
static get_language_name_from_extension( $extension, $lookup=array())
Given a file extension, this method returns either a valid geshi language name, or the empty string i...
set_strings_highlighting($flag)
Turns highlighting on/off for strings.
remove_keyword($key, $word, $recompile=true)
Removes a keyword from a keyword group.
add_keyword_group($key, $styles, $case_sensitive=true, $words=array())
Creates a new keyword group.
optimize_regexp_list($list, $regexp_delimiter='/')
this functions creates an optimized regular expression list of an array of strings.
_optimize_regexp_list_tokens_to_string(&$tokens, $recursed=false)
this function creates the appropriate regexp string of an token array you should not call this functi...
const GESHI_NUMBER_FLT_NONSCI_F
Number format to highlight floating-point numbers without support for scientific notation.
get_line_style($line)
Get's the style that is used for the specified line.
get_multiline_span()
Get current setting for multiline spans, see GeSHi->enable_multiline_span().
enable_multiline_span($flag)
Sets wether spans and other HTML markup generated by GeSHi can span over multiple lines or not...
set_numbers_highlighting($flag)
Turns highlighting on/off for numbers.
__construct($source='', $language='', $path='')
#-
const GESHI_COMMENTS
Used in language files to mark comments.
set_keyword_group_style($key, $style, $preserve_defaults=false)
Sets the style for a keyword group.
set_escape_characters_highlighting($flag=true)
Turns highlighting on/off for escaped characters.
set_regexps_style($key, $style, $preserve_defaults=false)
Sets the styles for regexps.
const GESHI_REPLACE
The key of the regex array defining what bracket group in a matched search to use as a replacement...
const GESHI_NUMBER_HEX_PREFIX
Number format to highlight hex numbers with a prefix 0x.
set_comments_style($key, $style, $preserve_defaults=false)
Sets the styles for comment groups.
const GESHI_NUMBER_BIN_PREFIX_0B
Number format to highlight binary numbers with a prefix 0b (C)
const GESHI_MAX_PCRE_SUBPATTERNS(!function_exists('stripos'))
make sure we can call stripos
const GESHI_HEADER_DIV
Use a "div" to surround the source.
change_case($instr)
Changes the case of a keyword for those languages where a change is asked for.
enable_inner_code_block($flag)
Sets whether to force a surrounding block around the highlighted code or not.
parse_code()
Returns the code in $this->source, highlighted and surrounded by the nessecary HTML.
const GESHI_ERROR_NO_SUCH_LANG
The language specified does not exist.
set_encoding($encoding)
Sets the encoding used for htmlspecialchars(), for international support.
$highlight_extra_lines_styles
const GESHI_CAPS_UPPER
Uppercase keywords found.
const GESHI_ERROR_INVALID_HEADER_TYPE
The header type passed to GeSHi->set_header_type() was invalid.
set_brackets_highlighting($flag)
Turns highlighting on/off for brackets.
const GESHI_NO_LINE_NUMBERS(!defined('GESHI_SECURITY_PARANOID'))
Use no line numbers when building the result.
const GESHI_NUMBER_OCT_PREFIX_0O
Number format to highlight octal numbers with a prefix 0o (logtalk)
const GESHI_NUMBER_BIN_SUFFIX
Number format to highlight binary numbers with a suffix "b".
const GESHI_HEADER_PRE_TABLE
Use a "table" to surround the source:
const GESHI_NUMBER_BIN_PREFIX_PERCENT
Number format to highlight binary numbers with a prefix %.
get_supported_languages($full_names=false)
Get supported langs or an associative array lang=>full_name.
optimize_keyword_group($key)
compile optimized regexp list for keyword group
const GESHI_VERSION
The version of this GeSHi file.
get_language_name()
Gets a human-readable language name (thanks to Simon Patterson for the idea :))
const GESHI_HEADER_PRE
Use a "pre" to surround the source.
enable_ids($flag=true)
Whether CSS IDs should be added to each line.
handle_keyword_replace($match)
Handles replacements of keywords to include markup and links if requested.
const GESHI_VISITED
Links in the source in the :visited state.
enable_strict_mode($mode=true)
Enables/disables strict highlighting.
set_tab_width($width)
Sets how many spaces a tab is substituted for.
parse_non_string_part($stuff_to_parse)
Takes a string that has no strings or comments in it, and highlights stuff like keywords, numbers and methods.
const GESHI_NUMBER_FLT_NONSCI
Number format to highlight floating-point numbers without support for scientific notation.
const GESHI_SEARCH
The key of the regex array defining what to search for.
set_brackets_style($style, $preserve_defaults=false)
Sets the styles for brackets.
Create styles array
The data for the language used.
const GESHI_LINK
Links in the source in the :link state.
const GESHI_ERROR_FILE_NOT_READABLE
GeSHi could not open a file for reading (generally a language file)
const GESHI_FANCY_LINE_NUMBERS
Use fancy line numbers when building the result.
set_language_path($path)
Sets the path to the directory containing the language files.
const GESHI_CAPS_LOWER
Leave keywords found as the case that they are.
set_url_for_keyword_group($group, $url)
Sets the base URL to be used for keywords.
get_stylesheet($economy_mode=true)
Returns a stylesheet for the highlighted code.
const GESHI_NUMBER_OCT_PREFIX_AT
Number format to highlight octal numbers with a leading @ (Used in HiSofts Devpac series)...
set_numbers_style($style, $preserve_defaults=false, $group=0)
Sets the styles for numbers.
const GESHI_MAYBE
Strict mode might apply, and can be enabled or disabled by GeSHi->enable_strict_mode().
set_script_style($style, $preserve_defaults=false, $group=0)
Sets the styles for strict code blocks.
set_overall_id($id)
Sets the overall id for this block of code.
start_line_numbers_at($number)
Sets what number line numbers should start at.
set_header_type($type)
Sets the type of header to be used.
const GESHI_NUMBER_FLT_SCI_SHORT
Number format to highlight floating-point numbers with support for scientific notation (E) and option...
handle_multiline_regexps($matches)
handles newlines in REGEXPS matches.
indent(&$result)
Swaps out spaces and tabs for HTML indentation.
set_methods_highlighting($flag)
Turns highlighting on/off for methods.
const GESHI_NEVER
#+ private
load_from_file($file_name, $lookup=array())
Given a file name, this method loads its contents in, and attempts to set the language automatically...
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
enable_important_blocks($flag)
Sets whether context-important blocks are highlighted.
const GESHI_NUMBER_HEX_PREFIX_DOLLAR
Number format to highlight hex numbers with a prefix $.
set_methods_style($key, $style, $preserve_defaults=false)
Sets the styles for methods.
set_footer_content($content)
Sets the content of the footer block.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
set_comments_highlighting($key, $flag=true)
Turns highlighting on/off for comment groups.
get_time()
Gets the time taken to parse the code.
set_case_keywords($case)
Sets the case that keywords should use when found.
set_important_styles($styles)
Sets styles for important parts of the code.
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
const GESHI_NUMBER_INT_BASIC
Basic number format for integers.
const GESHI_CAPS_NO_CHANGE
Lowercase keywords found.
set_link_styles($type, $styles)
Sets styles for links in code.
remove_keyword_group($key)
Removes a keyword group.
const GESHI_NUMBER_OCT_PREFIX
Number format to highlight octal numbers with a leading zero.
header()
Creates the header for the code block (with correct attributes)
const GESHI_NUMBER_OCT_SUFFIX
Number format to highlight octal numbers with a suffix of o.
set_overall_class($class)
Sets the overall classname for this block of code.
set_line_style($style1, $style2='', $preserve_defaults=false)
Sets the styles for the line numbers.
handle_regexps_callback($matches)
handles regular expressions highlighting-definitions with callback functions
const GESHI_END_IMPORTANT
The ender for important parts of the source.
add_keyword($key, $word)
Adds a keyword to a keyword group for highlighting.
const GESHI_HEADER_NONE
Use nothing to surround the source.
set_symbols_highlighting($flag)
Turns highlighting on/off for symbols.
merge_arrays()
Merges arrays recursively, overwriting values of the first array with values of later arrays...
const GESHI_ALWAYS
Strict mode always applies.
build_parse_cache()
Setup caches needed for parsing.
set_use_language_tab_width($use)
Sets whether or not to use tab-stop width specifed by language.
set_language($language, $force_reset=false)
Sets the language for this object.
const GESHI_AFTER
The key of the regex array defining what bracket group in a matched search to put after the replaceme...