!c99Shell v. 1.0 pre-release build #16!

Software: Apache/2.2.3 (CentOS). PHP/5.1.6 

uname -a: Linux mx-ll-110-164-51-230.static.3bb.co.th 2.6.18-194.el5PAE #1 SMP Fri Apr 2 15:37:44
EDT 2010 i686
 

uid=48(apache) gid=48(apache) groups=48(apache) 

Safe-mode: OFF (not secure)

/var/www/html/alumni/inc/geshi/   drwxr-xr-x
Free 50.97 GB of 127.8 GB (39.88%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     geshi.php (116.66 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

/**

 * GeSHi - Generic Syntax Highlighter

 *

 * The GeSHi class for Generic Syntax Highlighting. Please refer to the

 * documentation at http://qbnz.com/highlighter/documentation.php for more

 * information about how to use this class.

 *

 * For changes, release notes, TODOs etc, see the relevant files in the docs/

 * directory.

 *

 *   This file is part of GeSHi.

 *

 *  GeSHi is free software; you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation; either version 2 of the License, or

 *  (at your option) any later version.

 *

 *  GeSHi is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with GeSHi; if not, write to the Free Software

 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 *

 * @package    geshi

 * @subpackage core

 * @author     Nigel McNie <nigel@geshi.org>

 * @copyright  (C) 2004 - 2007 Nigel McNie

 * @license    http://gnu.org/copyleft/gpl.html GNU GPL

 *

 */



//

// GeSHi Constants

// You should use these constant names in your programs instead of

// their values - you never know when a value may change in a future

// version

//



/** The version of this GeSHi file */

define('GESHI_VERSION''1.0.7.19');



// Define the root directory for the GeSHi code tree

if (!defined('GESHI_ROOT')) {

    
/** The root directory for GeSHi */

    
define('GESHI_ROOT'dirname(__FILE__) . DIRECTORY_SEPARATOR);

}

/** The language file directory for GeSHi

    @access private */

define('GESHI_LANG_ROOT'GESHI_ROOT 'geshi' DIRECTORY_SEPARATOR);





// Line numbers - use with enable_line_numbers()

/** Use no line numbers when building the result */

define('GESHI_NO_LINE_NUMBERS'0);

/** Use normal line numbers when building the result */

define('GESHI_NORMAL_LINE_NUMBERS'1);

/** Use fancy line numbers when building the result */

define('GESHI_FANCY_LINE_NUMBERS'2);



// Container HTML type

/** Use nothing to surround the source */

define('GESHI_HEADER_NONE'0);

/** Use a "div" to surround the source */

define('GESHI_HEADER_DIV'1);

/** Use a "pre" to surround the source */

define('GESHI_HEADER_PRE'2);



// Capatalisation constants

/** Lowercase keywords found */

define('GESHI_CAPS_NO_CHANGE'0);

/** Uppercase keywords found */

define('GESHI_CAPS_UPPER'1);

/** Leave keywords found as the case that they are */

define('GESHI_CAPS_LOWER'2);



// Link style constants

/** Links in the source in the :link state */

define('GESHI_LINK'0);

/** Links in the source in the :hover state */

define('GESHI_HOVER'1);

/** Links in the source in the :active state */

define('GESHI_ACTIVE'2);

/** Links in the source in the :visited state */

define('GESHI_VISITED'3);



// Important string starter/finisher

// Note that if you change these, they should be as-is: i.e., don't

// write them as if they had been run through htmlentities()

/** The starter for important parts of the source */

define('GESHI_START_IMPORTANT''<BEGIN GeSHi>');

/** The ender for important parts of the source */

define('GESHI_END_IMPORTANT''<END GeSHi>');



/**#@+

 *  @access private

 */

// When strict mode applies for a language

/** Strict mode never applies (this is the most common) */

define('GESHI_NEVER'0);

/** Strict mode *might* apply, and can be enabled or

    disabled by {@link GeSHi::enable_strict_mode()} */

define('GESHI_MAYBE'1);

/** Strict mode always applies */

define('GESHI_ALWAYS'2);



// Advanced regexp handling constants, used in language files

/** The key of the regex array defining what to search for */

define('GESHI_SEARCH'0);

/** The key of the regex array defining what bracket group in a

    matched search to use as a replacement */

define('GESHI_REPLACE'1);

/** The key of the regex array defining any modifiers to the regular expression */

define('GESHI_MODIFIERS'2);

/** The key of the regex array defining what bracket group in a

    matched search to put before the replacement */

define('GESHI_BEFORE'3);

/** The key of the regex array defining what bracket group in a

    matched search to put after the replacement */

define('GESHI_AFTER'4);

/** The key of the regex array defining a custom keyword to use

    for this regexp's html tag class */

define('GESHI_CLASS'5);



/** Used in language files to mark comments */

define('GESHI_COMMENTS'0);



// Error detection - use these to analyse faults

/** No sourcecode to highlight was specified

 * @deprecated

 */

define('GESHI_ERROR_NO_INPUT'1);

/** The language specified does not exist */

define('GESHI_ERROR_NO_SUCH_LANG'2);

/** GeSHi could not open a file for reading (generally a language file) */

define('GESHI_ERROR_FILE_NOT_READABLE'3);

/** The header type passed to {@link GeSHi::set_header_type()} was invalid */

define('GESHI_ERROR_INVALID_HEADER_TYPE'4);

/** The line number type passed to {@link GeSHi::enable_line_numbers()} was invalid */

define('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE'5);

/**#@-*/





/**

 * The GeSHi Class.

 *

 * Please refer to the documentation for GeSHi 1.0.X that is available

 * at http://qbnz.com/highlighter/documentation.php for more information

 * about how to use this class.

 *

 * @package   geshi

 * @author    Nigel McNie <nigel@geshi.org>

 * @copyright (C) 2004 - 2007 Nigel McNie

 */

class GeSHi {

    
/**#@+

     * @access private

     */

    /**

     * The source code to highlight

     * @var string

     */

    
var $source '';



    
/**

     * The language to use when highlighting

     * @var string

     */

    
var $language '';



    
/**

     * The data for the language used

     * @var array

     */

    
var $language_data = array();



    
/**

     * The path to the language files

     * @var string

     */

    
var $language_path GESHI_LANG_ROOT;



    
/**

     * The error message associated with an error

     * @var string

     * @todo check err reporting works

     */

    
var $error false;



    
/**

     * Possible error messages

     * @var array

     */

    
var $error_messages = array(

        
GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',

        
GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',

        
GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',

        
GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'

    
);



    
/**

     * Whether highlighting is strict or not

     * @var boolean

     */

    
var $strict_mode false;



    
/**

     * Whether to use CSS classes in output

     * @var boolean

     */

    
var $use_classes false;



    
/**

     * The type of header to use. Can be one of the following

     * values:

     *

     * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.

     * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.

     * - GESHI_HEADER_NONE: No header is outputted.

     *

     * @var int

     */

    
var $header_type GESHI_HEADER_PRE;



    
/**

     * Array of permissions for which lexics should be highlighted

     * @var array

     */

    
var $lexic_permissions = array(

        
'KEYWORDS' =>    array(),

        
'COMMENTS' =>    array('MULTI' => true),

        
'REGEXPS' =>     array(),

        
'ESCAPE_CHAR' => true,

        
'BRACKETS' =>    true,

        
'SYMBOLS' =>     true,

        
'STRINGS' =>     true,

        
'NUMBERS' =>     true,

        
'METHODS' =>     true,

        
'SCRIPT' =>      true

    
);



    
/**

     * The time it took to parse the code

     * @var double

     */

    
var $time 0;



    
/**

     * The content of the header block

     * @var string

     */

    
var $header_content '';



    
/**

     * The content of the footer block

     * @var string

     */

    
var $footer_content '';



    
/**

     * The style of the header block

     * @var string

     */

    
var $header_content_style '';



    
/**

     * The style of the footer block

     * @var string

     */

    
var $footer_content_style '';



    
/**

     * The styles for hyperlinks in the code

     * @var array

     */

    
var $link_styles = array();



    
/**

     * Whether important blocks should be recognised or not

     * @var boolean

     * @deprecated

     * @todo REMOVE THIS FUNCTIONALITY!

     */

    
var $enable_important_blocks false;



    
/**

     * Styles for important parts of the code

     * @var string

     * @deprecated

     * @todo As above - rethink the whole idea of important blocks as it is buggy and

     * will be hard to implement in 1.2

     */

    
var $important_styles 'font-weight: bold; color: red;'// Styles for important parts of the code



    /**

     * Whether CSS IDs should be added to the code

     * @var boolean

     */

    
var $add_ids false;



    
/**

     * Lines that should be highlighted extra

     * @var array

     */

    
var $highlight_extra_lines = array();



    
/**

     * Styles of extra-highlighted lines

     * @var string

     */

    
var $highlight_extra_lines_style 'color: #cc0; background-color: #ffc;';



    
/**

     * Number at which line numbers should start at

     * @var int

     */

    
var $line_numbers_start 1;



    
/**

     * The overall style for this code block

     * @var string

     */

    
var $overall_style '';



    
/**

     *  The style for the actual code

     * @var string

     */

    
var $code_style 'font-family: \'Courier New\', Courier, monospace; font-weight: normal;';



    
/**

     * The overall class for this code block

     * @var string

     */

    
var $overall_class '';



    
/**

     * The overall ID for this code block

     * @var string

     */

    
var $overall_id '';



    
/**

     * Line number styles

     * @var string

     */

    
var $line_style1 'font-family: \'Courier New\', Courier, monospace; color: black; font-weight: normal; font-style: normal;';



    
/**

     * Line number styles for fancy lines

     * @var string

     */

    
var $line_style2 'font-weight: bold;';



    
/**

     * Flag for how line nubmers are displayed

     * @var boolean

     */

    
var $line_numbers GESHI_NO_LINE_NUMBERS;



    
/**

     * The "nth" value for fancy line highlighting

     * @var int

     */

    
var $line_nth_row 0;



    
/**

     * The size of tab stops

     * @var int

     */

    
var $tab_width 8;



    
/**

     * Default target for keyword links

     * @var string

     */

    
var $link_target '';



    
/**

     * The encoding to use for entity encoding

     * NOTE: no longer used

     * @var string

     */

    
var $encoding 'ISO-8859-1';



    
/**

     * Should keywords be linked?

     * @var boolean

     */

    
var $keyword_links true;



    
/**#@-*/



    /**

     * Creates a new GeSHi object, with source and language

     *

     * @param string The source code to highlight

     * @param string The language to highlight the source with

     * @param string The path to the language file directory. <b>This

     *               is deprecated!</b> I've backported the auto path

     *               detection from the 1.1.X dev branch, so now it

     *               should be automatically set correctly. If you have

     *               renamed the language directory however, you will

     *               still need to set the path using this parameter or

     *               {@link GeSHi::set_language_path()}

     * @since 1.0.0

     */

    
function GeSHi($source$language$path '') {

        
$this->set_source($source);

        
$this->set_language_path($path);

        
$this->set_language($language);

    }



    
/**

     * Returns an error message associated with the last GeSHi operation,

     * or false if no error has occured

     *

     * @return string|false An error message if there has been an error, else false

     * @since  1.0.0

     */

    
function error() {

        if (
$this->error) {

            
$msg $this->error_messages[$this->error];

            
$debug_tpl_vars = array(

                
'{LANGUAGE}' => $this->language,

                
'{PATH}' => $this->language_path

            
);

            foreach (
$debug_tpl_vars as $tpl => $var) {

                
$msg str_replace($tpl$var$msg);

            }

            return 
"<br /><strong>GeSHi Error:</strong> $msg (code $this->error)<br />";

        }

        return 
false;

    }



    
/**

     * Gets a human-readable language name (thanks to Simon Patterson

     * for the idea :))

     *

     * @return string The name for the current language

     * @since  1.0.2

     */

    
function get_language_name() {

        if (
GESHI_ERROR_NO_SUCH_LANG == $this->error) {

            return 
$this->language_data['LANG_NAME'] . ' (Unknown Language)';

        }

        return 
$this->language_data['LANG_NAME'];

    }



    
/**

     * Sets the source code for this object

     *

     * @param string The source code to highlight

     * @since 1.0.0

     */

    
function set_source($source) {

        
$this->source $source;

        
$this->highlight_extra_lines = array();

    }



    
/**

     * Sets the language for this object

     *

     * @param string The name of the language to use

     * @since 1.0.0

     */

    
function set_language($language) {

        
$this->error false;

        
$this->strict_mode GESHI_NEVER;



        
$language preg_replace('#[^a-zA-Z0-9\-_]#'''$language);

        
$this->language strtolower($language);



        
$file_name $this->language_path $this->language '.php';

        if (!
is_readable($file_name)) {

            
$this->error GESHI_ERROR_NO_SUCH_LANG;

            return;

        }

        
// Load the language for parsing

        
$this->load_language($file_name);

    }



    
/**

     * Sets the path to the directory containing the language files. Note

     * that this path is relative to the directory of the script that included

     * geshi.php, NOT geshi.php itself.

     *

     * @param string The path to the language directory

     * @since 1.0.0

     * @deprecated The path to the language files should now be automatically

     *             detected, so this method should no longer be needed. The

     *             1.1.X branch handles manual setting of the path differently

     *             so this method will disappear in 1.2.0.

     */

    
function set_language_path($path) {

        if (
$path) {

            
$this->language_path = ('/' == substr($pathstrlen($path) - 11)) ? $path $path '/';

            
$this->set_language($this->language);        // otherwise set_language_path has no effect

        
}

    }



    
/**

     * Sets the type of header to be used.

     *

     * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This

     * means more source code but more control over tab width and line-wrapping.

     * GESHI_HEADER_PRE means that a "pre" is used - less source, but less

     * control. Default is GESHI_HEADER_PRE.

     *

     * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code

     * should be outputted.

     *

     * @param int The type of header to be used

     * @since 1.0.0

     */

    
function set_header_type($type) {

        if (
GESHI_HEADER_DIV != $type && GESHI_HEADER_PRE != $type && GESHI_HEADER_NONE != $type) {

            
$this->error GESHI_ERROR_INVALID_HEADER_TYPE;

            return;

        }

        
$this->header_type $type;

        
// Set a default overall style if the header is a <div>

        
if (GESHI_HEADER_DIV == $type && !$this->overall_style) {

            
$this->overall_style 'font-family: monospace;';

        }

    }



    
/**

     * Sets the styles for the code that will be outputted

     * when this object is parsed. The style should be a

     * string of valid stylesheet declarations

     *

     * @param string  The overall style for the outputted code block

     * @param boolean Whether to merge the styles with the current styles or not

     * @since 1.0.0

     */

    
function set_overall_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->overall_style $style;

        }

        else {

            
$this->overall_style .= $style;

        }

    }



    
/**

     * Sets the overall classname for this block of code. This

     * class can then be used in a stylesheet to style this object's

     * output

     *

     * @param string The class name to use for this block of code

     * @since 1.0.0

     */

    
function set_overall_class($class) {

        
$this->overall_class $class;

    }



    
/**

     * Sets the overall id for this block of code. This id can then

     * be used in a stylesheet to style this object's output

     *

     * @param string The ID to use for this block of code

     * @since 1.0.0

     */

    
function set_overall_id($id) {

        
$this->overall_id $id;

    }



    
/**

     * Sets whether CSS classes should be used to highlight the source. Default

     * is off, calling this method with no arguments will turn it on

     *

     * @param boolean Whether to turn classes on or not

     * @since 1.0.0

     */

    
function enable_classes($flag true) {

        
$this->use_classes = ($flag) ? true false;

    }



    
/**

     * Sets the style for the actual code. This should be a string

     * containing valid stylesheet declarations. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * Note: Use this method to override any style changes you made to

     * the line numbers if you are using line numbers, else the line of

     * code will have the same style as the line number! Consult the

     * GeSHi documentation for more information about this.

     *

     * @param string  The style to use for actual code

     * @param boolean Whether to merge the current styles with the new styles

     */

    
function set_code_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->code_style $style;

        }

        else {

            
$this->code_style .= $style;

        }

    }



    
