43define(
'GESHI_VERSION', 
'1.0.9.0');
 
   46if (!defined(
'GESHI_ROOT')) {
 
   48    define(
'GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
 
   52define(
'GESHI_LANG_ROOT', GESHI_ROOT . 
'geshi' . DIRECTORY_SEPARATOR);
 
   55if (!defined(
'GESHI_SECURITY_PARANOID')) {
 
   57    define(
'GESHI_SECURITY_PARANOID', 
false);
 
   62define(
'GESHI_NO_LINE_NUMBERS', 0);
 
   64define(
'GESHI_NORMAL_LINE_NUMBERS', 1);
 
   66define(
'GESHI_FANCY_LINE_NUMBERS', 2);
 
   70define(
'GESHI_HEADER_NONE', 0);
 
   72define(
'GESHI_HEADER_DIV', 1);
 
   74define(
'GESHI_HEADER_PRE', 2);
 
   76define(
'GESHI_HEADER_PRE_VALID', 3);
 
   90define(
'GESHI_HEADER_PRE_TABLE', 4);
 
   94define(
'GESHI_CAPS_NO_CHANGE', 0);
 
   96define(
'GESHI_CAPS_UPPER', 1);
 
   98define(
'GESHI_CAPS_LOWER', 2);
 
  102define(
'GESHI_LINK', 0);
 
  104define(
'GESHI_HOVER', 1);
 
  106define(
'GESHI_ACTIVE', 2);
 
  108define(
'GESHI_VISITED', 3);
 
  114define(
'GESHI_START_IMPORTANT', 
'<BEGIN GeSHi>');
 
  116define(
'GESHI_END_IMPORTANT', 
'<END GeSHi>');
 
  123define(
'GESHI_NEVER', 0);
 
  126define(
'GESHI_MAYBE', 1);
 
  128define(
'GESHI_ALWAYS', 2);
 
  132define(
'GESHI_SEARCH', 0);
 
  135define(
'GESHI_REPLACE', 1);
 
  137define(
'GESHI_MODIFIERS', 2);
 
  140define(
'GESHI_BEFORE', 3);
 
  143define(
'GESHI_AFTER', 4);
 
  146define(
'GESHI_CLASS', 5);
 
  149define(
'GESHI_COMMENTS', 0);
 
  155define(
'GESHI_MAX_PCRE_SUBPATTERNS', 500);
 
  161define(
'GESHI_MAX_PCRE_LENGTH', 12288);
 
  165define(
'GESHI_NUMBER_INT_BASIC', 1);        
 
  167define(
'GESHI_NUMBER_INT_CSTYLE', 2);       
 
  169define(
'GESHI_NUMBER_BIN_SUFFIX', 16);           
 
  171define(
'GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   
 
  173define(
'GESHI_NUMBER_BIN_PREFIX_0B', 64);        
 
  175define(
'GESHI_NUMBER_OCT_PREFIX', 256);           
 
  177define(
'GESHI_NUMBER_OCT_PREFIX_0O', 512);           
 
  179define(
'GESHI_NUMBER_OCT_PREFIX_AT', 1024);           
 
  181define(
'GESHI_NUMBER_OCT_SUFFIX', 2048);           
 
  183define(
'GESHI_NUMBER_HEX_PREFIX', 4096);           
 
  185define(
'GESHI_NUMBER_HEX_PREFIX_DOLLAR', 8192);           
 
  187define(
'GESHI_NUMBER_HEX_SUFFIX', 16384);           
 
  189define(
'GESHI_NUMBER_FLT_NONSCI', 65536);          
 
  191define(
'GESHI_NUMBER_FLT_NONSCI_F', 131072);       
 
  193define(
'GESHI_NUMBER_FLT_SCI_SHORT', 262144);      
 
  195define(
'GESHI_NUMBER_FLT_SCI_ZERO', 524288);       
 
  202define(
'GESHI_ERROR_NO_INPUT', 1);
 
  204define(
'GESHI_ERROR_NO_SUCH_LANG', 2);
 
  206define(
'GESHI_ERROR_FILE_NOT_READABLE', 3);
 
  208define(
'GESHI_ERROR_INVALID_HEADER_TYPE', 4);
 
  210define(
'GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
 
  299        'KEYWORDS' =>    array(),
 
  300        'COMMENTS' =>    array(
'MULTI' => 
true),
 
  301        'REGEXPS' =>     array(),
 
  302        'ESCAPE_CHAR' => 
true,
 
  419    protected $code_style = 
'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
 
  591            $debug_tpl_vars = array(
 
  592                '{LANGUAGE}' => $this->language,
 
  593                '{PATH}' => $this->language_path
 
  596                array_keys($debug_tpl_vars),
 
  597                array_values($debug_tpl_vars),
 
  598                $this->error_messages[$this->
error]);
 
  600            return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
 
  614            return $this->language_data[
'LANG_NAME'] . 
' (Unknown Language)';
 
  616        return $this->language_data[
'LANG_NAME'];
 
  627        $this->highlight_extra_lines = array();
 
  654        $this->
error = 
false;
 
  658            $this->loaded_language = 
false;
 
  665        $file_name = $this->language_path . 
$language . 
'.php';
 
  666        if ($file_name == $this->loaded_language) {
 
  674        if (!is_readable($file_name)) {
 
  696        if(strpos(
$path,
':')) {
 
  698            if(DIRECTORY_SEPARATOR == 
"\\") {
 
  699                if(!preg_match(
'#^[a-zA-Z]:#', 
$path) || 
false !== strpos(
$path, 
':', 2)) {
 
  706        if(preg_match(
'#[^/a-zA-Z0-9_\.\-\\\s:]#', 
$path)) {
 
  710        if(GESHI_SECURITY_PARANOID && 
false !== strpos(
$path, 
'/.')) {
 
  714        if(GESHI_SECURITY_PARANOID && 
false !== strpos(
$path, 
'..')) {
 
  735        $dir = dir($this->language_path);
 
  738        while (
false !== ($entry = $dir->read()))
 
  740            $full_path = $this->language_path.$entry;
 
  743            if (is_dir($full_path)) {
 
  748            if (!preg_match(
'/^([^.]+)\.php$/', $entry, $matches)) {
 
  753            $langname = $matches[1];
 
  756            if ($full_names === 
true)
 
  760                    $back[$langname] = $fullname; 
 
  788        $fullpath = $this->language_path.$language.
'.php';
 
  791        if (
false === (
$data = file_get_contents($fullpath))) {
 
  792            $this->
error = sprintf(
'Geshi::get_lang_fullname() Unknown Language: %s', 
$language);
 
  797        if (!preg_match(
'/\'LANG_NAME\'\s*=>\s*\'((?:[^\']|\\\')+?)\'/', 
$data, $matches)) {
 
  798            $this->
error = sprintf(
'Geshi::get_lang_fullname(%s): Regex can not detect language', 
$language);
 
  803        return stripcslashes($matches[1]);
 
  829        $this->header_type = 
$type;
 
  842        if (!$preserve_defaults) {
 
  843            $this->overall_style = 
$style;
 
  845            $this->overall_style .= 
$style;
 
  858        $this->overall_class = $class;
 
  869        $this->overall_id = 
$id;
 
  880        $this->use_classes = ($flag) ? 
true : 
false;
 
  899        if (!$preserve_defaults) {
 
  900            $this->code_style = 
$style;
 
  902            $this->code_style .= 
$style;
 
  926        if (!$preserve_defaults) {
 
  927            $this->line_style1 = $style1;
 
  930            $this->line_style1 .= $style1;
 
  957        $this->line_numbers = $flag;
 
  958        $this->line_nth_row = $nth_row;
 
  971        $this->allow_multiline_span = (bool) $flag;
 
  998            foreach($this->language_data[
'STYLES'][
'KEYWORDS'] as $_key => $_value) {
 
  999                if (!$preserve_defaults) {
 
 1000                    $this->language_data[
'STYLES'][
'KEYWORDS'][$_key] = 
$style;
 
 1002                    $this->language_data[
'STYLES'][
'KEYWORDS'][$_key] .= 
$style;
 
 1006            if (!$preserve_defaults) {
 
 1007                $this->language_data[
'STYLES'][
'KEYWORDS'][
$key] = 
$style;
 
 1009                $this->language_data[
'STYLES'][
'KEYWORDS'][
$key] .= 
$style;
 
 1014        if (!isset($this->lexic_permissions[
'KEYWORDS'][
$key])) {
 
 1015            $this->lexic_permissions[
'KEYWORDS'][
$key] = 
true;
 
 1027        $this->lexic_permissions[
'KEYWORDS'][
$key] = ($flag) ? 
true : 
false;
 
 1043            foreach($this->language_data[
'STYLES'][
'COMMENTS'] as $_key => $_value) {
 
 1044                if (!$preserve_defaults) {
 
 1045                    $this->language_data[
'STYLES'][
'COMMENTS'][$_key] = 
$style;
 
 1047                    $this->language_data[
'STYLES'][
'COMMENTS'][$_key] .= 
$style;
 
 1051            if (!$preserve_defaults) {
 
 1052                $this->language_data[
'STYLES'][
'COMMENTS'][
$key] = 
$style;
 
 1054                $this->language_data[
'STYLES'][
'COMMENTS'][
$key] .= 
$style;
 
 1067        $this->lexic_permissions[
'COMMENTS'][
$key] = ($flag) ? 
true : 
false;
 
 1082        if (!$preserve_defaults) {
 
 1083            $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$group] = 
$style;
 
 1085            $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$group] .= 
$style;
 
 1096        $this->lexic_permissions[
'ESCAPE_CHAR'] = ($flag) ? 
true : 
false;
 
 1114        if (!$preserve_defaults) {
 
 1115            $this->language_data[
'STYLES'][
'BRACKETS'][0] = 
$style;
 
 1117            $this->language_data[
'STYLES'][
'BRACKETS'][0] .= 
$style;
 
 1132        $this->lexic_permissions[
'BRACKETS'] = ($flag) ? 
true : 
false;
 
 1148        if (!$preserve_defaults) {
 
 1149            $this->language_data[
'STYLES'][
'SYMBOLS'][$group] = 
$style;
 
 1151            $this->language_data[
'STYLES'][
'SYMBOLS'][$group] .= 
$style;
 
 1168        $this->lexic_permissions[
'SYMBOLS'] = ($flag) ? 
true : 
false;
 
 1186        if (!$preserve_defaults) {
 
 1187            $this->language_data[
'STYLES'][
'STRINGS'][$group] = 
$style;
 
 1189            $this->language_data[
'STYLES'][
'STRINGS'][$group] .= 
$style;
 
 1200        $this->lexic_permissions[
'STRINGS'] = ($flag) ? 
true : 
false;
 
 1216        if (!$preserve_defaults) {
 
 1217            $this->language_data[
'STYLES'][
'SCRIPT'][$group] = 
$style;
 
 1219            $this->language_data[
'STYLES'][
'SCRIPT'][$group] .= 
$style;
 
 1235        if (!$preserve_defaults) {
 
 1236            $this->language_data[
'STYLES'][
'NUMBERS'][$group] = 
$style;
 
 1238            $this->language_data[
'STYLES'][
'NUMBERS'][$group] .= 
$style;
 
 1249        $this->lexic_permissions[
'NUMBERS'] = ($flag) ? 
true : 
false;
 
 1266        if (!$preserve_defaults) {
 
 1267            $this->language_data[
'STYLES'][
'METHODS'][
$key] = 
$style;
 
 1269            $this->language_data[
'STYLES'][
'METHODS'][
$key] .= 
$style;
 
 1280        $this->lexic_permissions[
'METHODS'] = ($flag) ? 
true : 
false;
 
 1296        if (!$preserve_defaults) {
 
 1297            $this->language_data[
'STYLES'][
'REGEXPS'][
$key] = 
$style;
 
 1299            $this->language_data[
'STYLES'][
'REGEXPS'][
$key] .= 
$style;
 
 1311        $this->lexic_permissions[
'REGEXPS'][
$key] = ($flag) ? 
true : 
false;
 
 1322        $this->language_data[
'CASE_SENSITIVE'][
$key] = ($case) ? 
true : 
false;
 
 1336        if (in_array($case, array(
 
 1338            $this->language_data[
'CASE_KEYWORDS'] = $case;
 
 1351        $this->tab_width = intval($width);
 
 1354        if ($this->tab_width < 1) {
 
 1356            $this->tab_width = 8;
 
 1367        $this->use_language_tab_width = (bool) $use;
 
 1378        if (!$this->use_language_tab_width ||
 
 1379            !isset($this->language_data[
'TAB_WIDTH'])) {
 
 1382            return $this->language_data[
'TAB_WIDTH'];
 
 1395        if (
GESHI_MAYBE == $this->language_data[
'STRICT_MODE_APPLIES']) {
 
 1422        $flag = $flag ? true : 
false;
 
 1423        foreach ($this->lexic_permissions as 
$key => $value) {
 
 1424            if (is_array($value)) {
 
 1425                foreach ($value as $k => $v) {
 
 1426                    $this->lexic_permissions[
$key][$k] = $flag;
 
 1429                $this->lexic_permissions[
$key] = $flag;
 
 1449        $extension = strtolower($extension);
 
 1451        if ( !is_array($lookup) || empty($lookup)) {
 
 1453                '6502acme' => array( 
'a', 
's', 
'asm', 
'inc' ),
 
 1454                '6502tasm' => array( 
'a', 
's', 
'asm', 
'inc' ),
 
 1455                '6502kickass' => array( 
'a', 
's', 
'asm', 
'inc' ),
 
 1456                '68000devpac' => array( 
'a', 
's', 
'asm', 
'inc' ),
 
 1457                'abap' => array(
'abap'),
 
 1458                'actionscript' => array(
'as'),
 
 1459                'ada' => array(
'a', 
'ada', 
'adb', 
'ads'),
 
 1460                'apache' => array(
'conf'),
 
 1461                'asm' => array(
'ash', 
'asm', 
'inc'),
 
 1462                'asp' => array(
'asp'),
 
 1463                'bash' => array(
'sh'),
 
 1464                'bf' => array(
'bf'),
 
 1465                'c' => array(
'c', 
'h'),
 
 1466                'c_mac' => array(
'c', 
'h'),
 
 1467                'caddcl' => array(),
 
 1468                'cadlisp' => array(),
 
 1469                'cdfg' => array(
'cdfg'),
 
 1470                'cobol' => array(
'cbl'),
 
 1471                'cpp' => array(
'cpp', 
'hpp', 
'C', 
'H', 
'CPP', 
'HPP'),
 
 1472                'csharp' => array(
'cs'),
 
 1473                'css' => array(
'css'),
 
 1475                'delphi' => array(
'dpk', 
'dpr', 
'pp', 
'pas'),
 
 1476                'diff' => array(
'diff', 
'patch'),
 
 1477                'dos' => array(
'bat', 
'cmd'),
 
 1478                'gdb' => array(
'kcrash', 
'crash', 
'bt'),
 
 1479                'gettext' => array(
'po', 
'pot'),
 
 1480                'gml' => array(
'gml'),
 
 1481                'gnuplot' => array(
'plt'),
 
 1482                'groovy' => array(
'groovy'),
 
 1483                'haskell' => array(
'hs'),
 
 1484                'haxe' => array(
'hx'),
 
 1485                'html4strict' => array(
'html', 
'htm'),
 
 1486                'ini' => array(
'ini', 
'desktop', 
'vbp'),
 
 1487                'java' => array(
'java'),
 
 1488                'javascript' => array(
'js'),
 
 1489                'klonec' => array(
'kl1'),
 
 1490                'klonecpp' => array(
'klx'),
 
 1491                'latex' => array(
'tex'),
 
 1492                'lisp' => array(
'lisp'),
 
 1493                'lua' => array(
'lua'),
 
 1494                'matlab' => array(
'm'),
 
 1496                'mysql' => array(
'sql'),
 
 1500                'oracle8' => array(),
 
 1501                'oracle10' => array(),
 
 1502                'pascal' => array(
'pas'),
 
 1503                'perl' => array(
'pl', 
'pm'),
 
 1504                'php' => array(
'php', 
'php5', 
'phtml', 
'phps'),
 
 1505                'povray' => array(
'pov'),
 
 1506                'providex' => array(
'pvc', 
'pvx'),
 
 1507                'prolog' => array(
'pl'),
 
 1508                'python' => array(
'py'),
 
 1509                'qbasic' => array(
'bi'),
 
 1510                'reg' => array(
'reg'),
 
 1511                'ruby' => array(
'rb'),
 
 1512                'sas' => array(
'sas'),
 
 1513                'scala' => array(
'scala'),
 
 1514                'scheme' => array(
'scm'),
 
 1515                'scilab' => array(
'sci'),
 
 1516                'smalltalk' => array(
'st'),
 
 1517                'smarty' => array(),
 
 1518                'tcl' => array(
'tcl'),
 
 1519                'text' => array(
'txt'),
 
 1520                'vb' => array(
'bas', 
'ctl', 
'frm'),
 
 1521                'vbnet' => array(
'vb', 
'sln'),
 
 1522                'visualfoxpro' => array(),
 
 1523                'whitespace' => array(
'ws'),
 
 1524                'xml' => array(
'xml', 
'svg', 
'xrc', 
'vbproj', 
'csproj', 
'userprefs', 
'resx', 
'stetic', 
'settings', 
'manifest', 
'myapp'),
 
 1525                'z80' => array(
'z80', 
'asm', 
'inc')
 
 1529        foreach ($lookup as 
$lang => $extensions) {
 
 1530            if (in_array($extension, $extensions)) {
 
 1556        if (is_readable($file_name)) {
 
 1557            $this->
set_source(file_get_contents($file_name));
 
 1558            $this->
set_language(self::get_language_name_from_extension(substr(strrchr($file_name, 
'.'), 1), $lookup));
 
 1572        if (!is_array($this->language_data[
'KEYWORDS'][
$key])) {
 
 1573            $this->language_data[
'KEYWORDS'][
$key] = array();
 
 1575        if (!in_array($word, $this->language_data[
'KEYWORDS'][
$key])) {
 
 1576            $this->language_data[
'KEYWORDS'][
$key][] = $word;
 
 1579            if ($this->parse_cache_built) {
 
 1580                $subkey = count($this->language_data[
'CACHED_KEYWORD_LISTS'][
$key]) - 1;
 
 1581                $this->language_data[
'CACHED_KEYWORD_LISTS'][
$key][$subkey] .= 
'|' . preg_quote($word, 
'/');
 
 1600        $key_to_remove = array_search($word, $this->language_data[
'KEYWORDS'][
$key]);
 
 1601        if ($key_to_remove !== 
false) {
 
 1602            unset($this->language_data[
'KEYWORDS'][
$key][$key_to_remove]);
 
 1605            if ($recompile && $this->parse_cache_built) {
 
 1622        $words = (array) $words;
 
 1623        if  (empty($words)) {
 
 1629        $this->language_data[
'KEYWORDS'][
$key] = $words;
 
 1630        $this->lexic_permissions[
'KEYWORDS'][
$key] = 
true;
 
 1631        $this->language_data[
'CASE_SENSITIVE'][
$key] = $case_sensitive;
 
 1632        $this->language_data[
'STYLES'][
'KEYWORDS'][
$key] = $styles;
 
 1635        if ($this->parse_cache_built) {
 
 1649        unset($this->language_data[
'KEYWORDS'][
$key]);
 
 1650        unset($this->lexic_permissions[
'KEYWORDS'][
$key]);
 
 1651        unset($this->language_data[
'CASE_SENSITIVE'][
$key]);
 
 1652        unset($this->language_data[
'STYLES'][
'KEYWORDS'][
$key]);
 
 1655        unset($this->language_data[
'CACHED_KEYWORD_LISTS'][
$key]);
 
 1665        $this->language_data[
'CACHED_KEYWORD_LISTS'][
$key] =
 
 1667        $space_as_whitespace = 
false;
 
 1668        if(isset($this->language_data[
'PARSER_CONTROL'])) {
 
 1669            if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'])) {
 
 1670                if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'SPACE_AS_WHITESPACE'])) {
 
 1671                    $space_as_whitespace = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'SPACE_AS_WHITESPACE'];
 
 1673                if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
$key][
'SPACE_AS_WHITESPACE'])) {
 
 1674                    if(isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
$key][
'SPACE_AS_WHITESPACE'])) {
 
 1675                        $space_as_whitespace = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
$key][
'SPACE_AS_WHITESPACE'];
 
 1680        if($space_as_whitespace) {
 
 1681            foreach($this->language_data[
'CACHED_KEYWORD_LISTS'][
$key] as $rxk => $rxv) {
 
 1682                $this->language_data[
'CACHED_KEYWORD_LISTS'][
$key][$rxk] =
 
 1683                    str_replace(
" ", 
"\\s+", $rxv);
 
 1695        $this->header_content = $content;
 
 1705        $this->footer_content = $content;
 
 1715        $this->header_content_style = 
$style;
 
 1725        $this->footer_content_style = 
$style;
 
 1736        $this->force_code_block = (bool)$flag;
 
 1749        $this->language_data[
'URLS'][$group] = 
$url;
 
 1761        $this->link_styles[
$type] = $styles;
 
 1772            $this->link_target = 
'';
 
 1774            $this->link_target = 
' target="' . 
$target . 
'"';
 
 1785        $this->important_styles = $styles;
 
 1807        $this->add_ids = ($flag) ? 
true : 
false;
 
 1825        if (is_array($lines)) {
 
 1827            foreach ($lines as $line) {
 
 1832            $lines = intval($lines);
 
 1833            $this->highlight_extra_lines[$lines] = $lines;
 
 1837                unset($this->highlight_extra_lines_styles[$lines]);
 
 1838            } elseif (
$style === 
false) { 
 
 1839                unset($this->highlight_extra_lines[$lines]);
 
 1840                unset($this->highlight_extra_lines_styles[$lines]);
 
 1842                $this->highlight_extra_lines_styles[$lines] = 
$style;
 
 1854        $this->highlight_extra_lines_style = $styles;
 
 1883        $this->line_numbers_start = abs(intval($number));
 
 1900          $this->encoding = strtolower(
$encoding);
 
 1911        $this->keyword_links = (bool) $enable;
 
 1924        if($this->lexic_permissions[
'NUMBERS']) {
 
 1926            if(!isset($this->language_data[
'NUMBERS'])) {
 
 1927                $this->language_data[
'NUMBERS'] = 0;
 
 1930            if(is_array($this->language_data[
'NUMBERS'])) {
 
 1931                $this->language_data[
'NUMBERS_CACHE'] = $this->language_data[
'NUMBERS'];
 
 1933                $this->language_data[
'NUMBERS_CACHE'] = array();
 
 1934                if(!$this->language_data[
'NUMBERS']) {
 
 1935                    $this->language_data[
'NUMBERS'] =
 
 1940                for(
$i = 0, $j = $this->language_data[
'NUMBERS']; $j > 0; ++
$i, $j>>=1) {
 
 1942                    if(isset($this->language_data[
'STYLES'][
'NUMBERS'][1<<
$i])) {
 
 1943                        $this->language_data[
'STYLES'][
'NUMBERS'][
$i] =
 
 1944                            $this->language_data[
'STYLES'][
'NUMBERS'][1<<
$i];
 
 1945                        unset($this->language_data[
'STYLES'][
'NUMBERS'][1<<
$i]);
 
 1952                        if(isset($this->language_data[
'STYLES'][
'NUMBERS'][
$i])) {
 
 1953                            $this->language_data[
'NUMBERS_CACHE'][
$i] = 1 << 
$i;
 
 1955                            if(!isset($this->language_data[
'NUMBERS_CACHE'][0])) {
 
 1956                                $this->language_data[
'NUMBERS_CACHE'][0] = 0;
 
 1958                            $this->language_data[
'NUMBERS_CACHE'][0] |= 1 << 
$i;
 
 1974        if (empty($this->language_data)) {
 
 1983        if ($this->lexic_permissions[
'SYMBOLS'] && !empty($this->language_data[
'SYMBOLS'])) {
 
 1984            $this->language_data[
'MULTIPLE_SYMBOL_GROUPS'] = count($this->language_data[
'STYLES'][
'SYMBOLS']) > 1;
 
 1986            $this->language_data[
'SYMBOL_DATA'] = array();
 
 1987            $symbol_preg_multi = array(); 
 
 1988            $symbol_preg_single = array(); 
 
 1989            foreach ($this->language_data[
'SYMBOLS'] as 
$key => $symbols) {
 
 1990                if (is_array($symbols)) {
 
 1991                    foreach ($symbols as $sym) {
 
 1992                        $sym = $this->
hsc($sym);
 
 1993                        if (!isset($this->language_data[
'SYMBOL_DATA'][$sym])) {
 
 1994                            $this->language_data[
'SYMBOL_DATA'][$sym] = 
$key;
 
 1995                            if (isset($sym[1])) { 
 
 1996                                $symbol_preg_multi[] = preg_quote($sym, 
'/');
 
 2000                                    $symbol_preg_single[] = 
'\-';
 
 2002                                    $symbol_preg_single[] = preg_quote($sym, 
'/');
 
 2008                    $symbols = $this->
hsc($symbols);
 
 2009                    if (!isset($this->language_data[
'SYMBOL_DATA'][$symbols])) {
 
 2010                        $this->language_data[
'SYMBOL_DATA'][$symbols] = 0;
 
 2011                        if (isset($symbols[1])) { 
 
 2012                            $symbol_preg_multi[] = preg_quote($symbols, 
'/');
 
 2013                        } elseif ($symbols == 
'-') {
 
 2015                            $symbol_preg_single[] = 
'\-';
 
 2017                            $symbol_preg_single[] = preg_quote($symbols, 
'/');
 
 2027            $symbol_preg = array();
 
 2028            if (!empty($symbol_preg_multi)) {
 
 2029                rsort($symbol_preg_multi);
 
 2030                $symbol_preg[] = implode(
'|', $symbol_preg_multi);
 
 2032            if (!empty($symbol_preg_single)) {
 
 2033                rsort($symbol_preg_single);
 
 2034                $symbol_preg[] = 
'[' . implode(
'', $symbol_preg_single) . 
']';
 
 2036            $this->language_data[
'SYMBOL_SEARCH'] = implode(
"|", $symbol_preg);
 
 2041        $this->language_data[
'CACHED_KEYWORD_LISTS'] = array();
 
 2042        foreach (array_keys($this->language_data[
'KEYWORDS']) as 
$key) {
 
 2043            if (!isset($this->lexic_permissions[
'KEYWORDS'][
$key]) ||
 
 2044                    $this->lexic_permissions[
'KEYWORDS'][
$key]) {
 
 2050        if ($this->lexic_permissions[
'BRACKETS']) {
 
 2051            $this->language_data[
'CACHE_BRACKET_MATCH'] = array(
'[', 
']', 
'(', 
')', 
'{', 
'}');
 
 2052            if (!$this->use_classes && isset($this->language_data[
'STYLES'][
'BRACKETS'][0])) {
 
 2053                $this->language_data[
'CACHE_BRACKET_REPLACE'] = array(
 
 2054                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">[|>',
 
 2055                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">]|>',
 
 2056                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">(|>',
 
 2057                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">)|>',
 
 2058                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">{|>',
 
 2059                    '<| style="' . $this->language_data[
'STYLES'][
'BRACKETS'][0] . 
'">}|>',
 
 2063                $this->language_data[
'CACHE_BRACKET_REPLACE'] = array(
 
 2064                    '<| class="br0">[|>',
 
 2065                    '<| class="br0">]|>',
 
 2066                    '<| class="br0">(|>',
 
 2067                    '<| class="br0">)|>',
 
 2068                    '<| class="br0">{|>',
 
 2069                    '<| class="br0">}|>',
 
 2075        if($this->lexic_permissions[
'NUMBERS']) {
 
 2078            if(!isset($this->language_data[
'NUMBERS_CACHE'])) {
 
 2084            static $numbers_format = array(
 
 2086                    '(?:(?<![0-9a-z_\.%$@])|(?<=\.\.))(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2088                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2090                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[01]+?[bB](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2092                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])%[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2094                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0b[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2096                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2098                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0o[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2100                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])\@[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2102                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[0-7]+?o(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2104                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0x[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2106                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\$[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2108                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d[0-9a-fA-F]*?[hH](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2110                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2112                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2114                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
 
 2116                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)' 
 2121            $this->language_data[
'NUMBERS_RXCACHE'] = array();
 
 2122            foreach($this->language_data[
'NUMBERS_CACHE'] as 
$key => $rxdata) {
 
 2123                if(is_string($rxdata)) {
 
 2129                    for(
$i = 1; 
$i <= $rxdata; 
$i<<=1) {
 
 2131                            $rxuse[] = $numbers_format[
$i];
 
 2134                    $regexp = implode(
"|", $rxuse);
 
 2137                $this->language_data[
'NUMBERS_RXCACHE'][
$key] =
 
 2138                    "/(?<!<\|\/)(?<!<\|!REG3XP)(?<!<\|\/NUM!)(?<!\d\/>)($regexp)(?!(?:<DOT>|(?>[^<]))+>)(?![^<]*>)(?!\|>)(?!\/>)/i";
 
 2141            if(!isset($this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'])) {
 
 2142                $this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'] = 
'#\d#';
 
 2146        $this->parse_cache_built = 
true;
 
 2161        $start_time = microtime();
 
 2164        $code = str_replace(
"\r\n", 
"\n", $this->source);
 
 2168        if (empty($this->language_data)) {
 
 2179            $result = str_replace(array(
'<SEMI>', 
'<PIPE>'), array(
';', 
'|'), 
$result);
 
 2182            $this->
set_time($start_time, $start_time);
 
 2188        if (!$this->parse_cache_built) {
 
 2193        $length           = strlen(
$code);
 
 2194        $COMMENT_MATCHED  = 
false;
 
 2195        $stuff_to_parse   = 
'';
 
 2204        if ($this->strict_mode) {
 
 2210            $next_match_pointer = 
null;
 
 2212            $delim_copy = $this->language_data[
'SCRIPT_DELIMITERS'];
 
 2214            while (
$i < $length) {
 
 2215                $next_match_pos = $length + 1; 
 
 2216                foreach ($delim_copy as $dk => $delimiters) {
 
 2217                    if(is_array($delimiters)) {
 
 2218                        foreach ($delimiters as $open => $close) {
 
 2220                            if (!isset($matches[$dk][$open])) {
 
 2221                                $matches[$dk][$open] = array(
 
 2226                                    'open_strlen' => strlen($open),
 
 2229                                    'close_strlen' => strlen($close),
 
 2233                            if ($matches[$dk][$open][
'next_match'] < 
$i) {
 
 2235                                $open_pos = strpos(
$code, $open, 
$i);
 
 2236                                if ($open_pos === 
false) {
 
 2238                                    unset($delim_copy[$dk][$open]);
 
 2241                                $matches[$dk][$open][
'next_match'] = $open_pos;
 
 2243                            if ($matches[$dk][$open][
'next_match'] < $next_match_pos) {
 
 2245                                $matches[$dk][$open][
'close_pos'] =
 
 2246                                    strpos(
$code, $close, $matches[$dk][$open][
'next_match']+1);
 
 2248                                $next_match_pointer =& $matches[$dk][$open];
 
 2249                                $next_match_pos = $matches[$dk][$open][
'next_match'];
 
 2260                        if(preg_match($delimiters, 
$code, $matches_rx, PREG_OFFSET_CAPTURE, 
$i)) {
 
 2262                            if(isset($matches_rx[
'start']) && isset($matches_rx[
'end']))
 
 2264                                $matches[$dk] = array(
 
 2265                                    'next_match' => $matches_rx[
'start'][1],
 
 2268                                    'close_strlen' => strlen($matches_rx[
'end'][0]),
 
 2269                                    'close_pos' => $matches_rx[
'end'][1],
 
 2272                                $matches[$dk] = array(
 
 2273                                    'next_match' => $matches_rx[1][1],
 
 2276                                    'close_strlen' => strlen($matches_rx[2][0]),
 
 2277                                    'close_pos' => $matches_rx[2][1],
 
 2282                            unset($delim_copy[$dk]);
 
 2286                        if ($matches[$dk][
'next_match'] <= $next_match_pos) {
 
 2287                            $next_match_pointer =& $matches[$dk];
 
 2288                            $next_match_pos = $matches[$dk][
'next_match'];
 
 2295                    1 => substr(
$code, 
$i, $next_match_pos - 
$i)
 
 2299                if ($next_match_pos > $length) {
 
 2305                $parts[$k][0] = $next_match_pointer[
'dk'];
 
 2308                if(is_array($delim_copy[$next_match_pointer[
'dk']])) {
 
 2310                    $i = $next_match_pos + $next_match_pointer[
'open_strlen'];
 
 2312                        $close_pos = strpos(
$code, $next_match_pointer[
'close'], 
$i);
 
 2313                        if ($close_pos == 
false) {
 
 2316                        $i = $close_pos + $next_match_pointer[
'close_strlen'];
 
 2317                        if (
$i == $length) {
 
 2320                        if (
$code[
$i] == $next_match_pointer[
'open'][0] && ($next_match_pointer[
'open_strlen'] == 1 ||
 
 2321                            substr(
$code, 
$i, $next_match_pointer[
'open_strlen']) == $next_match_pointer[
'open'])) {
 
 2323                            foreach ($matches as $submatches) {
 
 2324                                foreach ($submatches as $match) {
 
 2325                                    if ($match[
'next_match'] == 
$i) {
 
 2336                    $close_pos = $next_match_pointer[
'close_pos'] + $next_match_pointer[
'close_strlen'];
 
 2340                if ($close_pos === 
false) {
 
 2342                    $parts[$k][1] = substr(
$code, $next_match_pos);
 
 2346                    $parts[$k][1] = substr(
$code, $next_match_pos, 
$i - $next_match_pos);
 
 2350            unset($delim_copy, $next_match_pointer, $next_match_pos, $matches);
 
 2353            if ($num_parts == 1 && $this->strict_mode == 
GESHI_MAYBE) {
 
 2389        $hq = isset($this->language_data[
'HARDQUOTE']) ? $this->language_data[
'HARDQUOTE'][0] : 
false;
 
 2390        $hq_strlen = strlen($hq);
 
 2398        $escaped_escape_char = $this->
hsc($this->language_data[
'ESCAPE_CHAR']);
 
 2401        $sc_disallowed_before = 
"";
 
 2402        $sc_disallowed_after = 
"";
 
 2404        if (isset($this->language_data[
'PARSER_CONTROL'])) {
 
 2405            if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'])) {
 
 2406                if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_BEFORE'])) {
 
 2407                    $sc_disallowed_before = $this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_BEFORE'];
 
 2409                if (isset($this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_AFTER'])) {
 
 2410                    $sc_disallowed_after = $this->language_data[
'PARSER_CONTROL'][
'COMMENTS'][
'DISALLOWED_AFTER'];
 
 2416        $is_string_starter = array();
 
 2417        if ($this->lexic_permissions[
'STRINGS']) {
 
 2418            foreach ($this->language_data[
'QUOTEMARKS'] as $quotemark) {
 
 2419                if (!isset($is_string_starter[$quotemark[0]])) {
 
 2420                    $is_string_starter[$quotemark[0]] = (string)$quotemark;
 
 2421                } elseif (is_string($is_string_starter[$quotemark[0]])) {
 
 2422                    $is_string_starter[$quotemark[0]] = array(
 
 2423                        $is_string_starter[$quotemark[0]],
 
 2426                    $is_string_starter[$quotemark[0]][] = $quotemark;
 
 2440                $endresult .= $this->
hsc($parts[
$key][1]);
 
 2441                unset($parts[
$key]);
 
 2446            $part = $parts[
$key][1];
 
 2448            $highlight_part = 
true;
 
 2449            if ($this->strict_mode && !is_null($parts[
$key][0])) {
 
 2451                $script_key = $parts[
$key][0];
 
 2452                $highlight_part = $this->language_data[
'HIGHLIGHT_STRICT_BLOCK'][$script_key];
 
 2453                if ($this->language_data[
'STYLES'][
'SCRIPT'][$script_key] != 
'' &&
 
 2454                    $this->lexic_permissions[
'SCRIPT']) {
 
 2457                    if (!$this->use_classes &&
 
 2458                        $this->language_data[
'STYLES'][
'SCRIPT'][$script_key] != 
'') {
 
 2459                        $attributes = 
' style="' . $this->language_data[
'STYLES'][
'SCRIPT'][$script_key] . 
'"';
 
 2463                    $result .= 
"<span$attributes>";
 
 2468            if ($highlight_part) {
 
 2474                $next_comment_regexp_key = 
'';
 
 2475                $next_comment_regexp_pos = -1;
 
 2476                $next_comment_multi_pos = -1;
 
 2477                $next_comment_single_pos = -1;
 
 2478                $comment_regexp_cache_per_key = array();
 
 2479                $comment_multi_cache_per_key = array();
 
 2480                $comment_single_cache_per_key = array();
 
 2481                $next_open_comment_multi = 
'';
 
 2482                $next_comment_single_key = 
'';
 
 2483                $escape_regexp_cache_per_key = array();
 
 2484                $next_escape_regexp_key = 
'';
 
 2485                $next_escape_regexp_pos = -1;
 
 2487                $length = strlen($part);
 
 2488                for (
$i = 0; 
$i < $length; ++
$i) {
 
 2494                    if (isset($this->language_data[
'COMMENT_REGEXP']) && $next_comment_regexp_pos < 
$i) {
 
 2495                        $next_comment_regexp_pos = $length;
 
 2496                        foreach ($this->language_data[
'COMMENT_REGEXP'] as $comment_key => $regexp) {
 
 2498                            if (isset($comment_regexp_cache_per_key[$comment_key]) &&
 
 2499                                ($comment_regexp_cache_per_key[$comment_key][
'pos'] >= 
$i ||
 
 2500                                 $comment_regexp_cache_per_key[$comment_key][
'pos'] === 
false)) {
 
 2502                                if ($comment_regexp_cache_per_key[$comment_key][
'pos'] === 
false) {
 
 2506                                $match_i = $comment_regexp_cache_per_key[$comment_key][
'pos'];
 
 2507                            } elseif (preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, 
$i)) {
 
 2508                                $match_i = $match[0][1];
 
 2510                                $comment_regexp_cache_per_key[$comment_key] = array(
 
 2511                                    'key' => $comment_key,
 
 2512                                    'length' => strlen($match[0][0]),
 
 2516                                $comment_regexp_cache_per_key[$comment_key][
'pos'] = 
false;
 
 2520                            if ($match_i !== 
false && $match_i < $next_comment_regexp_pos) {
 
 2521                                $next_comment_regexp_pos = $match_i;
 
 2522                                $next_comment_regexp_key = $comment_key;
 
 2523                                if ($match_i === 
$i) {
 
 2530                    $string_started = 
false;
 
 2532                    if (isset($is_string_starter[$char])) {
 
 2537                        if (is_array($is_string_starter[$char])) {
 
 2539                            foreach ($is_string_starter[$char] as $testchar) {
 
 2540                                if ($testchar === substr($part, 
$i, strlen($testchar)) &&
 
 2541                                    strlen($testchar) > strlen($char_new)) {
 
 2542                                    $char_new = $testchar;
 
 2543                                    $string_started = 
true;
 
 2546                            if ($string_started) {
 
 2550                            $testchar = $is_string_starter[$char];
 
 2551                            if ($testchar === substr($part, 
$i, strlen($testchar))) {
 
 2553                                $string_started = 
true;
 
 2556                        $char_len = strlen($char);
 
 2559                    if ($string_started && (
$i != $next_comment_regexp_pos)) {
 
 2561                        $string_key = array_search($char, $this->language_data[
'QUOTEMARKS']);
 
 2562                        if (!isset($this->language_data[
'STYLES'][
'STRINGS'][$string_key]) ||
 
 2563                            !isset($this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$string_key])) {
 
 2569                        $stuff_to_parse = 
'';
 
 2571                        if (!$this->use_classes) {
 
 2572                            $string_attributes = 
' style="' . $this->language_data[
'STYLES'][
'STRINGS'][$string_key] . 
'"';
 
 2574                            $string_attributes = 
' class="st'.$string_key.
'"';
 
 2578                        $string = 
"<span$string_attributes>" . 
GeSHi::hsc($char);
 
 2580                        $string_open = 
true;
 
 2582                        if(empty($this->language_data[
'ESCAPE_REGEXP'])) {
 
 2583                            $next_escape_regexp_pos = $length;
 
 2588                            $close_pos = strpos($part, $char, 
$start);
 
 2589                            if(
false === $close_pos) {
 
 2590                                $close_pos = $length;
 
 2593                            if($this->lexic_permissions[
'ESCAPE_CHAR']) {
 
 2595                                if (isset($this->language_data[
'ESCAPE_REGEXP']) && $next_escape_regexp_pos < 
$start) {
 
 2596                                    $next_escape_regexp_pos = $length;
 
 2597                                    foreach ($this->language_data[
'ESCAPE_REGEXP'] as $escape_key => $regexp) {
 
 2599                                        if (isset($escape_regexp_cache_per_key[$escape_key]) &&
 
 2600                                            ($escape_regexp_cache_per_key[$escape_key][
'pos'] >= 
$start ||
 
 2601                                             $escape_regexp_cache_per_key[$escape_key][
'pos'] === 
false)) {
 
 2603                                            if ($escape_regexp_cache_per_key[$escape_key][
'pos'] === 
false) {
 
 2607                                            $match_i = $escape_regexp_cache_per_key[$escape_key][
'pos'];
 
 2608                                        } elseif (preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, 
$start)) {
 
 2609                                            $match_i = $match[0][1];
 
 2611                                            $escape_regexp_cache_per_key[$escape_key] = array(
 
 2612                                                'key' => $escape_key,
 
 2613                                                'length' => strlen($match[0][0]),
 
 2617                                            $escape_regexp_cache_per_key[$escape_key][
'pos'] = 
false;
 
 2621                                        if ($match_i !== 
false && $match_i < $next_escape_regexp_pos) {
 
 2622                                            $next_escape_regexp_pos = $match_i;
 
 2623                                            $next_escape_regexp_key = $escape_key;
 
 2624                                            if ($match_i === 
$start) {
 
 2632                                if(
'' != $this->language_data[
'ESCAPE_CHAR']) {
 
 2633                                    $simple_escape = strpos($part, $this->language_data[
'ESCAPE_CHAR'], 
$start);
 
 2634                                    if(
false === $simple_escape) {
 
 2635                                        $simple_escape = $length;
 
 2638                                    $simple_escape = $length;
 
 2641                                $next_escape_regexp_pos = $length;
 
 2642                                $simple_escape = $length;
 
 2645                            if($simple_escape < $next_escape_regexp_pos &&
 
 2646                                $simple_escape < $length &&
 
 2647                                $simple_escape < $close_pos) {
 
 2649                                $es_pos = $simple_escape;
 
 2655                                if (!$this->use_classes) {
 
 2656                                    $escape_char_attributes = 
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][0] . 
'"';
 
 2658                                    $escape_char_attributes = 
' class="es0"';
 
 2662                                $string .= 
"<span$escape_char_attributes>" .
 
 2663                                    GeSHi::hsc($this->language_data[
'ESCAPE_CHAR']);
 
 2666                                $es_char = $part[$es_pos + 1];
 
 2667                                if ($es_char == 
"\n") {
 
 2669                                    $string .= 
"</span>\n";
 
 2671                                } elseif (ord($es_char) >= 128) {
 
 2674                                    if(function_exists(
'mb_substr')) {
 
 2675                                        $es_char_m = mb_substr(substr($part, $es_pos+1, 16), 0, 1, $this->encoding);
 
 2676                                        $string .= $es_char_m . 
'</span>';
 
 2677                                    } elseif (
'utf-8' == $this->encoding) {
 
 2678                                        if(preg_match(
"/[\xC2-\xDF][\x80-\xBF]".
 
 2679                                            "|\xE0[\xA0-\xBF][\x80-\xBF]".
 
 2680                                            "|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}".
 
 2681                                            "|\xED[\x80-\x9F][\x80-\xBF]".
 
 2682                                            "|\xF0[\x90-\xBF][\x80-\xBF]{2}".
 
 2683                                            "|[\xF1-\xF3][\x80-\xBF]{3}".
 
 2684                                            "|\xF4[\x80-\x8F][\x80-\xBF]{2}/s",
 
 2685                                            $part, $es_char_m, 
null, $es_pos + 1)) {
 
 2686                                            $es_char_m = $es_char_m[0];
 
 2688                                            $es_char_m = $es_char;
 
 2690                                        $string .= $this->
hsc($es_char_m) . 
'</span>';
 
 2692                                        $es_char_m = $this->
hsc($es_char);
 
 2694                                    $start = $es_pos + strlen($es_char_m) + 1;
 
 2696                                    $string .= $this->
hsc($es_char) . 
'</span>';
 
 2699                            } elseif ($next_escape_regexp_pos < $length &&
 
 2700                                $next_escape_regexp_pos < $close_pos) {
 
 2701                                $es_pos = $next_escape_regexp_pos;
 
 2706                                $escape = $escape_regexp_cache_per_key[$next_escape_regexp_key];
 
 2707                                $escape_str = substr($part, $es_pos, $escape[
'length']);
 
 2708                                $escape_key = $escape[
'key'];
 
 2711                                if (!$this->use_classes) {
 
 2712                                    $escape_char_attributes = 
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][$escape_key] . 
'"';
 
 2714                                    $escape_char_attributes = 
' class="es' . $escape_key . 
'"';
 
 2718                                $string .= 
"<span$escape_char_attributes>" .
 
 2719                                    $this->
hsc($escape_str) . 
'</span>';
 
 2721                                $start = $es_pos + $escape[
'length'];
 
 2724                                $string .= $this->
hsc(substr($part, 
$start, $close_pos - 
$start + $char_len)) . 
'</span>';
 
 2725                                $start = $close_pos + $char_len;
 
 2726                                $string_open = 
false;
 
 2728                        } 
while($string_open);
 
 2730                        if ($check_linenumbers) {
 
 2736                            $string = str_replace(
"\n", 
"</span>\n<span$string_attributes>", $string);
 
 2743                    } elseif ($this->lexic_permissions[
'STRINGS'] && $hq && $hq[0] == $char &&
 
 2744                        substr($part, 
$i, $hq_strlen) == $hq && (
$i != $next_comment_regexp_pos)) {
 
 2746                        if (!$this->use_classes) {
 
 2747                            $string_attributes = 
' style="' . $this->language_data[
'STYLES'][
'STRINGS'][
'HARD'] . 
'"';
 
 2748                            $escape_char_attributes = 
' style="' . $this->language_data[
'STYLES'][
'ESCAPE_CHAR'][
'HARD'] . 
'"';
 
 2750                            $string_attributes = 
' class="st_h"';
 
 2751                            $escape_char_attributes = 
' class="es_h"';
 
 2755                        $stuff_to_parse = 
'';
 
 2762                        while ($close_pos = strpos($part, $this->language_data[
'HARDQUOTE'][1], 
$start)) {
 
 2764                            if ($this->lexic_permissions[
'ESCAPE_CHAR'] && $part[$close_pos - 1] == $this->language_data[
'HARDCHAR'] &&
 
 2765                                ((
$i + $hq_strlen) != ($close_pos))) { 
 
 2767                                foreach ($this->language_data[
'HARDESCAPE'] as $hardescape) {
 
 2768                                    if (substr($part, $close_pos - 1, strlen($hardescape)) == $hardescape) {
 
 2770                                        $escape_char_pos = $close_pos - 1;
 
 2771                                        while ($escape_char_pos > 0
 
 2772                                                && $part[$escape_char_pos - 1] == $this->language_data[
'HARDCHAR']) {
 
 2775                                        if (($close_pos - $escape_char_pos) & 1) {
 
 2790                            $close_pos = $length;
 
 2794                        $string = substr($part, 
$i, $close_pos - 
$i + 1);
 
 2799                        if ($this->lexic_permissions[
'ESCAPE_CHAR'] && $this->language_data[
'ESCAPE_CHAR']) {
 
 2802                            while ($es_pos = strpos($string, $this->language_data[
'ESCAPE_CHAR'], 
$start)) {
 
 2806                                foreach ($this->language_data[
'HARDESCAPE'] as $hardescape) {
 
 2807                                    if (substr($string, $es_pos, strlen($hardescape)) == $hardescape) {
 
 2809                                        $new_string .= 
"<span$escape_char_attributes>" .
 
 2810                                            $this->
hsc($hardescape) . 
'</span>';
 
 2811                                        $start = $es_pos + strlen($hardescape);
 
 2818                                while (isset($string[$es_pos + 
$c]) && isset($string[$es_pos + 
$c + 1])
 
 2819                                    && $string[$es_pos + 
$c] == $this->language_data[
'ESCAPE_CHAR']
 
 2820                                    && $string[$es_pos + 
$c + 1] == $this->language_data[
'ESCAPE_CHAR']) {
 
 2824                                    $new_string .= 
"<span$escape_char_attributes>" .
 
 2825                                        str_repeat($escaped_escape_char, 
$c) .
 
 2830                                    $new_string .= $escaped_escape_char;
 
 2834                            $string = $new_string . $this->
hsc(substr($string, 
$start));
 
 2836                            $string = $this->
hsc($string);
 
 2839                        if ($check_linenumbers) {
 
 2845                            $string = str_replace(
"\n", 
"</span>\n<span$string_attributes>", $string);
 
 2848                        $result .= 
"<span$string_attributes>" . $string . 
'</span>';
 
 2853                        if (
$i == $next_comment_regexp_pos) {
 
 2854                            $COMMENT_MATCHED = 
true;
 
 2855                            $comment = $comment_regexp_cache_per_key[$next_comment_regexp_key];
 
 2856                            $test_str = $this->
hsc(substr($part, 
$i, 
$comment[
'length']));
 
 2859                            if ($this->lexic_permissions[
'COMMENTS'][
'MULTI']) {
 
 2860                                if (!$this->use_classes) {
 
 2861                                    $attributes = 
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][
$comment[
'key']] . 
'"';
 
 2866                                $test_str = 
"<span$attributes>" . $test_str . 
"</span>";
 
 2869                                if ($check_linenumbers) {
 
 2871                                    $test_str = str_replace(
 
 2872                                        "\n", 
"</span>\n<span$attributes>",
 
 2873                                        str_replace(
"\n ", 
"\n ", $test_str)
 
 2882                            $stuff_to_parse = 
'';
 
 2886                        if (!$COMMENT_MATCHED) {
 
 2888                            if (!empty($this->language_data[
'COMMENT_MULTI']) && $next_comment_multi_pos < 
$i) {
 
 2889                                $next_comment_multi_pos = $length;
 
 2890                                foreach ($this->language_data[
'COMMENT_MULTI'] as $open => $close) {
 
 2892                                    if (isset($comment_multi_cache_per_key[$open]) &&
 
 2893                                        ($comment_multi_cache_per_key[$open] >= 
$i ||
 
 2894                                         $comment_multi_cache_per_key[$open] === 
false)) {
 
 2896                                        if ($comment_multi_cache_per_key[$open] === 
false) {
 
 2900                                        $match_i = $comment_multi_cache_per_key[$open];
 
 2901                                    } elseif (($match_i = stripos($part, $open, 
$i)) !== 
false) {
 
 2902                                        $comment_multi_cache_per_key[$open] = $match_i;
 
 2904                                        $comment_multi_cache_per_key[$open] = 
false;
 
 2907                                    if ($match_i !== 
false && $match_i < $next_comment_multi_pos) {
 
 2908                                        $next_comment_multi_pos = $match_i;
 
 2909                                        $next_open_comment_multi = $open;
 
 2910                                        if ($match_i === 
$i) {
 
 2916                            if (
$i == $next_comment_multi_pos) {
 
 2917                                $open = $next_open_comment_multi;
 
 2918                                $close = $this->language_data[
'COMMENT_MULTI'][$open];
 
 2919                                $open_strlen = strlen($open);
 
 2920                                $close_strlen = strlen($close);
 
 2921                                $COMMENT_MATCHED = 
true;
 
 2922                                $test_str_match = $open;
 
 2924                                if ($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
 
 2927                                        if (!$this->use_classes) {
 
 2928                                            $attributes = 
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][
'MULTI'] . 
'"';
 
 2932                                        $test_str = 
"<span$attributes>" . $this->
hsc($open);
 
 2934                                        if (!$this->use_classes) {
 
 2935                                            $attributes = 
' style="' . $this->important_styles . 
'"';
 
 2942                                        $test_str = 
"<span$attributes>";
 
 2945                                    $test_str = $this->
hsc($open);
 
 2948                                $close_pos = strpos( $part, $close, 
$i + $open_strlen );
 
 2950                                if ($close_pos === 
false) {
 
 2951                                    $close_pos = $length;
 
 2955                                $rest_of_comment = $this->
hsc(substr($part, 
$i + $open_strlen, $close_pos - 
$i - $open_strlen + $close_strlen));
 
 2956                                if (($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
 
 2958                                    $check_linenumbers) {
 
 2961                                    $test_str .= str_replace(
 
 2962                                        "\n", 
"</span>\n<span$attributes>",
 
 2963                                        str_replace(
"\n ", 
"\n ", $rest_of_comment)
 
 2966                                    $test_str .= $rest_of_comment;
 
 2969                                if ($this->lexic_permissions[
'COMMENTS'][
'MULTI'] ||
 
 2971                                    $test_str .= 
'</span>';
 
 2974                                $i = $close_pos + $close_strlen - 1;
 
 2978                                $stuff_to_parse = 
'';
 
 2983                        if (!$COMMENT_MATCHED) {
 
 2985                            if (!empty($this->language_data[
'COMMENT_SINGLE']) && $next_comment_single_pos < 
$i) {
 
 2986                                $next_comment_single_pos = $length;
 
 2987                                foreach ($this->language_data[
'COMMENT_SINGLE'] as $comment_key => $comment_mark) {
 
 2989                                    if (isset($comment_single_cache_per_key[$comment_key]) &&
 
 2990                                        ($comment_single_cache_per_key[$comment_key] >= 
$i ||
 
 2991                                         $comment_single_cache_per_key[$comment_key] === 
false)) {
 
 2993                                        if ($comment_single_cache_per_key[$comment_key] === 
false) {
 
 2997                                        $match_i = $comment_single_cache_per_key[$comment_key];
 
 3001                                        ($match_i = stripos($part, $comment_mark, 
$i)) !== 
false) ||
 
 3004                                          (($match_i = strpos($part, $comment_mark, 
$i)) !== 
false))) {
 
 3005                                        $comment_single_cache_per_key[$comment_key] = $match_i;
 
 3007                                        $comment_single_cache_per_key[$comment_key] = 
false;
 
 3010                                    if ($match_i !== 
false && $match_i < $next_comment_single_pos) {
 
 3011                                        $next_comment_single_pos = $match_i;
 
 3012                                        $next_comment_single_key = $comment_key;
 
 3013                                        if ($match_i === 
$i) {
 
 3019                            if ($next_comment_single_pos == 
$i) {
 
 3020                                $comment_key = $next_comment_single_key;
 
 3021                                $comment_mark = $this->language_data[
'COMMENT_SINGLE'][$comment_key];
 
 3022                                $com_len = strlen($comment_mark);
 
 3026                                if ((empty($sc_disallowed_before) || (
$i == 0) ||
 
 3027                                    (
false === strpos($sc_disallowed_before, $part[
$i-1]))) &&
 
 3028                                    (empty($sc_disallowed_after) || ($length <= 
$i + $com_len) ||
 
 3029                                    (
false === strpos($sc_disallowed_after, $part[
$i + $com_len]))))
 
 3032                                    $COMMENT_MATCHED = 
true;
 
 3033                                    if ($this->lexic_permissions[
'COMMENTS'][$comment_key]) {
 
 3034                                        if (!$this->use_classes) {
 
 3035                                            $attributes = 
' style="' . $this->language_data[
'STYLES'][
'COMMENTS'][$comment_key] . 
'"';
 
 3039                                        $test_str = 
"<span$attributes>" . $this->
hsc($this->
change_case($comment_mark));
 
 3041                                        $test_str = $this->
hsc($comment_mark);
 
 3045                                    $close_pos = strpos($part, 
"\n", 
$i);
 
 3047                                    if ($close_pos === 
false) {
 
 3048                                        $close_pos = $length;
 
 3051                                    $test_str .= $this->
hsc(substr($part, 
$i + $com_len, $close_pos - 
$i - $com_len));
 
 3052                                    if ($this->lexic_permissions[
'COMMENTS'][$comment_key]) {
 
 3053                                        $test_str .= 
"</span>";
 
 3065                                    $stuff_to_parse = 
'';
 
 3072                    if (!$COMMENT_MATCHED) {
 
 3073                        $stuff_to_parse .= $char;
 
 3077                        $COMMENT_MATCHED = 
false;
 
 3082                $stuff_to_parse = 
'';
 
 3087            if ($STRICTATTRS != 
'') {
 
 3088                $result = str_replace(
"\n", 
"</span>\n<span$STRICTATTRS>", 
$result);
 
 3099        $endresult = str_replace(array(
'<SEMI>', 
'<PIPE>'), array(
';', 
'|'), $endresult);
 
 3108        $this->
set_time($start_time, microtime());
 
 3123        if (
false !== strpos(
$result, 
"\t")) {
 
 3124            $lines = explode(
"\n", 
$result);
 
 3127            $tab_string = 
' ' . str_repeat(
' ', 
$tab_width);
 
 3130                $line = $lines[
$key];
 
 3131                if (
false === strpos($line, 
"\t")) {
 
 3136                $length = strlen($line);
 
 3140                for (
$i = 0; 
$i < $length; ++
$i) {
 
 3153                        $lines[
$key] .= $char;
 
 3154                    } elseif (
'<' == $char) {
 
 3156                        $lines[
$key] .= 
'<';
 
 3157                    } elseif (
'&' == $char) {
 
 3158                        $substr = substr($line, 
$i + 3, 5);
 
 3159                        $posi = strpos($substr, 
';');
 
 3160                        if (
false === $posi) {
 
 3165                        $lines[
$key] .= $char;
 
 3166                    } elseif (
"\t" == $char) {
 
 3175                        if (($pos & 1) || 1 == $tab_end_width) {
 
 3176                            $str .= substr($tab_string, 6, $tab_end_width);
 
 3178                            $str .= substr($tab_string, 0, $tab_end_width+5);
 
 3180                        $lines[
$key] .= $str;
 
 3181                        $pos += $tab_end_width;
 
 3183                        if (
false === strpos($line, 
"\t", 
$i + 1)) {
 
 3184                            $lines[
$key] .= substr($line, 
$i + 1);
 
 3187                    } elseif (0 == $pos && 
' ' == $char) {
 
 3188                        $lines[
$key] .= 
' ';
 
 3191                        $lines[
$key] .= $char;
 
 3196            $result = implode(
"\n", $lines);
 
 3205            if ($this->line_ending === 
null) {
 
 3221        switch ($this->language_data[
'CASE_KEYWORDS']) {
 
 3223                return strtoupper($instr);
 
 3225                return strtolower($instr);
 
 3242        $keyword = $match[0];
 
 3243        $keyword_match = $match[1];
 
 3248        if ($this->keyword_links) {
 
 3251            if (isset($this->language_data[
'URLS'][$k]) &&
 
 3252                $this->language_data[
'URLS'][$k] != 
'') {
 
 3258                if (!$this->language_data[
'CASE_SENSITIVE'][$k] &&
 
 3259                    strpos($this->language_data[
'URLS'][$k], 
'{FNAME}') !== 
false) {
 
 3260                    foreach ($this->language_data[
'KEYWORDS'][$k] as $word) {
 
 3261                        if (strcasecmp($word, $keyword_match) == 0) {
 
 3266                    $word = $keyword_match;
 
 3269                $before = 
'<|UR1|"' .
 
 3278                            str_replace(
'+', 
'%20', urlencode($this->
hsc($word))),
 
 3279                            str_replace(
'+', 
'%20', urlencode($this->
hsc(strtolower($word)))),
 
 3280                            str_replace(
'+', 
'%20', urlencode($this->
hsc(strtoupper($word)))),
 
 3281                            str_replace(
'+', 
'%20', urlencode($this->
hsc(ucfirst($word)))),
 
 3283                        $this->language_data[
'URLS'][$k]
 
 3289        return $before . 
'<|/'. $k .
'/>' . $this->
change_case($keyword) . 
'|>' . $after;
 
 3303        return  ' style="' . call_user_func($this->language_data[
'STYLES'][
'REGEXPS'][$this->_rx_key], $matches[1]) . 
'"'. $matches[1] . 
'|>';
 
 3318        if ($this->_hmr_replace) {
 
 3322            foreach (array_keys($matches) as $k) {
 
 3323                $search[] = 
'\\' . $k;
 
 3326            $before = str_replace($search, $matches, $before);
 
 3327            $after = str_replace($search, $matches, $after);
 
 3328            $replace = str_replace($search, $matches, $replace);
 
 3330            $replace = $matches[0];
 
 3333                    . 
'<|!REG3XP' . $this->_hmr_key .
'!>' 
 3334                        . str_replace(
"\n", 
"|>\n<|!REG3XP" . $this->_hmr_key . 
'!>', $replace)
 
 3349        $stuff_to_parse = 
' ' . $this->
hsc($stuff_to_parse);
 
 3352        $disallowed_before = 
"(?<![a-zA-Z0-9\$_\|\#|^&";
 
 3353        $disallowed_after = 
"(?![a-zA-Z0-9_\|%\\-&;";
 
 3354        if ($this->lexic_permissions[
'STRINGS']) {
 
 3355            $quotemarks = preg_quote(implode($this->language_data[
'QUOTEMARKS']), 
'/');
 
 3356            $disallowed_before .= $quotemarks;
 
 3357            $disallowed_after .= $quotemarks;
 
 3359        $disallowed_before .= 
"])";
 
 3360        $disallowed_after .= 
"])";
 
 3362        $parser_control_pergroup = 
false;
 
 3363        if (isset($this->language_data[
'PARSER_CONTROL'])) {
 
 3364            if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'])) {
 
 3366                if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_BEFORE'])) {
 
 3367                    $disallowed_before = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_BEFORE'];
 
 3370                if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_AFTER'])) {
 
 3371                    $disallowed_after = $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][
'DISALLOWED_AFTER'];
 
 3374                $parser_control_pergroup = (count($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS']) - 
$x) > 0;
 
 3378        foreach (array_keys($this->language_data[
'KEYWORDS']) as $k) {
 
 3379            if (!isset($this->lexic_permissions[
'KEYWORDS'][$k]) ||
 
 3380                $this->lexic_permissions[
'KEYWORDS'][$k]) {
 
 3382                $case_sensitive = $this->language_data[
'CASE_SENSITIVE'][$k];
 
 3383                $modifiers = $case_sensitive ? 
'' : 
'i';
 
 3386                $disallowed_before_local = $disallowed_before;
 
 3387                $disallowed_after_local = $disallowed_after;
 
 3388                if ($parser_control_pergroup && isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k])) {
 
 3389                    if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_BEFORE'])) {
 
 3390                        $disallowed_before_local =
 
 3391                            $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_BEFORE'];
 
 3394                    if (isset($this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_AFTER'])) {
 
 3395                        $disallowed_after_local =
 
 3396                            $this->language_data[
'PARSER_CONTROL'][
'KEYWORDS'][$k][
'DISALLOWED_AFTER'];
 
 3400                $this->_kw_replace_group = $k;
 
 3404                for ($set = 0, $set_length = count($this->language_data[
'CACHED_KEYWORD_LISTS'][$k]); $set <  $set_length; ++$set) {
 
 3405                    $keywordset =& $this->language_data[
'CACHED_KEYWORD_LISTS'][$k][$set];
 
 3409                    $stuff_to_parse = preg_replace_callback(
 
 3410                        "/$disallowed_before_local({$keywordset})(?!<DOT>(?:htm|php|aspx?))$disallowed_after_local/$modifiers",
 
 3411                        array($this, 
'handle_keyword_replace'),
 
 3419        foreach ($this->language_data[
'REGEXPS'] as 
$key => $regexp) {
 
 3420            if ($this->lexic_permissions[
'REGEXPS'][
$key]) {
 
 3421                if (is_array($regexp)) {
 
 3426                        $this->_hmr_key = 
$key;
 
 3428                        $stuff_to_parse = preg_replace_callback(
 
 3429                            "/" . $regexp[
GESHI_SEARCH] . 
"/{$regexp[GESHI_MODIFIERS]}",
 
 3430                            array($this, 
'handle_multiline_regexps'),
 
 3432                        $this->_hmr_replace = 
false;
 
 3433                        $this->_hmr_before = 
'';
 
 3434                        $this->_hmr_after = 
'';
 
 3436                        $stuff_to_parse = preg_replace(
 
 3444                        $this->_hmr_key = 
$key;
 
 3445                        $stuff_to_parse = preg_replace_callback( 
"/(" . $regexp . 
")/",
 
 3446                                              array($this, 
'handle_multiline_regexps'), $stuff_to_parse);
 
 3447                        $this->_hmr_key = 
'';
 
 3449                        $stuff_to_parse = preg_replace( 
"/(" . $regexp . 
")/", 
"<|!REG3XP$key!>\\1|>", $stuff_to_parse);
 
 3456        $numbers_found = 
false;
 
 3458        if ($this->lexic_permissions[
'NUMBERS'] && preg_match($this->language_data[
'PARSER_CONTROL'][
'NUMBERS'][
'PRECHECK_RX'], $stuff_to_parse )) {
 
 3459            $numbers_found = 
true;
 
 3462            foreach($this->language_data[
'NUMBERS_RXCACHE'] as 
$id => $regexp) {
 
 3464                $stuff_to_parse = preg_replace($regexp, 
"<|/NUM!$id/>\\1|>", $stuff_to_parse);
 
 3471        foreach (array_keys($this->language_data[
'KEYWORDS']) as $k) {
 
 3472            if (!$this->use_classes) {
 
 3474                    (isset($this->language_data[
'STYLES'][
'KEYWORDS'][$k]) ?
 
 3475                    $this->language_data[
'STYLES'][
'KEYWORDS'][$k] : 
"") . 
'"';
 
 3479            $stuff_to_parse = str_replace(
"<|/$k/>", 
"<|$attributes>", $stuff_to_parse);
 
 3482        if ($numbers_found) {
 
 3484            foreach($this->language_data[
'NUMBERS_RXCACHE'] as 
$id => $regexp) {
 
 3489                if (!$this->use_classes) {
 
 3490                    $attributes = 
' style="' . $this->language_data[
'STYLES'][
'NUMBERS'][
$id] . 
'"';
 
 3496                $stuff_to_parse = str_replace(
"/NUM!$id/", 
$attributes, $stuff_to_parse);
 
 3502        if ($this->lexic_permissions[
'METHODS'] && $this->language_data[
'OOLANG']) {
 
 3503            $oolang_spaces = 
"[\s]*";
 
 3504            $oolang_before = 
"";
 
 3505            $oolang_after = 
"[a-zA-Z][a-zA-Z0-9_]*";
 
 3506            if (isset($this->language_data[
'PARSER_CONTROL'])) {
 
 3507                if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'])) {
 
 3508                    if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_BEFORE'])) {
 
 3509                        $oolang_before = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_BEFORE'];
 
 3511                    if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_AFTER'])) {
 
 3512                        $oolang_after = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_AFTER'];
 
 3514                    if (isset($this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_SPACES'])) {
 
 3515                        $oolang_spaces = $this->language_data[
'PARSER_CONTROL'][
'OOLANG'][
'MATCH_SPACES'];
 
 3520            foreach ($this->language_data[
'OBJECT_SPLITTERS'] as 
$key => 
$splitter) {
 
 3521                if (
false !== strpos($stuff_to_parse, 
$splitter)) {
 
 3522                    if (!$this->use_classes) {
 
 3523                        $attributes = 
' style="' . $this->language_data[
'STYLES'][
'METHODS'][
$key] . 
'"';
 
 3527                    $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);
 
 3538        if ($this->lexic_permissions[
'BRACKETS']) {
 
 3539            $stuff_to_parse = str_replace( $this->language_data[
'CACHE_BRACKET_MATCH'],
 
 3540                              $this->language_data[
'CACHE_BRACKET_REPLACE'], $stuff_to_parse );
 
 3545        if ($this->lexic_permissions[
'SYMBOLS'] && !empty($this->language_data[
'SYMBOLS'])) {
 
 3547            $n_symbols = preg_match_all(
"/<\|(?:<DOT>|[^>])+>(?:(?!\|>).*?)\|>|<\/a>|(?:" . $this->language_data[
'SYMBOL_SEARCH'] . 
")+(?![^<]+?>)/", $stuff_to_parse, $pot_symbols, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
 
 3549            for ($s_id = 0; $s_id < $n_symbols; ++$s_id) {
 
 3550                $symbol_match = $pot_symbols[$s_id][0][0];
 
 3551                if (strpos($symbol_match, 
'<') !== 
false || strpos($symbol_match, 
'>') !== 
false) {
 
 3555                    if(strpos($symbol_match, 
'<SEMI>') === 
false &&
 
 3556                        strpos($symbol_match, 
'<PIPE>') === 
false) {
 
 3563                $symbol_length = strlen($symbol_match);
 
 3564                $symbol_offset = $pot_symbols[$s_id][0][1];
 
 3565                unset($pot_symbols[$s_id]);
 
 3569                if ($this->language_data[
'MULTIPLE_SYMBOL_GROUPS']) {
 
 3572                    preg_match_all(
"/" . $this->language_data[
'SYMBOL_SEARCH'] . 
"/", $symbol_match, $sym_match_syms, PREG_PATTERN_ORDER);
 
 3573                    foreach ($sym_match_syms[0] as $sym_ms) {
 
 3575                        if (isset($this->language_data[
'SYMBOL_DATA'][$sym_ms])
 
 3576                            && ($this->language_data[
'SYMBOL_DATA'][$sym_ms] != $old_sym)) {
 
 3577                            if (-1 != $old_sym) {
 
 3580                            $old_sym = $this->language_data[
'SYMBOL_DATA'][$sym_ms];
 
 3581                            if (!$this->use_classes) {
 
 3582                                $symbol_hl .= 
'<| style="' . $this->language_data[
'STYLES'][
'SYMBOLS'][$old_sym] . 
'">';
 
 3584                                $symbol_hl .= 
'<| class="sy' . $old_sym . 
'">';
 
 3587                        $symbol_hl .= $sym_ms;
 
 3589                    unset($sym_match_syms);
 
 3593                    if (-1 != $old_sym) {
 
 3597                    if (!$this->use_classes) {
 
 3598                        $symbol_hl = 
'<| style="' . $this->language_data[
'STYLES'][
'SYMBOLS'][0] . 
'">';
 
 3600                        $symbol_hl = 
'<| class="sy0">';
 
 3602                    $symbol_hl .= $symbol_match . 
'|>';
 
 3605                $stuff_to_parse = substr_replace($stuff_to_parse, $symbol_hl, $symbol_offset + $global_offset, $symbol_length);
 
 3609                $global_offset += strlen($symbol_hl) - $symbol_length;
 
 3615        foreach (array_keys($this->language_data[
'REGEXPS']) as 
$key) {
 
 3616            if ($this->lexic_permissions[
'REGEXPS'][
$key]) {
 
 3617                if (is_callable($this->language_data[
'STYLES'][
'REGEXPS'][
$key])) {
 
 3618                    $this->_rx_key = 
$key;
 
 3619                    $stuff_to_parse = preg_replace_callback(
"/!REG3XP$key!(.*)\|>/U",
 
 3620                        array($this, 
'handle_regexps_callback'),
 
 3623                    if (!$this->use_classes) {
 
 3624                        $attributes = 
' style="' . $this->language_data[
'STYLES'][
'REGEXPS'][
$key] . 
'"';
 
 3626                        if (is_array($this->language_data[
'REGEXPS'][
$key]) &&
 
 3627                            array_key_exists(
GESHI_CLASS, $this->language_data[
'REGEXPS'][
$key])) {
 
 3634                    $stuff_to_parse = str_replace(
"!REG3XP$key!", 
"$attributes", $stuff_to_parse);
 
 3640        $stuff_to_parse = str_replace(
'<DOT>', 
'.', $stuff_to_parse);
 
 3643            if ($this->use_classes) {
 
 3644                $stuff_to_parse = str_replace(
'<|UR1|', 
'<a' . $this->link_target . 
' href=', $stuff_to_parse);
 
 3646                $stuff_to_parse = str_replace(
'<|UR1|', 
'<a' . $this->link_target . 
' style="' . $this->link_styles[
GESHI_LINK] . 
'" href=', $stuff_to_parse);
 
 3649            $stuff_to_parse = str_replace(
'<|UR1|', 
'<a' . $this->link_target . 
' href=', $stuff_to_parse);
 
 3656        $stuff_to_parse = str_replace(
'<|', 
'<span', $stuff_to_parse);
 
 3657        $stuff_to_parse = str_replace ( 
'|>', 
'</span>', $stuff_to_parse );
 
 3658        return substr($stuff_to_parse, 1);
 
 3669        $start = explode(
' ', $start_time);
 
 3670        $end = explode(
' ', $end_time);
 
 3690        $arrays = func_get_args();
 
 3691        $narrays = count($arrays);
 
 3695        for (
$i = 0; 
$i < $narrays; 
$i ++) {
 
 3696            if (!is_array($arrays[
$i])) {
 
 3698                trigger_error(
'Argument #' . (
$i+1) . 
' is not an array - trying to merge array with scalar! Returning false!', E_USER_WARNING);
 
 3707        for (
$i = 1; 
$i < $narrays; 
$i ++) {
 
 3708            foreach ($arrays[
$i] as 
$key => $value) {
 
 3709                if (is_array($value) && isset(
$ret[
$key])) {
 
 3730        if ($file_name == $this->loaded_language) {
 
 3736        $this->loaded_language = $file_name;
 
 3737        $this->parse_cache_built = 
false;
 
 3749        $this->strict_mode = $this->language_data[
'STRICT_MODE_APPLIES'];
 
 3753        foreach (array_keys($this->language_data[
'KEYWORDS']) as 
$key) {
 
 3754            if (!empty($this->language_data[
'KEYWORDS'][
$key])) {
 
 3755                $this->lexic_permissions[
'KEYWORDS'][
$key] = 
true;
 
 3757                $this->lexic_permissions[
'KEYWORDS'][
$key] = 
false;
 
 3761        foreach (array_keys($this->language_data[
'COMMENT_SINGLE']) as 
$key) {
 
 3762            $this->lexic_permissions[
'COMMENTS'][
$key] = 
true;
 
 3764        foreach (array_keys($this->language_data[
'REGEXPS']) as 
$key) {
 
 3765            $this->lexic_permissions[
'REGEXPS'][
$key] = 
true;
 
 3772        if (!empty($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS'])) {
 
 3773            foreach ($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS'] as $flag => $value) {
 
 3776                if ($flag == 
'ALL') {
 
 3780                if (!isset($this->lexic_permissions[$flag])) {
 
 3784                if (is_array($this->lexic_permissions[$flag])) {
 
 3785                    foreach ($this->lexic_permissions[$flag] as 
$key => $val) {
 
 3786                        $this->lexic_permissions[$flag][
$key] = $perm;
 
 3789                    $this->lexic_permissions[$flag] = $perm;
 
 3792            unset($this->language_data[
'PARSER_CONTROL'][
'ENABLE_FLAGS']);
 
 3797        if(!isset($this->language_data[
'HARDCHAR'])) {
 
 3798            $this->language_data[
'HARDCHAR'] = $this->language_data[
'ESCAPE_CHAR'];
 
 3802        $style_filename = substr($file_name, 0, -4) . 
'.style.php';
 
 3803        if (is_readable($style_filename)) {
 
 3805            if (isset($style_data)) {
 
 3810            include $style_filename;
 
 3813            if (isset($style_data) && is_array($style_data)) {
 
 3814                $this->language_data[
'STYLES'] =
 
 3815                    $this->
merge_arrays($this->language_data[
'STYLES'], $style_data);
 
 3838            $this->
indent($parsed_code);
 
 3843        $parsed_code = preg_replace(
'#<span[^>]+>(\s*)</span>#', 
'\\1', $parsed_code);
 
 3847        if ($this->add_ids && !$this->overall_id) {
 
 3848            $this->overall_id = 
'geshi-' . substr(md5(microtime()), 0, 4);
 
 3853        $code = explode(
"\n", $parsed_code);
 
 3854        $parsed_code = $this->
header();
 
 3876                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
 
 3878                    if ($this->use_classes) {
 
 3880                        $attrs[
'class'][] = 
'li2';
 
 3881                        $def_attr = 
' class="de2"';
 
 3888                        $def_attr = 
' style="' . $this->code_style . 
'"';
 
 3891                    if ($this->use_classes) {
 
 3893                        $attrs[
'class'][] = 
'li1';
 
 3894                        $def_attr = 
' class="de1"';
 
 3898                        $def_attr = 
' style="' . $this->code_style . 
'"';
 
 3904                    $start = 
"<pre$def_attr>";
 
 3908                    $start = 
"<div$def_attr>";
 
 3915                if ($this->add_ids) {
 
 3916                    $attrs[
'id'][] = 
"$this->overall_id-$i";
 
 3920                if (in_array(
$i, $this->highlight_extra_lines)) {
 
 3921                    if ($this->use_classes) {
 
 3922                        if (isset($this->highlight_extra_lines_styles[
$i])) {
 
 3923                            $attrs[
'class'][] = 
"lx$i";
 
 3925                            $attrs[
'class'][] = 
"ln-xtra";
 
 3934                foreach ($attrs as 
$key => $attr) {
 
 3935                    $attr_string .= 
' ' . 
$key . 
'="' . implode(
' ', $attr) . 
'"';
 
 3938                $parsed_code .= 
"<li$attr_string>$start{$code[$i-1]}$end</li>$ls";
 
 3943            if ($this->use_classes) {
 
 3952                    if ($this->use_classes) {
 
 3953                        $attrs = 
' class="ln"';
 
 3955                        $attrs = 
' style="'. $this->table_linenumber_style .
'"';
 
 3957                    $parsed_code .= 
'<td'.$attrs.
'><pre'.
$attributes.
'>';
 
 3967                            $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
 
 3969                            if ($this->use_classes) {
 
 3970                                $parsed_code .= 
'<span class="xtra li2"><span class="de2">';
 
 3975                                $parsed_code .= 
'<span style="display:block;' . $this->line_style2 . 
'">' 
 3976                                                  .
'<span style="' . $this->code_style .
'">';
 
 3981                        if (in_array(
$i + 1, $this->highlight_extra_lines)) {
 
 3982                            if ($this->use_classes) {
 
 3983                                if (isset($this->highlight_extra_lines_styles[
$i])) {
 
 3984                                    $parsed_code .= 
"<span class=\"xtra lx$i\">";
 
 3986                                    $parsed_code .= 
"<span class=\"xtra ln-xtra\">";
 
 3989                                $parsed_code .= 
"<span style=\"display:block;" . $this->
get_line_style(
$i) . 
"\">";
 
 3993                        $parsed_code .= $this->line_numbers_start + 
$i;
 
 3995                            $parsed_code .= str_repeat(
'</span>', $close);
 
 3996                        } elseif (
$i != 
$n) {
 
 3997                            $parsed_code .= 
"\n";
 
 4000                    $parsed_code .= 
'</pre></td><td'.$attributes.
'>';
 
 4015                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
 
 4017                    if ($this->use_classes) {
 
 4018                        $parsed_code .= 
'<span class="xtra li2"><span class="de2">';
 
 4023                        $parsed_code .= 
'<span style="display:block;' . $this->line_style2 . 
'">' 
 4024                                          .
'<span style="' . $this->code_style .
'">';
 
 4029                if (in_array(
$i + 1, $this->highlight_extra_lines)) {
 
 4030                    if ($this->use_classes) {
 
 4031                        if (isset($this->highlight_extra_lines_styles[
$i])) {
 
 4032                            $parsed_code .= 
"<span class=\"xtra lx$i\">";
 
 4034                            $parsed_code .= 
"<span class=\"xtra ln-xtra\">";
 
 4037                        $parsed_code .= 
"<span style=\"display:block;" . $this->
get_line_style($i) . 
"\">";
 
 4045                  $parsed_code .= str_repeat(
'</span>', $close);
 
 4048                elseif (
$i + 1 < 
$n) {
 
 4049                    $parsed_code .= 
"\n";
 
 4055                $parsed_code .= 
'</pre>';
 
 4058                $parsed_code .= 
'</td>';
 
 4062        $parsed_code .= $this->
footer();
 
 4078        if ($this->overall_class != 
'') {
 
 4079            $attributes .= 
" ".$this->_genCSSName($this->overall_class);
 
 4083        if ($this->overall_id != 
'') {
 
 4086        if ($this->overall_style != 
'' && !$this->use_classes) {
 
 4087            $attributes .= 
' style="' . $this->overall_style . 
'"';
 
 4090        $ol_attributes = 
'';
 
 4092        if ($this->line_numbers_start != 1) {
 
 4093            $ol_attributes .= 
' start="' . $this->line_numbers_start . 
'"';
 
 4104            if ($this->use_classes) {
 
 4105                $attr = 
' class="head"';
 
 4107                $attr = 
" style=\"{$this->header_content_style}\"";
 
 4110                $header = 
"<thead><tr><td colspan=\"2\" $attr>$header</td></tr></thead>";
 
 4112                $header = 
"<div$attr>$header</div>";
 
 4118                return "$header<ol$attributes$ol_attributes>";
 
 4120            return $header . ($this->force_code_block ? 
'<div>' : 
'');
 
 4126                return "<pre$attributes>$header<ol$ol_attributes>";
 
 4129                return "<div$attributes>$header<ol$ol_attributes>";
 
 4131                return "<table$attributes>$header<tbody><tr class=\"li1\">";
 
 4135                return "<pre$attributes>$header"  .
 
 4136                    ($this->force_code_block ? 
'<div>' : 
'');
 
 4138                return "<div$attributes>$header" .
 
 4139                    ($this->force_code_block ? 
'<div>' : 
'');
 
 4154                $footer = str_replace(
"\n", 
'', $footer);;
 
 4158            if ($this->use_classes) {
 
 4159                $attr = 
' class="foot"';
 
 4161                $attr = 
" style=\"{$this->footer_content_style}\"";
 
 4164                $footer = 
"<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
 
 4166                $footer = 
"<div$attr>$footer</div>";
 
 4176                return "</ol>$footer</div>";
 
 4178            return ($this->force_code_block ? 
'</div>' : 
'') .
 
 4183                return "</tr></tbody>$footer</table>";
 
 4185            return ($this->force_code_block ? 
'</div>' : 
'') .
 
 4190                return "</ol>$footer</pre>";
 
 4192            return ($this->force_code_block ? 
'</div>' : 
'') .
 
 4206        $keywords = $replacements = array();
 
 4208        $keywords[] = 
'<TIME>';
 
 4209        $keywords[] = 
'{TIME}';
 
 4210        $replacements[] = $replacements[] = number_format(
$time = $this->
get_time(), 3);
 
 4212        $keywords[] = 
'<LANGUAGE>';
 
 4213        $keywords[] = 
'{LANGUAGE}';
 
 4214        $replacements[] = $replacements[] = $this->language_data[
'LANG_NAME'];
 
 4216        $keywords[] = 
'<VERSION>';
 
 4217        $keywords[] = 
'{VERSION}';
 
 4220        $keywords[] = 
'<SPEED>';
 
 4221        $keywords[] = 
'{SPEED}';
 
 4225            $speed = strlen($this->source) / 
$time;
 
 4226            if ($speed >= 1024) {
 
 4227                $speed = sprintf(
"%.2f KB/s", $speed / 1024.0);
 
 4229                $speed = sprintf(
"%.0f B/s", $speed);
 
 4232        $replacements[] = $replacements[] = $speed;
 
 4234        return str_replace($keywords, $replacements, $instr);
 
 4289    protected function hsc($string, $quote_style = ENT_COMPAT) {
 
 4291        static $aTransSpecchar = array(
 
 4307        switch ($quote_style) {
 
 4309                unset($aTransSpecchar[
'"']);
 
 4312                $aTransSpecchar[
"'"] = 
'''; 
 
 4317        return strtr($string, $aTransSpecchar);
 
 4329        return (is_numeric(
$name[0]) ? 
'_' : 
'') . 
$name;
 
 4351        if(!isset($this->language_data[
'NUMBERS_CACHE'])) {
 
 4358        if ($this->overall_id) {
 
 4359            $selector = 
'#' . $this->
_genCSSName($this->overall_id);
 
 4361            $selector = 
'.' . $this->
_genCSSName($this->language);
 
 4362            if ($this->overall_class) {
 
 4363                $selector .= 
'.' . $this->
_genCSSName($this->overall_class);
 
 4369        if (!$economy_mode) {
 
 4370            $stylesheet = 
"/**\n".
 
 4371                " * GeSHi Dynamically Generated Stylesheet\n".
 
 4372                " * --------------------------------------\n".
 
 4373                " * Dynamically generated stylesheet for {$this->language}\n".
 
 4374                " * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n".
 
 4375                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
 
 4376                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
 
 4377                " * --------------------------------------\n".
 
 4380            $stylesheet = 
"/**\n".
 
 4381                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
 
 4382                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
 
 4392            $stylesheet .= 
"$selector.de1, $selector.de2 {{$this->code_style}}\n";
 
 4397        if ($this->overall_style != 
'') {
 
 4398            $stylesheet .= 
"$selector {{$this->overall_style}}\n";
 
 4405        foreach ($this->link_styles as 
$key => 
$style) {
 
 4409                        $stylesheet .= 
"{$selector}a:link {{$style}}\n";
 
 4412                        $stylesheet .= 
"{$selector}a:hover {{$style}}\n";
 
 4415                        $stylesheet .= 
"{$selector}a:active {{$style}}\n";
 
 4418                        $stylesheet .= 
"{$selector}a:visited {{$style}}\n";
 
 4426        if ($this->header_content_style != 
'') {
 
 4427            $stylesheet .= 
"$selector.head {{$this->header_content_style}}\n";
 
 4429        if ($this->footer_content_style != 
'') {
 
 4430            $stylesheet .= 
"$selector.foot {{$this->footer_content_style}}\n";
 
 4435        if ($this->important_styles != 
'') {
 
 4436            $stylesheet .= 
"$selector.imp {{$this->important_styles}}\n";
 
 4441            $stylesheet .= 
"{$selector}li, {$selector}.li1 {{$this->line_style1}}\n";
 
 4443        if ((!$economy_mode || $this->line_numbers != 
GESHI_NO_LINE_NUMBERS) && $this->table_linenumber_style != 
'') {
 
 4444            $stylesheet .= 
"{$selector}.ln {{$this->table_linenumber_style}}\n";
 
 4448            $stylesheet .= 
"{$selector}.li2 {{$this->line_style2}}\n";
 
 4452        foreach ($this->language_data[
'STYLES'][
'KEYWORDS'] as $group => $styles) {
 
 4453            if ($styles != 
'' && (!$economy_mode ||
 
 4454                (isset($this->lexic_permissions[
'KEYWORDS'][$group]) &&
 
 4455                $this->lexic_permissions[
'KEYWORDS'][$group]))) {
 
 4456                $stylesheet .= 
"$selector.kw$group {{$styles}}\n";
 
 4459        foreach ($this->language_data[
'STYLES'][
'COMMENTS'] as $group => $styles) {
 
 4460            if ($styles != 
'' && (!$economy_mode ||
 
 4461                (isset($this->lexic_permissions[
'COMMENTS'][$group]) &&
 
 4462                $this->lexic_permissions[
'COMMENTS'][$group]) ||
 
 4463                (!empty($this->language_data[
'COMMENT_REGEXP']) &&
 
 4464                !empty($this->language_data[
'COMMENT_REGEXP'][$group])))) {
 
 4465                $stylesheet .= 
"$selector.co$group {{$styles}}\n";
 
 4468        foreach ($this->language_data[
'STYLES'][
'ESCAPE_CHAR'] as $group => $styles) {
 
 4469            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'ESCAPE_CHAR'])) {
 
 4471                if ($group === 
'HARD') {
 
 4474                $stylesheet .= 
"$selector.es$group {{$styles}}\n";
 
 4477        foreach ($this->language_data[
'STYLES'][
'BRACKETS'] as $group => $styles) {
 
 4478            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'BRACKETS'])) {
 
 4479                $stylesheet .= 
"$selector.br$group {{$styles}}\n";
 
 4482        foreach ($this->language_data[
'STYLES'][
'SYMBOLS'] as $group => $styles) {
 
 4483            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'SYMBOLS'])) {
 
 4484                $stylesheet .= 
"$selector.sy$group {{$styles}}\n";
 
 4487        foreach ($this->language_data[
'STYLES'][
'STRINGS'] as $group => $styles) {
 
 4488            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'STRINGS'])) {
 
 4490                if ($group === 
'HARD') {
 
 4493                $stylesheet .= 
"$selector.st$group {{$styles}}\n";
 
 4496        foreach ($this->language_data[
'STYLES'][
'NUMBERS'] as $group => $styles) {
 
 4497            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'NUMBERS'])) {
 
 4498                $stylesheet .= 
"$selector.nu$group {{$styles}}\n";
 
 4501        foreach ($this->language_data[
'STYLES'][
'METHODS'] as $group => $styles) {
 
 4502            if ($styles != 
'' && (!$economy_mode || $this->lexic_permissions[
'METHODS'])) {
 
 4503                $stylesheet .= 
"$selector.me$group {{$styles}}\n";
 
 4507        foreach ($this->language_data[
'STYLES'][
'SCRIPT'] as $group => $styles) {
 
 4508            if ($styles != 
'') {
 
 4509                $stylesheet .= 
"$selector.sc$group {{$styles}}\n";
 
 4512        foreach ($this->language_data[
'STYLES'][
'REGEXPS'] as $group => $styles) {
 
 4513            if ($styles != 
'' && (!$economy_mode ||
 
 4514                (isset($this->lexic_permissions[
'REGEXPS'][$group]) &&
 
 4515                $this->lexic_permissions[
'REGEXPS'][$group]))) {
 
 4516                if (is_array($this->language_data[
'REGEXPS'][$group]) &&
 
 4517                    array_key_exists(
GESHI_CLASS, $this->language_data[
'REGEXPS'][$group])) {
 
 4518                    $stylesheet .= 
"$selector.";
 
 4519                    $stylesheet .= $this->language_data[
'REGEXPS'][$group][
GESHI_CLASS];
 
 4520                    $stylesheet .= 
" {{$styles}}\n";
 
 4522                    $stylesheet .= 
"$selector.re$group {{$styles}}\n";
 
 4527        if (!$economy_mode || (count($this->highlight_extra_lines)!=count($this->highlight_extra_lines_styles))) {
 
 4528            $stylesheet .= 
"{$selector}.ln-xtra, {$selector}li.ln-xtra, {$selector}div.ln-xtra {{$this->highlight_extra_lines_style}}\n";
 
 4530        $stylesheet .= 
"{$selector}span.xtra { display:block; }\n";
 
 4531        foreach ($this->highlight_extra_lines_styles as $lineid => 
$linestyle) {
 
 4532            $stylesheet .= 
"{$selector}.lx$lineid, {$selector}li.lx$lineid, {$selector}div.lx$lineid {{$linestyle}}\n";
 
 4546        if (isset($this->highlight_extra_lines_styles[$line])) {
 
 4547            $style = $this->highlight_extra_lines_styles[$line];
 
 4570        $regex_chars = array(
'.', 
'\\', 
'+', 
'-', 
'*', 
'?', 
'[', 
'^', 
']', 
'$',
 
 4571            '(', 
')', 
'{', 
'}', 
'=', 
'!', 
'<', 
'>', 
'|', 
':', $regexp_delimiter);
 
 4573        $regexp_list = array(
'');
 
 4574        $num_subpatterns = 0;
 
 4579        $prev_keys = array();
 
 4582        for (
$i = 0, $i_max = count(
$list); 
$i < $i_max; ++
$i) {
 
 4586                $num_subpatterns = substr_count($regexp_list[$list_key], 
'(?:');
 
 4591            $entry = preg_quote((
string) 
$list[
$i], $regexp_delimiter);
 
 4592            $pointer = &$tokens;
 
 4597                if (isset($prev_keys[$level])) {
 
 4598                    if ($prev_keys[$level] == $entry) {
 
 4603                    while (isset($entry[$char]) && isset($prev_keys[$level][$char])
 
 4604                            && $entry[$char] == $prev_keys[$level][$char]) {
 
 4609                        if ($char == strlen($prev_keys[$level])) {
 
 4611                            $pointer = &$pointer[$prev_keys[$level]];
 
 4614                            $new_key_part1 = substr($prev_keys[$level], 0, $char);
 
 4615                            $new_key_part2 = substr($prev_keys[$level], $char);
 
 4617                            if (in_array($new_key_part1[0], $regex_chars)
 
 4618                                || in_array($new_key_part2[0], $regex_chars)) {
 
 4620                                $pointer[$entry] = array(
'' => 
true);
 
 4621                                array_splice($prev_keys, $level, count($prev_keys), $entry);
 
 4622                                $cur_len += strlen($entry);
 
 4626                                $pointer[$new_key_part1] = array($new_key_part2 => $pointer[$prev_keys[$level]]);
 
 4627                                unset($pointer[$prev_keys[$level]]);
 
 4628                                $pointer = &$pointer[$new_key_part1];
 
 4630                                array_splice($prev_keys, $level, count($prev_keys), array($new_key_part1, $new_key_part2));
 
 4631                                $cur_len += strlen($new_key_part2);
 
 4635                        $entry = substr($entry, $char);
 
 4640                if ($level == 0 && !empty($tokens)) {
 
 4643                    $new_subpatterns = substr_count($new_entry, 
'(?:');
 
 4645                        $regexp_list[++$list_key] = $new_entry;
 
 4646                        $num_subpatterns = $new_subpatterns;
 
 4648                        if (!empty($regexp_list[$list_key])) {
 
 4649                            $new_entry = 
'|' . $new_entry;
 
 4651                        $regexp_list[$list_key] .= $new_entry;
 
 4652                        $num_subpatterns += $new_subpatterns;
 
 4658                $pointer[$entry] = array(
'' => 
true);
 
 4659                array_splice($prev_keys, $level, count($prev_keys), $entry);
 
 4661                $cur_len += strlen($entry);
 
 4669            if ( !empty($regexp_list[$list_key]) ) {
 
 4672            $regexp_list[$list_key] = $new_entry;
 
 4674            if (!empty($regexp_list[$list_key])) {
 
 4675                $new_entry = 
'|' . $new_entry;
 
 4677            $regexp_list[$list_key] .= $new_entry;
 
 4679        return $regexp_list;
 
 4694        foreach ($tokens as 
$token => $sub_tokens) {
 
 4696            $close_entry = isset($sub_tokens[
'']);
 
 4697            unset($sub_tokens[
'']);
 
 4698            if (!empty($sub_tokens)) {
 
 4714            $list = preg_replace(
'#\(\?\:(.)\)\?#', 
'\1?', 
$list);
 
 4718            if (!isset($callback_2)) {
 
 4719                $callback_2 = 
function($matches) {
 
 4720                    return "[" . str_replace(
"|", 
"", $matches[1]) . 
"]";
 
 4723            $list = preg_replace_callback(
'#\(\?\:((?:.\|)+.)\)#', $callback_2, 
$list);
 
 4726        return substr(
$list, 0, -1);
 
 4731if (!function_exists(
'geshi_highlight')) {
 
 4743    function geshi_highlight($string, 
$language, 
$path = 
null, $return = 
false) {
 
 4748            return '<code>' . 
$geshi->parse_code() . 
'</code>';
 
 4751        echo 
'<code>' . 
$geshi->parse_code() . 
'</code>';
 
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.
_genCSSName($name)
Generate a CSS class name from a given string.
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='')
Creates a new GeSHi object, with source and language.
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.
strip_language_name($language)
Clean up the language name to prevent malicious code injection.
$highlight_extra_lines_styles
if(!array_key_exists('StateId', $_REQUEST)) $id
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_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_MAX_PCRE_SUBPATTERNS
some old PHP / PCRE subpatterns only support up to xxx subpatterns in regular expressions.
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_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.
if(array_key_exists('yes', $_REQUEST)) $attributes
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
if(isset($_REQUEST['delete'])) $list