44define(
'GESHI_VERSION', 
'1.0.8.12');
 
   49    define(
'GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
 
   53define(
'GESHI_LANG_ROOT', GESHI_ROOT . 
'geshi' . DIRECTORY_SEPARATOR);
 
   56if (!
defined(
'GESHI_SECURITY_PARANOID')) {
 
   58    define(
'GESHI_SECURITY_PARANOID', 
false);
 
   63define(
'GESHI_NO_LINE_NUMBERS', 0);
 
   65define(
'GESHI_NORMAL_LINE_NUMBERS', 1);
 
   67define(
'GESHI_FANCY_LINE_NUMBERS', 2);
 
   71define(
'GESHI_HEADER_NONE', 0);
 
   73define(
'GESHI_HEADER_DIV', 1);
 
   75define(
'GESHI_HEADER_PRE', 2);
 
   77define(
'GESHI_HEADER_PRE_VALID', 3);
 
   91define(
'GESHI_HEADER_PRE_TABLE', 4);
 
   95define(
'GESHI_CAPS_NO_CHANGE', 0);
 
   97define(
'GESHI_CAPS_UPPER', 1);
 
   99define(
'GESHI_CAPS_LOWER', 2);
 
  103define(
'GESHI_LINK', 0);
 
  105define(
'GESHI_HOVER', 1);
 
  107define(
'GESHI_ACTIVE', 2);
 
  109define(
'GESHI_VISITED', 3);
 
  115define(
'GESHI_START_IMPORTANT', 
'<BEGIN GeSHi>');
 
  117define(
'GESHI_END_IMPORTANT', 
'<END GeSHi>');
 
  124define(
'GESHI_NEVER', 0);
 
  127define(
'GESHI_MAYBE', 1);
 
  129define(
'GESHI_ALWAYS', 2);
 
  133define(
'GESHI_SEARCH', 0);
 
  136define(
'GESHI_REPLACE', 1);
 
  138define(
'GESHI_MODIFIERS', 2);
 
  141define(
'GESHI_BEFORE', 3);
 
  144define(
'GESHI_AFTER', 4);
 
  147define(
'GESHI_CLASS', 5);
 
  150define(
'GESHI_COMMENTS', 0);
 
  153define(
'GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, 
'4.3.3') === 1));
 
  156if (!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)) {
 
  189define(
'GESHI_MAX_PCRE_SUBPATTERNS', 500);
 
  195define(
'GESHI_MAX_PCRE_LENGTH', 12288);
 
  199define(
'GESHI_NUMBER_INT_BASIC', 1);        
 
  201define(
'GESHI_NUMBER_INT_CSTYLE', 2);       
 
  203define(
'GESHI_NUMBER_BIN_SUFFIX', 16);           
 
  205define(
'GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   
 
  207define(
'GESHI_NUMBER_BIN_PREFIX_0B', 64);        
 
  209define(
'GESHI_NUMBER_OCT_PREFIX', 256);           
 
  211define(
'GESHI_NUMBER_OCT_PREFIX_0O', 512);           
 
  213define(
'GESHI_NUMBER_OCT_PREFIX_AT', 1024);           
 
  215define(
'GESHI_NUMBER_OCT_SUFFIX', 2048);           
 
  217define(
'GESHI_NUMBER_HEX_PREFIX', 4096);           
 
  219define(
'GESHI_NUMBER_HEX_PREFIX_DOLLAR', 8192);           
 
  221define(
'GESHI_NUMBER_HEX_SUFFIX', 16384);           
 
  223define(
'GESHI_NUMBER_FLT_NONSCI', 65536);          
 
  225define(
'GESHI_NUMBER_FLT_NONSCI_F', 131072);       
 
  227define(
'GESHI_NUMBER_FLT_SCI_SHORT', 262144);      
 
  229define(
'GESHI_NUMBER_FLT_SCI_ZERO', 524288);       
 
  236define(
'GESHI_ERROR_NO_INPUT', 1);
 
  238define(
'GESHI_ERROR_NO_SUCH_LANG', 2);
 
  240define(
'GESHI_ERROR_FILE_NOT_READABLE', 3);
 
  242define(
'GESHI_ERROR_INVALID_HEADER_TYPE', 4);
 
  244define(
'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;';
 
  628            $debug_tpl_vars = array(
 
  629                '{LANGUAGE}' => $this->language,
 
  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;
 
  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; 
 
  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;
 
 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);
 
 2190            $result = str_replace(array(
'<SEMI>', 
'<PIPE>'), array(
';', 
'|'), 
$result);
 
 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) {
 
 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);
 
 3701        $this->time = $end[0] + $end[1] - 
$start[0] - 
$start[1];
 
 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();
 
 4111        $attributes = 
' class="' . $this->
_genCSSName($this->language);
 
 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);
 
 4390            $selector = 
'.' . $this->
_genCSSName($this->language);
 
 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);
 
 4761if (!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>';
 
sprintf('%.4f', $callTime)
if(strncmp( $real_path, SOURCE_ROOT, $base_path_len)) if(!file_exists($path)) $geshi
An exception for terminatinating execution or to throw for unit testing.
get_line_style($line)
Get's the style that is used for the specified line.
enable_multiline_span($flag)
Sets wether spans and other HTML markup generated by GeSHi can span over multiple lines or not.
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...
get_language_name()
Gets a human-readable language name (thanks to Simon Patterson for the idea :))
set_language($language, $force_reset=false)
Sets the language for this object.
build_parse_cache()
Setup caches needed for parsing.
enable_highlighting($flag=true)
Enables all highlighting.
header()
Creates the header for the code block (with correct attributes)
set_tab_width($width)
Sets how many spaces a tab is substituted for.
handle_regexps_callback($matches)
handles regular expressions highlighting-definitions with callback functions
set_script_style($style, $preserve_defaults=false, $group=0)
Sets the styles for strict code blocks.
get_time()
Gets the time taken to parse the code.
merge_arrays()
Merges arrays recursively, overwriting values of the first array with values of later arrays.
enable_line_numbers($flag, $nth_row=5)
Sets whether line numbers should be displayed.
set_use_language_tab_width($use)
Sets whether or not to use tab-stop width specifed by language.
set_url_for_keyword_group($group, $url)
Sets the base URL to be used for keywords.
get_supported_languages($full_names=false)
Get supported langs or an associative array lang=>full_name.
_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...
set_time($start_time, $end_time)
Sets the time taken to parse the code.
optimize_keyword_group($key)
compile optimized regexp list for keyword group
build_style_cache()
Setup caches needed for styling.
enable_important_blocks($flag)
Sets whether context-important blocks are highlighted.
set_regexps_style($key, $style, $preserve_defaults=false)
Sets the styles for regexps.
set_overall_style($style, $preserve_defaults=false)
Sets the styles for the code that will be outputted when this object is parsed.
set_overall_class($class)
Sets the overall classname for this block of code.
set_important_styles($styles)
Sets styles for important parts of the code.
handle_multiline_regexps($matches)
handles newlines in REGEXPS matches.
start_line_numbers_at($number)
Sets what number line numbers should start at.
set_brackets_highlighting($flag)
Turns highlighting on/off for brackets.
indent(&$result)
Swaps out spaces and tabs for HTML indentation.
set_case_sensitivity($key, $case)
Sets whether a set of keywords are checked for in a case sensitive manner.
set_numbers_style($style, $preserve_defaults=false, $group=0)
Sets the styles for numbers.
set_encoding($encoding)
Sets the encoding used for htmlspecialchars(), for international support.
set_regexps_highlighting($key, $flag)
Turns highlighting on/off for regexps.
set_header_content($content)
Sets the content of the header block.
set_numbers_highlighting($flag)
Turns highlighting on/off for numbers.
optimize_regexp_list($list, $regexp_delimiter='/')
this functions creates an optimized regular expression list of an array of strings.
replace_keywords($instr)
Replaces certain keywords in the header and footer with certain configuration values.
load_language($file_name)
Gets language information and stores it for later use.
enable_classes($flag=true)
Sets whether CSS classes should be used to highlight the source.
remove_keyword_group($key)
Removes a keyword group.
set_footer_content_style($style)
Sets the style for the footer content.
set_keyword_group_highlighting($key, $flag=true)
Turns highlighting on/off for a keyword group.
parse_code()
Returns the code in $this->source, highlighted and surrounded by the nessecary HTML.
$highlight_extra_lines_style
set_strings_style($style, $preserve_defaults=false, $group=0)
Sets the styles for strings.
get_version()
Returns the version of GeSHi.
get_multiline_span()
Get current setting for multiline spans, see GeSHi->enable_multiline_span().
enable_keyword_links($enable=true)
Turns linking of keywords on or off.
remove_keyword($key, $word, $recompile=true)
Removes a keyword from a keyword group.
set_footer_content($content)
Sets the content of the footer block.
add_keyword_group($key, $styles, $case_sensitive=true, $words=array())
Creates a new keyword group.
parse_non_string_part($stuff_to_parse)
Takes a string that has no strings or comments in it, and highlights stuff like keywords,...
finalise(&$parsed_code)
Takes the parsed code and various options, and creates the HTML surrounding it to make it look nice.
set_line_style($style1, $style2='', $preserve_defaults=false)
Sets the styles for the line numbers.
disable_highlighting()
Disables all highlighting.
change_case($instr)
Changes the case of a keyword for those languages where a change is asked for.
set_symbols_style($style, $preserve_defaults=false, $group=0)
Sets the styles for symbols.
set_escape_characters_highlighting($flag=true)
Turns highlighting on/off for escaped characters.
set_case_keywords($case)
Sets the case that keywords should use when found.
set_link_styles($type, $styles)
Sets styles for links in code.
set_language_path($path)
Sets the path to the directory containing the language files.
footer()
Returns the footer for the code block.
set_comments_highlighting($key, $flag=true)
Turns highlighting on/off for comment groups.
enable_strict_mode($mode=true)
Enables/disables strict highlighting.
hsc($string, $quote_style=ENT_COMPAT)
Secure replacement for PHP built-in function htmlspecialchars().
set_strings_highlighting($flag)
Turns highlighting on/off for strings.
add_keyword($key, $word)
Adds a keyword to a keyword group for highlighting.
handle_keyword_replace($match)
Handles replacements of keywords to include markup and links if requested.
set_overall_id($id)
Sets the overall id for this block of code.
enable_inner_code_block($flag)
Sets whether to force a surrounding block around the highlighted code or not.
set_header_type($type)
Sets the type of header to be used.
__construct($source='', $language='', $path='')
#-
set_symbols_highlighting($flag)
Turns highlighting on/off for symbols.
load_from_file($file_name, $lookup=array())
Given a file name, this method loads its contents in, and attempts to set the language automatically.
set_methods_style($key, $style, $preserve_defaults=false)
Sets the styles for methods.
enable_ids($flag=true)
Whether CSS IDs should be added to each line.
get_real_tab_width()
Returns the tab width to use, based on the current language and user preference.
set_line_ending($line_ending)
Sets the line-ending.
set_header_content_style($style)
Sets the style for the header content.
set_brackets_style($style, $preserve_defaults=false)
Sets the styles for brackets.
set_comments_style($key, $style, $preserve_defaults=false)
Sets the styles for comment groups.
highlight_lines_extra($lines, $style=null)
Specifies which lines to highlight extra.
error()
Returns an error message associated with the last GeSHi operation, or false if no error has occurred.
set_keyword_group_style($key, $style, $preserve_defaults=false)
Sets the style for a keyword group.
set_link_target($target)
Sets the target for links in code.
get_language_fullname($language)
Get full_name for a lang or false.
set_escape_characters_style($style, $preserve_defaults=false, $group=0)
Sets the styles for escaped characters.
get_stylesheet($economy_mode=true)
Returns a stylesheet for the highlighted code.
set_highlight_lines_extra_style($styles)
Sets the style for extra-highlighted lines.
set_code_style($style, $preserve_defaults=false)
Sets the style for the actual code.
set_source($source)
Sets the source code for this object.
set_methods_highlighting($flag)
Turns highlighting on/off for methods.
$highlight_extra_lines_styles
const GESHI_NUMBER_INT_BASIC
Basic number format for integers.
const GESHI_MAYBE
Strict mode might apply, and can be enabled or disabled by GeSHi->enable_strict_mode().
const GESHI_HOVER
Links in the source in the :hover state.
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 %.
const GESHI_VISITED
Links in the source in the :visited state.
const GESHI_NUMBER_OCT_PREFIX_0O
Number format to highlight octal numbers with a prefix 0o (logtalk)
const GESHI_NUMBER_FLT_NONSCI
Number format to highlight floating-point numbers without support for scientific notation.
const GESHI_MAX_PCRE_SUBPATTERNS(!function_exists('stripos'))
make sure we can call stripos
const GESHI_LINK
Links in the source in the :link state.
const GESHI_NUMBER_FLT_NONSCI_F
Number format to highlight floating-point numbers without support for scientific notation.
const GESHI_NUMBER_INT_CSTYLE
Enhanced number format for integers like seen in C.
const GESHI_CAPS_NO_CHANGE
Lowercase keywords found.
const GESHI_HEADER_PRE_VALID
Use a pre to wrap lines when line numbers are enabled or to wrap the whole code.
const GESHI_NUMBER_BIN_PREFIX_0B
Number format to highlight binary numbers with a prefix 0b (C)
const GESHI_ACTIVE
Links in the source in the :active state.
const GESHI_BEFORE
The key of the regex array defining what bracket group in a matched search to put before the replacem...
const GESHI_ERROR_INVALID_HEADER_TYPE
The header type passed to GeSHi->set_header_type() was invalid.
const GESHI_NUMBER_OCT_PREFIX
Number format to highlight octal numbers with a leading zero.
const GESHI_NUMBER_OCT_PREFIX_AT
Number format to highlight octal numbers with a leading @ (Used in HiSofts Devpac series).
const GESHI_NUMBER_HEX_SUFFIX
Number format to highlight hex numbers with a suffix of h.
const GESHI_SEARCH
The key of the regex array defining what to search for.
const GESHI_NUMBER_BIN_SUFFIX
Number format to highlight binary numbers with a suffix "b".
const GESHI_NUMBER_OCT_SUFFIX
Number format to highlight octal numbers with a suffix of o.
const GESHI_LANG_ROOT(!defined('GESHI_ROOT'))
The language file directory for GeSHi @access private.
const GESHI_HEADER_NONE
Use nothing to surround the source.
const GESHI_CLASS
The key of the regex array defining a custom keyword to use for this regexp's html tag class.
const GESHI_NUMBER_HEX_PREFIX
Number format to highlight hex numbers with a prefix 0x.
const GESHI_NUMBER_HEX_PREFIX_DOLLAR
Number format to highlight hex numbers with a prefix $.
const GESHI_AFTER
The key of the regex array defining what bracket group in a matched search to put after the replaceme...
const GESHI_HEADER_DIV
Use a "div" to surround the source.
const GESHI_NUMBER_FLT_SCI_ZERO
Number format to highlight floating-point numbers with support for scientific notation (E) and requir...
const GESHI_NORMAL_LINE_NUMBERS
Use normal line numbers when building the result.
const GESHI_ERROR_FILE_NOT_READABLE
GeSHi could not open a file for reading (generally a language file)
const GESHI_PHP_PRE_433
Used to work around missing PHP features.
const GESHI_NO_LINE_NUMBERS(!defined('GESHI_SECURITY_PARANOID'))
Use no line numbers when building the result.
const GESHI_ALWAYS
Strict mode always applies.
const GESHI_REPLACE
The key of the regex array defining what bracket group in a matched search to use as a replacement.
const GESHI_VERSION
The version of this GeSHi file.
const GESHI_FANCY_LINE_NUMBERS
Use fancy line numbers when building the result.
const GESHI_ERROR_INVALID_LINE_NUMBER_TYPE
The line number type passed to GeSHi->enable_line_numbers() was invalid.
const GESHI_ERROR_NO_SUCH_LANG
The language specified does not exist.
const GESHI_CAPS_LOWER
Leave keywords found as the case that they are.
const GESHI_START_IMPORTANT
The starter for important parts of the source.
const GESHI_HEADER_PRE
Use a "pre" to surround the source.
const GESHI_COMMENTS
Used in language files to mark comments.
const GESHI_NEVER
#+ @access private
const GESHI_MAX_PCRE_LENGTH
it's also important not to generate too long regular expressions be generous here....
const GESHI_NUMBER_FLT_SCI_SHORT
Number format to highlight floating-point numbers with support for scientific notation (E) and option...
const GESHI_END_IMPORTANT
The ender for important parts of the source.
const GESHI_MODIFIERS
The key of the regex array defining any modifiers to the regular expression.
const GESHI_CAPS_UPPER
Uppercase keywords found.
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'