/**

     * Sets the styles for the line numbers.

     *

     * @param string The style for the line numbers that are "normal"

     * @param string|boolean If a string, this is the style of the line

     *        numbers that are "fancy", otherwise if boolean then this

     *        defines whether the normal styles should be merged with the

     *        new normal styles or not

     * @param boolean If set, is the flag for whether to merge the "fancy"

     *        styles with the current styles or not

     * @since 1.0.2

     */

    
function set_line_style($style1$style2 ''$preserve_defaults false) {

        if (
is_bool($style2)) {

            
$preserve_defaults $style2;

            
$style2 '';

        }

        if (!
$preserve_defaults) {

            
$this->line_style1 $style1;

            
$this->line_style2 $style2;

        }

        else {

            
$this->line_style1 .= $style1;

            
$this->line_style2 .= $style2;

        }

    }



    
/**

     * Sets whether line numbers should be displayed.

     *

     * Valid values for the first parameter are:

     *

     *  - GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed

     *  - GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed

     *  - GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed

     *

     * For fancy line numbers, the second parameter is used to signal which lines

     * are to be fancy. For example, if the value of this parameter is 5 then every

     * 5th line will be fancy.

     *

     * @param int How line numbers should be displayed

     * @param int Defines which lines are fancy

     * @since 1.0.0

     */

    
function enable_line_numbers($flag$nth_row 5) {

        if (
GESHI_NO_LINE_NUMBERS != $flag && GESHI_NORMAL_LINE_NUMBERS != $flag

            
&& GESHI_FANCY_LINE_NUMBERS != $flag) {

            
$this->error GESHI_ERROR_INVALID_LINE_NUMBER_TYPE;

        }

        
$this->line_numbers $flag;

        
$this->line_nth_row $nth_row;

    }



    
/**

     * Sets the style for a keyword group. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param int     The key of the keyword group to change the styles of

     * @param string  The style to make the keywords

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_keyword_group_style($key$style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['KEYWORDS'][$key] = $style;

        }

        else {

            
$this->language_data['STYLES']['KEYWORDS'][$key] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for a keyword group

     *

     * @param int     The key of the keyword group to turn on or off

     * @param boolean Whether to turn highlighting for that group on or off

     * @since 1.0.0

     */

    
