190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber<?php
290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/**
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * GeSHi - Generic Syntax Highlighter
490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * The GeSHi class for Generic Syntax Highlighting. Please refer to the
690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * documentation at http://qbnz.com/highlighter/documentation.php for more
790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * information about how to use this class.
890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * For changes, release notes, TODOs etc, see the relevant files in the docs/
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * directory.
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *   This file is part of GeSHi.
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  GeSHi is free software; you can redistribute it and/or modify
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  it under the terms of the GNU General Public License as published by
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  the Free Software Foundation; either version 2 of the License, or
1790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  (at your option) any later version.
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  GeSHi is distributed in the hope that it will be useful,
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  but WITHOUT ANY WARRANTY; without even the implied warranty of
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  GNU General Public License for more details.
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  You should have received a copy of the GNU General Public License
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  along with GeSHi; if not, write to the Free Software
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @package    geshi
2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @subpackage core
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @author     Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @copyright  (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @license    http://gnu.org/copyleft/gpl.html GNU GPL
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// GeSHi Constants
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// You should use these constant names in your programs instead of
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// their values - you never know when a value may change in a future
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// version
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The version of this GeSHi file */
4490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_VERSION', '1.0.8.3');
4590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Define the root directory for the GeSHi code tree
4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberif (!defined('GESHI_ROOT')) {
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /** The root directory for GeSHi */
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    define('GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The language file directory for GeSHi
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    @access private */
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_LANG_ROOT', GESHI_ROOT . 'geshi' . DIRECTORY_SEPARATOR);
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Define if GeSHi should be paranoid about security
5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberif (!defined('GESHI_SECURITY_PARANOID')) {
5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /** Tells GeSHi to be paranoid about security settings */
5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    define('GESHI_SECURITY_PARANOID', false);
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Line numbers - use with enable_line_numbers()
6290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use no line numbers when building the result */
6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NO_LINE_NUMBERS', 0);
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use normal line numbers when building the result */
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NORMAL_LINE_NUMBERS', 1);
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use fancy line numbers when building the result */
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_FANCY_LINE_NUMBERS', 2);
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Container HTML type
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use nothing to surround the source */
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HEADER_NONE', 0);
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use a "div" to surround the source */
7390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HEADER_DIV', 1);
7490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use a "pre" to surround the source */
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HEADER_PRE', 2);
7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Use a pre to wrap lines when line numbers are enabled or to wrap the whole code. */
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HEADER_PRE_VALID', 3);
7890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/**
7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Use a "table" to surround the source:
8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  <table>
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *    <thead><tr><td colspan="2">$header</td></tr></thead>
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *    <tbody><tr><td><pre>$linenumbers</pre></td><td><pre>$code></pre></td></tr></tbody>
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *    <tfooter><tr><td colspan="2">$footer</td></tr></tfoot>
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  </table>
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * this is essentially only a workaround for Firefox, see sf#1651996 or take a look at
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * https://bugzilla.mozilla.org/show_bug.cgi?id=365805
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @note when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE
9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
9190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HEADER_PRE_TABLE', 4);
9290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Capatalisation constants
9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Lowercase keywords found */
9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_CAPS_NO_CHANGE', 0);
9690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Uppercase keywords found */
9790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_CAPS_UPPER', 1);
9890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Leave keywords found as the case that they are */
9990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_CAPS_LOWER', 2);
10090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Link style constants
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Links in the source in the :link state */
10390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_LINK', 0);
10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Links in the source in the :hover state */
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_HOVER', 1);
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Links in the source in the :active state */
10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ACTIVE', 2);
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Links in the source in the :visited state */
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_VISITED', 3);
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Important string starter/finisher
11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Note that if you change these, they should be as-is: i.e., don't
11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// write them as if they had been run through htmlentities()
11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The starter for important parts of the source */
11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_START_IMPORTANT', '<BEGIN GeSHi>');
11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The ender for important parts of the source */
11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_END_IMPORTANT', '<END GeSHi>');
11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/**#@+
12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *  @access private
12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
12290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// When strict mode applies for a language
12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Strict mode never applies (this is the most common) */
12490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NEVER', 0);
12590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Strict mode *might* apply, and can be enabled or
12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    disabled by {@link GeSHi->enable_strict_mode()} */
12790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_MAYBE', 1);
12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Strict mode always applies */
12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ALWAYS', 2);
13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Advanced regexp handling constants, used in language files
13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining what to search for */
13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_SEARCH', 0);
13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining what bracket group in a
13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    matched search to use as a replacement */
13690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_REPLACE', 1);
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining any modifiers to the regular expression */
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_MODIFIERS', 2);
13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining what bracket group in a
14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    matched search to put before the replacement */
14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_BEFORE', 3);
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining what bracket group in a
14390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    matched search to put after the replacement */
14490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_AFTER', 4);
14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The key of the regex array defining a custom keyword to use
14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for this regexp's html tag class */
14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_CLASS', 5);
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Used in language files to mark comments */
15090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_COMMENTS', 0);
15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Used to work around missing PHP features **/
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, '4.3.3') === 1));
15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** make sure we can call stripos **/
15690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberif (!function_exists('stripos')) {
15790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    // the offset param of preg_match is not supported below PHP 4.3.3
15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    if (GESHI_PHP_PRE_433) {
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /**
16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         * @ignore
16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         */
16290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        function stripos($haystack, $needle, $offset = null) {
16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!is_null($offset)) {
16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $haystack = substr($haystack, $offset);
16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
16690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return $match[0][1];
16890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
16990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return false;
17090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
17190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
17290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    else {
17390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /**
17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         * @ignore
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         */
17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        function stripos($haystack, $needle, $offset = null) {
17790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
17890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return $match[0][1];
17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return false;
18190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
18390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
18490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
18590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** some old PHP / PCRE subpatterns only support up to xxx subpatterns in
18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    regular expressions. Set this to false if your PCRE lib is up to date
18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    @see GeSHi->optimize_regexp_list()
18890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    **/
18990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_MAX_PCRE_SUBPATTERNS', 500);
19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** it's also important not to generate too long regular expressions
19190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    be generous here... but keep in mind, that when reaching this limit we
19290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    still have to close open patterns. 12k should do just fine on a 16k limit.
19390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    @see GeSHi->optimize_regexp_list()
19490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    **/
19590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_MAX_PCRE_LENGTH', 12288);
19690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//Number format specification
19890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Basic number format for integers */
19990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_INT_BASIC', 1);        //Default integers \d+
20090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Enhanced number format for integers like seen in C */
20190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_INT_CSTYLE', 2);       //Default C-Style \d+[lL]?
20290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight binary numbers with a suffix "b" */
20390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_BIN_SUFFIX', 16);           //[01]+[bB]
20490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight binary numbers with a prefix % */
20590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   //%[01]+
20690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight binary numbers with a prefix 0b (C) */
20790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_BIN_PREFIX_0B', 64);        //0b[01]+
20890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight octal numbers with a leading zero */
20990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_OCT_PREFIX', 256);           //0[0-7]+
21090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight octal numbers with a suffix of o */
21190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_OCT_SUFFIX', 512);           //[0-7]+[oO]
21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight hex numbers with a prefix 0x */
21390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_HEX_PREFIX', 4096);           //0x[0-9a-fA-F]+
21490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight hex numbers with a suffix of h */
21590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_HEX_SUFFIX', 8192);           //[0-9][0-9a-fA-F]*h
21690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight floating-point numbers without support for scientific notation */
21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_FLT_NONSCI', 65536);          //\d+\.\d+
21890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight floating-point numbers without support for scientific notation */
21990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_FLT_NONSCI_F', 131072);       //\d+(\.\d+)?f
22090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight floating-point numbers with support for scientific notation (E) and optional leading zero */
22190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_FLT_SCI_SHORT', 262144);      //\.\d+e\d+
22290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** Number format to highlight floating-point numbers with support for scientific notation (E) and required leading digit */
22390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_NUMBER_FLT_SCI_ZERO', 524288);       //\d+(\.\d+)?e\d+
22490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//Custom formats are passed by RX array
22590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// Error detection - use these to analyse faults
22790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** No sourcecode to highlight was specified
22890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @deprecated
22990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
23090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ERROR_NO_INPUT', 1);
23190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The language specified does not exist */
23290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ERROR_NO_SUCH_LANG', 2);
23390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** GeSHi could not open a file for reading (generally a language file) */
23490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ERROR_FILE_NOT_READABLE', 3);
23590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The header type passed to {@link GeSHi->set_header_type()} was invalid */
23690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ERROR_INVALID_HEADER_TYPE', 4);
23790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/** The line number type passed to {@link GeSHi->enable_line_numbers()} was invalid */
23890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberdefine('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/**#@-*/
24090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
24190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
24290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/**
24390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * The GeSHi Class.
24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
24590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * Please refer to the documentation for GeSHi 1.0.X that is available
24690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * at http://qbnz.com/highlighter/documentation.php for more information
24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * about how to use this class.
24890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
24990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @package   geshi
25090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @author    Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
25190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
25290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
25390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberclass GeSHi {
25490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**#@+
25590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
25690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
25790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
25890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The source code to highlight
25990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
26090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
26190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $source = '';
26290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
26390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
26490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The language to use when highlighting
26590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
26690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $language = '';
26890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
26990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
27090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The data for the language used
27190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
27290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
27390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $language_data = array();
27490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
27690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The path to the language files
27790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
27890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
27990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $language_path = GESHI_LANG_ROOT;
28090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
28290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The error message associated with an error
28390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
28490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo check err reporting works
28590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
28690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $error = false;
28790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
28890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
28990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Possible error messages
29090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
29190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
29290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $error_messages = array(
29390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',
29490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',
29590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',
29690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'
29790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    );
29890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
29990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
30090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Whether highlighting is strict or not
30190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
30290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
30390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $strict_mode = false;
30490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
30590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
30690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Whether to use CSS classes in output
30790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
30890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
30990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $use_classes = false;
31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
31190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
31290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The type of header to use. Can be one of the following
31390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * values:
31490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
31590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.
31690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.
31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * - GESHI_HEADER_NONE: No header is outputted.
31890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
31990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var int
32090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $header_type = GESHI_HEADER_PRE;
32290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
32390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Array of permissions for which lexics should be highlighted
32590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
32690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
32790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $lexic_permissions = array(
32890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'KEYWORDS' =>    array(),
32990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'COMMENTS' =>    array('MULTI' => true),
33090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'REGEXPS' =>     array(),
33190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'ESCAPE_CHAR' => true,
33290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'BRACKETS' =>    true,
33390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'SYMBOLS' =>     false,
33490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'STRINGS' =>     true,
33590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'NUMBERS' =>     true,
33690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'METHODS' =>     true,
33790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        'SCRIPT' =>      true
33890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    );
33990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
34190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The time it took to parse the code
34290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var double
34390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
34490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $time = 0;
34590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
34690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
34790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The content of the header block
34890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
34990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
35090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $header_content = '';
35190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
35390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The content of the footer block
35490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
35590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
35690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $footer_content = '';
35790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
35890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
35990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The style of the header block
36090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
36190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $header_content_style = '';
36390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
36590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The style of the footer block
36690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
36790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
36890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $footer_content_style = '';
36990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
37190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Tells if a block around the highlighted source should be forced
37290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * if not using line numbering
37390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
37490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
37590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $force_code_block = false;
37690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
37790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
37890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The styles for hyperlinks in the code
37990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
38090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
38190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $link_styles = array();
38290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
38390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
38490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Whether important blocks should be recognised or not
38590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
38690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated
38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo REMOVE THIS FUNCTIONALITY!
38890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
38990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $enable_important_blocks = false;
39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
39290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Styles for important parts of the code
39390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated
39590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo As above - rethink the whole idea of important blocks as it is buggy and
39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * will be hard to implement in 1.2
39790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
39890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $important_styles = 'font-weight: bold; color: red;'; // Styles for important parts of the code
39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
40090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
40190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Whether CSS IDs should be added to the code
40290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
40390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
40490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $add_ids = false;
40590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
40690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
40790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Lines that should be highlighted extra
40890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
40990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
41090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $highlight_extra_lines = array();
41190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Styles of lines that should be highlighted extra
41490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
41590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
41690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $highlight_extra_lines_styles = array();
41790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
41890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Styles of extra-highlighted lines
42090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
42190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
42290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $highlight_extra_lines_style = 'background-color: #ffc;';
42390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
42490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
42590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The line ending
42690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * If null, nl2br() will be used on the result string.
42790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Otherwise, all instances of \n will be replaced with $line_ending
42890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
43090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_ending = null;
43190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
43290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
43390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Number at which line numbers should start at
43490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var int
43590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
43690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_numbers_start = 1;
43790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
43890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
43990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The overall style for this code block
44090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
44190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
44290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $overall_style = 'font-family:monospace;';
44390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
44490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
44590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  The style for the actual code
44690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
44790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
44890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $code_style = 'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
44990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
45090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
45190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The overall class for this code block
45290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
45390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
45490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $overall_class = '';
45590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
45690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
45790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The overall ID for this code block
45890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
45990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
46090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $overall_id = '';
46190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
46390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Line number styles
46490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
46590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
46690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_style1 = 'font-weight: normal; vertical-align:top;';
46790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
46890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
46990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Line number styles for fancy lines
47090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
47190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
47290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_style2 = 'font-weight: bold; vertical-align:top;';
47390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
47590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
47690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
47790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
47890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $table_linenumber_style = 'width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;';
47990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
48190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Flag for how line numbers are displayed
48290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
48390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
48490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_numbers = GESHI_NO_LINE_NUMBERS;
48590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
48690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
48790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Flag to decide if multi line spans are allowed. Set it to false to make sure
48890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * each tag is closed before and reopened after each linefeed.
48990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
49090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
49190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $allow_multiline_span = true;
49290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
49390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
49490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The "nth" value for fancy line highlighting
49590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var int
49690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
49790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $line_nth_row = 0;
49890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
49990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
50090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The size of tab stops
50190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var int
50290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
50390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $tab_width = 8;
50490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
50590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
50690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Should we use language-defined tab stop widths?
50790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var int
50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
50990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $use_language_tab_width = false;
51090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
51190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
51290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Default target for keyword links
51390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
51490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $link_target = '';
51690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
51790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
51890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The encoding to use for entity encoding
51990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * NOTE: Used with Escape Char Sequences to fix UTF-8 handling (cf. SF#2037598)
52090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
52190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
52290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $encoding = 'utf-8';
52390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Should keywords be linked?
52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var boolean
52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
52890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $keyword_links = true;
52990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Currently loaded language file
53290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.22
53490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
53590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $loaded_language = '';
53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
53890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Wether the caches needed for parsing are built or not
53990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
54090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var bool
54190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
54290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
54390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $parse_cache_built = false;
54490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
54590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
54690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Work around for Suhosin Patch with disabled /e modifier
54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
54890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Note from suhosins author in config file:
54990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * <blockquote>
55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   The /e modifier inside <code>preg_replace()</code> allows code execution.
55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   Often it is the cause for remote code execution exploits. It is wise to
55290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   deactivate this feature and test where in the application it is used.
55390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   The developer using the /e modifier should be made aware that he should
55490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   use <code>preg_replace_callback()</code> instead
55590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * </blockquote>
55690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
55790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var array
55890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
55990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
56090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_kw_replace_group = 0;
56190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_rx_key = 0;
56290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
56390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * some "callback parameters" for handle_multiline_regexps
56590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
56690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
56890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @var string
56990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
57090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_hmr_before = '';
57190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_hmr_replace = '';
57290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_hmr_after = '';
57390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    var $_hmr_key = 0;
57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**#@-*/
57690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
57890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Creates a new GeSHi object, with source and language
57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
58090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The source code to highlight
58190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The language to highlight the source with
58290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The path to the language file directory. <b>This
58390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               is deprecated!</b> I've backported the auto path
58490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               detection from the 1.1.X dev branch, so now it
58590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               should be automatically set correctly. If you have
58690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               renamed the language directory however, you will
58790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               still need to set the path using this parameter or
58890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               {@link GeSHi->set_language_path()}
58990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
59090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function GeSHi($source = '', $language = '', $path = '') {
59290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!empty($source)) {
59390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_source($source);
59490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
59590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!empty($language)) {
59690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_language($language);
59790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->set_language_path($path);
59990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
60290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Returns an error message associated with the last GeSHi operation,
60390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * or false if no error has occured
60490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
60590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string|false An error message if there has been an error, else false
60690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
60790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
60890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function error() {
60990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->error) {
61090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Put some template variables for debugging here ...
61190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $debug_tpl_vars = array(
61290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                '{LANGUAGE}' => $this->language,
61390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                '{PATH}' => $this->language_path
61490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            );
61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $msg = str_replace(
61690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                array_keys($debug_tpl_vars),
61790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                array_values($debug_tpl_vars),
61890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->error_messages[$this->error]);
61990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
62190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
62290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return false;
62390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
62490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
62690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Gets a human-readable language name (thanks to Simon Patterson
62790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * for the idea :))
62890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
62990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The name for the current language
63090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.2
63190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
63290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_language_name() {
63390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_ERROR_NO_SUCH_LANG == $this->error) {
63490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return $this->language_data['LANG_NAME'] . ' (Unknown Language)';
63590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
63690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $this->language_data['LANG_NAME'];
63790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
63890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
63990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
64090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the source code for this object
64190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
64290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The source code to highlight
64390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
64590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_source($source) {
64690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->source = $source;
64790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->highlight_extra_lines = array();
64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
64990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
65090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
65190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the language for this object
65290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
65390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @note since 1.0.8 this function won't reset language-settings by default anymore!
65490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *       if you need this set $force_reset = true
65590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
65690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The name of the language to use
65790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
65890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
65990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_language($language, $force_reset = false) {
66090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($force_reset) {
66190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->loaded_language = false;
66290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
66390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
66490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Clean up the language name to prevent malicious code injection
66590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
66690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
66790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $language = strtolower($language);
66890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
66990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Retreive the full filename
67090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $file_name = $this->language_path . $language . '.php';
67190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($file_name == $this->loaded_language) {
67290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // this language is already loaded!
67390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
67490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
67590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
67690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language = $language;
67790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
67890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->error = false;
67990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->strict_mode = GESHI_NEVER;
68090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
68190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Check if we can read the desired file
68290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!is_readable($file_name)) {
68390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->error = GESHI_ERROR_NO_SUCH_LANG;
68490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
68590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
68690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
68790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Load the language for parsing
68890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->load_language($file_name);
68990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
69090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
69190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
69290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the path to the directory containing the language files. Note
69390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * that this path is relative to the directory of the script that included
69490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * geshi.php, NOT geshi.php itself.
69590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
69690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The path to the language directory
69790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
69890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated The path to the language files should now be automatically
69990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *             detected, so this method should no longer be needed. The
70090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *             1.1.X branch handles manual setting of the path differently
70190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *             so this method will disappear in 1.2.0.
70290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
70390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_language_path($path) {
70490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(strpos($path,':')) {
70590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Security Fix to prevent external directories using fopen wrappers.
70690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if(DIRECTORY_SEPARATOR == "\\") {
70790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(!preg_match('#^[a-zA-Z]:#', $path) || false !== strpos($path, ':', 2)) {
70890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    return;
70990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
71090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
71190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return;
71290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
71390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
71490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(preg_match('#[^/a-zA-Z0-9_\.\-\\\s:]#', $path)) {
71590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Security Fix to prevent external directories using fopen wrappers.
71690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
71790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
71890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '/.')) {
71990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Security Fix to prevent external directories using fopen wrappers.
72090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
72190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
72290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '..')) {
72390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Security Fix to prevent external directories using fopen wrappers.
72490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
72590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
72690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($path) {
72790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_path = ('/' == $path[strlen($path) - 1]) ? $path : $path . '/';
72890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_language($this->language); // otherwise set_language_path has no effect
72990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
73090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
73190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
73290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
73390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the type of header to be used.
73490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
73590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This
73690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * means more source code but more control over tab width and line-wrapping.
73790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * GESHI_HEADER_PRE means that a "pre" is used - less source, but less
73890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * control. Default is GESHI_HEADER_PRE.
73990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
74090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code
74190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * should be outputted.
74290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
74390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The type of header to be used
74490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
74590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
74690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_header_type($type) {
74790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Check if we got a valid header type
74890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!in_array($type, array(GESHI_HEADER_NONE, GESHI_HEADER_DIV,
74990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            GESHI_HEADER_PRE, GESHI_HEADER_PRE_VALID, GESHI_HEADER_PRE_TABLE))) {
75090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->error = GESHI_ERROR_INVALID_HEADER_TYPE;
75190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
75290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
75390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
75490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Set that new header type
75590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->header_type = $type;
75690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
75790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
75890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
75990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for the code that will be outputted
76090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * when this object is parsed. The style should be a
76190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * string of valid stylesheet declarations
76290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
76390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The overall style for the outputted code block
76490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the styles with the current styles or not
76590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
76690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
76790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_overall_style($style, $preserve_defaults = false) {
76890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
76990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->overall_style = $style;
77090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
77190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->overall_style .= $style;
77290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
77390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
77490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
77590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
77690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the overall classname for this block of code. This
77790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * class can then be used in a stylesheet to style this object's
77890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * output
77990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
78090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The class name to use for this block of code
78190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
78290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
78390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_overall_class($class) {
78490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->overall_class = $class;
78590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
78690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
78790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
78890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the overall id for this block of code. This id can then
78990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * be used in a stylesheet to style this object's output
79090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
79190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The ID to use for this block of code
79290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
79390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
79490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_overall_id($id) {
79590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->overall_id = $id;
79690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
79790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
79890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
79990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether CSS classes should be used to highlight the source. Default
80090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * is off, calling this method with no arguments will turn it on
80190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
80290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn classes on or not
80390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
80490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
80590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_classes($flag = true) {
80690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->use_classes = ($flag) ? true : false;
80790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
80890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
80990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
81090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the style for the actual code. This should be a string
81190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * containing valid stylesheet declarations. If $preserve_defaults is
81290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
81390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
81490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
81590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Note: Use this method to override any style changes you made to
81690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * the line numbers if you are using line numbers, else the line of
81790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * code will have the same style as the line number! Consult the
81890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * GeSHi documentation for more information about this.
81990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
82090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to use for actual code
82190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the current styles with the new styles
82290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
82390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
82490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_code_style($style, $preserve_defaults = false) {
82590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
82690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->code_style = $style;
82790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
82890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->code_style .= $style;
82990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
83090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
83190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
83290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
83390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for the line numbers.
83490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
83590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The style for the line numbers that are "normal"
83690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string|boolean If a string, this is the style of the line
83790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *        numbers that are "fancy", otherwise if boolean then this
83890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *        defines whether the normal styles should be merged with the
83990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *        new normal styles or not
84090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean If set, is the flag for whether to merge the "fancy"
84190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *        styles with the current styles or not
84290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
84390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
84490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_line_style($style1, $style2 = '', $preserve_defaults = false) {
84590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Check if we got 2 or three parameters
84690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (is_bool($style2)) {
84790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $preserve_defaults = $style2;
84890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $style2 = '';
84990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
85090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
85190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Actually set the new styles
85290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
85390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->line_style1 = $style1;
85490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->line_style2 = $style2;
85590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
85690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->line_style1 .= $style1;
85790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->line_style2 .= $style2;
85890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
85990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
86090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
86190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
86290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether line numbers should be displayed.
86390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
86490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Valid values for the first parameter are:
86590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
86690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed
86790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed
86890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed
86990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
87090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * For fancy line numbers, the second parameter is used to signal which lines
87190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * are to be fancy. For example, if the value of this parameter is 5 then every
87290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * 5th line will be fancy.
87390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
87490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int How line numbers should be displayed
87590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int Defines which lines are fancy
87690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
87790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
87890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_line_numbers($flag, $nth_row = 5) {
87990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_NO_LINE_NUMBERS != $flag && GESHI_NORMAL_LINE_NUMBERS != $flag
88090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            && GESHI_FANCY_LINE_NUMBERS != $flag) {
88190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->error = GESHI_ERROR_INVALID_LINE_NUMBER_TYPE;
88290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
88390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->line_numbers = $flag;
88490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->line_nth_row = $nth_row;
88590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
88690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
88790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
88890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets wether spans and other HTML markup generated by GeSHi can
88990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * span over multiple lines or not. Defaults to true to reduce overhead.
89090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Set it to false if you want to manipulate the output or manually display
89190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * the code in an ordered list.
89290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
89390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Wether multiline spans are allowed or not
89490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.22
89590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
89690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_multiline_span($flag) {
89790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->allow_multiline_span = (bool) $flag;
89890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
89990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
90090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
90190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Get current setting for multiline spans, see GeSHi->enable_multiline_span().
90290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
90390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @see enable_multiline_span
90490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return bool
90590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
90690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_multiline_span() {
90790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $this->allow_multiline_span;
90890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
90990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
91090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
91190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the style for a keyword group. If $preserve_defaults is
91290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
91390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
91490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
91590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the keyword group to change the styles of
91690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the keywords
91790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
91890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
91990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
92090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
92190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_keyword_group_style($key, $style, $preserve_defaults = false) {
92290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Set the style for this keyword group
92390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
92490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['KEYWORDS'][$key] = $style;
92590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
92690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['KEYWORDS'][$key] .= $style;
92790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
92890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
92990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Update the lexic permissions
93090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!isset($this->lexic_permissions['KEYWORDS'][$key])) {
93190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->lexic_permissions['KEYWORDS'][$key] = true;
93290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
93390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
93490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
93590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
93690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for a keyword group
93790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
93890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the keyword group to turn on or off
93990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for that group on or off
94090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
94190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
94290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_keyword_group_highlighting($key, $flag = true) {
94390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['KEYWORDS'][$key] = ($flag) ? true : false;
94490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
94590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
94690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
94790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for comment groups.  If $preserve_defaults is
94890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
94990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
95090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
95190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the comment group to change the styles of
95290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the comments
95390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
95490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
95590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
95690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
95790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_comments_style($key, $style, $preserve_defaults = false) {
95890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
95990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['COMMENTS'][$key] = $style;
96090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
96190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['COMMENTS'][$key] .= $style;
96290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
96390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
96490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
96590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
96690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for comment groups
96790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
96890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the comment group to turn on or off
96990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for that group on or off
97090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
97190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
97290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_comments_highlighting($key, $flag = true) {
97390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['COMMENTS'][$key] = ($flag) ? true : false;
97490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
97590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
97690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
97790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for escaped characters. If $preserve_defaults is
97890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
97990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
98090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
98190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the escape characters
98290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
98390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
98490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
98590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
98690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_escape_characters_style($style, $preserve_defaults = false, $group = 0) {
98790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
98890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] = $style;
98990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
99090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] .= $style;
99190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
99290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
99390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
99490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
99590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for escaped characters
99690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
99790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for escape characters on or off
99890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
99990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
100090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_escape_characters_highlighting($flag = true) {
100190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['ESCAPE_CHAR'] = ($flag) ? true : false;
100290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
100390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
100490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
100590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for brackets. If $preserve_defaults is
100690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
100790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
100890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
100990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This method is DEPRECATED: use set_symbols_style instead.
101090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This method will be removed in 1.2.X
101190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
101290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the brackets
101390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
101490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
101590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
101690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated In favour of set_symbols_style
101790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
101890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_brackets_style($style, $preserve_defaults = false) {
101990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
102090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['BRACKETS'][0] = $style;
102190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
102290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['BRACKETS'][0] .= $style;
102390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
102490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
102590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
102690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
102790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for brackets
102890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
102990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This method is DEPRECATED: use set_symbols_highlighting instead.
103090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This method will be remove in 1.2.X
103190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
103290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for brackets on or off
103390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
103490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated In favour of set_symbols_highlighting
103590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
103690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_brackets_highlighting($flag) {
103790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['BRACKETS'] = ($flag) ? true : false;
103890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
103990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
104090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
104190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for symbols. If $preserve_defaults is
104290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
104390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
104490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
104590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the symbols
104690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
104790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
104890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     Tells the group of symbols for which style should be set.
104990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.1
105090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
105190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_symbols_style($style, $preserve_defaults = false, $group = 0) {
105290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Update the style of symbols
105390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
105490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['SYMBOLS'][$group] = $style;
105590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
105690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['SYMBOLS'][$group] .= $style;
105790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
105890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
105990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // For backward compatibility
106090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (0 == $group) {
106190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_brackets_style ($style, $preserve_defaults);
106290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
106390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
106490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
106590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
106690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for symbols
106790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
106890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for symbols on or off
106990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
107090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
107190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_symbols_highlighting($flag) {
107290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Update lexic permissions for this symbol group
107390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['SYMBOLS'] = ($flag) ? true : false;
107490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
107590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // For backward compatibility
107690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->set_brackets_highlighting ($flag);
107790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
107890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
107990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
108090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for strings. If $preserve_defaults is
108190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
108290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
108390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
108490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the escape characters
108590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
108690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
108790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
108890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
108990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_strings_style($style, $preserve_defaults = false) {
109090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
109190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['STRINGS'][0] = $style;
109290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
109390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['STRINGS'][0] .= $style;
109490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
109590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
109690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
109790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
109890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for strings
109990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
110090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for strings on or off
110190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
110290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
110390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_strings_highlighting($flag) {
110490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['STRINGS'] = ($flag) ? true : false;
110590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
110690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
110790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
110890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for numbers. If $preserve_defaults is
110990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
111090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
111190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
111290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the numbers
111390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
111490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
111590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
111690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
111790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_numbers_style($style, $preserve_defaults = false) {
111890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
111990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['NUMBERS'][0] = $style;
112090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
112190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['NUMBERS'][0] .= $style;
112290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
112390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
112490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
112590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
112690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for numbers
112790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
112890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for numbers on or off
112990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
113090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
113190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_numbers_highlighting($flag) {
113290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['NUMBERS'] = ($flag) ? true : false;
113390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
113490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
113590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
113690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for methods. $key is a number that references the
113790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * appropriate "object splitter" - see the language file for the language
113890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * you are highlighting to get this number. If $preserve_defaults is
113990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
114090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
114190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
114290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the object splitter to change the styles of
114390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the methods
114490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
114590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
114690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
114790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
114890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_methods_style($key, $style, $preserve_defaults = false) {
114990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
115090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['METHODS'][$key] = $style;
115190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
115290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['METHODS'][$key] .= $style;
115390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
115490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
115590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
115690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
115790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for methods
115890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
115990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for methods on or off
116090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
116190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
116290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_methods_highlighting($flag) {
116390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['METHODS'] = ($flag) ? true : false;
116490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
116590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
116690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
116790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the styles for regexps. If $preserve_defaults is
116890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * true, then styles are merged with the default styles, with the
116990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * user defined styles having priority
117090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
117190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string  The style to make the regular expression matches
117290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to merge the new styles with the old or just
117390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                to overwrite them
117490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
117590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
117690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_regexps_style($key, $style, $preserve_defaults = false) {
117790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$preserve_defaults) {
117890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['REGEXPS'][$key] = $style;
117990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
118090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['STYLES']['REGEXPS'][$key] .= $style;
118190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
118290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
118390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
118490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
118590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns highlighting on/off for regexps
118690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
118790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int     The key of the regular expression group to turn on or off
118890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to turn highlighting for the regular expression group on or off
118990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
119090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
119190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_regexps_highlighting($key, $flag) {
119290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['REGEXPS'][$key] = ($flag) ? true : false;
119390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
119490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
119590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
119690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether a set of keywords are checked for in a case sensitive manner
119790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
119890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The key of the keyword group to change the case sensitivity of
119990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to check in a case sensitive manner or not
120090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
120190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
120290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_case_sensitivity($key, $case) {
120390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['CASE_SENSITIVE'][$key] = ($case) ? true : false;
120490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
120590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
120690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
120790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the case that keywords should use when found. Use the constants:
120890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
120990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_CAPS_NO_CHANGE: leave keywords as-is
121090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_CAPS_UPPER: convert all keywords to uppercase where found
121190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *  - GESHI_CAPS_LOWER: convert all keywords to lowercase where found
121290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
121390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int A constant specifying what to do with matched keywords
121490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.1
121590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
121690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_case_keywords($case) {
121790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (in_array($case, array(
121890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            GESHI_CAPS_NO_CHANGE, GESHI_CAPS_UPPER, GESHI_CAPS_LOWER))) {
121990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['CASE_KEYWORDS'] = $case;
122090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
122190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
122290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
122390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
122490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets how many spaces a tab is substituted for
122590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
122690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Widths below zero are ignored
122790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
122890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The tab width
122990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
123090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
123190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_tab_width($width) {
123290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->tab_width = intval($width);
123390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
123490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Check if it fit's the constraints:
123590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->tab_width < 1) {
123690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Return it to the default
123790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->tab_width = 8;
123890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
123990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
124090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
124190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
124290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether or not to use tab-stop width specifed by language
124390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
124490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to use language-specific tab-stop widths
124590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.20
124690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
124790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_use_language_tab_width($use) {
124890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->use_language_tab_width = (bool) $use;
124990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
125090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
125190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
125290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Returns the tab width to use, based on the current language and user
125390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * preference
125490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
125590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return int Tab width
125690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.20
125790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
125890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_real_tab_width() {
125990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$this->use_language_tab_width ||
126090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            !isset($this->language_data['TAB_WIDTH'])) {
126190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return $this->tab_width;
126290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
126390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return $this->language_data['TAB_WIDTH'];
126490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
126590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
126690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
126790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
126890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Enables/disables strict highlighting. Default is off, calling this
126990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * method without parameters will turn it on. See documentation
127090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * for more details on strict mode and where to use it.
127190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
127290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to enable strict mode or not
127390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
127490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
127590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_strict_mode($mode = true) {
127690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_MAYBE == $this->language_data['STRICT_MODE_APPLIES']) {
127790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->strict_mode = ($mode) ? GESHI_ALWAYS : GESHI_NEVER;
127890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
127990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
128090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
128190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
128290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Disables all highlighting
128390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
128490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
128590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo  Rewrite with array traversal
128690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated In favour of enable_highlighting
128790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
128890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function disable_highlighting() {
128990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->enable_highlighting(false);
129090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
129190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
129290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
129390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Enables all highlighting
129490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
129590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The optional flag parameter was added in version 1.0.7.21 and can be used
129690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * to enable (true) or disable (false) all highlighting.
129790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
129890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
129990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean A flag specifying whether to enable or disable all highlighting
130090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo  Rewrite with array traversal
130190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
130290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_highlighting($flag = true) {
130390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $flag = $flag ? true : false;
130490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->lexic_permissions as $key => $value) {
130590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (is_array($value)) {
130690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                foreach ($value as $k => $v) {
130790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->lexic_permissions[$key][$k] = $flag;
130890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
130990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
131090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions[$key] = $flag;
131190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
131290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
131390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
131490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Context blocks
131590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->enable_important_blocks = $flag;
131690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
131790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
131890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
131990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Given a file extension, this method returns either a valid geshi language
132090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * name, or the empty string if it couldn't be found
132190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
132290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The extension to get a language name for
132390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param array  A lookup array to use instead of the default one
132490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.5
132590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo Re-think about how this method works (maybe make it private and/or make it
132690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *       a extension->lang lookup?)
132790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo static?
132890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
132990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_language_name_from_extension( $extension, $lookup = array() ) {
133090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ( !is_array($lookup) || empty($lookup)) {
133190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $lookup = array(
133290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'actionscript' => array('as'),
133390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'ada' => array('a', 'ada', 'adb', 'ads'),
133490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'apache' => array('conf'),
133590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'asm' => array('ash', 'asm', 'inc'),
133690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'asp' => array('asp'),
133790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'bash' => array('sh'),
133890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'bf' => array('bf'),
133990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'c' => array('c', 'h'),
134090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'c_mac' => array('c', 'h'),
134190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'caddcl' => array(),
134290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'cadlisp' => array(),
134390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'cdfg' => array('cdfg'),
134490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'cobol' => array('cbl'),
134590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'cpp' => array('cpp', 'hpp', 'C', 'H', 'CPP', 'HPP'),
134690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'csharp' => array('cs'),
134790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'css' => array('css'),
134890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'd' => array('d'),
134990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'delphi' => array('dpk', 'dpr', 'pp', 'pas'),
135090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'diff' => array('diff', 'patch'),
135190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'dos' => array('bat', 'cmd'),
135290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'gettext' => array('po', 'pot'),
135390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'gml' => array('gml'),
135490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'gnuplot' => array('plt'),
135590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'groovy' => array('groovy'),
135690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'haskell' => array('hs'),
135790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'html4strict' => array('html', 'htm'),
135890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'ini' => array('ini', 'desktop'),
135990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'java' => array('java'),
136090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'javascript' => array('js'),
136190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'klonec' => array('kl1'),
136290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'klonecpp' => array('klx'),
136390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'latex' => array('tex'),
136490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'lisp' => array('lisp'),
136590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'lua' => array('lua'),
136690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'matlab' => array('m'),
136790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'mpasm' => array(),
136890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'mysql' => array('sql'),
136990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'nsis' => array(),
137090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'objc' => array(),
137190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'oobas' => array(),
137290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'oracle8' => array(),
137390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'oracle10' => array(),
137490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'pascal' => array('pas'),
137590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'perl' => array('pl', 'pm'),
137690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'php' => array('php', 'php5', 'phtml', 'phps'),
137790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'povray' => array('pov'),
137890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'providex' => array('pvc', 'pvx'),
137990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'prolog' => array('pl'),
138090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'python' => array('py'),
138190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'qbasic' => array('bi'),
138290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'reg' => array('reg'),
138390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'ruby' => array('rb'),
138490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'sas' => array('sas'),
138590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'scala' => array('scala'),
138690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'scheme' => array('scm'),
138790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'scilab' => array('sci'),
138890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'smalltalk' => array('st'),
138990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'smarty' => array(),
139090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'tcl' => array('tcl'),
139190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'vb' => array('bas'),
139290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'vbnet' => array(),
139390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'visualfoxpro' => array(),
139490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'whitespace' => array('ws'),
139590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'xml' => array('xml', 'svg'),
139690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                'z80' => array('z80', 'asm', 'inc')
139790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            );
139890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
139990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
140090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($lookup as $lang => $extensions) {
140190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (in_array($extension, $extensions)) {
140290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return $lang;
140390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
140490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
140590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return '';
140690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
140790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
140890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
140990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Given a file name, this method loads its contents in, and attempts
141090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * to set the language automatically. An optional lookup table can be
141190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * passed for looking up the language name. If not specified a default
141290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * table is used
141390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
141490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The language table is in the form
141590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * <pre>array(
141690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   'lang_name' => array('extension', 'extension', ...),
141790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *   'lang_name' ...
141890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * );</pre>
141990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
142090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The filename to load the source from
142190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param array  A lookup array to use instead of the default one
142290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo Complete rethink of this and above method
142390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.5
142490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
142590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function load_from_file($file_name, $lookup = array()) {
142690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (is_readable($file_name)) {
142790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_source(file_get_contents($file_name));
142890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_language($this->get_language_name_from_extension(substr(strrchr($file_name, '.'), 1), $lookup));
142990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
143090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->error = GESHI_ERROR_FILE_NOT_READABLE;
143190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
143290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
143390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
143490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
143590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Adds a keyword to a keyword group for highlighting
143690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
143790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int    The key of the keyword group to add the keyword to
143890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The word to add to the keyword group
143990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
144090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
144190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function add_keyword($key, $word) {
144290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!in_array($word, $this->language_data['KEYWORDS'][$key])) {
144390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['KEYWORDS'][$key][] = $word;
144490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
144590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //NEW in 1.0.8 don't recompile the whole optimized regexp, simply append it
144690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->parse_cache_built) {
144790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $subkey = count($this->language_data['CACHED_KEYWORD_LISTS'][$key]) - 1;
144890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['CACHED_KEYWORD_LISTS'][$key][$subkey] .= '|' . preg_quote($word, '/');
144990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
145090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
145190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
145290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
145390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
145490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Removes a keyword from a keyword group
145590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
145690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int    The key of the keyword group to remove the keyword from
145790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The word to remove from the keyword group
145890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param bool   Wether to automatically recompile the optimized regexp list or not.
145990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               Note: if you set this to false and @see GeSHi->parse_code() was already called once,
146090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               for the current language, you have to manually call @see GeSHi->optimize_keyword_group()
146190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               or the removed keyword will stay in cache and still be highlighted! On the other hand
146290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               it might be too expensive to recompile the regexp list for every removal if you want to
146390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               remove a lot of keywords.
146490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
146590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
146690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function remove_keyword($key, $word, $recompile = true) {
146790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $key_to_remove = array_search($word, $this->language_data['KEYWORDS'][$key]);
146890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($key_to_remove !== false) {
146990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($this->language_data['KEYWORDS'][$key][$key_to_remove]);
147090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
147190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //NEW in 1.0.8, optionally recompile keyword group
147290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($recompile && $this->parse_cache_built) {
147390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->optimize_keyword_group($key);
147490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
147590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
147690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
147790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
147890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
147990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Creates a new keyword group
148090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
148190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int    The key of the keyword group to create
148290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The styles for the keyword group
148390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether the keyword group is case sensitive ornot
148490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param array  The words to use for the keyword group
148590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
148690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
148790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function add_keyword_group($key, $styles, $case_sensitive = true, $words = array()) {
148890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $words = (array) $words;
148990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if  (empty($words)) {
149090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // empty word lists mess up highlighting
149190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return false;
149290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
149390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
149490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Add the new keyword group internally
149590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['KEYWORDS'][$key] = $words;
149690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->lexic_permissions['KEYWORDS'][$key] = true;
149790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['CASE_SENSITIVE'][$key] = $case_sensitive;
149890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['STYLES']['KEYWORDS'][$key] = $styles;
149990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
150090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //NEW in 1.0.8, cache keyword regexp
150190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->parse_cache_built) {
150290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->optimize_keyword_group($key);
150390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
150490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
150590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
150690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
150790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Removes a keyword group
150890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
150990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int    The key of the keyword group to remove
151090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
151190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
151290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function remove_keyword_group ($key) {
151390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Remove the keyword group internally
151490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($this->language_data['KEYWORDS'][$key]);
151590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($this->lexic_permissions['KEYWORDS'][$key]);
151690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($this->language_data['CASE_SENSITIVE'][$key]);
151790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($this->language_data['STYLES']['KEYWORDS'][$key]);
151890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
151990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //NEW in 1.0.8
152090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($this->language_data['CACHED_KEYWORD_LISTS'][$key]);
152190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
152290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
152390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
152490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * compile optimized regexp list for keyword group
152590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
152690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int   The key of the keyword group to compile & optimize
152790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
152890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
152990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function optimize_keyword_group($key) {
153090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['CACHED_KEYWORD_LISTS'][$key] =
153190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->optimize_regexp_list($this->language_data['KEYWORDS'][$key]);
153290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $space_as_whitespace = false;
153390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(isset($this->language_data['PARSER_CONTROL'])) {
153490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
153590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'])) {
153690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'];
153790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
153890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
153990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
154090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'];
154190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
154290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
154390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
154490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
154590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if($space_as_whitespace) {
154690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach($this->language_data['CACHED_KEYWORD_LISTS'][$key] as $rxk => $rxv) {
154790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['CACHED_KEYWORD_LISTS'][$key][$rxk] =
154890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    str_replace(" ", "\\s+", $rxv);
154990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
155090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
155190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
155290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
155390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
155490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the content of the header block
155590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
155690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The content of the header block
155790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
155890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
155990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_header_content($content) {
156090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->header_content = $content;
156190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
156290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
156390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
156490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the content of the footer block
156590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
156690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The content of the footer block
156790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
156890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
156990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_footer_content($content) {
157090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->footer_content = $content;
157190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
157290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
157390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
157490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the style for the header content
157590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
157690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The style for the header content
157790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
157890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
157990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_header_content_style($style) {
158090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->header_content_style = $style;
158190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
158290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
158390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
158490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the style for the footer content
158590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
158690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The style for the footer content
158790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
158890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
158990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_footer_content_style($style) {
159090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->footer_content_style = $style;
159190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
159290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
159390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
159490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether to force a surrounding block around
159590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * the highlighted code or not
159690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
159790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Tells whether to enable or disable this feature
159890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.20
159990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
160090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_inner_code_block($flag) {
160190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->force_code_block = (bool)$flag;
160290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
160390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
160490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
160590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the base URL to be used for keywords
160690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
160790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The key of the keyword group to set the URL for
160890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The URL to set for the group. If {FNAME} is in
160990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               the url somewhere, it is replaced by the keyword
161090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               that the URL is being made for
161190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
161290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
161390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_url_for_keyword_group($group, $url) {
161490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['URLS'][$group] = $url;
161590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
161690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
161790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
161890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets styles for links in code
161990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
162090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int A constant that specifies what state the style is being
162190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *            set for - e.g. :hover or :visited
162290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The styles to use for that state
162390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
162490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
162590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_link_styles($type, $styles) {
162690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->link_styles[$type] = $styles;
162790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
162890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
162990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
163090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the target for links in code
163190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
163290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The target for links in the code, e.g. _blank
163390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.3
163490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
163590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_link_target($target) {
163690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$target) {
163790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->link_target = '';
163890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
163990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->link_target = ' target="' . $target . '"';
164090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
164190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
164290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
164390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
164490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets styles for important parts of the code
164590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
164690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The styles to use on important parts of the code
164790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
164890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
164990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_important_styles($styles) {
165090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->important_styles = $styles;
165190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
165290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
165390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
165490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets whether context-important blocks are highlighted
165590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
165690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Tells whether to enable or disable highlighting of important blocks
165790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo REMOVE THIS SHIZ FROM GESHI!
165890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @deprecated
165990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
166090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
166190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_important_blocks($flag) {
166290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->enable_important_blocks = ( $flag ) ? true : false;
166390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
166490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
166590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
166690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Whether CSS IDs should be added to each line
166790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
166890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean If true, IDs will be added to each line.
166990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
167090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
167190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_ids($flag = true) {
167290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->add_ids = ($flag) ? true : false;
167390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
167490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
167590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
167690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Specifies which lines to highlight extra
167790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
167890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The extra style parameter was added in 1.0.7.21.
167990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
168090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param mixed An array of line numbers to highlight, or just a line
168190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              number on its own.
168290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string A string specifying the style to use for this line.
168390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              If null is specified, the default style is used.
168490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              If false is specified, the line will be removed from
168590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              special highlighting
168690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
168790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo  Some data replication here that could be cut down on
168890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
168990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function highlight_lines_extra($lines, $style = null) {
169090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (is_array($lines)) {
169190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Split up the job using single lines at a time
169290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($lines as $line) {
169390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->highlight_lines_extra($line, $style);
169490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
169590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
169690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Mark the line as being highlighted specially
169790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $lines = intval($lines);
169890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->highlight_extra_lines[$lines] = $lines;
169990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
170090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Decide on which style to use
170190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($style === null) { //Check if we should use default style
170290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($this->highlight_extra_lines_styles[$lines]);
170390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else if ($style === false) { //Check if to remove this line
170490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($this->highlight_extra_lines[$lines]);
170590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($this->highlight_extra_lines_styles[$lines]);
170690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
170790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->highlight_extra_lines_styles[$lines] = $style;
170890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
170990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
171090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
171190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
171290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
171390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the style for extra-highlighted lines
171490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
171590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The style for extra-highlighted lines
171690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
171790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
171890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_highlight_lines_extra_style($styles) {
171990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->highlight_extra_lines_style = $styles;
172090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
172190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
172290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
172390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the line-ending
172490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
172590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The new line-ending
172690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
172790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
172890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_line_ending($line_ending) {
172990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->line_ending = (string)$line_ending;
173090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
173190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
173290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
173390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets what number line numbers should start at. Should
173490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * be a positive integer, and will be converted to one.
173590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
173690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * <b>Warning:</b> Using this method will add the "start"
173790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * attribute to the &lt;ol&gt; that is used for line numbering.
173890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This is <b>not</b> valid XHTML strict, so if that's what you
173990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * care about then don't use this method. Firefox is getting
174090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * support for the CSS method of doing this in 1.1 and Opera
174190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * has support for the CSS method, but (of course) IE doesn't
174290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * so it's not worth doing it the CSS way yet.
174390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
174490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The number to start line numbers at
174590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
174690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
174790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function start_line_numbers_at($number) {
174890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->line_numbers_start = abs(intval($number));
174990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
175090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
175190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
175290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the encoding used for htmlspecialchars(), for international
175390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * support.
175490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
175590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * NOTE: This is not needed for now because htmlspecialchars() is not
175690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * being used (it has a security hole in PHP4 that has not been patched).
175790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Maybe in a future version it may make a return for speed reasons, but
175890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * I doubt it.
175990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
176090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The encoding to use for the source
176190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.3
176290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
176390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_encoding($encoding) {
176490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($encoding) {
176590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber          $this->encoding = strtolower($encoding);
176690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
176790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
176890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
176990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
177090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Turns linking of keywords on or off.
177190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
177290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean If true, links will be added to keywords
177390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
177490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
177590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function enable_keyword_links($enable = true) {
177690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->keyword_links = (bool) $enable;
177790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
177890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
177990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
178090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Setup caches needed for styling. This is automatically called in
178190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * parse_code() and get_stylesheet() when appropriate. This function helps
178290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * stylesheet generators as they rely on some style information being
178390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * preprocessed
178490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
178590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
178690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
178790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
178890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function build_style_cache() {
178990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Build the style cache needed to highlight numbers appropriate
179090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if($this->lexic_permissions['NUMBERS']) {
179190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //First check what way highlighting information for numbers are given
179290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if(!isset($this->language_data['NUMBERS'])) {
179390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['NUMBERS'] = 0;
179490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
179590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
179690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if(is_array($this->language_data['NUMBERS'])) {
179790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['NUMBERS_CACHE'] = $this->language_data['NUMBERS'];
179890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
179990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['NUMBERS_CACHE'] = array();
180090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(!$this->language_data['NUMBERS']) {
180190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->language_data['NUMBERS'] =
180290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        GESHI_NUMBER_INT_BASIC |
180390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        GESHI_NUMBER_FLT_NONSCI;
180490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
180590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
180690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                for($i = 0, $j = $this->language_data['NUMBERS']; $j > 0; ++$i, $j>>=1) {
180790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Rearrange style indices if required ...
180890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if(isset($this->language_data['STYLES']['NUMBERS'][1<<$i])) {
180990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->language_data['STYLES']['NUMBERS'][$i] =
181090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['STYLES']['NUMBERS'][1<<$i];
181190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        unset($this->language_data['STYLES']['NUMBERS'][1<<$i]);
181290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
181390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
181490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Check if this bit is set for highlighting
181590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if($j&1) {
181690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //So this bit is set ...
181790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Check if it belongs to group 0 or the actual stylegroup
181890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if(isset($this->language_data['STYLES']['NUMBERS'][$i])) {
181990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['NUMBERS_CACHE'][$i] = 1 << $i;
182090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
182190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if(!isset($this->language_data['NUMBERS_CACHE'][0])) {
182290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $this->language_data['NUMBERS_CACHE'][0] = 0;
182390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
182490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['NUMBERS_CACHE'][0] |= 1 << $i;
182590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
182690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
182790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
182890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
182990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
183090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
183190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
183290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
183390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Setup caches needed for parsing. This is automatically called in parse_code() when appropriate.
183490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This function makes stylesheet generators much faster as they do not need these caches.
183590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
183690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
183790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
183890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
183990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function build_parse_cache() {
184090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // cache symbol regexp
184190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //As this is a costy operation, we avoid doing it for multiple groups ...
184290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Instead we perform it for all symbols at once.
184390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
184490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //For this to work, we need to reorganize the data arrays.
184590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
184690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['MULTIPLE_SYMBOL_GROUPS'] = count($this->language_data['STYLES']['SYMBOLS']) > 1;
184790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
184890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['SYMBOL_DATA'] = array();
184990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $symbol_preg_multi = array(); // multi char symbols
185090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $symbol_preg_single = array(); // single char symbols
185190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($this->language_data['SYMBOLS'] as $key => $symbols) {
185290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_array($symbols)) {
185390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    foreach ($symbols as $sym) {
185490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $sym = $this->hsc($sym);
185590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!isset($this->language_data['SYMBOL_DATA'][$sym])) {
185690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['SYMBOL_DATA'][$sym] = $key;
185790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (isset($sym[1])) { // multiple chars
185890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $symbol_preg_multi[] = preg_quote($sym, '/');
185990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else { // single char
186090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($sym == '-') {
186190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // don't trigger range out of order error
186290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $symbol_preg_single[] = '\-';
186390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
186490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $symbol_preg_single[] = preg_quote($sym, '/');
186590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
186690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
186790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
186890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
186990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
187090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $symbols = $this->hsc($symbols);
187190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!isset($this->language_data['SYMBOL_DATA'][$symbols])) {
187290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->language_data['SYMBOL_DATA'][$symbols] = 0;
187390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (isset($symbols[1])) { // multiple chars
187490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $symbol_preg_multi[] = preg_quote($symbols, '/');
187590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else if ($symbols == '-') {
187690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // don't trigger range out of order error
187790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $symbol_preg_single[] = '\-';
187890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else { // single char
187990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $symbol_preg_single[] = preg_quote($symbols, '/');
188090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
188190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
188290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
188390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
188490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
188590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Now we have an array with each possible symbol as the key and the style as the actual data.
188690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //This way we can set the correct style just the moment we highlight ...
188790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //
188890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Now we need to rewrite our array to get a search string that
188990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $symbol_preg = array();
189090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!empty($symbol_preg_multi)) {
189190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                rsort($symbol_preg_multi);
189290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_preg[] = implode('|', $symbol_preg_multi);
189390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
189490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!empty($symbol_preg_single)) {
189590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                rsort($symbol_preg_single);
189690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_preg[] = '[' . implode('', $symbol_preg_single) . ']';
189790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
189890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['SYMBOL_SEARCH'] = implode("|", $symbol_preg);
189990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
190090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
190190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // cache optimized regexp for keyword matching
190290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // remove old cache
190390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data['CACHED_KEYWORD_LISTS'] = array();
190490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
190590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!isset($this->lexic_permissions['KEYWORDS'][$key]) ||
190690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->lexic_permissions['KEYWORDS'][$key]) {
190790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->optimize_keyword_group($key);
190890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
190990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
191090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
191190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // brackets
191290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['BRACKETS']) {
191390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['CACHE_BRACKET_MATCH'] = array('[', ']', '(', ')', '{', '}');
191490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!$this->use_classes && isset($this->language_data['STYLES']['BRACKETS'][0])) {
191590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['CACHE_BRACKET_REPLACE'] = array(
191690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#91;|>',
191790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#93;|>',
191890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#40;|>',
191990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#41;|>',
192090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#123;|>',
192190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#125;|>',
192290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                );
192390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
192490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            else {
192590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['CACHE_BRACKET_REPLACE'] = array(
192690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#91;|>',
192790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#93;|>',
192890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#40;|>',
192990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#41;|>',
193090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#123;|>',
193190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '<| class="br0">&#125;|>',
193290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                );
193390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
193490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
193590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
193690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Build the parse cache needed to highlight numbers appropriate
193790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if($this->lexic_permissions['NUMBERS']) {
193890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Check if the style rearrangements have been processed ...
193990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //This also does some preprocessing to check which style groups are useable ...
194090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if(!isset($this->language_data['NUMBERS_CACHE'])) {
194190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->build_style_cache();
194290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
194390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
194490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Number format specification
194590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //All this formats are matched case-insensitively!
194690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            static $numbers_format = array(
194790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_INT_BASIC =>
194890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z\.])',
194990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_INT_CSTYLE =>
195090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z\.])',
195190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_BIN_SUFFIX =>
195290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[01]+?b(?![0-9a-z\.])',
195390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_BIN_PREFIX_PERCENT =>
195490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])%[01]+?(?![0-9a-z\.])',
195590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_BIN_PREFIX_0B =>
195690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0b[01]+?(?![0-9a-z\.])',
195790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_OCT_PREFIX =>
195890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0[0-7]+?(?![0-9a-z\.])',
195990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_OCT_SUFFIX =>
196090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[0-7]+?o(?![0-9a-z\.])',
196190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_HEX_PREFIX =>
196290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0x[0-9a-f]+?(?![0-9a-z\.])',
196390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_HEX_SUFFIX =>
196490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d[0-9a-f]*?h(?![0-9a-z\.])',
196590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_FLT_NONSCI =>
196690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z\.])',
196790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_FLT_NONSCI_F =>
196890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z\.])',
196990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_FLT_SCI_SHORT =>
197090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z\.])',
197190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                GESHI_NUMBER_FLT_SCI_ZERO =>
197290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z\.])'
197390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                );
197490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
197590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //At this step we have an associative array with flag groups for a
197690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //specific style or an string denoting a regexp given its index.
197790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['NUMBERS_RXCACHE'] = array();
197890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach($this->language_data['NUMBERS_CACHE'] as $key => $rxdata) {
197990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(is_string($rxdata)) {
198090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $regexp = $rxdata;
198190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
198290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //This is a bitfield of number flags to highlight:
198390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Build an array, implode them together and make this the actual RX
198490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $rxuse = array();
198590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    for($i = 1; $i <= $rxdata; $i<<=1) {
198690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if($rxdata & $i) {
198790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $rxuse[] = $numbers_format[$i];
198890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
198990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
199090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $regexp = implode("|", $rxuse);
199190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
199290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
199390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['NUMBERS_RXCACHE'][$key] =
199490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    "/(?<!<\|\/NUM!)(?<!\d\/>)($regexp)(?!\|>)/i";
199590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
199690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
199790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
199890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->parse_cache_built = true;
199990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
200090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
200190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
200290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Returns the code in $this->source, highlighted and surrounded by the
200390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * nessecary HTML.
200490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
200590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This should only be called ONCE, cos it's SLOW! If you want to highlight
200690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * the same source multiple times, you're better off doing a whole lot of
200790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * str_replaces to replace the &lt;span&gt;s
200890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
200990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
201090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
201190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function parse_code () {
201290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Start the timer
201390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $start_time = microtime();
201490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
201590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Firstly, if there is an error, we won't highlight
201690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->error) {
201790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Escape the source for output
201890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $result = $this->hsc($this->source);
201990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
202090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //This fix is related to SF#1923020, but has to be applied regardless of
202190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //actually highlighting symbols.
202290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $result = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $result);
202390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
202490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Timing is irrelevant
202590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->set_time($start_time, $start_time);
202690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->finalise($result);
202790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return $result;
202890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
202990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
203090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // make sure the parse cache is up2date
203190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$this->parse_cache_built) {
203290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->build_parse_cache();
203390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
203490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
203590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Replace all newlines to a common form.
203690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $code = str_replace("\r\n", "\n", $this->source);
203790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $code = str_replace("\r", "\n", $code);
203890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
203990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Add spaces for regular expression matching and line numbers
204090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        $code = "\n" . $code . "\n";
204190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
204290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Initialise various stuff
204390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $length           = strlen($code);
204490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $COMMENT_MATCHED  = false;
204590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stuff_to_parse   = '';
204690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $endresult        = '';
204790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
204890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // "Important" selections are handled like multiline comments
204990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // @todo GET RID OF THIS SHIZ
205090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->enable_important_blocks) {
205190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['COMMENT_MULTI'][GESHI_START_IMPORTANT] = GESHI_END_IMPORTANT;
205290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
205390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
205490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->strict_mode) {
205590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Break the source into bits. Each bit will be a portion of the code
205690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // within script delimiters - for example, HTML between < and >
205790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $k = 0;
205890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $parts = array();
205990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $matches = array();
206090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $next_match_pointer = null;
206190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // we use a copy to unset delimiters on demand (when they are not found)
206290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $delim_copy = $this->language_data['SCRIPT_DELIMITERS'];
206390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $i = 0;
206490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            while ($i < $length) {
206590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_match_pos = $length + 1; // never true
206690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                foreach ($delim_copy as $dk => $delimiters) {
206790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if(is_array($delimiters)) {
206890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        foreach ($delimiters as $open => $close) {
206990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // make sure the cache is setup properly
207090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (!isset($matches[$dk][$open])) {
207190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $matches[$dk][$open] = array(
207290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'next_match' => -1,
207390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'dk' => $dk,
207490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
207590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'open' => $open, // needed for grouping of adjacent code blocks (see below)
207690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'open_strlen' => strlen($open),
207790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
207890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'close' => $close,
207990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'close_strlen' => strlen($close),
208090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                );
208190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
208290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // Get the next little bit for this opening string
208390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($matches[$dk][$open]['next_match'] < $i) {
208490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // only find the next pos if it was not already cached
208590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $open_pos = strpos($code, $open, $i);
208690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($open_pos === false) {
208790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // no match for this delimiter ever
208890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    unset($delim_copy[$dk][$open]);
208990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    continue;
209090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
209190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $matches[$dk][$open]['next_match'] = $open_pos;
209290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
209390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($matches[$dk][$open]['next_match'] < $next_match_pos) {
209490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //So we got a new match, update the close_pos
209590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $matches[$dk][$open]['close_pos'] =
209690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    strpos($code, $close, $matches[$dk][$open]['next_match']+1);
209790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
209890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_match_pointer =& $matches[$dk][$open];
209990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_match_pos = $matches[$dk][$open]['next_match'];
210090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
210190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
210290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
210390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //So we should match an RegExp as Strict Block ...
210490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        /**
210590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         * The value in $delimiters is expected to be an RegExp
210690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         * containing exactly 2 matching groups:
210790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         *  - Group 1 is the opener
210890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         *  - Group 2 is the closer
210990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                         */
211090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if(!GESHI_PHP_PRE_433 && //Needs proper rewrite to work with PHP >=4.3.0; 4.3.3 is guaranteed to work.
211190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            preg_match($delimiters, $code, $matches_rx, PREG_OFFSET_CAPTURE, $i)) {
211290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            //We got a match ...
211390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $matches[$dk] = array(
211490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                'next_match' => $matches_rx[1][1],
211590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                'dk' => $dk,
211690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
211790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                'close_strlen' => strlen($matches_rx[2][0]),
211890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                'close_pos' => $matches_rx[2][1],
211990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                );
212090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
212190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // no match for this delimiter ever
212290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            unset($delim_copy[$dk]);
212390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            continue;
212490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
212590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
212690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($matches[$dk]['next_match'] <= $next_match_pos) {
212790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $next_match_pointer =& $matches[$dk];
212890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $next_match_pos = $matches[$dk]['next_match'];
212990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
213090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
213190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
213290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // non-highlightable text
213390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parts[$k] = array(
213490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    1 => substr($code, $i, $next_match_pos - $i)
213590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                );
213690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                ++$k;
213790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
213890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($next_match_pos > $length) {
213990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // out of bounds means no next match was found
214090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    break;
214190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
214290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
214390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // highlightable code
214490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parts[$k][0] = $next_match_pointer['dk'];
214590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
214690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Only combine for non-rx script blocks
214790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if(is_array($delim_copy[$next_match_pointer['dk']])) {
214890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // group adjacent script blocks, e.g. <foobar><asdf> should be one block, not three!
214990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $i = $next_match_pos + $next_match_pointer['open_strlen'];
215090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    while (true) {
215190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $close_pos = strpos($code, $next_match_pointer['close'], $i);
215290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($close_pos == false) {
215390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
215490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
215590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $i = $close_pos + $next_match_pointer['close_strlen'];
215690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($i == $length) {
215790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
215890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
215990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($code[$i] == $next_match_pointer['open'][0] && ($next_match_pointer['open_strlen'] == 1 ||
216090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            substr($code, $i, $next_match_pointer['open_strlen']) == $next_match_pointer['open'])) {
216190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // merge adjacent but make sure we don't merge things like <tag><!-- comment -->
216290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            foreach ($matches as $submatches) {
216390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                foreach ($submatches as $match) {
216490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($match['next_match'] == $i) {
216590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // a different block already matches here!
216690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        break 3;
216790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
216890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
216990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
217090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
217190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
217290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
217390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
217490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
217590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $close_pos = $next_match_pointer['close_pos'] + $next_match_pointer['close_strlen'];
217690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $i = $close_pos;
217790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
217890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
217990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($close_pos === false) {
218090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // no closing delimiter found!
218190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $parts[$k][1] = substr($code, $next_match_pos);
218290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ++$k;
218390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    break;
218490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
218590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $parts[$k][1] = substr($code, $next_match_pos, $i - $next_match_pos);
218690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ++$k;
218790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
218890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
218990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($delim_copy, $next_match_pointer, $next_match_pos, $matches);
219090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $num_parts = $k;
219190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
219290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($num_parts == 1 && $this->strict_mode == GESHI_MAYBE) {
219390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // when we have only one part, we don't have anything to highlight at all.
219490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // if we have a "maybe" strict language, this should be handled as highlightable code
219590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parts = array(
219690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    0 => array(
219790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        0 => '',
219890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        1 => ''
219990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ),
220090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    1 => array(
220190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        0 => null,
220290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        1 => $parts[0][1]
220390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    )
220490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                );
220590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $num_parts = 2;
220690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
220790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
220890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
220990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Not strict mode - simply dump the source into
221090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // the array at index 1 (the first highlightable block)
221190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $parts = array(
221290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                0 => array(
221390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    0 => '',
221490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    1 => ''
221590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                ),
221690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                1 => array(
221790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    0 => null,
221890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    1 => $code
221990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                )
222090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            );
222190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $num_parts = 2;
222290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
222390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
222490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Unset variables we won't need any longer
222590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        unset($code);
222690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
222790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Preload some repeatedly used values regarding hardquotes ...
222890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $hq = isset($this->language_data['HARDQUOTE']) ? $this->language_data['HARDQUOTE'][0] : false;
222990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $hq_strlen = strlen($hq);
223090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
223190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Preload if line numbers are to be generated afterwards
223290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Added a check if line breaks should be forced even without line numbers, fixes SF#1727398
223390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $check_linenumbers = $this->line_numbers != GESHI_NO_LINE_NUMBERS ||
223490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            !empty($this->highlight_extra_lines) || !$this->allow_multiline_span;
223590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
223690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //preload the escape char for faster checking ...
223790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $escaped_escape_char = $this->hsc($this->language_data['ESCAPE_CHAR']);
223890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
223990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // this is used for single-line comments
224090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $sc_disallowed_before = "";
224190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $sc_disallowed_after = "";
224290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
224390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (isset($this->language_data['PARSER_CONTROL'])) {
224490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($this->language_data['PARSER_CONTROL']['COMMENTS'])) {
224590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'])) {
224690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $sc_disallowed_before = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'];
224790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
224890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'])) {
224990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $sc_disallowed_after = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'];
225090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
225190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
225290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
225390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
225490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Fix for SF#1932083: Multichar Quotemarks unsupported
225590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $is_string_starter = array();
225690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['STRINGS']) {
225790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($this->language_data['QUOTEMARKS'] as $quotemark) {
225890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (!isset($is_string_starter[$quotemark[0]])) {
225990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $is_string_starter[$quotemark[0]] = (string)$quotemark;
226090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else if (is_string($is_string_starter[$quotemark[0]])) {
226190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $is_string_starter[$quotemark[0]] = array(
226290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $is_string_starter[$quotemark[0]],
226390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $quotemark);
226490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
226590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $is_string_starter[$quotemark[0]][] = $quotemark;
226690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
226790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
226890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
226990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
227090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Now we go through each part. We know that even-indexed parts are
227190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // code that shouldn't be highlighted, and odd-indexed parts should
227290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // be highlighted
227390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for ($key = 0; $key < $num_parts; ++$key) {
227490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $STRICTATTRS = '';
227590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
227690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // If this block should be highlighted...
227790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!($key & 1)) {
227890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Else not a block to highlight
227990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $endresult .= $this->hsc($parts[$key][1]);
228090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($parts[$key]);
228190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                continue;
228290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
228390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
228490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $result = '';
228590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $part = $parts[$key][1];
228690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
228790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $highlight_part = true;
228890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->strict_mode && !is_null($parts[$key][0])) {
228990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // get the class key for this block of code
229090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $script_key = $parts[$key][0];
229190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $highlight_part = $this->language_data['HIGHLIGHT_STRICT_BLOCK'][$script_key];
229290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->language_data['STYLES']['SCRIPT'][$script_key] != '' &&
229390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->lexic_permissions['SCRIPT']) {
229490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Add a span element around the source to
229590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // highlight the overall source block
229690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$this->use_classes &&
229790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->language_data['STYLES']['SCRIPT'][$script_key] != '') {
229890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' style="' . $this->language_data['STYLES']['SCRIPT'][$script_key] . '"';
229990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
230090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' class="sc' . $script_key . '"';
230190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
230290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $result .= "<span$attributes>";
230390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $STRICTATTRS = $attributes;
230490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
230590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
230690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
230790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($highlight_part) {
230890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Now, highlight the code in this block. This code
230990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // is really the engine of GeSHi (along with the method
231090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // parse_non_string_part).
231190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
231290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // cache comment regexps incrementally
231390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_comment_regexp_key = '';
231490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_comment_regexp_pos = -1;
231590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_comment_multi_pos = -1;
231690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_comment_single_pos = -1;
231790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $comment_regexp_cache_per_key = array();
231890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $comment_multi_cache_per_key = array();
231990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $comment_single_cache_per_key = array();
232090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_open_comment_multi = '';
232190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_comment_single_key = '';
232290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $escape_regexp_cache_per_key = array();
232390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_escape_regexp_key = '';
232490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $next_escape_regexp_pos = -1;
232590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
232690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $length = strlen($part);
232790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                for ($i = 0; $i < $length; ++$i) {
232890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Get the next char
232990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $char = $part[$i];
233090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $char_len = 1;
233190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
233290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // update regexp comment cache if needed
233390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['COMMENT_REGEXP']) && $next_comment_regexp_pos < $i) {
233490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $next_comment_regexp_pos = $length;
233590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        foreach ($this->language_data['COMMENT_REGEXP'] as $comment_key => $regexp) {
233690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $match_i = false;
233790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (isset($comment_regexp_cache_per_key[$comment_key]) &&
233890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                ($comment_regexp_cache_per_key[$comment_key]['pos'] >= $i ||
233990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                 $comment_regexp_cache_per_key[$comment_key]['pos'] === false)) {
234090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // we have already matched something
234190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($comment_regexp_cache_per_key[$comment_key]['pos'] === false) {
234290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // this comment is never matched
234390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    continue;
234490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
234590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $match_i = $comment_regexp_cache_per_key[$comment_key]['pos'];
234690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else if (
234790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
234890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $i), $match, PREG_OFFSET_CAPTURE)) ||
234990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $i))
235090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                ) {
235190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $match_i = $match[0][1];
235290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (GESHI_PHP_PRE_433) {
235390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $match_i += $i;
235490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
235590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
235690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $comment_regexp_cache_per_key[$comment_key] = array(
235790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'key' => $comment_key,
235890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'length' => strlen($match[0][0]),
235990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    'pos' => $match_i
236090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                );
236190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
236290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $comment_regexp_cache_per_key[$comment_key]['pos'] = false;
236390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                continue;
236490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
236590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
236690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($match_i !== false && $match_i < $next_comment_regexp_pos) {
236790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_comment_regexp_pos = $match_i;
236890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_comment_regexp_key = $comment_key;
236990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($match_i === $i) {
237090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    break;
237190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
237290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
237390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
237490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
237590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
237690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $string_started = false;
237790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
237890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($is_string_starter[$char])) {
237990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // Possibly the start of a new string ...
238090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
238190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Check which starter it was ...
238290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Fix for SF#1932083: Multichar Quotemarks unsupported
238390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (is_array($is_string_starter[$char])) {
238490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $char_new = '';
238590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            foreach ($is_string_starter[$char] as $testchar) {
238690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($testchar === substr($part, $i, strlen($testchar)) &&
238790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    strlen($testchar) > strlen($char_new)) {
238890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $char_new = $testchar;
238990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $string_started = true;
239090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
239190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
239290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($string_started) {
239390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $char = $char_new;
239490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
239590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
239690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $testchar = $is_string_starter[$char];
239790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($testchar === substr($part, $i, strlen($testchar))) {
239890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $char = $testchar;
239990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string_started = true;
240090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
240190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
240290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $char_len = strlen($char);
240390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
240490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
240590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($string_started && $i != $next_comment_regexp_pos) {
240690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // Hand out the correct style information for this string
240790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string_key = array_search($char, $this->language_data['QUOTEMARKS']);
240890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!isset($this->language_data['STYLES']['STRINGS'][$string_key]) ||
240990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            !isset($this->language_data['STYLES']['ESCAPE_CHAR'][$string_key])) {
241090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string_key = 0;
241190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
241290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
241390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // parse the stuff before this
241490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $result .= $this->parse_non_string_part($stuff_to_parse);
241590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = '';
241690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
241790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!$this->use_classes) {
241890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][$string_key] . '"';
241990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
242090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string_attributes = ' class="st'.$string_key.'"';
242190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
242290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
242390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // now handle the string
242490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string = "<span$string_attributes>" . GeSHi::hsc($char);
242590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $start = $i + $char_len;
242690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string_open = true;
242790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
242890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if(empty($this->language_data['ESCAPE_REGEXP'])) {
242990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $next_escape_regexp_pos = $length;
243090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
243190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
243290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        do {
243390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            //Get the regular ending pos ...
243490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $close_pos = strpos($part, $char, $start);
243590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if(false === $close_pos) {
243690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $close_pos = $length;
243790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
243890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
243990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if($this->lexic_permissions['ESCAPE_CHAR']) {
244090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // update escape regexp cache if needed
244190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (isset($this->language_data['ESCAPE_REGEXP']) && $next_escape_regexp_pos < $start) {
244290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $next_escape_regexp_pos = $length;
244390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    foreach ($this->language_data['ESCAPE_REGEXP'] as $escape_key => $regexp) {
244490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $match_i = false;
244590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if (isset($escape_regexp_cache_per_key[$escape_key]) &&
244690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            ($escape_regexp_cache_per_key[$escape_key]['pos'] >= $start ||
244790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                             $escape_regexp_cache_per_key[$escape_key]['pos'] === false)) {
244890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            // we have already matched something
244990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            if ($escape_regexp_cache_per_key[$escape_key]['pos'] === false) {
245090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                // this comment is never matched
245190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                continue;
245290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            }
245390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $match_i = $escape_regexp_cache_per_key[$escape_key]['pos'];
245490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else if (
245590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
245690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $start), $match, PREG_OFFSET_CAPTURE)) ||
245790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $start))
245890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            ) {
245990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $match_i = $match[0][1];
246090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            if (GESHI_PHP_PRE_433) {
246190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                $match_i += $start;
246290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            }
246390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
246490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $escape_regexp_cache_per_key[$escape_key] = array(
246590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                'key' => $escape_key,
246690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                'length' => strlen($match[0][0]),
246790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                'pos' => $match_i
246890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            );
246990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else {
247090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $escape_regexp_cache_per_key[$escape_key]['pos'] = false;
247190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            continue;
247290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
247390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
247490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if ($match_i !== false && $match_i < $next_escape_regexp_pos) {
247590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $next_escape_regexp_pos = $match_i;
247690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $next_escape_regexp_key = $escape_key;
247790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            if ($match_i === $start) {
247890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                break;
247990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            }
248090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
248190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
248290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
248390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
248490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Find the next simple escape position
248590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if('' != $this->language_data['ESCAPE_CHAR']) {
248690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $simple_escape = strpos($part, $this->language_data['ESCAPE_CHAR'], $start);
248790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if(false === $simple_escape) {
248890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $simple_escape = $length;
248990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
249090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
249190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $simple_escape = $length;
249290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
249390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
249490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_escape_regexp_pos = $length;
249590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $simple_escape = $length;
249690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
249790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
249890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if($simple_escape < $next_escape_regexp_pos &&
249990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $simple_escape < $length &&
250090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $simple_escape < $close_pos) {
250190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //The nexxt escape sequence is a simple one ...
250290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $es_pos = $simple_escape;
250390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
250490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Add the stuff not in the string yet ...
250590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string .= $this->hsc(substr($part, $start, $es_pos - $start));
250690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
250790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Get the style for this escaped char ...
250890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (!$this->use_classes) {
250990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][0] . '"';
251090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
251190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $escape_char_attributes = ' class="es0"';
251290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
251390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
251490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Add the style for the escape char ...
251590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string .= "<span$escape_char_attributes>" .
251690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    GeSHi::hsc($this->language_data['ESCAPE_CHAR']);
251790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
251890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Get the byte AFTER the ESCAPE_CHAR we just found
251990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $es_char = $part[$es_pos + 1];
252090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($es_char == "\n") {
252190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // don't put a newline around newlines
252290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $string .= "</span>\n";
252390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $start = $es_pos + 2;
252490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else if (ord($es_char) >= 128) {
252590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    //This is an non-ASCII char (UTF8 or single byte)
252690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    //This code tries to work around SF#2037598 ...
252790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if(function_exists('mb_substr')) {
252890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $es_char_m = mb_substr(substr($part, $es_pos+1, 16), 0, 1, $this->encoding);
252990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $string .= $es_char_m . '</span>';
253090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else if (!GESHI_PHP_PRE_433 && 'utf-8' == $this->encoding) {
253190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if(preg_match("/[\xC2-\xDF][\x80-\xBF]".
253290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|\xE0[\xA0-\xBF][\x80-\xBF]".
253390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}".
253490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|\xED[\x80-\x9F][\x80-\xBF]".
253590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|\xF0[\x90-\xBF][\x80-\xBF]{2}".
253690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|[\xF1-\xF3][\x80-\xBF]{3}".
253790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            "|\xF4[\x80-\x8F][\x80-\xBF]{2}/s",
253890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $part, $es_char_m, null, $es_pos + 1)) {
253990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $es_char_m = $es_char_m[0];
254090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else {
254190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $es_char_m = $es_char;
254290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
254390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $string .= $this->hsc($es_char_m) . '</span>';
254490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else {
254590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $es_char_m = $this->hsc($es_char);
254690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
254790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $start = $es_pos + strlen($es_char_m) + 1;
254890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
254990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $string .= $this->hsc($es_char) . '</span>';
255090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $start = $es_pos + 2;
255190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
255290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else if ($next_escape_regexp_pos < $length &&
255390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_escape_regexp_pos < $close_pos) {
255490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $es_pos = $next_escape_regexp_pos;
255590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Add the stuff not in the string yet ...
255690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string .= $this->hsc(substr($part, $start, $es_pos - $start));
255790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
255890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Get the key and length of this match ...
255990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $escape = $escape_regexp_cache_per_key[$next_escape_regexp_key];
256090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $escape_str = substr($part, $es_pos, $escape['length']);
256190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $escape_key = $escape['key'];
256290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
256390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Get the style for this escaped char ...
256490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (!$this->use_classes) {
256590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][$escape_key] . '"';
256690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
256790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $escape_char_attributes = ' class="es' . $escape_key . '"';
256890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
256990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
257090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Add the style for the escape char ...
257190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string .= "<span$escape_char_attributes>" .
257290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $this->hsc($escape_str) . '</span>';
257390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
257490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $start = $es_pos + $escape['length'];
257590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
257690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //Copy the remainder of the string ...
257790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string .= $this->hsc(substr($part, $start, $close_pos - $start + $char_len)) . '</span>';
257890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $start = $close_pos + $char_len;
257990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $string_open = false;
258090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
258190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } while($string_open);
258290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
258390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($check_linenumbers) {
258490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // Are line numbers used? If, we should end the string before
258590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // the newline and begin it again (so when <li>s are put in the source
258690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // remains XHTML compliant)
258790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // note to self: This opens up possibility of config files specifying
258890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // that languages can/cannot have multiline strings???
258990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
259090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
259190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
259290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $result .= $string;
259390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string = '';
259490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $i = $start - 1;
259590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        continue;
259690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else if ($this->lexic_permissions['STRINGS'] && $hq && $hq[0] == $char &&
259790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        substr($part, $i, $hq_strlen) == $hq) {
259890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // The start of a hard quoted string
259990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!$this->use_classes) {
260090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS']['HARD'] . '"';
260190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR']['HARD'] . '"';
260290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
260390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string_attributes = ' class="st_h"';
260490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $escape_char_attributes = ' class="es_h"';
260590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
260690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // parse the stuff before this
260790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $result .= $this->parse_non_string_part($stuff_to_parse);
260890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = '';
260990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
261090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // now handle the string
261190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string = '';
261290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
261390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // look for closing quote
261490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $start = $i + $hq_strlen;
261590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        while ($close_pos = strpos($part, $this->language_data['HARDQUOTE'][1], $start)) {
261690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $start = $close_pos + 1;
261790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($this->lexic_permissions['ESCAPE_CHAR'] && $part[$close_pos - 1] == $this->language_data['HARDCHAR']) {
261890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // make sure this quote is not escaped
261990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
262090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if (substr($part, $close_pos - 1, strlen($hardescape)) == $hardescape) {
262190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // check wether this quote is escaped or if it is something like '\\'
262290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $escape_char_pos = $close_pos - 1;
262390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        while ($escape_char_pos > 0
262490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                && $part[$escape_char_pos - 1] == $this->language_data['HARDCHAR']) {
262590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            --$escape_char_pos;
262690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
262790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if (($close_pos - $escape_char_pos) & 1) {
262890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            // uneven number of escape chars => this quote is escaped
262990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            continue 2;
263090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
263190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
263290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
263390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
263490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
263590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // found closing quote
263690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
263790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
263890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
263990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Found the closing delimiter?
264090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!$close_pos) {
264190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // span till the end of this $part when no closing delimiter is found
264290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $close_pos = $length;
264390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
264490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
264590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Get the actual string
264690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string = substr($part, $i, $close_pos - $i + 1);
264790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $i = $close_pos;
264890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
264990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // handle escape chars and encode html chars
265090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // (special because when we have escape chars within our string they may not be escaped)
265190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($this->lexic_permissions['ESCAPE_CHAR'] && $this->language_data['ESCAPE_CHAR']) {
265290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $start = 0;
265390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $new_string = '';
265490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            while ($es_pos = strpos($string, $this->language_data['ESCAPE_CHAR'], $start)) {
265590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // hmtl escape stuff before
265690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $new_string .= $this->hsc(substr($string, $start, $es_pos - $start));
265790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // check if this is a hard escape
265890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
265990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if (substr($string, $es_pos, strlen($hardescape)) == $hardescape) {
266090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // indeed, this is a hardescape
266190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $new_string .= "<span$escape_char_attributes>" .
266290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $this->hsc($hardescape) . '</span>';
266390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $start = $es_pos + strlen($hardescape);
266490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        continue 2;
266590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
266690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
266790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // not a hard escape, but a normal escape
266890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // they come in pairs of two
266990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $c = 0;
267090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                while (isset($string[$es_pos + $c]) && isset($string[$es_pos + $c + 1])
267190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    && $string[$es_pos + $c] == $this->language_data['ESCAPE_CHAR']
267290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    && $string[$es_pos + $c + 1] == $this->language_data['ESCAPE_CHAR']) {
267390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $c += 2;
267490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
267590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($c) {
267690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $new_string .= "<span$escape_char_attributes>" .
267790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        str_repeat($escaped_escape_char, $c) .
267890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        '</span>';
267990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $start = $es_pos + $c;
268090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
268190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // this is just a single lonely escape char...
268290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $new_string .= $escaped_escape_char;
268390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $start = $es_pos + 1;
268490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
268590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
268690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string = $new_string . $this->hsc(substr($string, $start));
268790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
268890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string = $this->hsc($string);
268990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
269090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
269190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($check_linenumbers) {
269290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // Are line numbers used? If, we should end the string before
269390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // the newline and begin it again (so when <li>s are put in the source
269490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // remains XHTML compliant)
269590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // note to self: This opens up possibility of config files specifying
269690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // that languages can/cannot have multiline strings???
269790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
269890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
269990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
270090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $result .= "<span$string_attributes>" . $string . '</span>';
270190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $string = '';
270290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        continue;
270390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
270490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Have a look for regexp comments
270590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($i == $next_comment_regexp_pos) {
270690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $COMMENT_MATCHED = true;
270790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $comment = $comment_regexp_cache_per_key[$next_comment_regexp_key];
270890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $test_str = $this->hsc(substr($part, $i, $comment['length']));
270990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
271090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            //@todo If remove important do remove here
271190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($this->lexic_permissions['COMMENTS']['MULTI']) {
271290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (!$this->use_classes) {
271390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment['key']] . '"';
271490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
271590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $attributes = ' class="co' . $comment['key'] . '"';
271690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
271790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
271890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $test_str = "<span$attributes>" . $test_str . "</span>";
271990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
272090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // Short-cut through all the multiline code
272190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($check_linenumbers) {
272290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // strreplace to put close span and open span around multiline newlines
272390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str = str_replace(
272490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        "\n", "</span>\n<span$attributes>",
272590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        str_replace("\n ", "\n&nbsp;", $test_str)
272690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    );
272790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
272890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
272990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
273090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $i += $comment['length'] - 1;
273190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
273290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // parse the rest
273390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $result .= $this->parse_non_string_part($stuff_to_parse);
273490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $stuff_to_parse = '';
273590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
273690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
273790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // If we haven't matched a regexp comment, try multi-line comments
273890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!$COMMENT_MATCHED) {
273990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // Is this a multiline comment?
274090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (!empty($this->language_data['COMMENT_MULTI']) && $next_comment_multi_pos < $i) {
274190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_comment_multi_pos = $length;
274290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                foreach ($this->language_data['COMMENT_MULTI'] as $open => $close) {
274390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $match_i = false;
274490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if (isset($comment_multi_cache_per_key[$open]) &&
274590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        ($comment_multi_cache_per_key[$open] >= $i ||
274690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                         $comment_multi_cache_per_key[$open] === false)) {
274790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // we have already matched something
274890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if ($comment_multi_cache_per_key[$open] === false) {
274990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            // this comment is never matched
275090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            continue;
275190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
275290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $match_i = $comment_multi_cache_per_key[$open];
275390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else if (($match_i = stripos($part, $open, $i)) !== false) {
275490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $comment_multi_cache_per_key[$open] = $match_i;
275590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else {
275690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $comment_multi_cache_per_key[$open] = false;
275790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        continue;
275890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
275990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($match_i !== false && $match_i < $next_comment_multi_pos) {
276090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $next_comment_multi_pos = $match_i;
276190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $next_open_comment_multi = $open;
276290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if ($match_i === $i) {
276390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            break;
276490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
276590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
276690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
276790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
276890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($i == $next_comment_multi_pos) {
276990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $open = $next_open_comment_multi;
277090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $close = $this->language_data['COMMENT_MULTI'][$open];
277190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $open_strlen = strlen($open);
277290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $close_strlen = strlen($close);
277390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $COMMENT_MATCHED = true;
277490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $test_str_match = $open;
277590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                //@todo If remove important do remove here
277690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
277790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $open == GESHI_START_IMPORTANT) {
277890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($open != GESHI_START_IMPORTANT) {
277990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if (!$this->use_classes) {
278090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS']['MULTI'] . '"';
278190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else {
278290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' class="coMULTI"';
278390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
278490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $test_str = "<span$attributes>" . $this->hsc($open);
278590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else {
278690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if (!$this->use_classes) {
278790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' style="' . $this->important_styles . '"';
278890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else {
278990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' class="imp"';
279090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
279190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
279290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // We don't include the start of the comment if it's an
279390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // "important" part
279490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $test_str = "<span$attributes>";
279590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
279690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
279790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str = $this->hsc($open);
279890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
279990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
280090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $close_pos = strpos( $part, $close, $i + $open_strlen );
280190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
280290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($close_pos === false) {
280390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $close_pos = $length;
280490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
280590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
280690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // Short-cut through all the multiline code
280790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $rest_of_comment = $this->hsc(substr($part, $i + $open_strlen, $close_pos - $i - $open_strlen + $close_strlen));
280890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (($this->lexic_permissions['COMMENTS']['MULTI'] ||
280990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str_match == GESHI_START_IMPORTANT) &&
281090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $check_linenumbers) {
281190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
281290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // strreplace to put close span and open span around multiline newlines
281390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str .= str_replace(
281490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        "\n", "</span>\n<span$attributes>",
281590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        str_replace("\n ", "\n&nbsp;", $rest_of_comment)
281690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    );
281790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
281890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str .= $rest_of_comment;
281990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
282090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
282190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
282290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str_match == GESHI_START_IMPORTANT) {
282390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str .= '</span>';
282490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
282590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
282690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $i = $close_pos + $close_strlen - 1;
282790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
282890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // parse the rest
282990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $result .= $this->parse_non_string_part($stuff_to_parse);
283090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $stuff_to_parse = '';
283190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
283290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
283390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
283490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // If we haven't matched a multiline comment, try single-line comments
283590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!$COMMENT_MATCHED) {
283690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // cache potential single line comment occurances
283790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (!empty($this->language_data['COMMENT_SINGLE']) && $next_comment_single_pos < $i) {
283890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $next_comment_single_pos = $length;
283990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                foreach ($this->language_data['COMMENT_SINGLE'] as $comment_key => $comment_mark) {
284090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $match_i = false;
284190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if (isset($comment_single_cache_per_key[$comment_key]) &&
284290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        ($comment_single_cache_per_key[$comment_key] >= $i ||
284390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                         $comment_single_cache_per_key[$comment_key] === false)) {
284490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // we have already matched something
284590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if ($comment_single_cache_per_key[$comment_key] === false) {
284690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            // this comment is never matched
284790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            continue;
284890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
284990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $match_i = $comment_single_cache_per_key[$comment_key];
285090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else if (
285190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // case sensitive comments
285290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        ($this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
285390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        ($match_i = stripos($part, $comment_mark, $i)) !== false) ||
285490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        // non case sensitive
285590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        (!$this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
285690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                          (($match_i = strpos($part, $comment_mark, $i)) !== false))) {
285790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $comment_single_cache_per_key[$comment_key] = $match_i;
285890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else {
285990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $comment_single_cache_per_key[$comment_key] = false;
286090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        continue;
286190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
286290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($match_i !== false && $match_i < $next_comment_single_pos) {
286390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $next_comment_single_pos = $match_i;
286490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $next_comment_single_key = $comment_key;
286590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if ($match_i === $i) {
286690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            break;
286790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
286890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
286990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
287090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
287190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($next_comment_single_pos == $i) {
287290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $comment_key = $next_comment_single_key;
287390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $comment_mark = $this->language_data['COMMENT_SINGLE'][$comment_key];
287490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $com_len = strlen($comment_mark);
287590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
287690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // This check will find special variables like $# in bash
287790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // or compiler directives of Delphi beginning {$
287890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if ((empty($sc_disallowed_before) || ($i == 0) ||
287990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    (false === strpos($sc_disallowed_before, $part[$i-1]))) &&
288090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    (empty($sc_disallowed_after) || ($length <= $i + $com_len) ||
288190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    (false === strpos($sc_disallowed_after, $part[$i + $com_len]))))
288290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                {
288390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // this is a valid comment
288490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $COMMENT_MATCHED = true;
288590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
288690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        if (!$this->use_classes) {
288790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment_key] . '"';
288890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        } else {
288990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                            $attributes = ' class="co' . $comment_key . '"';
289090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        }
289190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $test_str = "<span$attributes>" . $this->hsc($this->change_case($comment_mark));
289290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    } else {
289390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $test_str = $this->hsc($comment_mark);
289490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
289590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
289690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    //Check if this comment is the last in the source
289790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $close_pos = strpos($part, "\n", $i);
289890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $oops = false;
289990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($close_pos === false) {
290090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $close_pos = $length;
290190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $oops = true;
290290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
290390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $test_str .= $this->hsc(substr($part, $i + $com_len, $close_pos - $i - $com_len));
290490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
290590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                        $test_str .= "</span>";
290690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
290790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
290890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // Take into account that the comment might be the last in the source
290990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    if (!$oops) {
291090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                      $test_str .= "\n";
291190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    }
291290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
291390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $i = $close_pos;
291490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
291590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    // parse the rest
291690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $result .= $this->parse_non_string_part($stuff_to_parse);
291790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $stuff_to_parse = '';
291890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
291990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
292090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
292190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
292290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
292390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Where are we adding this char?
292490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$COMMENT_MATCHED) {
292590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse .= $char;
292690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
292790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $result .= $test_str;
292890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        unset($test_str);
292990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $COMMENT_MATCHED = false;
293090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
293190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
293290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Parse the last bit
293390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result .= $this->parse_non_string_part($stuff_to_parse);
293490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stuff_to_parse = '';
293590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
293690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result .= $this->hsc($part);
293790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
293890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Close the <span> that surrounds the block
293990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($STRICTATTRS != '') {
294090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result = str_replace("\n", "</span>\n<span$STRICTATTRS>", $result);
294190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result .= '</span>';
294290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
294390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
294490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $endresult .= $result;
294590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($part, $parts[$key], $result);
294690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
294790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
294890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //This fix is related to SF#1923020, but has to be applied regardless of
294990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //actually highlighting symbols.
295090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /** NOTE: memorypeak #3 */
295190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $endresult = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $endresult);
295290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
295390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        // Parse the last stuff (redundant?)
295490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        $result .= $this->parse_non_string_part($stuff_to_parse);
295590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
295690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Lop off the very first and last spaces
295790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        $result = substr($result, 1, -1);
295890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
295990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // We're finished: stop timing
296090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->set_time($start_time, microtime());
296190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
296290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->finalise($endresult);
296390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $endresult;
296490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
296590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
296690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
296790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Swaps out spaces and tabs for HTML indentation. Not needed if
296890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * the code is in a pre block...
296990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
297090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  string The source to indent (reference!)
297190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
297290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
297390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
297490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function indent(&$result) {
297590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /// Replace tabs with the correct number of spaces
297690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (false !== strpos($result, "\t")) {
297790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $lines = explode("\n", $result);
297890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $result = null;//Save memory while we process the lines individually
297990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $tab_width = $this->get_real_tab_width();
298090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $tab_string = '&nbsp;' . str_repeat(' ', $tab_width);
298190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
298290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for ($key = 0, $n = count($lines); $key < $n; $key++) {
298390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $line = $lines[$key];
298490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (false === strpos($line, "\t")) {
298590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    continue;
298690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
298790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
298890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $pos = 0;
298990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $length = strlen($line);
299090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $lines[$key] = ''; // reduce memory
299190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
299290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $IN_TAG = false;
299390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                for ($i = 0; $i < $length; ++$i) {
299490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $char = $line[$i];
299590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Simple engine to work out whether we're in a tag.
299690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // If we are we modify $pos. This is so we ignore HTML
299790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // in the line and only workout the tab replacement
299890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // via the actual content of the string
299990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // This test could be improved to include strings in the
300090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // html so that < or > would be allowed in user's styles
300190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // (e.g. quotes: '<' '>'; or similar)
300290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($IN_TAG) {
300390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ('>' == $char) {
300490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $IN_TAG = false;
300590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
300690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= $char;
300790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else if ('<' == $char) {
300890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $IN_TAG = true;
300990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= '<';
301090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else if ('&' == $char) {
301190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $substr = substr($line, $i + 3, 5);
301290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $posi = strpos($substr, ';');
301390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (false === $posi) {
301490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            ++$pos;
301590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
301690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $pos -= $posi+2;
301790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
301890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= $char;
301990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else if ("\t" == $char) {
302090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $str = '';
302190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // OPTIMISE - move $strs out. Make an array:
302290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // $tabs = array(
302390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //  1 => '&nbsp;',
302490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //  2 => '&nbsp; ',
302590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //  3 => '&nbsp; &nbsp;' etc etc
302690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // to use instead of building a string every time
302790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $tab_end_width = $tab_width - ($pos % $tab_width); //Moved out of the look as it doesn't change within the loop
302890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (($pos & 1) || 1 == $tab_end_width) {
302990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $str .= substr($tab_string, 6, $tab_end_width);
303090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
303190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $str .= substr($tab_string, 0, $tab_end_width+5);
303290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
303390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= $str;
303490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $pos += $tab_end_width;
303590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
303690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (false === strpos($line, "\t", $i + 1)) {
303790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $lines[$key] .= substr($line, $i + 1);
303890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
303990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
304090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else if (0 == $pos && ' ' == $char) {
304190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= '&nbsp;';
304290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        ++$pos;
304390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
304490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $lines[$key] .= $char;
304590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        ++$pos;
304690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
304790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
304890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
304990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $result = implode("\n", $lines);
305090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($lines);//We don't need the lines separated beyond this --- free them!
305190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
305290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Other whitespace
305390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // BenBE: Fix to reduce the number of replacements to be done
305490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $result = preg_replace('/^ /m', '&nbsp;', $result);
305590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $result = str_replace('  ', ' &nbsp;', $result);
305690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
305790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->line_numbers == GESHI_NO_LINE_NUMBERS) {
305890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->line_ending === null) {
305990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result = nl2br($result);
306090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
306190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $result = str_replace("\n", $this->line_ending, $result);
306290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
306390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
306490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
306590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
306690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
306790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Changes the case of a keyword for those languages where a change is asked for
306890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
306990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  string The keyword to change the case of
307090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The keyword with its case changed
307190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
307290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
307390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
307490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function change_case($instr) {
307590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        switch ($this->language_data['CASE_KEYWORDS']) {
307690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            case GESHI_CAPS_UPPER:
307790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return strtoupper($instr);
307890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            case GESHI_CAPS_LOWER:
307990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return strtolower($instr);
308090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            default:
308190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return $instr;
308290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
308390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
308490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
308590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
308690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Handles replacements of keywords to include markup and links if requested
308790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
308890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  string The keyword to add the Markup to
308990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return The HTML for the match found
309090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.8
309190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
309290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
309390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo   Get rid of ender in keyword links
309490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
309590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function handle_keyword_replace($match) {
309690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $k = $this->_kw_replace_group;
309790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keyword = $match[0];
309890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
309990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $before = '';
310090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $after = '';
310190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
310290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->keyword_links) {
310390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Keyword links have been ebabled
310490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
310590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($this->language_data['URLS'][$k]) &&
310690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['URLS'][$k] != '') {
310790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // There is a base group for this keyword
310890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
310990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Old system: strtolower
311090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //$keyword = ( $this->language_data['CASE_SENSITIVE'][$group] ) ? $keyword : strtolower($keyword);
311190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // New system: get keyword from language file to get correct case
311290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (!$this->language_data['CASE_SENSITIVE'][$k] &&
311390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    strpos($this->language_data['URLS'][$k], '{FNAME}') !== false) {
311490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    foreach ($this->language_data['KEYWORDS'][$k] as $word) {
311590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (strcasecmp($word, $keyword) == 0) {
311690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            break;
311790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
311890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
311990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
312090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $word = $keyword;
312190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
312290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
312390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $before = '<|UR1|"' .
312490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    str_replace(
312590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        array(
312690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '{FNAME}',
312790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '{FNAMEL}',
312890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '{FNAMEU}',
312990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '.'),
313090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        array(
313190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            str_replace('+', '%20', urlencode($this->hsc($word))),
313290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            str_replace('+', '%20', urlencode($this->hsc(strtolower($word)))),
313390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            str_replace('+', '%20', urlencode($this->hsc(strtoupper($word)))),
313490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '<DOT>'),
313590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->language_data['URLS'][$k]
313690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ) . '">';
313790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $after = '</a>';
313890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
313990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
314090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
314190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $before . '<|/'. $k .'/>' . $this->change_case($keyword) . '|>' . $after;
314290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
314390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
314490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
314590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * handles regular expressions highlighting-definitions with callback functions
314690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
314790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @note this is a callback, don't use it directly
314890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
314990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param array the matches array
315090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return The highlighted string
315190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
315290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
315390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
315490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function handle_regexps_callback($matches) {
315590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // before: "' style=\"' . call_user_func(\"$func\", '\\1') . '\"\\1|>'",
315690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return  ' style="' . call_user_func($this->language_data['STYLES']['REGEXPS'][$this->_rx_key], $matches[1]) . '"'. $matches[1] . '|>';
315790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
315890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
315990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
316090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * handles newlines in REGEXPS matches. Set the _hmr_* vars before calling this
316190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
316290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @note this is a callback, don't use it directly
316390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
316490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param array the matches array
316590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string
316690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
316790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
316890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
316990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function handle_multiline_regexps($matches) {
317090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $before = $this->_hmr_before;
317190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $after = $this->_hmr_after;
317290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->_hmr_replace) {
317390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $replace = $this->_hmr_replace;
317490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $search = array();
317590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
317690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach (array_keys($matches) as $k) {
317790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $search[] = '\\' . $k;
317890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
317990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
318090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $before = str_replace($search, $matches, $before);
318190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $after = str_replace($search, $matches, $after);
318290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $replace = str_replace($search, $matches, $replace);
318390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
318490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $replace = $matches[0];
318590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
318690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $before
318790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    . '<|!REG3XP' . $this->_hmr_key .'!>'
318890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        . str_replace("\n", "|>\n<|!REG3XP" . $this->_hmr_key . '!>', $replace)
318990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    . '|>'
319090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber              . $after;
319190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
319290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
319390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
319490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Takes a string that has no strings or comments in it, and highlights
319590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * stuff like keywords, numbers and methods.
319690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
319790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The string to parse for keyword, numbers etc.
319890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
319990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
320090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo BUGGY! Why? Why not build string and return?
320190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
320290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function parse_non_string_part($stuff_to_parse) {
320390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stuff_to_parse = ' ' . $this->hsc($stuff_to_parse);
320490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
320590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Regular expressions
320690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['REGEXPS'] as $key => $regexp) {
320790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->lexic_permissions['REGEXPS'][$key]) {
320890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_array($regexp)) {
320990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
321090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // produce valid HTML when we match multiple lines
321190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_replace = $regexp[GESHI_REPLACE];
321290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_before = $regexp[GESHI_BEFORE];
321390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_key = $key;
321490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_after = $regexp[GESHI_AFTER];
321590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = preg_replace_callback(
321690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            "/" . $regexp[GESHI_SEARCH] . "/{$regexp[GESHI_MODIFIERS]}",
321790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            array($this, 'handle_multiline_regexps'),
321890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $stuff_to_parse);
321990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_replace = false;
322090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_before = '';
322190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_after = '';
322290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
322390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = preg_replace(
322490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            '/' . $regexp[GESHI_SEARCH] . '/' . $regexp[GESHI_MODIFIERS],
322590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $regexp[GESHI_BEFORE] . '<|!REG3XP'. $key .'!>' . $regexp[GESHI_REPLACE] . '|>' . $regexp[GESHI_AFTER],
322690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $stuff_to_parse);
322790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
322890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
322990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
323090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // produce valid HTML when we match multiple lines
323190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_key = $key;
323290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = preg_replace_callback( "/(" . $regexp . ")/",
323390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                              array($this, 'handle_multiline_regexps'), $stuff_to_parse);
323490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->_hmr_key = '';
323590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
323690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse = preg_replace( "/(" . $regexp . ")/", "<|!REG3XP$key!>\\1|>", $stuff_to_parse);
323790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
323890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
323990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
324090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
324190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
324290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Highlight numbers. As of 1.0.8 we support diffent types of numbers
324390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $numbers_found = false;
324490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['NUMBERS'] && preg_match('#\d#', $stuff_to_parse )) {
324590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $numbers_found = true;
324690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
324790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //For each of the formats ...
324890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
324990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Check if it should be highlighted ...
325090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stuff_to_parse = preg_replace($regexp, "<|/NUM!$id/>\\1|>", $stuff_to_parse);
325190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
325290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
325390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
325490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Highlight keywords
325590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $disallowed_before = "(?<![a-zA-Z0-9\$_\|\#;>|^&";
325690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
325790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['STRINGS']) {
325890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $quotemarks = preg_quote(implode($this->language_data['QUOTEMARKS']), '/');
325990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $disallowed_before .= $quotemarks;
326090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $disallowed_after .= $quotemarks;
326190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
326290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $disallowed_before .= "])";
326390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $disallowed_after .= "])";
326490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
326590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $parser_control_pergroup = false;
326690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (isset($this->language_data['PARSER_CONTROL'])) {
326790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
326890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $x = 0; // check wether per-keyword-group parser_control is enabled
326990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
327090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $disallowed_before = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
327190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ++$x;
327290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
327390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
327490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $disallowed_after = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
327590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ++$x;
327690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
327790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parser_control_pergroup = (count($this->language_data['PARSER_CONTROL']['KEYWORDS']) - $x) > 0;
327890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
327990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
328090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
328190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // if this is changed, don't forget to change it below
328290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        if (!empty($disallowed_before)) {
328390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//            $disallowed_before = "(?<![$disallowed_before])";
328490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        }
328590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        if (!empty($disallowed_after)) {
328690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//            $disallowed_after = "(?![$disallowed_after])";
328790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//        }
328890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
328990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
329090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!isset($this->lexic_permissions['KEYWORDS'][$k]) ||
329190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['KEYWORDS'][$k]) {
329290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
329390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $case_sensitive = $this->language_data['CASE_SENSITIVE'][$k];
329490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $modifiers = $case_sensitive ? '' : 'i';
329590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
329690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // NEW in 1.0.8 - per-keyword-group parser control
329790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $disallowed_before_local = $disallowed_before;
329890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $disallowed_after_local = $disallowed_after;
329990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($parser_control_pergroup && isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k])) {
330090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'])) {
330190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $disallowed_before_local =
330290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'];
330390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
330490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
330590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'])) {
330690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $disallowed_after_local =
330790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'];
330890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
330990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
331090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
331190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->_kw_replace_group = $k;
331290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
331390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //NEW in 1.0.8, the cached regexp list
331490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // since we don't want PHP / PCRE to crash due to too large patterns we split them into smaller chunks
331590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                for ($set = 0, $set_length = count($this->language_data['CACHED_KEYWORD_LISTS'][$k]); $set <  $set_length; ++$set) {
331690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $keywordset =& $this->language_data['CACHED_KEYWORD_LISTS'][$k][$set];
331790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Might make a more unique string for putting the number in soon
331890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Basically, we don't put the styles in yet because then the styles themselves will
331990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // get highlighted if the language has a CSS keyword in it (like CSS, for example ;))
332090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stuff_to_parse = preg_replace_callback(
332190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        "/$disallowed_before_local({$keywordset})(?!\<DOT\>(?:htm|php))$disallowed_after_local/$modifiers",
332290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        array($this, 'handle_keyword_replace'),
332390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse
332490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        );
332590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
332690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
332790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
332890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
332990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
333090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Now that's all done, replace /[number]/ with the correct styles
333190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
333290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
333390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!$this->use_classes) {
333490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attributes = ' style="' .
333590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    (isset($this->language_data['STYLES']['KEYWORDS'][$k]) ?
333690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->language_data['STYLES']['KEYWORDS'][$k] : "") . '"';
333790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
333890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attributes = ' class="kw' . $k . '"';
333990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
334090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stuff_to_parse = str_replace("<|/$k/>", "<|$attributes>", $stuff_to_parse);
334190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
334290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
334390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($numbers_found) {
334490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Put number styles in
334590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
334690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//Commented out for now, as this needs some review ...
334790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                if ($numbers_permissions & $id) {
334890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Get the appropriate style ...
334990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Checking for unset styles is done by the style cache builder ...
335090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$this->use_classes) {
335190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' style="' . $this->language_data['STYLES']['NUMBERS'][$id] . '"';
335290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
335390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' class="nu'.$id.'"';
335490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
335590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
335690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Set in the correct styles ...
335790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stuff_to_parse = str_replace("/NUM!$id/", $attributes, $stuff_to_parse);
335890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//                }
335990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
336090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
336190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
336290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Highlight methods and fields in objects
336390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['METHODS'] && $this->language_data['OOLANG']) {
336490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $oolang_spaces = "[\s]*";
336590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $oolang_before = "";
336690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $oolang_after = "[a-zA-Z][a-zA-Z0-9_]*";
336790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($this->language_data['PARSER_CONTROL'])) {
336890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($this->language_data['PARSER_CONTROL']['OOLANG'])) {
336990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'])) {
337090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $oolang_before = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'];
337190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
337290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'])) {
337390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $oolang_after = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'];
337490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
337590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'])) {
337690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $oolang_spaces = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'];
337790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
337890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
337990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
338090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
338190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($this->language_data['OBJECT_SPLITTERS'] as $key => $splitter) {
338290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (false !== strpos($stuff_to_parse, $splitter)) {
338390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$this->use_classes) {
338490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' style="' . $this->language_data['STYLES']['METHODS'][$key] . '"';
338590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
338690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' class="me' . $key . '"';
338790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
338890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $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);
338990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
339090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
339190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
339290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
339390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
339490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Highlight brackets. Yes, I've tried adding a semi-colon to this list.
339590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // You try it, and see what happens ;)
339690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // TODO: Fix lexic permissions not converting entities if shouldn't
339790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // be highlighting regardless
339890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
339990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['BRACKETS']) {
340090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stuff_to_parse = str_replace( $this->language_data['CACHE_BRACKET_MATCH'],
340190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                              $this->language_data['CACHE_BRACKET_REPLACE'], $stuff_to_parse );
340290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
340390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
340490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
340590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //FIX for symbol highlighting ...
340690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
340790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Get all matches and throw away those witin a block that is already highlighted... (i.e. matched by a regexp)
340890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $n_symbols = preg_match_all("/<\|(?:<DOT>|[^>])+>(?:(?!\|>).*?)\|>|<\/a>|(?:" . $this->language_data['SYMBOL_SEARCH'] . ")+/", $stuff_to_parse, $pot_symbols, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
340990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $global_offset = 0;
341090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for ($s_id = 0; $s_id < $n_symbols; ++$s_id) {
341190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_match = $pot_symbols[$s_id][0][0];
341290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (strpos($symbol_match, '<') !== false || strpos($symbol_match, '>') !== false) {
341390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // already highlighted blocks _must_ include either < or >
341490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // so if this conditional applies, we have to skip this match
341590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // BenBE: UNLESS the block contains <SEMI> or <PIPE>
341690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if(strpos($symbol_match, '<SEMI>') === false &&
341790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        strpos($symbol_match, '<PIPE>') === false) {
341890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        continue;
341990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
342090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
342190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
342290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // if we reach this point, we have a valid match which needs to be highlighted
342390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
342490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_length = strlen($symbol_match);
342590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_offset = $pot_symbols[$s_id][0][1];
342690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($pot_symbols[$s_id]);
342790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_end = $symbol_length + $symbol_offset;
342890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $symbol_hl = "";
342990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
343090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // if we have multiple styles, we have to handle them properly
343190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->language_data['MULTIPLE_SYMBOL_GROUPS']) {
343290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $old_sym = -1;
343390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Split the current stuff to replace into its atomic symbols ...
343490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    preg_match_all("/" . $this->language_data['SYMBOL_SEARCH'] . "/", $symbol_match, $sym_match_syms, PREG_PATTERN_ORDER);
343590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    foreach ($sym_match_syms[0] as $sym_ms) {
343690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Check if consequtive symbols belong to the same group to save output ...
343790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (isset($this->language_data['SYMBOL_DATA'][$sym_ms])
343890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            && ($this->language_data['SYMBOL_DATA'][$sym_ms] != $old_sym)) {
343990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (-1 != $old_sym) {
344090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $symbol_hl .= "|>";
344190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
344290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $old_sym = $this->language_data['SYMBOL_DATA'][$sym_ms];
344390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (!$this->use_classes) {
344490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $symbol_hl .= '<| style="' . $this->language_data['STYLES']['SYMBOLS'][$old_sym] . '">';
344590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
344690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $symbol_hl .= '<| class="sy' . $old_sym . '">';
344790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
344890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
344990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $symbol_hl .= $sym_ms;
345090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
345190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    unset($sym_match_syms);
345290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
345390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Close remaining tags and insert the replacement at the right position ...
345490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //Take caution if symbol_hl is empty to avoid doubled closing spans.
345590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (-1 != $old_sym) {
345690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $symbol_hl .= "|>";
345790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
345890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
345990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$this->use_classes) {
346090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $symbol_hl = '<| style="' . $this->language_data['STYLES']['SYMBOLS'][0] . '">';
346190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
346290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $symbol_hl = '<| class="sy0">';
346390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
346490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $symbol_hl .= $symbol_match . '|>';
346590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
346690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
346790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stuff_to_parse = substr_replace($stuff_to_parse, $symbol_hl, $symbol_offset + $global_offset, $symbol_length);
346890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
346990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // since we replace old text with something of different size,
347090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // we'll have to keep track of the differences
347190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $global_offset += strlen($symbol_hl) - $symbol_length;
347290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
347390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
347490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //FIX for symbol highlighting ...
347590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
347690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Add class/style for regexps
347790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['REGEXPS']) as $key) {
347890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->lexic_permissions['REGEXPS'][$key]) {
347990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_callable($this->language_data['STYLES']['REGEXPS'][$key])) {
348090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->_rx_key = $key;
348190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stuff_to_parse = preg_replace_callback("/!REG3XP$key!(.*)\|>/U",
348290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        array($this, 'handle_regexps_callback'),
348390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stuff_to_parse);
348490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
348590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (!$this->use_classes) {
348690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attributes = ' style="' . $this->language_data['STYLES']['REGEXPS'][$key] . '"';
348790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
348890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (is_array($this->language_data['REGEXPS'][$key]) &&
348990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$key])) {
349090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $attributes = ' class="' .
349190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $this->language_data['REGEXPS'][$key][GESHI_CLASS] . '"';
349290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
349390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                           $attributes = ' class="re' . $key . '"';
349490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
349590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
349690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stuff_to_parse = str_replace("!REG3XP$key!", "$attributes", $stuff_to_parse);
349790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
349890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
349990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
350090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
350190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Replace <DOT> with . for urls
350290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stuff_to_parse = str_replace('<DOT>', '.', $stuff_to_parse);
350390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Replace <|UR1| with <a href= for urls also
350490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (isset($this->link_styles[GESHI_LINK])) {
350590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->use_classes) {
350690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
350790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
350890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' style="' . $this->link_styles[GESHI_LINK] . '" href=', $stuff_to_parse);
350990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
351090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
351190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
351290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
351390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
351490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
351590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // NOW we add the span thingy ;)
351690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //
351790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
351890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stuff_to_parse = str_replace('<|', '<span', $stuff_to_parse);
351990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stuff_to_parse = str_replace ( '|>', '</span>', $stuff_to_parse );
352090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return substr($stuff_to_parse, 1);
352190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
352290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
352390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
352490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Sets the time taken to parse the code
352590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
352690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param microtime The time when parsing started
352790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param microtime The time when parsing ended
352890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
352990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
353090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
353190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function set_time($start_time, $end_time) {
353290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $start = explode(' ', $start_time);
353390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $end = explode(' ', $end_time);
353490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->time = $end[0] + $end[1] - $start[0] - $start[1];
353590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
353690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
353790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
353890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Gets the time taken to parse the code
353990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
354090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return double The time taken to parse the code
354190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.2
354290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
354390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_time() {
354490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $this->time;
354590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
354690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
354790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
354890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Merges arrays recursively, overwriting values of the first array with values of later arrays
354990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
355090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.8
355190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
355290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
355390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function merge_arrays() {
355490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $arrays = func_get_args();
355590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $narrays = count($arrays);
355690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
355790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // check arguments
355890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
355990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for ($i = 0; $i < $narrays; $i ++) {
356090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!is_array($arrays[$i])) {
356190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // also array_merge_recursive returns nothing in this case
356290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning false!', E_USER_WARNING);
356390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return false;
356490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
356590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
356690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
356790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // the first array is in the output set in every case
356890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $ret = $arrays[0];
356990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
357090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // merege $ret with the remaining arrays
357190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for ($i = 1; $i < $narrays; $i ++) {
357290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($arrays[$i] as $key => $value) {
357390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_array($value) && isset($ret[$key])) {
357490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
357590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be false.
357690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $ret[$key] = $this->merge_arrays($ret[$key], $value);
357790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
357890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $ret[$key] = $value;
357990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
358090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
358190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
358290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
358390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $ret;
358490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
358590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
358690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
358790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Gets language information and stores it for later use
358890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
358990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The filename of the language file you want to load
359090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.0
359190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
359290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @todo Needs to load keys for lexic permissions for keywords, regexps etc
359390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
359490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function load_language($file_name) {
359590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($file_name == $this->loaded_language) {
359690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // this file is already loaded!
359790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return;
359890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
359990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
360090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Prepare some stuff before actually loading the language file
360190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->loaded_language = $file_name;
360290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->parse_cache_built = false;
360390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->enable_highlighting();
360490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $language_data = array();
360590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
360690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Load the language file
360790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        require $file_name;
360890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
360990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Perhaps some checking might be added here later to check that
361090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // $language data is a valid thing but maybe not
361190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->language_data = $language_data;
361290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
361390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Set strict mode if should be set
361490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $this->strict_mode = $this->language_data['STRICT_MODE_APPLIES'];
361590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
361690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Set permissions for all lexics to true
361790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // so they'll be highlighted by default
361890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
361990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!empty($this->language_data['KEYWORDS'][$key])) {
362090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['KEYWORDS'][$key] = true;
362190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
362290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['KEYWORDS'][$key] = false;
362390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
362490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
362590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
362690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['COMMENT_SINGLE']) as $key) {
362790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->lexic_permissions['COMMENTS'][$key] = true;
362890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
362990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach (array_keys($this->language_data['REGEXPS']) as $key) {
363090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->lexic_permissions['REGEXPS'][$key] = true;
363190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
363290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
363390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // for BenBE and future code reviews:
363490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // we can use empty here since we only check for existance and emptiness of an array
363590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // if it is not an array at all but rather false or null this will work as intended as well
363690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // even if $this->language_data['PARSER_CONTROL'] is undefined this won't trigger a notice
363790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!empty($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'])) {
363890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            foreach ($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'] as $flag => $value) {
363990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // it's either true or false and maybe is true as well
364090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $perm = $value !== GESHI_NEVER;
364190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($flag == 'ALL') {
364290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->enable_highlighting($perm);
364390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    continue;
364490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
364590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (!isset($this->lexic_permissions[$flag])) {
364690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // unknown lexic permission
364790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    continue;
364890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
364990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_array($this->lexic_permissions[$flag])) {
365090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    foreach ($this->lexic_permissions[$flag] as $key => $val) {
365190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $this->lexic_permissions[$flag][$key] = $perm;
365290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
365390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
365490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->lexic_permissions[$flag] = $perm;
365590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
365690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
365790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS']);
365890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
365990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
366090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Fix: Problem where hardescapes weren't handled if no ESCAPE_CHAR was given
366190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //You need to set one for HARDESCAPES only in this case.
366290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(!isset($this->language_data['HARDCHAR'])) {
366390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->language_data['HARDCHAR'] = $this->language_data['ESCAPE_CHAR'];
366490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
366590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
366690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //NEW in 1.0.8: Allow styles to be loaded from a separate file to override defaults
366790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $style_filename = substr($file_name, 0, -4) . '.style.php';
366890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (is_readable($style_filename)) {
366990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Clear any style_data that could have been set before ...
367090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($style_data)) {
367190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($style_data);
367290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
367390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
367490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Read the Style Information from the style file
367590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            include $style_filename;
367690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
367790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Apply the new styles to our current language styles
367890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (isset($style_data) && is_array($style_data)) {
367990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->language_data['STYLES'] =
368090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $this->merge_arrays($this->language_data['STYLES'], $style_data);
368190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
368290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
368390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
368490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
368590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
368690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Takes the parsed code and various options, and creates the HTML
368790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * surrounding it to make it look nice.
368890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
368990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  string The code already parsed (reference!)
369090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
369190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
369290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
369390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function finalise(&$parsed_code) {
369490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Remove end parts of important declarations
369590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // This is BUGGY!! My fault for bad code: fix coming in 1.2
369690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // @todo Remove this crap
369790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->enable_important_blocks &&
369890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            (strpos($parsed_code, $this->hsc(GESHI_START_IMPORTANT)) === false)) {
369990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $parsed_code = str_replace($this->hsc(GESHI_END_IMPORTANT), '', $parsed_code);
370090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
370190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
370290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Add HTML whitespace stuff if we're using the <div> header
370390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) {
370490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->indent($parsed_code);
370590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
370690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
370790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // purge some unnecessary stuff
370890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /** NOTE: memorypeak #1 */
370990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $parsed_code = preg_replace('#<span[^>]+>(\s*)</span>#', '\\1', $parsed_code);
371090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
371190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // If we are using IDs for line numbers, there needs to be an overall
371290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // ID set to prevent collisions.
371390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->add_ids && !$this->overall_id) {
371490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->overall_id = 'geshi-' . substr(md5(microtime()), 0, 4);
371590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
371690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
371790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Get code into lines
371890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /** NOTE: memorypeak #2 */
371990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $code = explode("\n", $parsed_code);
372090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $parsed_code = $this->header();
372190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
372290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // If we're using line numbers, we insert <li>s and appropriate
372390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // markup to style them (otherwise we don't need to do anything)
372490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->line_numbers != GESHI_NO_LINE_NUMBERS && $this->header_type != GESHI_HEADER_PRE_TABLE) {
372590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // If we're using the <pre> header, we shouldn't add newlines because
372690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // the <pre> will line-break them (and the <li>s already do this for us)
372790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $ls = ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) ? "\n" : '';
372890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
372990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Set vars to defaults for following loop
373090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $i = 0;
373190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
373290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Foreach line...
373390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for ($i = 0, $n = count($code); $i < $n;) {
373490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Reset the attributes for a new line ...
373590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attrs = array();
373690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
373790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Make lines have at least one space in them if they're empty
373890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // BenBE: Checking emptiness using trim instead of relying on blanks
373990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ('' == trim($code[$i])) {
374090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $code[$i] = '&nbsp;';
374190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
374290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
374390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // If this is a "special line"...
374490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
374590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
374690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Set the attributes to style the line
374790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
374890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //$attr = ' class="li2"';
374990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs['class'][] = 'li2';
375090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $def_attr = ' class="de2"';
375190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
375290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //$attr = ' style="' . $this->line_style2 . '"';
375390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs['style'][] = $this->line_style2;
375490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // This style "covers up" the special styles set for special lines
375590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // so that styles applied to special lines don't apply to the actual
375690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // code on that line
375790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $def_attr = ' style="' . $this->code_style . '"';
375890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
375990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
376090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
376190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //$attr = ' class="li1"';
376290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs['class'][] = 'li1';
376390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $def_attr = ' class="de1"';
376490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
376590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //$attr = ' style="' . $this->line_style1 . '"';
376690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs['style'][] = $this->line_style1;
376790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $def_attr = ' style="' . $this->code_style . '"';
376890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
376990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
377090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
377190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Check which type of tag to insert for this line
377290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->header_type == GESHI_HEADER_PRE_VALID) {
377390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $start = "<pre$def_attr>";
377490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $end = '</pre>';
377590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
377690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Span or div?
377790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $start = "<div$def_attr>";
377890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $end = '</div>';
377990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
378090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
378190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                ++$i;
378290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
378390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Are we supposed to use ids? If so, add them
378490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->add_ids) {
378590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $attrs['id'][] = "$this->overall_id-$i";
378690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
378790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
378890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Is this some line with extra styles???
378990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (in_array($i, $this->highlight_extra_lines)) {
379090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
379190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (isset($this->highlight_extra_lines_styles[$i])) {
379290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $attrs['class'][] = "lx$i";
379390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
379490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $attrs['class'][] = "ln-xtra";
379590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
379690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
379790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        array_push($attrs['style'], $this->get_line_style($i));
379890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
379990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
380090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
380190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Add in the line surrounded by appropriate list HTML
380290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attr_string = '';
380390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                foreach ($attrs as $key => $attr) {
380490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $attr_string .= ' ' . $key . '="' . implode(' ', $attr) . '"';
380590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
380690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
380790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= "<li$attr_string>$start{$code[$i-1]}$end</li>$ls";
380890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($code[$i - 1]);
380990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
381090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
381190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $n = count($code);
381290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->use_classes) {
381390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attributes = ' class="de1"';
381490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
381590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attributes = ' style="'. $this->code_style .'"';
381690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
381790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE_VALID) {
381890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= '<pre'. $attributes .'>';
381990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
382090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
382190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
382290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs = ' class="ln"';
382390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
382490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $attrs = ' style="'. $this->table_linenumber_style .'"';
382590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
382690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $parsed_code .= '<td'.$attrs.'><pre'.$attributes.'>';
382790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // get linenumbers
382890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // we don't merge it with the for below, since it should be better for
382990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // memory consumption this way
383090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // @todo: but... actually it would still be somewhat nice to merge the two loops
383190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    //        the mem peaks are at different positions
383290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    for ($i = 0; $i < $n; ++$i) {
383390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $close = 0;
383490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // fancy lines
383590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
383690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
383790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // Set the attributes to style the line
383890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($this->use_classes) {
383990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $parsed_code .= '<span class="xtra li2"><span class="de2">';
384090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
384190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // This style "covers up" the special styles set for special lines
384290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // so that styles applied to special lines don't apply to the actual
384390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // code on that line
384490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
384590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                                  .'<span style="' . $this->code_style .'">';
384690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
384790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $close += 2;
384890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
384990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        //Is this some line with extra styles???
385090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (in_array($i + 1, $this->highlight_extra_lines)) {
385190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if ($this->use_classes) {
385290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                if (isset($this->highlight_extra_lines_styles[$i])) {
385390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $parsed_code .= "<span class=\"xtra lx$i\">";
385490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                } else {
385590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                    $parsed_code .= "<span class=\"xtra ln-xtra\">";
385690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                }
385790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
385890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
385990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
386090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            ++$close;
386190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
386290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $parsed_code .= $this->line_numbers_start + $i;
386390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($close) {
386490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $parsed_code .= str_repeat('</span>', $close);
386590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else if ($i != $n) {
386690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $parsed_code .= "\n";
386790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
386890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
386990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $parsed_code .= '</pre></td><td'.$attributes.'>';
387090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
387190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= '<pre'. $attributes .'>';
387290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
387390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // No line numbers, but still need to handle highlighting lines extra.
387490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // Have to use divs so the full width of the code is highlighted
387590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $close = 0;
387690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            for ($i = 0; $i < $n; ++$i) {
387790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // Make lines have at least one space in them if they're empty
387890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // BenBE: Checking emptiness using trim instead of relying on blanks
387990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ('' == trim($code[$i])) {
388090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $code[$i] = '&nbsp;';
388190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
388290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // fancy lines
388390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
388490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
388590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // Set the attributes to style the line
388690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
388790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $parsed_code .= '<span class="xtra li2"><span class="de2">';
388890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
388990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // This style "covers up" the special styles set for special lines
389090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // so that styles applied to special lines don't apply to the actual
389190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // code on that line
389290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
389390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                          .'<span style="' . $this->code_style .'">';
389490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
389590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $close += 2;
389690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
389790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                //Is this some line with extra styles???
389890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (in_array($i + 1, $this->highlight_extra_lines)) {
389990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($this->use_classes) {
390090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (isset($this->highlight_extra_lines_styles[$i])) {
390190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $parsed_code .= "<span class=\"xtra lx$i\">";
390290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
390390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $parsed_code .= "<span class=\"xtra ln-xtra\">";
390490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
390590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
390690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
390790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
390890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ++$close;
390990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
391090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
391190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= $code[$i];
391290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
391390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($close) {
391490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  $parsed_code .= str_repeat('</span>', $close);
391590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                  $close = 0;
391690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
391790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                elseif ($i + 1 < $n) {
391890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $parsed_code .= "\n";
391990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
392090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($code[$i]);
392190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
392290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
392390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE_VALID || $this->header_type == GESHI_HEADER_PRE_TABLE) {
392490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= '</pre>';
392590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
392690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
392790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $parsed_code .= '</td>';
392890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
392990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
393090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
393190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $parsed_code .= $this->footer();
393290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
393390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
393490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
393590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Creates the header for the code block (with correct attributes)
393690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
393790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The header for the code block
393890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
393990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
394090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
394190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function header() {
394290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Get attributes needed
394390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        /**
394490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         * @todo   Document behaviour change - class is outputted regardless of whether
394590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         *         we're using classes or not. Same with style
394690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber         */
394790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $attributes = ' class="' . $this->language;
394890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->overall_class != '') {
394990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $attributes .= " ".$this->overall_class;
395090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
395190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $attributes .= '"';
395290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
395390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->overall_id != '') {
395490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $attributes .= " id=\"{$this->overall_id}\"";
395590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
395690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->overall_style != '') {
395790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $attributes .= ' style="' . $this->overall_style . '"';
395890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
395990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
396090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $ol_attributes = '';
396190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
396290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->line_numbers_start != 1) {
396390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $ol_attributes .= ' start="' . $this->line_numbers_start . '"';
396490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
396590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
396690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Get the header HTML
396790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $header = $this->header_content;
396890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($header) {
396990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE || $this->header_type == GESHI_HEADER_PRE_VALID) {
397090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $header = str_replace("\n", '', $header);
397190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
397290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $header = $this->replace_keywords($header);
397390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
397490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->use_classes) {
397590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attr = ' class="head"';
397690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
397790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attr = " style=\"{$this->header_content_style}\"";
397890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
397990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
398090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $header = "<thead><tr><td colspan=\"2\" $attr>$header</td></tr></thead>";
398190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
398290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $header = "<div$attr>$header</div>";
398390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
398490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
398590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
398690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_HEADER_NONE == $this->header_type) {
398790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
398890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "$header<ol$attributes$ol_attributes>";
398990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
399090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return $header . ($this->force_code_block ? '<div>' : '');
399190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
399290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
399390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Work out what to return and do it
399490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
399590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE) {
399690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "<pre$attributes>$header<ol$ol_attributes>";
399790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else if ($this->header_type == GESHI_HEADER_DIV ||
399890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->header_type == GESHI_HEADER_PRE_VALID) {
399990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "<div$attributes>$header<ol$ol_attributes>";
400090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else if ($this->header_type == GESHI_HEADER_PRE_TABLE) {
400190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "<table$attributes>$header<tbody><tr class=\"li1\">";
400290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
400390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
400490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE) {
400590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "<pre$attributes>$header"  .
400690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ($this->force_code_block ? '<div>' : '');
400790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
400890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "<div$attributes>$header" .
400990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    ($this->force_code_block ? '<div>' : '');
401090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
401190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
401290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
401390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
401490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
401590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Returns the footer for the code block.
401690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
401790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The footer for the code block
401890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
401990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
402090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
402190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function footer() {
402290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $footer = $this->footer_content;
402390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($footer) {
402490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE) {
402590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $footer = str_replace("\n", '', $footer);;
402690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
402790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $footer = $this->replace_keywords($footer);
402890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
402990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->use_classes) {
403090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attr = ' class="foot"';
403190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
403290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $attr = " style=\"{$this->footer_content_style}\"";
403390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
403490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
403590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $footer = "<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
403690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
403790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $footer = "<div$attr>$footer</div>";
403890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
403990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
404090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
404190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_HEADER_NONE == $this->header_type) {
404290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return ($this->line_numbers != GESHI_NO_LINE_NUMBERS) ? '</ol>' . $footer : $footer;
404390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
404490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
404590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->header_type == GESHI_HEADER_DIV || $this->header_type == GESHI_HEADER_PRE_VALID) {
404690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
404790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "</ol>$footer</div>";
404890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
404990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return ($this->force_code_block ? '</div>' : '') .
405090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                "$footer</div>";
405190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
405290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
405390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
405490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "</tr></tbody>$footer</table>";
405590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
405690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return ($this->force_code_block ? '</div>' : '') .
405790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                "$footer</div>";
405890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
405990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else {
406090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
406190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                return "</ol>$footer</pre>";
406290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
406390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return ($this->force_code_block ? '</div>' : '') .
406490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                "$footer</pre>";
406590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
406690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
406790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
406890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
406990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Replaces certain keywords in the header and footer with
407090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * certain configuration values
407190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
407290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  string The header or footer content to do replacement on
407390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The header or footer with replaced keywords
407490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.2
407590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
407690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
407790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function replace_keywords($instr) {
407890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords = $replacements = array();
407990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
408090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '<TIME>';
408190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '{TIME}';
408290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $replacements[] = $replacements[] = number_format($time = $this->get_time(), 3);
408390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
408490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '<LANGUAGE>';
408590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '{LANGUAGE}';
408690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $replacements[] = $replacements[] = $this->language_data['LANG_NAME'];
408790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
408890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '<VERSION>';
408990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '{VERSION}';
409090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $replacements[] = $replacements[] = GESHI_VERSION;
409190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
409290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '<SPEED>';
409390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $keywords[] = '{SPEED}';
409490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($time <= 0) {
409590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $speed = 'N/A';
409690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
409790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $speed = strlen($this->source) / $time;
409890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($speed >= 1024) {
409990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $speed = sprintf("%.2f KB/s", $speed / 1024.0);
410090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            } else {
410190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $speed = sprintf("%.0f B/s", $speed);
410290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
410390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
410490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $replacements[] = $replacements[] = $speed;
410590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
410690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return str_replace($keywords, $replacements, $instr);
410790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
410890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
410990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
411090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Secure replacement for PHP built-in function htmlspecialchars().
411190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
411290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * See ticket #427 (http://wush.net/trac/wikka/ticket/427) for the rationale
411390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * for this replacement function.
411490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
411590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The INTERFACE for this function is almost the same as that for
411690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * htmlspecialchars(), with the same default for quote style; however, there
411790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * is no 'charset' parameter. The reason for this is as follows:
411890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
411990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * The PHP docs say:
412090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *      "The third argument charset defines character set used in conversion."
412190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
412290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * I suspect PHP's htmlspecialchars() is working at the byte-value level and
412390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * thus _needs_ to know (or asssume) a character set because the special
412490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * characters to be replaced could exist at different code points in
412590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * different character sets. (If indeed htmlspecialchars() works at
412690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * byte-value level that goes some  way towards explaining why the
412790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * vulnerability would exist in this function, too, and not only in
412890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * htmlentities() which certainly is working at byte-value level.)
412990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
413090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * This replacement function however works at character level and should
413190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * therefore be "immune" to character set differences - so no charset
413290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * parameter is needed or provided. If a third parameter is passed, it will
413390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * be silently ignored.
413490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
413590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * In the OUTPUT there is a minor difference in that we use '&#39;' instead
413690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * of PHP's '&#039;' for a single quote: this provides compatibility with
413790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *      get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)
413890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * (see comment by mikiwoz at yahoo dot co dot uk on
413990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * http://php.net/htmlspecialchars); it also matches the entity definition
414090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * for XML 1.0
414190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * (http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters).
414290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Like PHP we use a numeric character reference instead of '&apos;' for the
414390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * single quote. For the other special characters we use the named entity
414490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * references, as PHP is doing.
414590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
414690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @author      {@link http://wikkawiki.org/JavaWoman Marjolein Katsma}
414790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
414890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @license     http://www.gnu.org/copyleft/lgpl.html
414990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              GNU Lesser General Public License
415090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @copyright   Copyright 2007, {@link http://wikkawiki.org/CreditsPage
415190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *              Wikka Development Team}
415290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
415390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access      private
415490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param       string  $string string to be converted
415590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param       integer $quote_style
415690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                      - ENT_COMPAT:   escapes &, <, > and double quote (default)
415790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                      - ENT_NOQUOTES: escapes only &, < and >
415890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *                      - ENT_QUOTES:   escapes &, <, >, double and single quotes
415990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return      string  converted string
416090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since       1.0.7.18
416190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
416290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function hsc($string, $quote_style = ENT_COMPAT) {
416390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // init
416490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        static $aTransSpecchar = array(
416590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '&' => '&amp;',
416690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '"' => '&quot;',
416790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '<' => '&lt;',
416890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '>' => '&gt;',
416990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
417090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //This fix is related to SF#1923020, but has to be applied
417190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //regardless of actually highlighting symbols.
417290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
417390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //Circumvent a bug with symbol highlighting
417490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //This is required as ; would produce undesirable side-effects if it
417590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //was not to be processed as an entity.
417690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            ';' => '<SEMI>', // Force ; to be processed as entity
417790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '|' => '<PIPE>' // Force | to be processed as entity
417890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            );                      // ENT_COMPAT set
417990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
418090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        switch ($quote_style) {
418190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            case ENT_NOQUOTES: // don't convert double quotes
418290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                unset($aTransSpecchar['"']);
418390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                break;
418490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            case ENT_QUOTES: // convert single quotes as well
418590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $aTransSpecchar["'"] = '&#39;'; // (apos) htmlspecialchars() uses '&#039;'
418690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                break;
418790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
418890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
418990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // return translated string
419090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return strtr($string, $aTransSpecchar);
419190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
419290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
419390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
419490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Returns a stylesheet for the highlighted code. If $economy mode
419590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * is true, we only return the stylesheet declarations that matter for
419690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * this code block instead of the whole thing
419790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
419890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param  boolean Whether to use economy mode or not
419990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string A stylesheet built on the data for the current language
420090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since  1.0.0
420190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
420290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_stylesheet($economy_mode = true) {
420390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // If there's an error, chances are that the language file
420490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // won't have populated the language data file, so we can't
420590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // risk getting a stylesheet...
420690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->error) {
420790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return '';
420890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
420990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
421090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //Check if the style rearrangements have been processed ...
421190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //This also does some preprocessing to check which style groups are useable ...
421290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if(!isset($this->language_data['NUMBERS_CACHE'])) {
421390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $this->build_style_cache();
421490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
421590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
421690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // First, work out what the selector should be. If there's an ID,
421790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // that should be used, the same for a class. Otherwise, a selector
421890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // of '' means that these styles will be applied anywhere
421990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->overall_id) {
422090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $selector = '#' . $this->overall_id;
422190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
422290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $selector = '.' . $this->language;
422390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($this->overall_class) {
422490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $selector .= '.' . $this->overall_class;
422590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
422690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
422790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $selector .= ' ';
422890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
422990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Header of the stylesheet
423090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$economy_mode) {
423190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet = "/**\n".
423290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * GeSHi Dynamically Generated Stylesheet\n".
423390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * --------------------------------------\n".
423490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * Dynamically generated stylesheet for {$this->language}\n".
423590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n".
423690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n" .
423790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
423890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * --------------------------------------\n".
423990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " */\n";
424090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
424190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet = "/**\n".
424290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann\n" .
424390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
424490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                " */\n";
424590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
424690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
424790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Set the <ol> to have no effect at all if there are line numbers
424890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // (<ol>s have margins that should be destroyed so all layout is
424990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // controlled by the set_overall_style method, which works on the
425090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // <pre> or <div> container). Additionally, set default styles for lines
425190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
425290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //$stylesheet .= "$selector, {$selector}ol, {$selector}ol li {margin: 0;}\n";
425390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "$selector.de1, $selector.de2 {{$this->code_style}}\n";
425490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
425590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
425690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Add overall styles
425790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: neglect economy_mode, empty styles are meaningless
425890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->overall_style != '') {
425990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "$selector {{$this->overall_style}}\n";
426090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
426190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
426290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Add styles for links
426390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: economy mode does not make _any_ sense here
426490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //       either the style is empty and thus no selector is needed
426590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //       or the appropriate key is given.
426690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->link_styles as $key => $style) {
426790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($style != '') {
426890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                switch ($key) {
426990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    case GESHI_LINK:
427090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stylesheet .= "{$selector}a:link {{$style}}\n";
427190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        break;
427290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    case GESHI_HOVER:
427390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stylesheet .= "{$selector}a:hover {{$style}}\n";
427490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        break;
427590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    case GESHI_ACTIVE:
427690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stylesheet .= "{$selector}a:active {{$style}}\n";
427790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        break;
427890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    case GESHI_VISITED:
427990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $stylesheet .= "{$selector}a:visited {{$style}}\n";
428090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        break;
428190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
428290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
428390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
428490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
428590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Header and footer
428690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: neglect economy_mode, empty styles are meaningless
428790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->header_content_style != '') {
428890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "$selector.head {{$this->header_content_style}}\n";
428990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
429090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->footer_content_style != '') {
429190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "$selector.foot {{$this->footer_content_style}}\n";
429290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
429390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
429490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Styles for important stuff
429590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: neglect economy_mode, empty styles are meaningless
429690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($this->important_styles != '') {
429790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "$selector.imp {{$this->important_styles}}\n";
429890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
429990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
430090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Simple line number styles
430190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->line_style1 != '') {
430290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "{$selector}li, {$selector}.li1 {{$this->line_style1}}\n";
430390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
430490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->table_linenumber_style != '') {
430590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "{$selector}.ln {{$this->table_linenumber_style}}\n";
430690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
430790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // If there is a style set for fancy line numbers, echo it out
430890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ((!$economy_mode || $this->line_numbers == GESHI_FANCY_LINE_NUMBERS) && $this->line_style2 != '') {
430990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "{$selector}.li2 {{$this->line_style2}}\n";
431090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
431190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
431290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: empty styles are meaningless
431390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['KEYWORDS'] as $group => $styles) {
431490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode ||
431590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                (isset($this->lexic_permissions['KEYWORDS'][$group]) &&
431690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['KEYWORDS'][$group]))) {
431790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.kw$group {{$styles}}\n";
431890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
431990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
432090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['COMMENTS'] as $group => $styles) {
432190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode ||
432290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                (isset($this->lexic_permissions['COMMENTS'][$group]) &&
432390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['COMMENTS'][$group]) ||
432490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                (!empty($this->language_data['COMMENT_REGEXP']) &&
432590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                !empty($this->language_data['COMMENT_REGEXP'][$group])))) {
432690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.co$group {{$styles}}\n";
432790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
432890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
432990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['ESCAPE_CHAR'] as $group => $styles) {
433090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['ESCAPE_CHAR'])) {
433190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // NEW: since 1.0.8 we have to handle hardescapes
433290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($group === 'HARD') {
433390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $group = '_h';
433490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
433590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.es$group {{$styles}}\n";
433690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
433790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
433890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['BRACKETS'] as $group => $styles) {
433990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['BRACKETS'])) {
434090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.br$group {{$styles}}\n";
434190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
434290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
434390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['SYMBOLS'] as $group => $styles) {
434490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['SYMBOLS'])) {
434590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.sy$group {{$styles}}\n";
434690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
434790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
434890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['STRINGS'] as $group => $styles) {
434990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['STRINGS'])) {
435090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // NEW: since 1.0.8 we have to handle hardquotes
435190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($group === 'HARD') {
435290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $group = '_h';
435390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
435490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.st$group {{$styles}}\n";
435590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
435690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
435790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['NUMBERS'] as $group => $styles) {
435890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['NUMBERS'])) {
435990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.nu$group {{$styles}}\n";
436090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
436190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
436290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['METHODS'] as $group => $styles) {
436390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode || $this->lexic_permissions['METHODS'])) {
436490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.me$group {{$styles}}\n";
436590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
436690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
436790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // note: neglect economy_mode, empty styles are meaningless
436890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['SCRIPT'] as $group => $styles) {
436990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '') {
437090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $stylesheet .= "$selector.sc$group {{$styles}}\n";
437190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
437290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
437390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->language_data['STYLES']['REGEXPS'] as $group => $styles) {
437490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($styles != '' && (!$economy_mode ||
437590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                (isset($this->lexic_permissions['REGEXPS'][$group]) &&
437690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $this->lexic_permissions['REGEXPS'][$group]))) {
437790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (is_array($this->language_data['REGEXPS'][$group]) &&
437890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$group])) {
437990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stylesheet .= "$selector.";
438090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stylesheet .= $this->language_data['REGEXPS'][$group][GESHI_CLASS];
438190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stylesheet .= " {{$styles}}\n";
438290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                } else {
438390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $stylesheet .= "$selector.re$group {{$styles}}\n";
438490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
438590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
438690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
438790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // Styles for lines being highlighted extra
438890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$economy_mode || (count($this->highlight_extra_lines)!=count($this->highlight_extra_lines_styles))) {
438990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "{$selector}.ln-xtra, {$selector}li.ln-xtra, {$selector}div.ln-xtra {{$this->highlight_extra_lines_style}}\n";
439090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
439190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $stylesheet .= "{$selector}span.xtra { display:block; }\n";
439290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($this->highlight_extra_lines_styles as $lineid => $linestyle) {
439390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $stylesheet .= "{$selector}.lx$lineid, {$selector}li.lx$lineid, {$selector}div.lx$lineid {{$linestyle}}\n";
439490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
439590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
439690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $stylesheet;
439790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
439890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
439990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
440090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Get's the style that is used for the specified line
440190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
440290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param int The line number information is requested for
440390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @access private
440490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.7.21
440590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
440690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function get_line_style($line) {
440790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        //$style = null;
440890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $style = null;
440990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (isset($this->highlight_extra_lines_styles[$line])) {
441090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $style = $this->highlight_extra_lines_styles[$line];
441190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else { // if no "extra" style assigned
441290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $style = $this->highlight_extra_lines_style;
441390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
441490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
441590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $style;
441690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
441790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
441890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
441990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * this functions creates an optimized regular expression list
442090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * of an array of strings.
442190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    *
442290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * Example:
442390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * <code>$list = array('faa', 'foo', 'foobar');
442490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    *          => string 'f(aa|oo(bar)?)'</code>
442590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    *
442690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @param $list array of (unquoted) strings
442790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @param $regexp_delimiter your regular expression delimiter, @see preg_quote()
442890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @return string for regular expression
442990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @author Milian Wolff <mail@milianw.de>
443090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @since 1.0.8
443190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @access private
443290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    */
443390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function optimize_regexp_list($list, $regexp_delimiter = '/') {
443490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $regex_chars = array('.', '\\', '+', '*', '?', '[', '^', ']', '$',
443590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            '(', ')', '{', '}', '=', '!', '<', '>', '|', ':', $regexp_delimiter);
443690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        sort($list);
443790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $regexp_list = array('');
443890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $num_subpatterns = 0;
443990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $list_key = 0;
444090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
444190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // the tokens which we will use to generate the regexp list
444290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $tokens = array();
444390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $prev_keys = array();
444490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // go through all entries of the list and generate the token list
444590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $cur_len = 0;
444690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for ($i = 0, $i_max = count($list); $i < $i_max; ++$i) {
444790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if ($cur_len > GESHI_MAX_PCRE_LENGTH) {
444890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // seems like the length of this pcre is growing exorbitantly
444990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $regexp_list[++$list_key] = $this->_optimize_regexp_list_tokens_to_string($tokens);
445090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $num_subpatterns = substr_count($regexp_list[$list_key], '(?:');
445190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $tokens = array();
445290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $cur_len = 0;
445390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
445490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $level = 0;
445590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $entry = preg_quote((string) $list[$i], $regexp_delimiter);
445690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $pointer = &$tokens;
445790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // properly assign the new entry to the correct position in the token array
445890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // possibly generate smaller common denominator keys
445990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            while (true) {
446090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // get the common denominator
446190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if (isset($prev_keys[$level])) {
446290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($prev_keys[$level] == $entry) {
446390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // this is a duplicate entry, skip it
446490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        continue 2;
446590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
446690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $char = 0;
446790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    while (isset($entry[$char]) && isset($prev_keys[$level][$char])
446890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            && $entry[$char] == $prev_keys[$level][$char]) {
446990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        ++$char;
447090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
447190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if ($char > 0) {
447290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        // this entry has at least some chars in common with the current key
447390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if ($char == strlen($prev_keys[$level])) {
447490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // current key is totally matched, i.e. this entry has just some bits appended
447590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $pointer = &$pointer[$prev_keys[$level]];
447690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        } else {
447790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            // only part of the keys match
447890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $new_key_part1 = substr($prev_keys[$level], 0, $char);
447990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $new_key_part2 = substr($prev_keys[$level], $char);
448090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
448190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            if (in_array($new_key_part1[0], $regex_chars)
448290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                || in_array($new_key_part2[0], $regex_chars)) {
448390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // this is bad, a regex char as first character
448490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $pointer[$entry] = array('' => true);
448590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                array_splice($prev_keys, $level, count($prev_keys), $entry);
448690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $cur_len += strlen($entry);
448790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                continue;
448890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            } else {
448990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // relocate previous tokens
449090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $pointer[$new_key_part1] = array($new_key_part2 => $pointer[$prev_keys[$level]]);
449190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                unset($pointer[$prev_keys[$level]]);
449290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $pointer = &$pointer[$new_key_part1];
449390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                // recreate key index
449490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                array_splice($prev_keys, $level, count($prev_keys), array($new_key_part1, $new_key_part2));
449590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                $cur_len += strlen($new_key_part2);
449690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            }
449790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
449890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        ++$level;
449990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $entry = substr($entry, $char);
450090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        continue;
450190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
450290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // else: fall trough, i.e. no common denominator was found
450390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
450490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($level == 0 && !empty($tokens)) {
450590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // we can dump current tokens into the string and throw them away afterwards
450690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
450790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $new_subpatterns = substr_count($new_entry, '(?:');
450890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + $new_subpatterns > GESHI_MAX_PCRE_SUBPATTERNS) {
450990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $regexp_list[++$list_key] = $new_entry;
451090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $num_subpatterns = $new_subpatterns;
451190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    } else {
451290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        if (!empty($regexp_list[$list_key])) {
451390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                            $new_entry = '|' . $new_entry;
451490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        }
451590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $regexp_list[$list_key] .= $new_entry;
451690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                        $num_subpatterns += $new_subpatterns;
451790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    }
451890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $tokens = array();
451990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $cur_len = 0;
452090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
452190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                // no further common denominator found
452290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $pointer[$entry] = array('' => true);
452390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                array_splice($prev_keys, $level, count($prev_keys), $entry);
452490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
452590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $cur_len += strlen($entry);
452690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                break;
452790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
452890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($list[$i]);
452990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
453090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // make sure the last tokens get converted as well
453190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
453290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + substr_count($new_entry, '(?:') > GESHI_MAX_PCRE_SUBPATTERNS) {
453390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $regexp_list[++$list_key] = $new_entry;
453490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        } else {
453590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!empty($regexp_list[$list_key])) {
453690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $new_entry = '|' . $new_entry;
453790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
453890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $regexp_list[$list_key] .= $new_entry;
453990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
454090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return $regexp_list;
454190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
454290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
454390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * this function creates the appropriate regexp string of an token array
454490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * you should not call this function directly, @see $this->optimize_regexp_list().
454590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    *
454690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @param &$tokens array of tokens
454790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @param $recursed bool to know wether we recursed or not
454890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @return string
454990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @author Milian Wolff <mail@milianw.de>
455090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @since 1.0.8
455190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    * @access private
455290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    */
455390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function _optimize_regexp_list_tokens_to_string(&$tokens, $recursed = false) {
455490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $list = '';
455590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        foreach ($tokens as $token => $sub_tokens) {
455690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $list .= $token;
455790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $close_entry = isset($sub_tokens['']);
455890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            unset($sub_tokens['']);
455990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!empty($sub_tokens)) {
456090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $list .= '(?:' . $this->_optimize_regexp_list_tokens_to_string($sub_tokens, true) . ')';
456190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                if ($close_entry) {
456290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    // make sub_tokens optional
456390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                    $list .= '?';
456490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
456590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
456690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $list .= '|';
456790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
456890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if (!$recursed) {
456990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // do some optimizations
457090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // common trailing strings
457190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // BUGGY!
457290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //$list = preg_replace_callback('#(?<=^|\:|\|)\w+?(\w+)(?:\|.+\1)+(?=\|)#', create_function(
457390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            //    '$matches', 'return "(?:" . preg_replace("#" . preg_quote($matches[1], "#") . "(?=\||$)#", "", $matches[0]) . ")" . $matches[1];'), $list);
457490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // (?:p)? => p?
457590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $list = preg_replace('#\(\?\:(.)\)\?#', '\1?', $list);
457690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // (?:a|b|c|d|...)? => [abcd...]?
457790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            // TODO: a|bb|c => [ac]|bb
457890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            static $callback_2;
457990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            if (!isset($callback_2)) {
458090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                $callback_2 = create_function('$matches', 'return "[" . str_replace("|", "", $matches[1]) . "]";');
458190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
458290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            $list = preg_replace_callback('#\(\?\:((?:.\|)+.)\)#', $callback_2, $list);
458390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
458490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        // return $list without trailing pipe
458590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return substr($list, 0, -1);
458690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
458790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber} // End Class GeSHi
458890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
458990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
459090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberif (!function_exists('geshi_highlight')) {
459190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    /**
459290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * Easy way to highlight stuff. Behaves just like highlight_string
459390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *
459490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The code to highlight
459590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The language to highlight the code in
459690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param string The path to the language files. You can leave this blank if you need
459790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     *               as from version 1.0.7 the path should be automatically detected
459890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @param boolean Whether to return the result or to echo
459990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @return string The code highlighted (if $return is true)
460090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     * @since 1.0.2
460190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber     */
460290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    function geshi_highlight($string, $language, $path = null, $return = false) {
460390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $geshi = new GeSHi($string, $language, $path);
460490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        $geshi->set_header_type(GESHI_HEADER_NONE);
460590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
460690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($return) {
460790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return '<code>' . $geshi->parse_code() . '</code>';
460890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
460990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
461090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        echo '<code>' . $geshi->parse_code() . '</code>';
461190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
461290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        if ($geshi->error()) {
461390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            return false;
461490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
461590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return true;
461690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
461790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
461890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
461990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber?>