function set_keyword_group_highlighting($key$flag true) {

        
$this->lexic_permissions['KEYWORDS'][$key] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for comment groups.  If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param int     The key of the comment group to change the styles of

     * @param string  The style to make the comments

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_comments_style($key$style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['COMMENTS'][$key] = $style;

        }

        else {

            
$this->language_data['STYLES']['COMMENTS'][$key] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for comment groups

     *

     * @param int     The key of the comment group to turn on or off

     * @param boolean Whether to turn highlighting for that group on or off

     * @since 1.0.0

     */

    
function set_comments_highlighting($key$flag true) {

        
$this->lexic_permissions['COMMENTS'][$key] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for escaped characters. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param string  The style to make the escape characters

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_escape_characters_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['ESCAPE_CHAR'][0] = $style;

        }

        else {

            
$this->language_data['STYLES']['ESCAPE_CHAR'][0] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for escaped characters

     *

     * @param boolean Whether to turn highlighting for escape characters on or off

     * @since 1.0.0

     */

    
function set_escape_characters_highlighting($flag true) {

        
$this->lexic_permissions['ESCAPE_CHAR'] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for brackets. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * This method is DEPRECATED: use set_symbols_style instead.

     * This method will be removed in 1.2.X

     *

     * @param string  The style to make the brackets

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     * @deprecated In favour of set_symbols_style

     */

    
function set_brackets_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['BRACKETS'][0] = $style;

        }

        else {

            
$this->language_data['STYLES']['BRACKETS'][0] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for brackets

     *

     * This method is DEPRECATED: use set_symbols_highlighting instead.

     * This method will be remove in 1.2.X

     *

     * @param boolean Whether to turn highlighting for brackets on or off

     * @since 1.0.0

     * @deprecated In favour of set_symbols_highlighting

     */

    
function set_brackets_highlighting($flag) {

        
$this->lexic_permissions['BRACKETS'] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for symbols. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param string  The style to make the symbols

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.1

     */

    
function set_symbols_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['SYMBOLS'][0] = $style;

        }

        else {

            
$this->language_data['STYLES']['SYMBOLS'][0] .= $style;

        }

        
// For backward compatibility

        
$this->set_brackets_style ($style$preserve_defaults);

    }



    
/**

     * Turns highlighting on/off for symbols

     *

     * @param boolean Whether to turn highlighting for symbols on or off

     * @since 1.0.0

     */

    
function set_symbols_highlighting($flag) {

        
$this->lexic_permissions['SYMBOLS'] = ($flag) ? true false;

        
// For backward compatibility

        
$this->set_brackets_highlighting ($flag);

    }



    
/**

     * Sets the styles for strings. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param string  The style to make the escape characters

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_strings_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['STRINGS'][0] = $style;

        }

        else {

            
$this->language_data['STYLES']['STRINGS'][0] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for strings

     *

     * @param boolean Whether to turn highlighting for strings on or off

     * @since 1.0.0

     */

    
function set_strings_highlighting($flag) {

        
$this->lexic_permissions['STRINGS'] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for numbers. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param string  The style to make the numbers

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_numbers_style($style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['NUMBERS'][0] = $style;

        }

        else {

            
$this->language_data['STYLES']['NUMBERS'][0] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for numbers

     *

     * @param boolean Whether to turn highlighting for numbers on or off

     * @since 1.0.0

     */

    
function set_numbers_highlighting($flag) {

        
$this->lexic_permissions['NUMBERS'] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for methods. $key is a number that references the

     * appropriate "object splitter" - see the language file for the language

     * you are highlighting to get this number. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param int     The key of the object splitter to change the styles of

     * @param string  The style to make the methods

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_methods_style($key$style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['METHODS'][$key] = $style;

        }

        else {

            
$this->language_data['STYLES']['METHODS'][$key] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for methods

     *

     * @param boolean Whether to turn highlighting for methods on or off

     * @since 1.0.0

     */

    
function set_methods_highlighting($flag) {

        
$this->lexic_permissions['METHODS'] = ($flag) ? true false;

    }



    
/**

     * Sets the styles for regexps. If $preserve_defaults is

     * true, then styles are merged with the default styles, with the

     * user defined styles having priority

     *

     * @param string  The style to make the regular expression matches

     * @param boolean Whether to merge the new styles with the old or just

     *                to overwrite them

     * @since 1.0.0

     */

    
function set_regexps_style($key$style$preserve_defaults false) {

        if (!
$preserve_defaults) {

            
$this->language_data['STYLES']['REGEXPS'][$key] = $style;

        }

        else {

            
$this->language_data['STYLES']['REGEXPS'][$key] .= $style;

        }

    }



    
/**

     * Turns highlighting on/off for regexps

     *

     * @param int     The key of the regular expression group to turn on or off

     * @param boolean Whether to turn highlighting for the regular expression group on or off

     * @since 1.0.0

     */

    
function set_regexps_highlighting($key$flag) {

        
$this->lexic_permissions['REGEXPS'][$key] = ($flag) ? true false;

    }



    
/**

     * Sets whether a set of keywords are checked for in a case sensitive manner

     *

     * @param int The key of the keyword group to change the case sensitivity of

     * @param boolean Whether to check in a case sensitive manner or not

     * @since 1.0.0

     */

    
function set_case_sensitivity($key$case) {

        
$this->language_data['CASE_SENSITIVE'][$key] = ($case) ? true false;

    }



    
/**

     * Sets the case that keywords should use when found. Use the constants:

     *

     *  - GESHI_CAPS_NO_CHANGE: leave keywords as-is

     *  - GESHI_CAPS_UPPER: convert all keywords to uppercase where found

     *  - GESHI_CAPS_LOWER: convert all keywords to lowercase where found

     *

     * @param int A constant specifying what to do with matched keywords

     * @since 1.0.1

     * @todo  Error check the passed value

     */

    
function set_case_keywords($case) {

        
$this->language_data['CASE_KEYWORDS'] = $case;

    }



    
/**

     * Sets how many spaces a tab is substituted for

     *

     * Widths below zero are ignored

     *

     * @param int The tab width

     * @since 1.0.0

     */

    
function set_tab_width($width) {

        
$this->tab_width intval($width);

    }



    
/**

     * Enables/disables strict highlighting. Default is off, calling this

     * method without parameters will turn it on. See documentation

     * for more details on strict mode and where to use it.

     *

     * @param boolean Whether to enable strict mode or not

     * @since 1.0.0

     */

    
function enable_strict_mode($mode true) {

        if (
GESHI_MAYBE == $this->language_data['STRICT_MODE_APPLIES']) {

          
$this->strict_mode = ($mode) ? true false;

        }

    }



    
/**

     * Disables all highlighting

     *

     * @since 1.0.0

     * @todo Rewrite with an array traversal

     */

    
function disable_highlighting() {

        foreach (
$this->lexic_permissions as $key => $value) {

            if (
is_array($value)) {

                foreach (
$value as $k => $v) {

                    
$this->lexic_permissions[$key][$k] = false;

                }

            }

            else {

                
$this->lexic_permissions[$key] = false;

            }

        }

        
// Context blocks

        
$this->enable_important_blocks false;

    }



    
/**

     * Enables all highlighting

     *

     * @since 1.0.0

     * @todo  Rewrite with array traversal

     */

    
function enable_highlighting() {

        foreach (
$this->lexic_permissions as $key => $value) {

            if (
is_array($value)) {

                foreach (
$value as $k => $v) {

                    
$this->lexic_permissions[$key][$k] = true;

                }

            }

            else {

                
$this->lexic_permissions[$key] = true;

            }

        }

        
// Context blocks

        
$this->enable_important_blocks true;

    }



    
/**

     * Given a file extension, this method returns either a valid geshi language

     * name, or the empty string if it couldn't be found

     *

     * @param string The extension to get a language name for

     * @param array  A lookup array to use instead of the default

     * @since 1.0.5

     * @todo Re-think about how this method works (maybe make it private and/or make it

     *       a extension->lang lookup?)

     * @todo static?

     */

    
function get_language_name_from_extension$extension$lookup = array() ) {

        if ( !
$lookup ) {

            
$lookup = array(

                
'actionscript' => array('as'),

                
'ada' => array('a''ada''adb''ads'),

                
'apache' => array('conf'),

                
'asm' => array('ash''asm'),

                
'asp' => array('asp'),

                
'bash' => array('sh'),

                
'c' => array('c''h'),

                
'c_mac' => array('c''h'),

                
'caddcl' => array(),

                
'cadlisp' => array(),

                
'cdfg' => array('cdfg'),

                
'cpp' => array('cpp''h''hpp'),

                
'csharp' => array(),

                
'css' => array('css'),

                
'delphi' => array('dpk''dpr'),

                
'html4strict' => array('html''htm'),

                
'java' => array('java'),

                
'javascript' => array('js'),

                
'lisp' => array('lisp'),

                
'lua' => array('lua'),

                
'mpasm' => array(),

                
'nsis' => array(),

                
'objc' => array(),

                
'oobas' => array(),

                
'oracle8' => array(),

                
'pascal' => array('pas'),

                
'perl' => array('pl''pm'),

                
'php' => array('php''php5''phtml''phps'),

                
'python' => array('py'),

                
'qbasic' => array('bi'),

                
'sas' => array('sas'),

                
'smarty' => array(),

                
'vb' => array('bas'),

                
'vbnet' => array(),

                
'visualfoxpro' => array(),

                
'xml' => array('xml')

            );

        }



        foreach (
$lookup as $lang => $extensions) {

            foreach (
$extensions as $ext) {

                if (
$ext == $extension) {

                    return 
$lang;

                }

            }

        }

        return 
'';

    }



    
/**

     * Given a file name, this method loads its contents in, and attempts

     * to set the language automatically. An optional lookup table can be

     * passed for looking up the language name. If not specified a default

     * table is used

     *

     * The language table is in the form

     * <pre>array(

     *   'lang_name' => array('extension', 'extension', ...),

     *   'lang_name' ...

     * );</pre>

     *

     * @todo Complete rethink of this and above method

     * @since 1.0.5

     */

    
function load_from_file($file_name$lookup = array()) {

        if (
is_readable($file_name)) {

            
$this->set_source(implode(''file($file_name)));

            
$this->set_language($this->get_language_name_from_extension(substr(strrchr($file_name'.'), 1), $lookup));

        }

        else {

            
$this->error GESHI_ERROR_FILE_NOT_READABLE;

        }

    }



    
/**

     * Adds a keyword to a keyword group for highlighting

     *

     * @param int    The key of the keyword group to add the keyword to

     * @param string The word to add to the keyword group

     * @since 1.0.0

     */

    
function add_keyword($key$word) {

        
$this->language_data['KEYWORDS'][$key][] = $word;

    }



    
/**

     * Removes a keyword from a keyword group

     *

     * @param int    The key of the keyword group to remove the keyword from

     * @param string The word to remove from the keyword group

     * @since 1.0.0

     */

    
function remove_keyword($key$word) {

        
$this->language_data['KEYWORDS'][$key] =

            
array_diff($this->language_data['KEYWORDS'][$key], array($word));

    }



    
/**

     * Creates a new keyword group

     *

     * @param int    The key of the keyword group to create

     * @param string The styles for the keyword group

     * @param boolean Whether the keyword group is case sensitive ornot

     * @param array  The words to use for the keyword group

     * @since 1.0.0

     */

    
function add_keyword_group($key$styles$case_sensitive true$words = array()) {

        
$words = (array) $words;

        
$this->language_data['KEYWORDS'][$key] = $words;

        
$this->lexic_permissions['KEYWORDS'][$key] = true;

        
$this->language_data['CASE_SENSITIVE'][$key] = $case_sensitive;

        
$this->language_data['STYLES']['KEYWORDS'][$key] = $styles;

    }



    
/**

     * Removes a keyword group

     *

     * @param int    The key of the keyword group to remove

     * @since 1.0.0

     */

    
function remove_keyword_group ($key) {

        unset(
$this->language_data['KEYWORDS'][$key]);

        unset(
$this->lexic_permissions['KEYWORDS'][$key]);

        unset(
$this->language_data['CASE_SENSITIVE'][$key]);

        unset(
$this->language_data['STYLES']['KEYWORDS'][$key]);

    }



    
/**

     * Sets the content of the header block

     *

     * @param string The content of the header block

     * @since 1.0.2

     */

    
function set_header_content($content) {

        
$this->header_content $content;

    }



    
/**

     * Sets the content of the footer block

     *

     * @param string The content of the footer block

     * @since 1.0.2

     */

    
function set_footer_content($content) {

        
$this->footer_content $content;

    }



    
/**

     * Sets the style for the header content

     *

     * @param string The style for the header content

     * @since 1.0.2

     */

    
function set_header_content_style($style) {

        
$this->header_content_style $style;

    }



    
/**

     * Sets the style for the footer content

     *

     * @param string The style for the footer content

     * @since 1.0.2

     */

    
function set_footer_content_style($style) {

        
$this->footer_content_style $style;

    }



    
/**

     * Sets the base URL to be used for keywords

     *

     * @param int The key of the keyword group to set the URL for

     * @param string The URL to set for the group. If {FNAME} is in

     *               the url somewhere, it is replaced by the keyword

     *               that the URL is being made for

     * @since 1.0.2

     */

    
function set_url_for_keyword_group($group$url) {

        
$this->language_data['URLS'][$group] = $url;

    }



    
/**

     * Sets styles for links in code

     *

     * @param int A constant that specifies what state the style is being

     *            set for - e.g. :hover or :visited

     * @param string The styles to use for that state

     * @since 1.0.2

     */

    
function set_link_styles($type$styles) {

        
$this->link_styles[$type] = $styles;

    }



    
/**

     * Sets the target for links in code

     *

     * @param string The target for links in the code, e.g. _blank

     * @since 1.0.3

     */

    
function set_link_target($target) {

        if (!
$target) {

            
$this->link_target '';

        }

        else {

            
$this->link_target ' target="' $target '" ';

        }

    }



    
/**

     * Sets styles for important parts of the code

     *

     * @param string The styles to use on important parts of the code

     * @since 1.0.2

     */

    
function set_important_styles($styles) {

        
$this->important_styles $styles;

    }



    
/**

     * Sets whether context-important blocks are highlighted

     *

     * @todo REMOVE THIS SHIZ FROM GESHI!

     * @deprecated

     */

    
function enable_important_blocks($flag) {

        
$this->enable_important_blocks = ( $flag ) ? true false;

    }



    
/**

     * Whether CSS IDs should be added to each line

     *

     * @param boolean If true, IDs will be added to each line.

     * @since 1.0.2

     */

    
function enable_ids($flag true) {

        
$this->add_ids = ($flag) ? true false;

    }



    
/**

     * Specifies which lines to highlight extra

     *

     * @param mixed An array of line numbers to highlight, or just a line

     *              number on its own.

     * @since 1.0.2

     * @todo  Some data replication here that could be cut down on

     */

    
function highlight_lines_extra($lines) {

        if (
is_array($lines)) {

            foreach (
$lines as $line) {

                
$this->highlight_extra_lines[intval($line)] = intval($line);

            }

        }

        else {

            
$this->highlight_extra_lines[intval($lines)] = intval($lines);

        }

    }



    
/**

     * Sets the style for extra-highlighted lines

     *

     * @param string The style for extra-highlighted lines

     * @since 1.0.2

     */

    
function set_highlight_lines_extra_style($styles) {

        
$this->highlight_extra_lines_style $styles;

    }



    
/**

     * Sets what number line numbers should start at. Should

     * be a positive integer, and will be converted to one.

     *

     * <b>Warning:</b> Using this method will add the "start"

     * attribute to the &lt;ol&gt; that is used for line numbering.

     * This is <b>not</b> valid XHTML strict, so if that's what you

     * care about then don't use this method. Firefox is getting

     * support for the CSS method of doing this in 1.1 and Opera

     * has support for the CSS method, but (of course) IE doesn't

     * so it's not worth doing it the CSS way yet.

     *

     * @param int The number to start line numbers at

     * @since 1.0.2

     */

    
function start_line_numbers_at($number) {

        
$this->line_numbers_start abs(intval($number));

    }



    
/**

     * Sets the encoding used for htmlspecialchars(), for international

     * support.

     *

     * NOTE: This is not needed for now because htmlspecialchars() is not

     * being used (it has a security hole in PHP4 that has not been patched).

     * Maybe in a future version it may make a return for speed reasons, but

     * I doubt it.

     *

     * @param string The encoding to use for the source

     * @since 1.0.3

     */

    
function set_encoding($encoding) {

        if (
$encoding) {

          
$this->encoding $encoding;

        }

    }



    
/**

     * Turns linking of keywords on or off.

     *

     * @param boolean If true, links will be added to keywords

     */

    
function enable_keyword_links($enable true) {

        
$this->keyword_links = ($enable) ? true false;

    }



    
/**

     * Returns the code in $this->source, highlighted and surrounded by the

     * nessecary HTML.

     *

     * This should only be called ONCE, cos it's SLOW! If you want to highlight

     * the same source multiple times, you're better off doing a whole lot of

     * str_replaces to replace the &lt;span&gt;s

     *

     * @since 1.0.0

     */

    
function parse_code () {

        
// Start the timer

        
$start_time microtime();



        
// Firstly, if there is an error, we won't highlight

        
if ($this->error) {

            
$result GeSHi::hsc($this->source);

            
// Timing is irrelevant

            
$this->set_time($start_time$start_time);

            return 
$this->finalise($result);

        }



        
// Replace all newlines to a common form.

        
$code str_replace("\r\n""\n"$this->source);

        
$code str_replace("\r""\n"$code);

        
// Add spaces for regular expression matching and line numbers

        
$code "\n" $code "\n";



        
// Initialise various stuff

        
$length           strlen($code);

        
$STRING_OPEN      '';

        
$CLOSE_STRING     false;

        
$ESCAPE_CHAR_OPEN false;

        
$COMMENT_MATCHED  false;

        
// Turn highlighting on if strict mode doesn't apply to this language

        
$HIGHLIGHTING_ON  = ( !$this->strict_mode ) ? true '';

        
// Whether to highlight inside a block of code

        
$HIGHLIGHT_INSIDE_STRICT false;

        
$HARDQUOTE_OPEN false;

        
$STRICTATTRS '';

        
$stuff_to_parse   '';

        
$result           '';



        
// "Important" selections are handled like multiline comments

        // @todo GET RID OF THIS SHIZ

        
if ($this->enable_important_blocks) {

            
$this->language_data['COMMENT_MULTI'][GESHI_START_IMPORTANT] = GESHI_END_IMPORTANT;

        }



        if (
$this->strict_mode) {

            
// Break the source into bits. Each bit will be a portion of the code

            // within script delimiters - for example, HTML between < and >

            
$parts = array(=> array(=> ''));

            
$k 0;

            for (
$i 0$i $length$i++) {

                
$char substr($code$i1);

                if (!
$HIGHLIGHTING_ON) {

                    foreach (
$this->language_data['SCRIPT_DELIMITERS'] as $key => $delimiters) {

                        foreach (
$delimiters as $open => $close) {

                            
// Get the next little bit for this opening string

                            
$check substr($code$istrlen($open));

                            
// If it matches...

                            
if ($check == $open) {

                                
// We start a new block with the highlightable

                                // code in it

                                
$HIGHLIGHTING_ON $open;

                                
$i += strlen($open) - 1;

                                
$char $open;

                                
$parts[++$k][0] = $char;



                                
// No point going around again...

                                
break(2);

                            }

                        }

                    }

                }

                else {

                    foreach (
$this->language_data['SCRIPT_DELIMITERS'] as $key => $delimiters) {

                        foreach (
$delimiters as $open => $close) {

                            if (
$open == $HIGHLIGHTING_ON) {

                                
// Found the closing tag

                                
break(2);

                            }

                        }

                    }

                    
// We check code from our current position BACKWARDS. This is so

                    // the ending string for highlighting can be included in the block

                    
$check substr($code$i strlen($close) + 1strlen($close));

                    if (
$check == $close) {

                        
$HIGHLIGHTING_ON '';

                        
// Add the string to the rest of the string for this part

                        
$parts[$k][1] = ( isset($parts[$k][1]) ) ? $parts[$k][1] . $char $char;

                        
$parts[++$k][0] = '';

                        
$char '';

                    }

                }

                
$parts[$k][1] = ( isset($parts[$k][1]) ) ? $parts[$k][1] . $char $char;

            }

            
$HIGHLIGHTING_ON '';

        }

        else {

            
// Not strict mode - simply dump the source into

            // the array at index 1 (the first highlightable block)

            
$parts = array(

                
=> array(

                    
=> '',

                    
=> $code

                
)

            );

        }



        
// Now we go through each part. We know that even-indexed parts are

        // code that shouldn't be highlighted, and odd-indexed parts should

        // be highlighted

        
foreach ($parts as $key => $data) {

            
$part $data[1];

            
// If this block should be highlighted...

            
if ($key 2) {

                if (
$this->strict_mode) {

                    
// Find the class key for this block of code

                    
foreach ($this->language_data['SCRIPT_DELIMITERS'] as $script_key => $script_data) {

                        foreach (
$script_data as $open => $close) {

                            if (
$data[0] == $open) {

                                break(
2);

                            }

                        }

                    }



                    if (
$this->language_data['STYLES']['SCRIPT'][$script_key] != '' &&

                        
$this->lexic_permissions['SCRIPT']) {

                        
// Add a span element around the source to

                        // highlight the overall source block

                        
if (!$this->use_classes &&

                            
$this->language_data['STYLES']['SCRIPT'][$script_key] != '') {

                            
$attributes ' style="' $this->language_data['STYLES']['SCRIPT'][$script_key] . '"';

                        }

                        else {

                            
$attributes ' class="sc' $script_key '"';

                        }

                        
$result .= "<span$attributes>";

                        
$STRICTATTRS $attributes;

                    }

                }



                if (!
$this->strict_mode || $this->language_data['HIGHLIGHT_STRICT_BLOCK'][$script_key]) {

                    
// Now, highlight the code in this block. This code

                    // is really the engine of GeSHi (along with the method

                    // parse_non_string_part).

                    
$length strlen($part);

                    for (
$i 0$i $length$i++) {

                        
// Get the next char

                        
$char substr($part$i1);

                        
$hq = isset($this->language_data['HARDQUOTE']) ? $this->language_data['HARDQUOTE'][0] : false;

                        
// Is this char the newline and line numbers being used?

                        
if (($this->line_numbers != GESHI_NO_LINE_NUMBERS

                            
|| count($this->highlight_extra_lines) > 0)

                            && 
$char == "\n") {

                            
// If so, is there a string open? If there is, we should end it before

                            // the newline and begin it again (so when <li>s are put in the source

                            // remains XHTML compliant)

                            // note to self: This opens up possibility of config files specifying

                            // that languages can/cannot have multiline strings???

                            
if ($STRING_OPEN) {

                                if (!
$this->use_classes) {

                                    
$attributes ' style="' $this->language_data['STYLES']['STRINGS'][0] . '"';

                                }

                                else {

                                    
$attributes ' class="st0"';

                                }

                                
$char '</span>' $char "<span$attributes>";

                            }

                        }

                        else if (
$char == $STRING_OPEN) {

                            
// A match of a string delimiter

                            
if (($this->lexic_permissions['ESCAPE_CHAR'] && $ESCAPE_CHAR_OPEN) ||

                                (
$this->lexic_permissions['STRINGS'] && !$ESCAPE_CHAR_OPEN)) {

                                
$char GeSHi::hsc($char) . '</span>';

                            }

                            
$escape_me false;

                            if (
$HARDQUOTE_OPEN) {

                                if (
$ESCAPE_CHAR_OPEN) {

                                    
$escape_me true;

                                }

                                else {

                                    foreach (
$this->language_data['HARDESCAPE'] as $hardesc) {

                                        if (
substr($part$istrlen($hardesc)) == $hardesc) {

                                            
$escape_me true;

                                            break;

                                        }

                                    }

                                }

                            }



                            if (!
$ESCAPE_CHAR_OPEN) {

                                
$STRING_OPEN '';

                                
$CLOSE_STRING true;

                            }

                            if (!
$escape_me) {

                                
$HARDQUOTE_OPEN false;

                            }

                            
$ESCAPE_CHAR_OPEN false;

                        }

                        else if (
in_array($char$this->language_data['QUOTEMARKS']) &&

                            (
$STRING_OPEN == '') && $this->lexic_permissions['STRINGS']) {

                            
// The start of a new string

                            
$STRING_OPEN $char;

                            if (!
$this->use_classes) {

                                
$attributes ' style="' $this->language_data['STYLES']['STRINGS'][0] . '"';

                            }

                            else {

                                
$attributes ' class="st0"';

                            }

                            
$char "<span$attributes>" GeSHi::hsc($char);



                            
$result .= $this->parse_non_string_part$stuff_to_parse );

                            
$stuff_to_parse '';

                        }

                        else if (
$hq && substr($part$istrlen($hq)) == $hq &&

                            (
$STRING_OPEN == '') && $this->lexic_permissions['STRINGS']) {

                            
// The start of a hard quoted string

                            
$STRING_OPEN $this->language_data['HARDQUOTE'][1];

                            if (!
$this->use_classes) {

                                
$attributes ' style="' $this->language_data['STYLES']['STRINGS'][0] . '"';

                            }

                            else {

                                
$attributes ' class="st0"';

                            }

                            
$char "<span$attributes>" $hq;

                            
$i += strlen($hq) - 1;

                            
$HARDQUOTE_OPEN true;

                            
$result .= $this->parse_non_string_part($stuff_to_parse);

                            
$stuff_to_parse '';

                        }

                        else if (
$char == $this->language_data['ESCAPE_CHAR'] && $STRING_OPEN != '') {

                            
// An escape character

                            
if (!$ESCAPE_CHAR_OPEN) {

                                
$ESCAPE_CHAR_OPEN = !$HARDQUOTE_OPEN;  // true unless $HARDQUOTE_OPEN

                                
if ($HARDQUOTE_OPEN) {

                                    foreach (
$this->language_data['HARDESCAPE'] as $hard) {

                                        if (
substr($part$istrlen($hard)) == $hard) {

                                            
$ESCAPE_CHAR_OPEN true;

                                            break;

                                        }

                                    }

                                }

                                if (
$ESCAPE_CHAR_OPEN && $this->lexic_permissions['ESCAPE_CHAR']) {

                                    if (!
$this->use_classes) {

                                        
$attributes ' style="' $this->language_data['STYLES']['ESCAPE_CHAR'][0] . '"';

                                    }

                                    else {

                                        
$attributes ' class="es0"';

                                    }

                                    
$char "<span$attributes>" $char;

                                    if (
substr($code$i 11) == "\n") {

                                        
// escaping a newline, what's the point in putting the span around

                                        // the newline? It only causes hassles when inserting line numbers

                                        
$char .= '</span>';

                                        
$ESCAPE_CHAR_OPEN false;

                                    }

                                }

                            }

                            else {

                                
$ESCAPE_CHAR_OPEN false;

                                if (
$this->lexic_permissions['ESCAPE_CHAR']) {

                                    
$char .= '</span>';

                                }

                            }

                        }

                        else if (
$ESCAPE_CHAR_OPEN) {

                            if (
$this->lexic_permissions['ESCAPE_CHAR']) {

                                
$char .= '</span>';

                            }

                            
$ESCAPE_CHAR_OPEN false;

                            
$test_str $char;

                        }

                        else if (
$STRING_OPEN == '') {

                            
// Is this a multiline comment?

                            
foreach ($this->language_data['COMMENT_MULTI'] as $open => $close) {

                                
$com_len strlen($open);

                                
$test_str substr$part$i$com_len );

                                
$test_str_match $test_str;

                                if (
$open == $test_str) {

                                    
$COMMENT_MATCHED true;

                                    
//@todo If remove important do remove here

                                    
if ($this->lexic_permissions['COMMENTS']['MULTI'] ||

                                        
$test_str == GESHI_START_IMPORTANT) {

                                        if (
$test_str != GESHI_START_IMPORTANT) {

                                            if (!
$this->use_classes) {

                                                
$attributes ' style="' $this->language_data['STYLES']['COMMENTS']['MULTI'] . '"';

                                            }

                                            else {

                                                
$attributes ' class="coMULTI"';

                                            }

                                            
$test_str "<span$attributes>" GeSHi::hsc($test_str);

                                        }

                                        else {

                                            if (!
$this->use_classes) {

                                                
$attributes ' style="' $this->important_styles '"';

                                            }

                                            else {

                                                
$attributes ' class="imp"';

                                            }

                                            
// We don't include the start of the comment if it's an

                                            // "important" part

                                            
$test_str "<span$attributes>";

                                        }

                                    }

                                    else {

                                        
$test_str GeSHi::hsc($test_str);

                                    }



                                    
$close_pos strpos$part$close$i strlen($close) );



                                    
$oops false;

                                    if (
$close_pos === false) {

                                        
$close_pos strlen($part);

                                        
$oops true;

                                    }

                                    else {

                                        
$close_pos -= ($com_len strlen($close));

                                    }



                                    
// Short-cut through all the multiline code

                                    
$rest_of_comment GeSHi::hsc(substr($part$i $com_len$close_pos $i));

                                    if ((
$this->lexic_permissions['COMMENTS']['MULTI'] ||

                                        
$test_str_match == GESHI_START_IMPORTANT) &&

                                        (
$this->line_numbers != GESHI_NO_LINE_NUMBERS ||

                                        
count($this->highlight_extra_lines) > 0)) {

                                        
// strreplace to put close span and open span around multiline newlines

                                        
$test_str .= str_replace("\n""</span>\n<span$attributes>"$rest_of_comment);

                                    }

                                    else {

                                        
$test_str .= $rest_of_comment;

                                    }



                                    if (
$this->lexic_permissions['COMMENTS']['MULTI'] ||

                                        
$test_str_match == GESHI_START_IMPORTANT) {

                                        
$test_str .= '</span>';

                                        if (
$oops) {

                                            
$test_str .= "\n";

                                        }

                                    }

                                    
$i $close_pos $com_len 1;

                                    
// parse the rest

                                    
$result .= $this->parse_non_string_part($stuff_to_parse);

                                    
$stuff_to_parse '';

                                    break;

                                }

                            }

                            
// If we haven't matched a multiline comment, try single-line comments

                            
if (!$COMMENT_MATCHED) {

                                foreach (
$this->language_data['COMMENT_SINGLE'] as $comment_key => $comment_mark) {

                                    
$com_len strlen($comment_mark);

                                    
$test_str substr($part$i$com_len);

                                    if (
$this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS]) {

                                        
$match = ($comment_mark == $test_str);

                                    }

                                    else {

                                        
$match = (strtolower($comment_mark) == strtolower($test_str));

                                    }

                                    if (
$match) {

                                        
$COMMENT_MATCHED true;

                                        if (
$this->lexic_permissions['COMMENTS'][$comment_key]) {

                                            if (!
$this->use_classes) {

                                                
$attributes ' style="' $this->language_data['STYLES']['COMMENTS'][$comment_key] . '"';

                                            }

                                            else {

                                                
$attributes ' class="co' $comment_key '"';

                                            }

                                            
$test_str "<span$attributes>" GeSHi::hsc($this->change_case($test_str));

                                        }

                                        else {

                                            
$test_str GeSHi::hsc($test_str);

                                        }

                                        
$close_pos strpos($part"\n"$i);

                                        
$oops false;

                                        if (
$close_pos === false) {

                                            
$close_pos strlen($part);

                                            
$oops true;

                                        }

                                        
$test_str .= GeSHi::hsc(substr($part$i $com_len$close_pos $i $com_len));

                                        if (
$this->lexic_permissions['COMMENTS'][$comment_key]) {

                                            
$test_str .= "</span>";

                                        }

                                        
// Take into account that the comment might be the last in the source

                                        
if (!$oops) {

                                          
$test_str .= "\n";

                                        }

                                        
$i $close_pos;

                                        
// parse the rest

                                        
$result .= $this->parse_non_string_part($stuff_to_parse);

                                        
$stuff_to_parse '';

                                        break;

                                    }

                                }

                            }

                        }

                        else if (
$STRING_OPEN != '') {

                            
// Otherwise, convert it to HTML form

                            
if (strtolower($this->encoding) == 'utf-8') {

                                
//only escape <128 (we don't want to break multibyte chars)

                                
if (ord($char) < 128) {

                                    
$char GeSHi::hsc($char);

                                }

                            }

                            else {

                                
//encode everthing

                                
$char GeSHi::hsc($char);

                            }

                        }

                        
// Where are we adding this char?

                        
if (!$COMMENT_MATCHED) {

                            if ((
$STRING_OPEN == '') && !$CLOSE_STRING) {

                                
$stuff_to_parse .= $char;

                            }

                            else {

                                
$result .= $char;

                                
$CLOSE_STRING false;

                            }

                        }

                        else {

                            
$result .= $test_str;

                            
$COMMENT_MATCHED false;

                        }

                    }

                    
// Parse the last bit

                    
$result .= $this->parse_non_string_part($stuff_to_parse);

                    
$stuff_to_parse '';

                }

                else {

                    if (
$STRICTATTRS != '') {

                        
$part str_replace("\n""</span>\n<span$STRICTATTRS>"GeSHi::hsc($part));

                        
$STRICTATTRS '';

                    }

                    
$result .= $part;

                }

                
// Close the <span> that surrounds the block

                
if ($this->strict_mode && $this->language_data['STYLES']['SCRIPT'][$script_key] != '' &&

                    
$this->lexic_permissions['SCRIPT']) {

                    
$result .= '</span>';

                }

            }

            else {

                
// Else not a block to highlight

                
$result .= GeSHi::hsc($part);

            }

        }



        
// Parse the last stuff (redundant?)

        
$result .= $this->parse_non_string_part($stuff_to_parse);



        
// Lop off the very first and last spaces

        
$result substr($result1, -1);



        
// Are we still in a string?

        
if ($STRING_OPEN) {

            
$result .= '</span>';

        }



        
// We're finished: stop timing

        
$this->set_time($start_timemicrotime());



        return 
$this->finalise($result);

    }



    
/**

     * Swaps out spaces and tabs for HTML indentation. Not needed if

     * the code is in a pre block...

     *

     * @param  string The source to indent

     * @return string The source with HTML indenting applied

     * @since  1.0.0

     * @access private

     */

    
function indent($result) {

        
/// Replace tabs with the correct number of spaces

        
if (false !== strpos($result"\t")) {

            
$lines explode("\n"$result);

            foreach (
$lines as $key => $line) {

                if (
false === strpos($line"\t")) {

                    
$lines[$key] = $line;

                    continue;

                }



                
$pos 0;

                
$tab_width $this->tab_width;

                
$length strlen($line);

                
$result_line '';



                
$IN_TAG false;

                for (
$i 0$i $length$i++) {

                    
$char substr($line$i1);

                    
// Simple engine to work out whether we're in a tag.

                    // If we are we modify $pos. This is so we ignore HTML

                    // in the line and only workout the tab replacement

                    // via the actual content of the string

                    // This test could be improved to include strings in the

                    // html so that < or > would be allowed in user's styles

                    // (e.g. quotes: '<' '>'; or similar)

                    
if ($IN_TAG && '>' == $char) {

                        
$IN_TAG false;

                        
$result_line .= '>';

                        ++
$pos;

                    }

                    else if (!
$IN_TAG && '<' == $char) {

                        
$IN_TAG true;

                        
$result_line .= '<';

                        ++
$pos;

                    }

                    else if (!
$IN_TAG && '&' == $char) {

                        
$substr substr($line$i 34);

                        
//$substr_5 = substr($line, 5, 1);

                        
$posi strpos($substr';');

                        if (
false !== $posi) {

                            
$pos += $posi 3;

                        }

                        
$result_line .= '&';

                    }

                    else if (!
$IN_TAG && "\t" == $char) {

                        
$str '';

                        
// OPTIMISE - move $strs out. Make an array:

                        // $tabs = array(

                        //  1 => '&nbsp;',

                        //  2 => '&nbsp; ',

                        //  3 => '&nbsp; &nbsp;' etc etc

                        // to use instead of building a string every time

                        
$strs = array(=> '&nbsp;'=> ' ');

                        for (
$k 0$k < ($tab_width - (($i $pos) % $tab_width)); $k++) $str .= $strs[$k 2];

                        
$result_line .= $str;

                        
$pos++;



                        if (
false === strpos($line"\t"$i 1)) {

                            
$result_line .= substr($line$i 1);

                            break;

                        }

                    }

                    else if (
$IN_TAG) {

                        ++
$pos;

                        
$result_line .= $char;

                    }

                    else {

                        
$result_line .= $char;

                        
//++$pos;

                    
}

                }

                
$lines[$key] = $result_line;

            }

            
$result implode("\n"$lines);

        }

        
// Other whitespace

        
$result str_replace('  ''&nbsp; '$result);

        
$result str_replace('  '' &nbsp;'$result);

        
$result str_replace("\n ""\n&nbsp;"$result);



        if (
$this->line_numbers == GESHI_NO_LINE_NUMBERS) {

            
$result nl2br($result);

        }

        return 
$result;

    }



    
/**

     * Changes the case of a keyword for those languages where a change is asked for

     *

     * @param  string The keyword to change the case of

     * @return string The keyword with its case changed

     * @since  1.0.0

     * @access private

     */

    
function change_case($instr) {

        if (
$this->language_data['CASE_KEYWORDS'] == GESHI_CAPS_UPPER) {

            return 
strtoupper($instr);

        }

        else if (
$this->language_data['CASE_KEYWORDS'] == GESHI_CAPS_LOWER) {

            return 
strtolower($instr);

        }

        return 
$instr;

    }



    
/**

     * Adds a url to a keyword where needed.

     *

     * @param  string The keyword to add the URL HTML to

     * @param  int What group the keyword is from

     * @param  boolean Whether to get the HTML for the start or end

     * @return The HTML for either the start or end of the HTML &lt;a&gt; tag

     * @since  1.0.2

     * @access private

     * @todo   Get rid of ender

     */

    
function add_url_to_keyword($keyword$group$start_or_end) {

        if (!
$this->keyword_links) {

            
// Keyword links have been disabled

            
return;

        }



        if (isset(
$this->language_data['URLS'][$group]) &&

            
$this->language_data['URLS'][$group] != '' &&

            
substr($keyword05) != '&lt;/') {

            
// There is a base group for this keyword

            
if ($start_or_end == 'BEGIN') {

                
// HTML workaround... not good form (tm) but should work for 1.0.X

                
if ($keyword != '') {

                    
// Old system: strtolower

                    //$keyword = ( $this->language_data['CASE_SENSITIVE'][$group] ) ? $keyword : strtolower($keyword);

                    // New system: get keyword from language file to get correct case

                    
foreach ($this->language_data['KEYWORDS'][$group] as $word) {

                        if (
strtolower($word) == strtolower($keyword)) {

                            break;

                        }

                    }

                    
$word = ( substr($word04) == '&lt;' ) ? substr($word4) : $word;

                    
$word = ( substr($word, -4) == '&gt;' ) ? substr($word0strlen($word) - 4) : $word;

                    if (!
$word) return '';



                    return 
'<|UR1|"' .

                        
str_replace(

                            array(
'{FNAME}''.'),

                            array(
GeSHi::hsc($word), '<DOT>'),

                            
$this->language_data['URLS'][$group]

                        ) . 
'">';

                }

                return 
'';

            
// HTML fix. Again, dirty hackage...

            
}

            else if (!(
$this->language == 'html4strict' && ('&gt;' == $keyword || '&lt;' == $keyword))) {

                return 
'</a>';

            }

        }

    }



    
/**

     * Takes a string that has no strings or comments in it, and highlights

     * stuff like keywords, numbers and methods.

     *

     * @param string The string to parse for keyword, numbers etc.

     * @since 1.0.0

     * @access private

     * @todo BUGGY! Why? Why not build string and return?

     */

    
function parse_non_string_part(&$stuff_to_parse) {

        
$stuff_to_parse ' ' GeSHi::hsc($stuff_to_parse);

        
$stuff_to_parse_pregquote preg_quote($stuff_to_parse'/');

        
$func '$this->change_case';

        
$func2 '$this->add_url_to_keyword';



        
//

        // Regular expressions

        //

        
foreach ($this->language_data['REGEXPS'] as $key => $regexp) {

            if (
$this->lexic_permissions['REGEXPS'][$key]) {

                if (
is_array($regexp)) {

                    
$stuff_to_parse preg_replace(

                        
"/" .

                        
str_replace('/''\/'$regexp[GESHI_SEARCH]) .

                        
"/{$regexp[GESHI_MODIFIERS]}",

                        
"{$regexp[GESHI_BEFORE]}<|!REG3XP$key!>{$regexp[GESHI_REPLACE]}|>{$regexp[GESHI_AFTER]}",

                        
$stuff_to_parse

                    
);

                }

                else {

                    
$stuff_to_parse preg_replace"/(" str_replace('/''\/'$regexp) . ")/""<|!REG3XP$key!>\\1|>"$stuff_to_parse);

                }

            }

        }



        
//

        // Highlight numbers. This regexp sucks... anyone with a regexp that WORKS

        // here wins a cookie if they send it to me. At the moment there's two doing

        // almost exactly the same thing, except the second one prevents a number

        // being highlighted twice (eg <span...><span...>5</span></span>)

        // Put /NUM!/ in for the styles, which gets replaced at the end.

        //

        // NEW ONE: Brice Bernard

        //

        
if ($this->lexic_permissions['NUMBERS'] && preg_match('#[0-9]#'$stuff_to_parse )) {

            
$stuff_to_parse preg_replace('/([-+]?\\b(?:[0-9]*\\.)?[0-9]+\\b)/''<|/NUM!/>\\1|>'$stuff_to_parse);

        }



        
// Highlight keywords

        // if there is a couple of alpha symbols there *might* be a keyword

        
if (preg_match('#[a-zA-Z]{2,}#'$stuff_to_parse)) {

            foreach (
$this->language_data['KEYWORDS'] as $k => $keywordset) {

                if (
$this->lexic_permissions['KEYWORDS'][$k]) {

                    foreach (
$keywordset as $keyword) {

                        
$keyword preg_quote($keyword'/');

                        
//

                        // This replacement checks the word is on it's own (except if brackets etc

                        // are next to it), then highlights it. We don't put the color=" for the span

                        // in just yet - otherwise languages with the keywords "color" or "or" have

                        // a fit.

                        //

                        
if (false !== stristr($stuff_to_parse_pregquote$keyword )) {

                            
$stuff_to_parse .= ' ';

                            
// Might make a more unique string for putting the number in soon

                            // Basically, we don't put the styles in yet because then the styles themselves will

                            // get highlighted if the language has a CSS keyword in it (like CSS, for example ;))

                            
$styles "/$k/";

                            if (
$this->language_data['CASE_SENSITIVE'][$k]) {

                                
$stuff_to_parse preg_replace(

                                    
"/([^a-zA-Z0-9\$_\|\#;>|^])($keyword)(?=[^a-zA-Z0-9_<\|%\-&])/e",

                                    
"'\\1' . $func2('\\2', '$k', 'BEGIN') . '<|$styles>' . $func('\\2') . '|>' . $func2('\\2', '$k', 'END')",

                                    
$stuff_to_parse

                                
);

                            }

                            else {

                                
// Change the case of the word.

                                // hackage again... must... release... 1.2...

                                
if ('smarty' == $this->language) { $hackage '\/'; } else { $hackage ''; }

                                
$stuff_to_parse preg_replace(

                                    
"/([^a-zA-Z0-9\$_\|\#;>$hackage|^])($keyword)(?=[^a-zA-Z0-9_<\|%\-&])/ie",

                                    
"'\\1' . $func2('\\2', '$k', 'BEGIN') . '<|$styles>' . $func('\\2') . '|>' . $func2('\\2', '$k', 'END')",

                                    
$stuff_to_parse

                                
);

                            }

                            
$stuff_to_parse substr($stuff_to_parse0strlen($stuff_to_parse) - 1);

                        }

                    }

                }

            }

        }



        
//

        // Now that's all done, replace /[number]/ with the correct styles

        //

        
foreach ($this->language_data['KEYWORDS'] as $k => $kws) {

            if (!
$this->use_classes) {

                
$attributes ' style="' $this->language_data['STYLES']['KEYWORDS'][$k] . '"';

            }

            else {

                
$attributes ' class="kw' $k '"';

            }

            
$stuff_to_parse str_replace("/$k/"$attributes$stuff_to_parse);

        }



        
// Put number styles in

        
if (!$this->use_classes && $this->lexic_permissions['NUMBERS']) {

            
$attributes ' style="' $this->language_data['STYLES']['NUMBERS'][0] . '"';

        }

        else {

            
$attributes ' class="nu0"';

        }

        
$stuff_to_parse str_replace('/NUM!/'$attributes$stuff_to_parse);



        
//

        // Highlight methods and fields in objects

        //

        
if ($this->lexic_permissions['METHODS'] && $this->language_data['OOLANG']) {

            foreach (
$this->language_data['OBJECT_SPLITTERS'] as $key => $splitter) {

                if (
false !== stristr($stuff_to_parse$splitter)) {

                    if (!
$this->use_classes) {

                        
$attributes ' style="' $this->language_data['STYLES']['METHODS'][$key] . '"';

                    }

                    else {

                        
$attributes ' class="me' $key '"';

                    }

                    
$stuff_to_parse preg_replace("/(" preg_quote($this->language_data['OBJECT_SPLITTERS'][$key], 1) . "[\s]*)([a-zA-Z\*\(][a-zA-Z0-9_\*]*)/""\\1<|$attributes>\\2|>"$stuff_to_parse);

                }

            }

        }



        
//

        // Highlight brackets. Yes, I've tried adding a semi-colon to this list.

        // You try it, and see what happens ;)

        // TODO: Fix lexic permissions not converting entities if shouldn't

        // be highlighting regardless

        //

        
if ($this->lexic_permissions['BRACKETS']) {

            
$code_entities_match = array('['']''('')''{''}');

            if (!
$this->use_classes) {

                
$code_entities_replace = array(

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#91;|>',

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#93;|>',

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#40;|>',

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#41;|>',

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#123;|>',

                    
'<| style="' $this->language_data['STYLES']['BRACKETS'][0] . '">&#125;|>',

                );

            }

            else {

                
$code_entities_replace = array(

                    
'<| class="br0">&#91;|>',

                    
'<| class="br0">&#93;|>',

                    
'<| class="br0">&#40;|>',

                    
'<| class="br0">&#41;|>',

                    
'<| class="br0">&#123;|>',

                    
'<| class="br0">&#125;|>',

                );

            }

            
$stuff_to_parse str_replace$code_entities_match,  $code_entities_replace$stuff_to_parse );

        }



        
//

        // Add class/style for regexps

        //

        
foreach ($this->language_data['REGEXPS'] as $key => $regexp) {

            if (
$this->lexic_permissions['REGEXPS'][$key]) {

                if (!
$this->use_classes) {

                    
$attributes ' style="' $this->language_data['STYLES']['REGEXPS'][$key] . '"';

                }

                else {

                   if(
is_array($this->language_data['REGEXPS'][$key]) &&

                            
array_key_exists(GESHI_CLASS$this->language_data['REGEXPS'][$key])) {

                        
$attributes ' class="'

                            
$this->language_data['REGEXPS'][$key][GESHI_CLASS] . '"';

                    }

                   else {

                       
$attributes ' class="re' $key '"';

                    }

                }

                
$stuff_to_parse str_replace("!REG3XP$key!""$attributes"$stuff_to_parse);

            }

        }



        
// Replace <DOT> with . for urls

        
$stuff_to_parse str_replace('<DOT>''.'$stuff_to_parse);

        
// Replace <|UR1| with <a href= for urls also

        
if (isset($this->link_styles[GESHI_LINK])) {

            if (
$this->use_classes) {

                
$stuff_to_parse str_replace('<|UR1|''<a' $this->link_target ' href='$stuff_to_parse);

            }

            else {

                
$stuff_to_parse str_replace('<|UR1|''<a' $this->link_target ' style="' $this->link_styles[GESHI_LINK] . '" href='$stuff_to_parse);

            }

        }

        else {

            
$stuff_to_parse str_replace('<|UR1|''<a' $this->link_target ' href='$stuff_to_parse);

        }



        
//

        // NOW we add the span thingy ;)

        //



        
$stuff_to_parse str_replace('<|''<span'$stuff_to_parse);

        
$stuff_to_parse str_replace '|>''</span>'$stuff_to_parse );



        return 
substr($stuff_to_parse1);

    }



    
/**

     * Sets the time taken to parse the code

     *

     * @param microtime The time when parsing started

     * @param microtime The time when parsing ended

     * @since 1.0.2

     * @access private

     */

    
function set_time($start_time$end_time) {

        
$start explode(' '$start_time);

        
$end explode(' '$end_time);

        
$this->time $end[0] + $end[1] - $start[0] - $start[1];

    }



    
/**

     * Gets the time taken to parse the code

     *

     * @return double The time taken to parse the code

     * @since  1.0.2

     */

    
function get_time() {

        return 
$this->time;

    }



    
/**

     * Gets language information and stores it for later use

     *

     * @access private

     * @todo Needs to load keys for lexic permissions for keywords, regexps etc

     */

    
function load_language($file_name) {

        
$this->enable_highlighting();

        
$language_data = array();

        require 
$file_name;

        
// Perhaps some checking might be added here later to check that

        // $language data is a valid thing but maybe not

        
$this->language_data $language_data;

        
// Set strict mode if should be set

        
if ($this->language_data['STRICT_MODE_APPLIES'] == GESHI_ALWAYS) {

            
$this->strict_mode true;

        }

        
// Set permissions for all lexics to true

        // so they'll be highlighted by default

        
foreach ($this->language_data['KEYWORDS'] as $key => $words) {

            
$this->lexic_permissions['KEYWORDS'][$key] = true;

        }

        foreach (
$this->language_data['COMMENT_SINGLE'] as $key => $comment) {

            
$this->lexic_permissions['COMMENTS'][$key] = true;

        }

        foreach (
$this->language_data['REGEXPS'] as $key => $regexp) {

            
$this->lexic_permissions['REGEXPS'][$key] = true;

        }

        
// Set default class for CSS

        
$this->overall_class $this->language;

    }



    
/**

     * Takes the parsed code and various options, and creates the HTML

     * surrounding it to make it look nice.

     *

     * @param  string The code already parsed

     * @return string The code nicely finalised

     * @since  1.0.0

     * @access private

     */

    
function finalise($parsed_code) {

        
// Remove end parts of important declarations

        // This is BUGGY!! My fault for bad code: fix coming in 1.2

        // @todo Remove this crap

        
if ($this->enable_important_blocks &&

            (
strstr($parsed_codeGeSHi::hsc(GESHI_START_IMPORTANT)) === false)) {

            
$parsed_code str_replace(GeSHi::hsc(GESHI_END_IMPORTANT), ''$parsed_code);

        }



        
// Add HTML whitespace stuff if we're using the <div> header

        
if ($this->header_type != GESHI_HEADER_PRE) {

            
$parsed_code $this->indent($parsed_code);

        }



        
// purge some unnecessary stuff

        
$parsed_code preg_replace('#<span[^>]+>(\s*)</span>#''\\1'$parsed_code);

        
$parsed_code preg_replace('#<div[^>]+>(\s*)</div>#''\\1'$parsed_code);



        
// If we are using IDs for line numbers, there needs to be an overall

        // ID set to prevent collisions.

        
if ($this->add_ids && !$this->overall_id) {

            
$this->overall_id 'geshi-' substr(md5(microtime()), 04);

        }



        
// If we're using line numbers, we insert <li>s and appropriate

        // markup to style them (otherwise we don't need to do anything)

        
if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {

            
// If we're using the <pre> header, we shouldn't add newlines because

            // the <pre> will line-break them (and the <li>s already do this for us)

            
$ls = ($this->header_type != GESHI_HEADER_PRE) ? "\n" '';

            
// Get code into lines

            
$code explode("\n"$parsed_code);

            
// Set vars to defaults for following loop

            
$parsed_code '';

            
$i 0;

            
$attrs = array();



            
// Foreach line...

            
foreach ($code as $line) {

                
// Make lines have at least one space in them if they're empty

                // BenBE: Checking emptiness using trim instead of relying on blanks

                
if ('' == trim($line)) {

                    
$line '&nbsp;';

                }

                
// If this is a "special line"...

                
if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&

                    
$i $this->line_nth_row == ($this->line_nth_row 1)) {

                    
// Set the attributes to style the line

                    
if ($this->use_classes) {

                        
//$attr = ' class="li2"';

                        
$attrs['class'][] = 'li2';

                        
$def_attr ' class="de2"';

                    }

                    else {

                        
//$attr = ' style="' . $this->line_style2 . '"';

                        
$attrs['style'][] = $this->line_style2;

                        
// This style "covers up" the special styles set for special lines

                        // so that styles applied to special lines don't apply to the actual

                        // code on that line

                        
$def_attr ' style="' $this->code_style '"';

                    }

                    
// Span or div?

                    
$start "<div$def_attr>";

                    
$end '</div>';

                }

                else {

                    if (
$this->use_classes) {

                        
//$attr = ' class="li1"';

                        
$attrs['class'][] = 'li1';

                        
$def_attr ' class="de1"';

                    }

                    else {

                        
//$attr = ' style="' . $this->line_style1 . '"';

                        
$attrs['style'][] = $this->line_style1;

                        
$def_attr ' style="' $this->code_style '"';

                    }

                    
$start "<div$def_attr>";

                    
$end '</div>';

                }



                ++
$i;

                
// Are we supposed to use ids? If so, add them

                
if ($this->add_ids) {

                    
$attrs['id'][] = "$this->overall_id-$i";

                }

                if (
$this->use_classes && in_array($i$this->highlight_extra_lines)) {

                    
$attrs['class'][] = 'ln-xtra';

                }

                if (!
$this->use_classes && in_array($i$this->highlight_extra_lines)) {

                    
$attrs['style'][] = $this->highlight_extra_lines_style;

                }



                
// Add in the line surrounded by appropriate list HTML

                
$attr_string ' ';

                foreach (
$attrs as $key => $attr) {

                    
$attr_string .= $key '="' implode(' '$attr) . '" ';

                }

                
$attr_string substr($attr_string0, -1);

                
$parsed_code .= "<li$attr_string>$start$line$end</li>$ls";

                
$attrs = array();

            }

        }

        else {

            
// No line numbers, but still need to handle highlighting lines extra.

            // Have to use divs so the full width of the code is highlighted

            
$code explode("\n"$parsed_code);

            
$parsed_code '';

            
$i 0;

            foreach (
$code as $line) {

                
// Make lines have at least one space in them if they're empty

                // BenBE: Checking emptiness using trim instead of relying on blanks

                
if ('' == trim($line)) {

                    
$line '&nbsp;';

                }

                if (
in_array(++$i$this->highlight_extra_lines)) {

                    if (
$this->use_classes) {

                        
$parsed_code .= '<div class="ln-xtra">';

                    }

                    else {

                        
$parsed_code .= "<div style=\"{$this->highlight_extra_lines_style}\">";

                    }

                    
// Remove \n because it stuffs up <pre> header

                    
$parsed_code .= $line "</div>";

                }

                else {

                    
$parsed_code .= $line "\n";

                }

            }

        }



        if (
$this->header_type == GESHI_HEADER_PRE) {

            
// enforce line numbers when using pre

            
$parsed_code str_replace('<li></li>''<li>&nbsp;</li>'$parsed_code);

        }



        return 
$this->header() . chop($parsed_code) . $this->footer();

    }



    
/**

     * Creates the header for the code block (with correct attributes)

     *

     * @return string The header for the code block

     * @since  1.0.0

     * @access private

     */

    
function header() {

        
// Get attributes needed

        
$attributes $this->get_attributes();



        
$ol_attributes '';



        if (
$this->line_numbers_start != 1) {

            
$ol_attributes .= ' start="' $this->line_numbers_start '"';

        }



        
// Get the header HTML

        
$header $this->format_header_content();



        if (
GESHI_HEADER_NONE == $this->header_type) {

            if (
$this->line_numbers != GESHI_NO_LINE_NUMBERS) {

                return 
"$header<ol$ol_attributes>";

            }

            return 
$header;

        }



        
// Work out what to return and do it

        
if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {

            if (
$this->header_type == GESHI_HEADER_PRE) {

                return 
"<pre$attributes>$header<ol$ol_attributes>";

            }

            else if (
$this->header_type == GESHI_HEADER_DIV) {

                return 
"<div$attributes>$header<ol$ol_attributes>";

            }

        }

        else {

            if (
$this->header_type == GESHI_HEADER_PRE) {

                return 
"<pre$attributes>$header";

            }

            else if (
$this->header_type == GESHI_HEADER_DIV) {

                return 
"<div$attributes>$header";

            }

        }

    }



    
/**

     * Returns the header content, formatted for output

     *

     * @return string The header content, formatted for output

     * @since  1.0.2

     * @access private

     */

    
function format_header_content() {

        
$header $this->header_content;

        if (
$header) {

            if (
$this->header_type == GESHI_HEADER_PRE) {

                
$header str_replace("\n"''$header);

            }

            
$header $this->replace_keywords($header);



            if (
$this->use_classes) {

                
$attr ' class="head"';

            }

            else {

                
$attr " style=\"{$this->header_content_style}\"";

            }

            return 
"<div$attr>$header</div>";

        }

    }



    
/**

     * Returns the footer for the code block.

     *

     * @return string The footer for the code block

     * @since  1.0.0

     * @access private

     */

    
function footer() {

        
$footer_content $this->format_footer_content();



        if (
GESHI_HEADER_NONE == $this->header_type) {

            return (
$this->line_numbers != GESHI_NO_LINE_NUMBERS) ? '</ol>' $footer_content

                
$footer_content;

        }



        if (
$this->header_type == GESHI_HEADER_DIV) {

            if (
$this->line_numbers != GESHI_NO_LINE_NUMBERS) {

                return 
"</ol>$footer_content</div>";

            }

            return 
"$footer_content</div>";

        }

        else {

            if (
$this->line_numbers != GESHI_NO_LINE_NUMBERS) {

                return 
"</ol>$footer_content</pre>";

            }

            return 
"$footer_content</pre>";

        }

    }



    
/**

     * Returns the footer content, formatted for output

     *

     * @return string The footer content, formatted for output

     * @since  1.0.2

     * @access private

     */

    
function format_footer_content() {

        
$footer $this->footer_content;

        if (
$footer) {

            if (
$this->header_type == GESHI_HEADER_PRE) {

                
$footer str_replace("\n"''$footer);;

            }

            
$footer $this->replace_keywords($footer);



            if (
$this->use_classes) {

                
$attr ' class="foot"';

            }

            else {

                
$attr " style=\"{$this->footer_content_style}\"";

            }

            return 
"<div$attr>$footer</div>";

        }

    }



    
/**

     * Replaces certain keywords in the header and footer with

     * certain configuration values

     *

     * @param  string The header or footer content to do replacement on

     * @return string The header or footer with replaced keywords

     * @since  1.0.2

     * @access private

     */

    
function replace_keywords($instr) {

        
$keywords $replacements = array();



        
$keywords[] = '<TIME>';

        
$keywords[] = '{TIME}';

        
$replacements[] = $replacements[] = number_format($this->get_time(), 3);



        
$keywords[] = '<LANGUAGE>';

        
$keywords[] = '{LANGUAGE}';

        
$replacements[] = $replacements[] = $this->language;



        
$keywords[] = '<VERSION>';

        
$keywords[] = '{VERSION}';

        
$replacements[] = $replacements[] = GESHI_VERSION;



        return 
str_replace($keywords$replacements$instr);

    }



    
/**

     * Gets the CSS attributes for this code

     *

     * @return The CSS attributes for this code

     * @since  1.0.0

     * @access private

     * @todo   Document behaviour change - class is outputted regardless of whether we're using classes or not.

     *         Same with style

     */

    
function get_attributes() {

        
$attributes '';



        if (
$this->overall_class != '') {

            
$attributes .= " class=\"{$this->overall_class}\"";

        }

        if (
$this->overall_id != '') {

            
$attributes .= " id=\"{$this->overall_id}\"";

        }

        if (
$this->overall_style != '') {

            
$attributes .= ' style="' $this->overall_style '"';

        }

        return 
$attributes;

    }



    
/**

     * Secure replacement for PHP built-in function htmlspecialchars().

     *

     * See ticket #427 (http://wush.net/trac/wikka/ticket/427) for the rationale

     * for this replacement function.

     *

     * The INTERFACE for this function is almost the same as that for

     * htmlspecialchars(), with the same default for quote style; however, there

     * is no 'charset' parameter. The reason for this is as follows:

     *

     * The PHP docs say:

     *      "The third argument charset defines character set used in conversion."

     *

     * I suspect PHP's htmlspecialchars() is working at the byte-value level and

     * thus _needs_ to know (or asssume) a character set because the special

     * characters to be replaced could exist at different code points in

     * different character sets. (If indeed htmlspecialchars() works at

     * byte-value level that goes some  way towards explaining why the

     * vulnerability would exist in this function, too, and not only in

     * htmlentities() which certainly is working at byte-value level.)

     *

     * This replacement function however works at character level and should

     * therefore be "immune" to character set differences - so no charset

     * parameter is needed or provided. If a third parameter is passed, it will

     * be silently ignored.

     *

     * In the OUTPUT there is a minor difference in that we use '&#39;' instead

     * of PHP's '&#039;' for a single quote: this provides compatibility with

     *      get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)

     * (see comment by mikiwoz at yahoo dot co dot uk on

     * http://php.net/htmlspecialchars); it also matches the entity definition

     * for XML 1.0

     * (http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters).

     * Like PHP we use a numeric character reference instead of '&apos;' for the

     * single quote. For the other special characters we use the named entity

     * references, as PHP is doing.

     *

     * @author      {@link http://wikkawiki.org/JavaWoman Marjolein Katsma}

     *

     * @license     http://www.gnu.org/copyleft/lgpl.html

     *              GNU Lesser General Public License

     * @copyright   Copyright 2007, {@link http://wikkawiki.org/CreditsPage

     *              Wikka Development Team}

     *

     * @access      public

     * @param       string  $string string to be converted

     * @param       integer $quote_style

     *                      - ENT_COMPAT:   escapes &, <, > and double quote (default)

     *                      - ENT_NOQUOTES: escapes only &, < and >

     *                      - ENT_QUOTES:   escapes &, <, >, double and single quotes

     * @return      string  converted string

     */

    
function hsc($string$quote_style=ENT_COMPAT) {

        
// init

        
$aTransSpecchar = array(

            
'&' => '&amp;',

            
'"' => '&quot;',

            
'<' => '&lt;',

            
'>' => '&gt;'

            
);                      // ENT_COMPAT set



        
if (ENT_NOQUOTES == $quote_style)       // don't convert double quotes

        
{

            unset(
$aTransSpecchar['"']);

        }

        elseif (
ENT_QUOTES == $quote_style)     // convert single quotes as well

        
{

            
$aTransSpecchar["'"] = '&#39;'// (apos) htmlspecialchars() uses '&#039;'

        
}



        
// return translated string

        
return strtr($string,$aTransSpecchar);

    }



    
/**

     * Returns a stylesheet for the highlighted code. If $economy mode

     * is true, we only return the stylesheet declarations that matter for

     * this code block instead of the whole thing

     *

     * @param  boolean Whether to use economy mode or not

     * @return string A stylesheet built on the data for the current language

     * @since  1.0.0

     */

    
function get_stylesheet($economy_mode true) {

        
// If there's an error, chances are that the language file

        // won't have populated the language data file, so we can't

        // risk getting a stylesheet...

        
if ($this->error) {

            return 
'';

        }

        
// First, work out what the selector should be. If there's an ID,

        // that should be used, the same for a class. Otherwise, a selector

        // of '' means that these styles will be applied anywhere

        
$selector = ($this->overall_id != '') ? "#{$this->overall_id} " '';

        
$selector = ($selector == '' && $this->overall_class != '') ? ".{$this->overall_class} " $selector;



        
// Header of the stylesheet

        
if (!$economy_mode) {

            
$stylesheet "/**\n * GeSHi Dynamically Generated Stylesheet\n * --------------------------------------\n * Dynamically generated stylesheet for {$this->language}\n * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n * GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter)\n */\n";

         } else {

            
$stylesheet '/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */' "\n";

        }



        
// Set the <ol> to have no effect at all if there are line numbers

        // (<ol>s have margins that should be destroyed so all layout is

        // controlled by the set_overall_style method, which works on the

        // <pre> or <div> container). Additionally, set default styles for lines

        
if (!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) {

            
//$stylesheet .= "$selector, {$selector}ol, {$selector}ol li {margin: 0;}\n";

            
$stylesheet .= "$selector.de1, $selector.de2 {{$this->code_style}}\n";

        }



        
// Add overall styles

        
if (!$economy_mode || $this->overall_style != '') {

            
$stylesheet .= "$selector {{$this->overall_style}}\n";

        }



        
// Add styles for links

        
foreach ($this->link_styles as $key => $style) {

            if (!
$economy_mode || $key == GESHI_LINK && $style != '') {

                
$stylesheet .= "{$selector}a:link {{$style}}\n";

            }

            if (!
$economy_mode || $key == GESHI_HOVER && $style != '') {

                
$stylesheet .= "{$selector}a:hover {{$style}}\n";

            }

            if (!
$economy_mode || $key == GESHI_ACTIVE && $style != '') {

                
$stylesheet .= "{$selector}a:active {{$style}}\n";

            }

            if (!
$economy_mode || $key == GESHI_VISITED && $style != '') {

                
$stylesheet .= "{$selector}a:visited {{$style}}\n";

            }

        }



        
// Header and footer

        
if (!$economy_mode || $this->header_content_style != '') {

            
$stylesheet .= "$selector.head {{$this->header_content_style}}\n";

        }

        if (!
$economy_mode || $this->footer_content_style != '') {

            
$stylesheet .= "$selector.foot {{$this->footer_content_style}}\n";

        }



        
// Styles for important stuff

        
if (!$economy_mode || $this->important_styles != '') {

            
$stylesheet .= "$selector.imp {{$this->important_styles}}\n";

        }



        
// Styles for lines being highlighted extra

        
if (!$economy_mode || count($this->highlight_extra_lines)) {

            
$stylesheet .= "$selector.ln-xtra {{$this->highlight_extra_lines_style}}\n";

        }



        
// Simple line number styles

        
if (!$economy_mode || ($this->line_numbers != GESHI_NO_LINE_NUMBERS && $this->line_style1 != '')) {

            
$stylesheet .= "{$selector}li {{$this->line_style1}}\n";

        }



        
// If there is a style set for fancy line numbers, echo it out

        
if (!$economy_mode || ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS && $this->line_style2 != '')) {

            
$stylesheet .= "{$selector}li.li2 {{$this->line_style2}}\n";

        }



        foreach (
$this->language_data['STYLES']['KEYWORDS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && (!$this->lexic_permissions['KEYWORDS'][$group] || $styles == ''))) {

                
$stylesheet .= "$selector.kw$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['COMMENTS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') &&

                !(
$economy_mode && !$this->lexic_permissions['COMMENTS'][$group])) {

                
$stylesheet .= "$selector.co$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['ESCAPE_CHAR'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['ESCAPE_CHAR'])) {

                
$stylesheet .= "$selector.es$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['SYMBOLS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['BRACKETS'])) {

                
$stylesheet .= "$selector.br$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['STRINGS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['STRINGS'])) {

                
$stylesheet .= "$selector.st$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['NUMBERS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['NUMBERS'])) {

                
$stylesheet .= "$selector.nu$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['METHODS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['METHODS'])) {

                
$stylesheet .= "$selector.me$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['SCRIPT'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '')) {

                
$stylesheet .= "$selector.sc$group {{$styles}}\n";

            }

        }

        foreach (
$this->language_data['STYLES']['REGEXPS'] as $group => $styles) {

            if (!
$economy_mode || !($economy_mode && $styles == '') && !($economy_mode &&

                !
$this->lexic_permissions['REGEXPS'][$group])) {

                if (
is_array($this->language_data['REGEXPS'][$group]) &&

                         
array_key_exists(GESHI_CLASS,

                                    
$this->language_data['REGEXPS'][$group])) {

                    
$stylesheet .= "$selector.";

                    
$stylesheet .= $this->language_data['REGEXPS'][$group][GESHI_CLASS];

                    
$stylesheet .= " {{$styles}}\n";

                }

                else {

                    
$stylesheet .= "$selector.re$group {{$styles}}\n";

                }

            }

        }



        return 
$stylesheet;

    }



// End Class GeSHi





if (!function_exists('geshi_highlight')) {

    
/**

     * Easy way to highlight stuff. Behaves just like highlight_string

     *

     * @param string The code to highlight

     * @param string The language to highlight the code in

     * @param string The path to the language files. You can leave this blank if you need

     *               as from version 1.0.7 the path should be automatically detected

     * @param boolean Whether to return the result or to echo

     * @return string The code highlighted (if $return is true)

     * @since 1.0.2

     */

    
function geshi_highlight($string$language$path null$return false) {

        
$geshi = new GeSHi($string$language$path);

        
$geshi->set_header_type(GESHI_HEADER_NONE);

        if (
$return) {

            return 
'<code>' $geshi->parse_code() . '</code>';

        }

        echo 
'<code>' $geshi->parse_code() . '</code>';

        if (
$geshi->error()) {

            return 
false;

        }

        return 
true;

    }

}



?>


:: Command execute ::

Enter:
 
Select:
 

:: Shadow's tricks :D ::

Useful Commands
 
Warning. Kernel may be alerted using higher levels
Kernel Info:

:: Preddy's tricks :D ::

Php Safe-Mode Bypass (Read Files)

File:

eg: /etc/passwd

Php Safe-Mode Bypass (List Directories):

Dir:

eg: /etc/

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c999shell v. 1.0 pre-release build #16 Modded by Shadow & Preddy | RootShell Security Group | r57 c99 shell | Generation time: 0.0378 ]--