PageRenderTime 81ms CodeModel.GetById 20ms app.highlight 40ms RepoModel.GetById 1ms app.codeStats 2ms

/plugins/content/geshi/geshi/geshi.php

https://bitbucket.org/asosso/joomla25
PHP | 4758 lines | 2706 code | 404 blank | 1648 comment | 704 complexity | a42450e098d3a226bab73b7d462896ce MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2// no direct access
   3defined('_JEXEC') or die;
   4
   5/**
   6 * GeSHi - Generic Syntax Highlighter
   7 *
   8 * The GeSHi class for Generic Syntax Highlighting. Please refer to the
   9 * documentation at http://qbnz.com/highlighter/documentation.php for more
  10 * information about how to use this class.
  11 *
  12 * For changes, release notes, TODOs etc, see the relevant files in the docs/
  13 * directory.
  14 *
  15 *   This file is part of GeSHi.
  16 *
  17 *  GeSHi is free software; you can redistribute it and/or modify
  18 *  it under the terms of the GNU General Public License as published by
  19 *  the Free Software Foundation; either version 2 of the License, or
  20 *  (at your option) any later version.
  21 *
  22 *  GeSHi is distributed in the hope that it will be useful,
  23 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25 *  GNU General Public License for more details.
  26 *
  27 *  You should have received a copy of the GNU General Public License
  28 *  along with GeSHi; if not, write to the Free Software
  29 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  30 *
  31 * @package    geshi
  32 * @subpackage core
  33 * @author     Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
  34 * @copyright  (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
  35 * @license    http://gnu.org/copyleft/gpl.html GNU GPL
  36 *
  37 */
  38
  39//
  40// GeSHi Constants
  41// You should use these constant names in your programs instead of
  42// their values - you never know when a value may change in a future
  43// version
  44//
  45
  46/** The version of this GeSHi file */
  47define('GESHI_VERSION', '1.0.8.10');
  48
  49// Define the root directory for the GeSHi code tree
  50if (!defined('GESHI_ROOT')) {
  51    /** The root directory for GeSHi */
  52    define('GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
  53}
  54/** The language file directory for GeSHi
  55    @access private */
  56define('GESHI_LANG_ROOT', GESHI_ROOT . 'geshi' . DIRECTORY_SEPARATOR);
  57
  58// Define if GeSHi should be paranoid about security
  59if (!defined('GESHI_SECURITY_PARANOID')) {
  60    /** Tells GeSHi to be paranoid about security settings */
  61    define('GESHI_SECURITY_PARANOID', false);
  62}
  63
  64// Line numbers - use with enable_line_numbers()
  65/** Use no line numbers when building the result */
  66define('GESHI_NO_LINE_NUMBERS', 0);
  67/** Use normal line numbers when building the result */
  68define('GESHI_NORMAL_LINE_NUMBERS', 1);
  69/** Use fancy line numbers when building the result */
  70define('GESHI_FANCY_LINE_NUMBERS', 2);
  71
  72// Container HTML type
  73/** Use nothing to surround the source */
  74define('GESHI_HEADER_NONE', 0);
  75/** Use a "div" to surround the source */
  76define('GESHI_HEADER_DIV', 1);
  77/** Use a "pre" to surround the source */
  78define('GESHI_HEADER_PRE', 2);
  79/** Use a pre to wrap lines when line numbers are enabled or to wrap the whole code. */
  80define('GESHI_HEADER_PRE_VALID', 3);
  81/**
  82 * Use a "table" to surround the source:
  83 *
  84 *  <table>
  85 *    <thead><tr><td colspan="2">$header</td></tr></thead>
  86 *    <tbody><tr><td><pre>$linenumbers</pre></td><td><pre>$code></pre></td></tr></tbody>
  87 *    <tfooter><tr><td colspan="2">$footer</td></tr></tfoot>
  88 *  </table>
  89 *
  90 * this is essentially only a workaround for Firefox, see sf#1651996 or take a look at
  91 * https://bugzilla.mozilla.org/show_bug.cgi?id=365805
  92 * @note when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE
  93 */
  94define('GESHI_HEADER_PRE_TABLE', 4);
  95
  96// Capatalisation constants
  97/** Lowercase keywords found */
  98define('GESHI_CAPS_NO_CHANGE', 0);
  99/** Uppercase keywords found */
 100define('GESHI_CAPS_UPPER', 1);
 101/** Leave keywords found as the case that they are */
 102define('GESHI_CAPS_LOWER', 2);
 103
 104// Link style constants
 105/** Links in the source in the :link state */
 106define('GESHI_LINK', 0);
 107/** Links in the source in the :hover state */
 108define('GESHI_HOVER', 1);
 109/** Links in the source in the :active state */
 110define('GESHI_ACTIVE', 2);
 111/** Links in the source in the :visited state */
 112define('GESHI_VISITED', 3);
 113
 114// Important string starter/finisher
 115// Note that if you change these, they should be as-is: i.e., don't
 116// write them as if they had been run through htmlentities()
 117/** The starter for important parts of the source */
 118define('GESHI_START_IMPORTANT', '<BEGIN GeSHi>');
 119/** The ender for important parts of the source */
 120define('GESHI_END_IMPORTANT', '<END GeSHi>');
 121
 122/**#@+
 123 *  @access private
 124 */
 125// When strict mode applies for a language
 126/** Strict mode never applies (this is the most common) */
 127define('GESHI_NEVER', 0);
 128/** Strict mode *might* apply, and can be enabled or
 129    disabled by {@link GeSHi->enable_strict_mode()} */
 130define('GESHI_MAYBE', 1);
 131/** Strict mode always applies */
 132define('GESHI_ALWAYS', 2);
 133
 134// Advanced regexp handling constants, used in language files
 135/** The key of the regex array defining what to search for */
 136define('GESHI_SEARCH', 0);
 137/** The key of the regex array defining what bracket group in a
 138    matched search to use as a replacement */
 139define('GESHI_REPLACE', 1);
 140/** The key of the regex array defining any modifiers to the regular expression */
 141define('GESHI_MODIFIERS', 2);
 142/** The key of the regex array defining what bracket group in a
 143    matched search to put before the replacement */
 144define('GESHI_BEFORE', 3);
 145/** The key of the regex array defining what bracket group in a
 146    matched search to put after the replacement */
 147define('GESHI_AFTER', 4);
 148/** The key of the regex array defining a custom keyword to use
 149    for this regexp's html tag class */
 150define('GESHI_CLASS', 5);
 151
 152/** Used in language files to mark comments */
 153define('GESHI_COMMENTS', 0);
 154
 155/** Used to work around missing PHP features **/
 156define('GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, '4.3.3') === 1));
 157
 158/** make sure we can call stripos **/
 159if (!function_exists('stripos')) {
 160    // the offset param of preg_match is not supported below PHP 4.3.3
 161    if (GESHI_PHP_PRE_433) {
 162        /**
 163         * @ignore
 164         */
 165        function stripos($haystack, $needle, $offset = null) {
 166            if (!is_null($offset)) {
 167                $haystack = substr($haystack, $offset);
 168            }
 169            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
 170                return $match[0][1];
 171            }
 172            return false;
 173        }
 174    }
 175    else {
 176        /**
 177         * @ignore
 178         */
 179        function stripos($haystack, $needle, $offset = null) {
 180            if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
 181                return $match[0][1];
 182            }
 183            return false;
 184        }
 185    }
 186}
 187
 188/** some old PHP / PCRE subpatterns only support up to xxx subpatterns in
 189    regular expressions. Set this to false if your PCRE lib is up to date
 190    @see GeSHi->optimize_regexp_list()
 191    **/
 192define('GESHI_MAX_PCRE_SUBPATTERNS', 500);
 193/** it's also important not to generate too long regular expressions
 194    be generous here... but keep in mind, that when reaching this limit we
 195    still have to close open patterns. 12k should do just fine on a 16k limit.
 196    @see GeSHi->optimize_regexp_list()
 197    **/
 198define('GESHI_MAX_PCRE_LENGTH', 12288);
 199
 200//Number format specification
 201/** Basic number format for integers */
 202define('GESHI_NUMBER_INT_BASIC', 1);        //Default integers \d+
 203/** Enhanced number format for integers like seen in C */
 204define('GESHI_NUMBER_INT_CSTYLE', 2);       //Default C-Style \d+[lL]?
 205/** Number format to highlight binary numbers with a suffix "b" */
 206define('GESHI_NUMBER_BIN_SUFFIX', 16);           //[01]+[bB]
 207/** Number format to highlight binary numbers with a prefix % */
 208define('GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   //%[01]+
 209/** Number format to highlight binary numbers with a prefix 0b (C) */
 210define('GESHI_NUMBER_BIN_PREFIX_0B', 64);        //0b[01]+
 211/** Number format to highlight octal numbers with a leading zero */
 212define('GESHI_NUMBER_OCT_PREFIX', 256);           //0[0-7]+
 213/** Number format to highlight octal numbers with a prefix 0o (logtalk) */
 214define('GESHI_NUMBER_OCT_PREFIX_0O', 512);           //0[0-7]+
 215/** Number format to highlight octal numbers with a leading @ (Used in HiSofts Devpac series). */
 216define('GESHI_NUMBER_OCT_PREFIX_AT', 1024);           //@[0-7]+
 217/** Number format to highlight octal numbers with a suffix of o */
 218define('GESHI_NUMBER_OCT_SUFFIX', 2048);           //[0-7]+[oO]
 219/** Number format to highlight hex numbers with a prefix 0x */
 220define('GESHI_NUMBER_HEX_PREFIX', 4096);           //0x[0-9a-fA-F]+
 221/** Number format to highlight hex numbers with a prefix $ */
 222define('GESHI_NUMBER_HEX_PREFIX_DOLLAR', 8192);           //$[0-9a-fA-F]+
 223/** Number format to highlight hex numbers with a suffix of h */
 224define('GESHI_NUMBER_HEX_SUFFIX', 16384);           //[0-9][0-9a-fA-F]*h
 225/** Number format to highlight floating-point numbers without support for scientific notation */
 226define('GESHI_NUMBER_FLT_NONSCI', 65536);          //\d+\.\d+
 227/** Number format to highlight floating-point numbers without support for scientific notation */
 228define('GESHI_NUMBER_FLT_NONSCI_F', 131072);       //\d+(\.\d+)?f
 229/** Number format to highlight floating-point numbers with support for scientific notation (E) and optional leading zero */
 230define('GESHI_NUMBER_FLT_SCI_SHORT', 262144);      //\.\d+e\d+
 231/** Number format to highlight floating-point numbers with support for scientific notation (E) and required leading digit */
 232define('GESHI_NUMBER_FLT_SCI_ZERO', 524288);       //\d+(\.\d+)?e\d+
 233//Custom formats are passed by RX array
 234
 235// Error detection - use these to analyse faults
 236/** No sourcecode to highlight was specified
 237 * @deprecated
 238 */
 239define('GESHI_ERROR_NO_INPUT', 1);
 240/** The language specified does not exist */
 241define('GESHI_ERROR_NO_SUCH_LANG', 2);
 242/** GeSHi could not open a file for reading (generally a language file) */
 243define('GESHI_ERROR_FILE_NOT_READABLE', 3);
 244/** The header type passed to {@link GeSHi->set_header_type()} was invalid */
 245define('GESHI_ERROR_INVALID_HEADER_TYPE', 4);
 246/** The line number type passed to {@link GeSHi->enable_line_numbers()} was invalid */
 247define('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
 248/**#@-*/
 249
 250
 251/**
 252 * The GeSHi Class.
 253 *
 254 * Please refer to the documentation for GeSHi 1.0.X that is available
 255 * at http://qbnz.com/highlighter/documentation.php for more information
 256 * about how to use this class.
 257 *
 258 * @package   geshi
 259 * @author    Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
 260 * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
 261 */
 262class GeSHi {
 263    /**#@+
 264     * @access private
 265     */
 266    /**
 267     * The source code to highlight
 268     * @var string
 269     */
 270    var $source = '';
 271
 272    /**
 273     * The language to use when highlighting
 274     * @var string
 275     */
 276    var $language = '';
 277
 278    /**
 279     * The data for the language used
 280     * @var array
 281     */
 282    var $language_data = array();
 283
 284    /**
 285     * The path to the language files
 286     * @var string
 287     */
 288    var $language_path = GESHI_LANG_ROOT;
 289
 290    /**
 291     * The error message associated with an error
 292     * @var string
 293     * @todo check err reporting works
 294     */
 295    var $error = false;
 296
 297    /**
 298     * Possible error messages
 299     * @var array
 300     */
 301    var $error_messages = array(
 302        GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',
 303        GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',
 304        GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',
 305        GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'
 306    );
 307
 308    /**
 309     * Whether highlighting is strict or not
 310     * @var boolean
 311     */
 312    var $strict_mode = false;
 313
 314    /**
 315     * Whether to use CSS classes in output
 316     * @var boolean
 317     */
 318    var $use_classes = false;
 319
 320    /**
 321     * The type of header to use. Can be one of the following
 322     * values:
 323     *
 324     * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.
 325     * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.
 326     * - GESHI_HEADER_NONE: No header is outputted.
 327     *
 328     * @var int
 329     */
 330    var $header_type = GESHI_HEADER_PRE;
 331
 332    /**
 333     * Array of permissions for which lexics should be highlighted
 334     * @var array
 335     */
 336    var $lexic_permissions = array(
 337        'KEYWORDS' =>    array(),
 338        'COMMENTS' =>    array('MULTI' => true),
 339        'REGEXPS' =>     array(),
 340        'ESCAPE_CHAR' => true,
 341        'BRACKETS' =>    true,
 342        'SYMBOLS' =>     false,
 343        'STRINGS' =>     true,
 344        'NUMBERS' =>     true,
 345        'METHODS' =>     true,
 346        'SCRIPT' =>      true
 347    );
 348
 349    /**
 350     * The time it took to parse the code
 351     * @var double
 352     */
 353    var $time = 0;
 354
 355    /**
 356     * The content of the header block
 357     * @var string
 358     */
 359    var $header_content = '';
 360
 361    /**
 362     * The content of the footer block
 363     * @var string
 364     */
 365    var $footer_content = '';
 366
 367    /**
 368     * The style of the header block
 369     * @var string
 370     */
 371    var $header_content_style = '';
 372
 373    /**
 374     * The style of the footer block
 375     * @var string
 376     */
 377    var $footer_content_style = '';
 378
 379    /**
 380     * Tells if a block around the highlighted source should be forced
 381     * if not using line numbering
 382     * @var boolean
 383     */
 384    var $force_code_block = false;
 385
 386    /**
 387     * The styles for hyperlinks in the code
 388     * @var array
 389     */
 390    var $link_styles = array();
 391
 392    /**
 393     * Whether important blocks should be recognised or not
 394     * @var boolean
 395     * @deprecated
 396     * @todo REMOVE THIS FUNCTIONALITY!
 397     */
 398    var $enable_important_blocks = false;
 399
 400    /**
 401     * Styles for important parts of the code
 402     * @var string
 403     * @deprecated
 404     * @todo As above - rethink the whole idea of important blocks as it is buggy and
 405     * will be hard to implement in 1.2
 406     */
 407    var $important_styles = 'font-weight: bold; color: red;'; // Styles for important parts of the code
 408
 409    /**
 410     * Whether CSS IDs should be added to the code
 411     * @var boolean
 412     */
 413    var $add_ids = false;
 414
 415    /**
 416     * Lines that should be highlighted extra
 417     * @var array
 418     */
 419    var $highlight_extra_lines = array();
 420
 421    /**
 422     * Styles of lines that should be highlighted extra
 423     * @var array
 424     */
 425    var $highlight_extra_lines_styles = array();
 426
 427    /**
 428     * Styles of extra-highlighted lines
 429     * @var string
 430     */
 431    var $highlight_extra_lines_style = 'background-color: #ffc;';
 432
 433    /**
 434     * The line ending
 435     * If null, nl2br() will be used on the result string.
 436     * Otherwise, all instances of \n will be replaced with $line_ending
 437     * @var string
 438     */
 439    var $line_ending = null;
 440
 441    /**
 442     * Number at which line numbers should start at
 443     * @var int
 444     */
 445    var $line_numbers_start = 1;
 446
 447    /**
 448     * The overall style for this code block
 449     * @var string
 450     */
 451    var $overall_style = 'font-family:monospace;';
 452
 453    /**
 454     *  The style for the actual code
 455     * @var string
 456     */
 457    var $code_style = 'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
 458
 459    /**
 460     * The overall class for this code block
 461     * @var string
 462     */
 463    var $overall_class = '';
 464
 465    /**
 466     * The overall ID for this code block
 467     * @var string
 468     */
 469    var $overall_id = '';
 470
 471    /**
 472     * Line number styles
 473     * @var string
 474     */
 475    var $line_style1 = 'font-weight: normal; vertical-align:top;';
 476
 477    /**
 478     * Line number styles for fancy lines
 479     * @var string
 480     */
 481    var $line_style2 = 'font-weight: bold; vertical-align:top;';
 482
 483    /**
 484     * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
 485     * @var string
 486     */
 487    var $table_linenumber_style = 'width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;';
 488
 489    /**
 490     * Flag for how line numbers are displayed
 491     * @var boolean
 492     */
 493    var $line_numbers = GESHI_NO_LINE_NUMBERS;
 494
 495    /**
 496     * Flag to decide if multi line spans are allowed. Set it to false to make sure
 497     * each tag is closed before and reopened after each linefeed.
 498     * @var boolean
 499     */
 500    var $allow_multiline_span = true;
 501
 502    /**
 503     * The "nth" value for fancy line highlighting
 504     * @var int
 505     */
 506    var $line_nth_row = 0;
 507
 508    /**
 509     * The size of tab stops
 510     * @var int
 511     */
 512    var $tab_width = 8;
 513
 514    /**
 515     * Should we use language-defined tab stop widths?
 516     * @var int
 517     */
 518    var $use_language_tab_width = false;
 519
 520    /**
 521     * Default target for keyword links
 522     * @var string
 523     */
 524    var $link_target = '';
 525
 526    /**
 527     * The encoding to use for entity encoding
 528     * NOTE: Used with Escape Char Sequences to fix UTF-8 handling (cf. SF#2037598)
 529     * @var string
 530     */
 531    var $encoding = 'utf-8';
 532
 533    /**
 534     * Should keywords be linked?
 535     * @var boolean
 536     */
 537    var $keyword_links = true;
 538
 539    /**
 540     * Currently loaded language file
 541     * @var string
 542     * @since 1.0.7.22
 543     */
 544    var $loaded_language = '';
 545
 546    /**
 547     * Wether the caches needed for parsing are built or not
 548     *
 549     * @var bool
 550     * @since 1.0.8
 551     */
 552    var $parse_cache_built = false;
 553
 554    /**
 555     * Work around for Suhosin Patch with disabled /e modifier
 556     *
 557     * Note from suhosins author in config file:
 558     * <blockquote>
 559     *   The /e modifier inside <code>preg_replace()</code> allows code execution.
 560     *   Often it is the cause for remote code execution exploits. It is wise to
 561     *   deactivate this feature and test where in the application it is used.
 562     *   The developer using the /e modifier should be made aware that he should
 563     *   use <code>preg_replace_callback()</code> instead
 564     * </blockquote>
 565     *
 566     * @var array
 567     * @since 1.0.8
 568     */
 569    var $_kw_replace_group = 0;
 570    var $_rx_key = 0;
 571
 572    /**
 573     * some "callback parameters" for handle_multiline_regexps
 574     *
 575     * @since 1.0.8
 576     * @access private
 577     * @var string
 578     */
 579    var $_hmr_before = '';
 580    var $_hmr_replace = '';
 581    var $_hmr_after = '';
 582    var $_hmr_key = 0;
 583
 584    /**#@-*/
 585
 586    /**
 587     * Creates a new GeSHi object, with source and language
 588     *
 589     * @param string The source code to highlight
 590     * @param string The language to highlight the source with
 591     * @param string The path to the language file directory. <b>This
 592     *               is deprecated!</b> I've backported the auto path
 593     *               detection from the 1.1.X dev branch, so now it
 594     *               should be automatically set correctly. If you have
 595     *               renamed the language directory however, you will
 596     *               still need to set the path using this parameter or
 597     *               {@link GeSHi->set_language_path()}
 598     * @since 1.0.0
 599     */
 600    function GeSHi($source = '', $language = '', $path = '') {
 601        if (!empty($source)) {
 602            $this->set_source($source);
 603        }
 604        if (!empty($language)) {
 605            $this->set_language($language);
 606        }
 607        $this->set_language_path($path);
 608    }
 609
 610    /**
 611     * Returns an error message associated with the last GeSHi operation,
 612     * or false if no error has occured
 613     *
 614     * @return string|false An error message if there has been an error, else false
 615     * @since  1.0.0
 616     */
 617    function error() {
 618        if ($this->error) {
 619            //Put some template variables for debugging here ...
 620            $debug_tpl_vars = array(
 621                '{LANGUAGE}' => $this->language,
 622                '{PATH}' => $this->language_path
 623            );
 624            $msg = str_replace(
 625                array_keys($debug_tpl_vars),
 626                array_values($debug_tpl_vars),
 627                $this->error_messages[$this->error]);
 628
 629            return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
 630        }
 631        return false;
 632    }
 633
 634    /**
 635     * Gets a human-readable language name (thanks to Simon Patterson
 636     * for the idea :))
 637     *
 638     * @return string The name for the current language
 639     * @since  1.0.2
 640     */
 641    function get_language_name() {
 642        if (GESHI_ERROR_NO_SUCH_LANG == $this->error) {
 643            return $this->language_data['LANG_NAME'] . ' (Unknown Language)';
 644        }
 645        return $this->language_data['LANG_NAME'];
 646    }
 647
 648    /**
 649     * Sets the source code for this object
 650     *
 651     * @param string The source code to highlight
 652     * @since 1.0.0
 653     */
 654    function set_source($source) {
 655        $this->source = $source;
 656        $this->highlight_extra_lines = array();
 657    }
 658
 659    /**
 660     * Sets the language for this object
 661     *
 662     * @note since 1.0.8 this function won't reset language-settings by default anymore!
 663     *       if you need this set $force_reset = true
 664     *
 665     * @param string The name of the language to use
 666     * @since 1.0.0
 667     */
 668    function set_language($language, $force_reset = false) {
 669        if ($force_reset) {
 670            $this->loaded_language = false;
 671        }
 672
 673        //Clean up the language name to prevent malicious code injection
 674        $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
 675
 676        $language = strtolower($language);
 677
 678        //Retreive the full filename
 679        $file_name = $this->language_path . $language . '.php';
 680        if ($file_name == $this->loaded_language) {
 681            // this language is already loaded!
 682            return;
 683        }
 684
 685        $this->language = $language;
 686
 687        $this->error = false;
 688        $this->strict_mode = GESHI_NEVER;
 689
 690        //Check if we can read the desired file
 691        if (!is_readable($file_name)) {
 692            $this->error = GESHI_ERROR_NO_SUCH_LANG;
 693            return;
 694        }
 695
 696        // Load the language for parsing
 697        $this->load_language($file_name);
 698    }
 699
 700    /**
 701     * Sets the path to the directory containing the language files. Note
 702     * that this path is relative to the directory of the script that included
 703     * geshi.php, NOT geshi.php itself.
 704     *
 705     * @param string The path to the language directory
 706     * @since 1.0.0
 707     * @deprecated The path to the language files should now be automatically
 708     *             detected, so this method should no longer be needed. The
 709     *             1.1.X branch handles manual setting of the path differently
 710     *             so this method will disappear in 1.2.0.
 711     */
 712    function set_language_path($path) {
 713        if(strpos($path, ':')) {
 714            //Security Fix to prevent external directories using fopen wrappers.
 715            if(DIRECTORY_SEPARATOR == "\\") {
 716                if(!preg_match('#^[a-zA-Z]:#', $path) || false !== strpos($path, ':', 2)) {
 717                    return;
 718                }
 719            } else {
 720                return;
 721            }
 722        }
 723        if(preg_match('#[^/a-zA-Z0-9_\.\-\\\s:]#', $path)) {
 724            //Security Fix to prevent external directories using fopen wrappers.
 725            return;
 726        }
 727        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '/.')) {
 728            //Security Fix to prevent external directories using fopen wrappers.
 729            return;
 730        }
 731        if(GESHI_SECURITY_PARANOID && false !== strpos($path, '..')) {
 732            //Security Fix to prevent external directories using fopen wrappers.
 733            return;
 734        }
 735        if ($path) {
 736            $this->language_path = ('/' == $path[strlen($path) - 1]) ? $path : $path . '/';
 737            $this->set_language($this->language); // otherwise set_language_path has no effect
 738        }
 739    }
 740
 741    /**
 742     * Get supported langs or an associative array lang=>full_name.
 743     * @param boolean $longnames
 744     * @return array
 745     */
 746    function get_supported_languages($full_names=false)
 747    {
 748        // return array
 749        $back = array();
 750
 751        // we walk the lang root
 752        $dir = dir($this->language_path);
 753
 754        // foreach entry
 755        while (false !== ($entry = $dir->read()))
 756        {
 757            $full_path = $this->language_path.$entry;
 758
 759            // Skip all dirs
 760            if (is_dir($full_path)) {
 761                continue;
 762            }
 763
 764            // we only want lang.php files
 765            if (!preg_match('/^([^.]+)\.php$/', $entry, $matches)) {
 766                continue;
 767            }
 768
 769            // Raw lang name is here
 770            $langname = $matches[1];
 771
 772            // We want the fullname too?
 773            if ($full_names === true)
 774            {
 775                if (false !== ($fullname = $this->get_language_fullname($langname)))
 776                {
 777                    $back[$langname] = $fullname; // we go associative
 778                }
 779            }
 780            else
 781            {
 782                // just store raw langname
 783                $back[] = $langname;
 784            }
 785        }
 786
 787        $dir->close();
 788
 789        return $back;
 790    }
 791
 792    /**
 793     * Get full_name for a lang or false.
 794     * @param string $language short langname (html4strict for example)
 795     * @return mixed
 796     */
 797    function get_language_fullname($language)
 798    {
 799        //Clean up the language name to prevent malicious code injection
 800        $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
 801
 802        $language = strtolower($language);
 803
 804        // get fullpath-filename for a langname
 805        $fullpath = $this->language_path.$language.'.php';
 806
 807        // we need to get contents :S
 808        if (false === ($data = file_get_contents($fullpath))) {
 809            $this->error = sprintf('Geshi::get_lang_fullname() Unknown Language: %s', $language);
 810            return false;
 811        }
 812
 813        // match the langname
 814        if (!preg_match('/\'LANG_NAME\'\s*=>\s*\'((?:[^\']|\\\')+)\'/', $data, $matches)) {
 815            $this->error = sprintf('Geshi::get_lang_fullname(%s): Regex can not detect language', $language);
 816            return false;
 817        }
 818
 819        // return fullname for langname
 820        return stripcslashes($matches[1]);
 821    }
 822
 823    /**
 824     * Sets the type of header to be used.
 825     *
 826     * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This
 827     * means more source code but more control over tab width and line-wrapping.
 828     * GESHI_HEADER_PRE means that a "pre" is used - less source, but less
 829     * control. Default is GESHI_HEADER_PRE.
 830     *
 831     * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code
 832     * should be outputted.
 833     *
 834     * @param int The type of header to be used
 835     * @since 1.0.0
 836     */
 837    function set_header_type($type) {
 838        //Check if we got a valid header type
 839        if (!in_array($type, array(GESHI_HEADER_NONE, GESHI_HEADER_DIV,
 840            GESHI_HEADER_PRE, GESHI_HEADER_PRE_VALID, GESHI_HEADER_PRE_TABLE))) {
 841            $this->error = GESHI_ERROR_INVALID_HEADER_TYPE;
 842            return;
 843        }
 844
 845        //Set that new header type
 846        $this->header_type = $type;
 847    }
 848
 849    /**
 850     * Sets the styles for the code that will be outputted
 851     * when this object is parsed. The style should be a
 852     * string of valid stylesheet declarations
 853     *
 854     * @param string  The overall style for the outputted code block
 855     * @param boolean Whether to merge the styles with the current styles or not
 856     * @since 1.0.0
 857     */
 858    function set_overall_style($style, $preserve_defaults = false) {
 859        if (!$preserve_defaults) {
 860            $this->overall_style = $style;
 861        } else {
 862            $this->overall_style .= $style;
 863        }
 864    }
 865
 866    /**
 867     * Sets the overall classname for this block of code. This
 868     * class can then be used in a stylesheet to style this object's
 869     * output
 870     *
 871     * @param string The class name to use for this block of code
 872     * @since 1.0.0
 873     */
 874    function set_overall_class($class) {
 875        $this->overall_class = $class;
 876    }
 877
 878    /**
 879     * Sets the overall id for this block of code. This id can then
 880     * be used in a stylesheet to style this object's output
 881     *
 882     * @param string The ID to use for this block of code
 883     * @since 1.0.0
 884     */
 885    function set_overall_id($id) {
 886        $this->overall_id = $id;
 887    }
 888
 889    /**
 890     * Sets whether CSS classes should be used to highlight the source. Default
 891     * is off, calling this method with no arguments will turn it on
 892     *
 893     * @param boolean Whether to turn classes on or not
 894     * @since 1.0.0
 895     */
 896    function enable_classes($flag = true) {
 897        $this->use_classes = ($flag) ? true : false;
 898    }
 899
 900    /**
 901     * Sets the style for the actual code. This should be a string
 902     * containing valid stylesheet declarations. If $preserve_defaults is
 903     * true, then styles are merged with the default styles, with the
 904     * user defined styles having priority
 905     *
 906     * Note: Use this method to override any style changes you made to
 907     * the line numbers if you are using line numbers, else the line of
 908     * code will have the same style as the line number! Consult the
 909     * GeSHi documentation for more information about this.
 910     *
 911     * @param string  The style to use for actual code
 912     * @param boolean Whether to merge the current styles with the new styles
 913     * @since 1.0.2
 914     */
 915    function set_code_style($style, $preserve_defaults = false) {
 916        if (!$preserve_defaults) {
 917            $this->code_style = $style;
 918        } else {
 919            $this->code_style .= $style;
 920        }
 921    }
 922
 923    /**
 924     * Sets the styles for the line numbers.
 925     *
 926     * @param string The style for the line numbers that are "normal"
 927     * @param string|boolean If a string, this is the style of the line
 928     *        numbers that are "fancy", otherwise if boolean then this
 929     *        defines whether the normal styles should be merged with the
 930     *        new normal styles or not
 931     * @param boolean If set, is the flag for whether to merge the "fancy"
 932     *        styles with the current styles or not
 933     * @since 1.0.2
 934     */
 935    function set_line_style($style1, $style2 = '', $preserve_defaults = false) {
 936        //Check if we got 2 or three parameters
 937        if (is_bool($style2)) {
 938            $preserve_defaults = $style2;
 939            $style2 = '';
 940        }
 941
 942        //Actually set the new styles
 943        if (!$preserve_defaults) {
 944            $this->line_style1 = $style1;
 945            $this->line_style2 = $style2;
 946        } else {
 947            $this->line_style1 .= $style1;
 948            $this->line_style2 .= $style2;
 949        }
 950    }
 951
 952    /**
 953     * Sets whether line numbers should be displayed.
 954     *
 955     * Valid values for the first parameter are:
 956     *
 957     *  - GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed
 958     *  - GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed
 959     *  - GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed
 960     *
 961     * For fancy line numbers, the second parameter is used to signal which lines
 962     * are to be fancy. For example, if the value of this parameter is 5 then every
 963     * 5th line will be fancy.
 964     *
 965     * @param int How line numbers should be displayed
 966     * @param int Defines which lines are fancy
 967     * @since 1.0.0
 968     */
 969    function enable_line_numbers($flag, $nth_row = 5) {
 970        if (GESHI_NO_LINE_NUMBERS != $flag && GESHI_NORMAL_LINE_NUMBERS != $flag
 971            && GESHI_FANCY_LINE_NUMBERS != $flag) {
 972            $this->error = GESHI_ERROR_INVALID_LINE_NUMBER_TYPE;
 973        }
 974        $this->line_numbers = $flag;
 975        $this->line_nth_row = $nth_row;
 976    }
 977
 978    /**
 979     * Sets wether spans and other HTML markup generated by GeSHi can
 980     * span over multiple lines or not. Defaults to true to reduce overhead.
 981     * Set it to false if you want to manipulate the output or manually display
 982     * the code in an ordered list.
 983     *
 984     * @param boolean Wether multiline spans are allowed or not
 985     * @since 1.0.7.22
 986     */
 987    function enable_multiline_span($flag) {
 988        $this->allow_multiline_span = (bool) $flag;
 989    }
 990
 991    /**
 992     * Get current setting for multiline spans, see GeSHi->enable_multiline_span().
 993     *
 994     * @see enable_multiline_span
 995     * @return bool
 996     */
 997    function get_multiline_span() {
 998        return $this->allow_multiline_span;
 999    }
1000
1001    /**
1002     * Sets the style for a keyword group. If $preserve_defaults is
1003     * true, then styles are merged with the default styles, with the
1004     * user defined styles having priority
1005     *
1006     * @param int     The key of the keyword group to change the styles of
1007     * @param string  The style to make the keywords
1008     * @param boolean Whether to merge the new styles with the old or just
1009     *                to overwrite them
1010     * @since 1.0.0
1011     */
1012    function set_keyword_group_style($key, $style, $preserve_defaults = false) {
1013        //Set the style for this keyword group
1014        if (!$preserve_defaults) {
1015            $this->language_data['STYLES']['KEYWORDS'][$key] = $style;
1016        } else {
1017            $this->language_data['STYLES']['KEYWORDS'][$key] .= $style;
1018        }
1019
1020        //Update the lexic permissions
1021        if (!isset($this->lexic_permissions['KEYWORDS'][$key])) {
1022            $this->lexic_permissions['KEYWORDS'][$key] = true;
1023        }
1024    }
1025
1026    /**
1027     * Turns highlighting on/off for a keyword group
1028     *
1029     * @param int     The key of the keyword group to turn on or off
1030     * @param boolean Whether to turn highlighting for that group on or off
1031     * @since 1.0.0
1032     */
1033    function set_keyword_group_highlighting($key, $flag = true) {
1034        $this->lexic_permissions['KEYWORDS'][$key] = ($flag) ? true : false;
1035    }
1036
1037    /**
1038     * Sets the styles for comment groups.  If $preserve_defaults is
1039     * true, then styles are merged with the default styles, with the
1040     * user defined styles having priority
1041     *
1042     * @param int     The key of the comment group to change the styles of
1043     * @param string  The style to make the comments
1044     * @param boolean Whether to merge the new styles with the old or just
1045     *                to overwrite them
1046     * @since 1.0.0
1047     */
1048    function set_comments_style($key, $style, $preserve_defaults = false) {
1049        if (!$preserve_defaults) {
1050            $this->language_data['STYLES']['COMMENTS'][$key] = $style;
1051        } else {
1052            $this->language_data['STYLES']['COMMENTS'][$key] .= $style;
1053        }
1054    }
1055
1056    /**
1057     * Turns highlighting on/off for comment groups
1058     *
1059     * @param int     The key of the comment group to turn on or off
1060     * @param boolean Whether to turn highlighting for that group on or off
1061     * @since 1.0.0
1062     */
1063    function set_comments_highlighting($key, $flag = true) {
1064        $this->lexic_permissions['COMMENTS'][$key] = ($flag) ? true : false;
1065    }
1066
1067    /**
1068     * Sets the styles for escaped characters. If $preserve_defaults is
1069     * true, then styles are merged with the default styles, with the
1070     * user defined styles having priority
1071     *
1072     * @param string  The style to make the escape characters
1073     * @param boolean Whether to merge the new styles with the old or just
1074     *                to overwrite them
1075     * @since 1.0.0
1076     */
1077    function set_escape_characters_style($style, $preserve_defaults = false, $group = 0) {
1078        if (!$preserve_defaults) {
1079            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] = $style;
1080        } else {
1081            $this->language_data['STYLES']['ESCAPE_CHAR'][$group] .= $style;
1082        }
1083    }
1084
1085    /**
1086     * Turns highlighting on/off for escaped characters
1087     *
1088     * @param boolean Whether to turn highlighting for escape characters on or off
1089     * @since 1.0.0
1090     */
1091    function set_escape_characters_highlighting($flag = true) {
1092        $this->lexic_permissions['ESCAPE_CHAR'] = ($flag) ? true : false;
1093    }
1094
1095    /**
1096     * Sets the styles for brackets. If $preserve_defaults is
1097     * true, then styles are merged with the default styles, with the
1098     * user defined styles having priority
1099     *
1100     * This method is DEPRECATED: use set_symbols_style instead.
1101     * This method will be removed in 1.2.X
1102     *
1103     * @param string  The style to make the brackets
1104     * @param boolean Whether to merge the new styles with the old or just
1105     *                to overwrite them
1106     * @since 1.0.0
1107     * @deprecated In favour of set_symbols_style
1108     */
1109    function set_brackets_style($style, $preserve_defaults = false) {
1110        if (!$preserve_defaults) {
1111            $this->language_data['STYLES']['BRACKETS'][0] = $style;
1112        } else {
1113            $this->language_data['STYLES']['BRACKETS'][0] .= $style;
1114        }
1115    }
1116
1117    /**
1118     * Turns highlighting on/off for brackets
1119     *
1120     * This method is DEPRECATED: use set_symbols_highlighting instead.
1121     * This method will be remove in 1.2.X
1122     *
1123     * @param boolean Whether to turn highlighting for brackets on or off
1124     * @since 1.0.0
1125     * @deprecated In favour of set_symbols_highlighting
1126     */
1127    function set_brackets_highlighting($flag) {
1128        $this->lexic_permissions['BRACKETS'] = ($flag) ? true : false;
1129    }
1130
1131    /**
1132     * Sets the styles for symbols. If $preserve_defaults is
1133     * true, then styles are merged with the default styles, with the
1134     * user defined styles having priority
1135     *
1136     * @param string  The style to make the symbols
1137     * @param boolean Whether to merge the new styles with the old or just
1138     *                to overwrite them
1139     * @param int     Tells the group of symbols for which style should be set.
1140     * @since 1.0.1
1141     */
1142    function set_symbols_style($style, $preserve_defaults = false, $group = 0) {
1143        // Update the style of symbols
1144        if (!$preserve_defaults) {
1145            $this->language_data['STYLES']['SYMBOLS'][$group] = $style;
1146        } else {
1147            $this->language_data['STYLES']['SYMBOLS'][$group] .= $style;
1148        }
1149
1150        // For backward compatibility
1151        if (0 == $group) {
1152            $this->set_brackets_style ($style, $preserve_defaults);
1153        }
1154    }
1155
1156    /**
1157     * Turns highlighting on/off for symbols
1158     *
1159     * @param boolean Whether to turn highlighting for symbols on or off
1160     * @since 1.0.0
1161     */
1162    function set_symbols_highlighting($flag) {
1163        // Update lexic permissions for this symbol group
1164        $this->lexic_permissions['SYMBOLS'] = ($flag) ? true : false;
1165
1166        // For backward compatibility
1167        $this->set_brackets_highlighting ($flag);
1168    }
1169
1170    /**
1171     * Sets the styles for strings. If $preserve_defaults is
1172     * true, then styles are merged with the default styles, with the
1173     * user defined styles having priority
1174     *
1175     * @param string  The style to make the escape characters
1176     * @param boolean Whether to merge the new styles with the old or just
1177     *                to overwrite them
1178     * @param int     Tells the group of strings for which style should be set.
1179     * @since 1.0.0
1180     */
1181    function set_strings_style($style, $preserve_defaults = false, $group = 0) {
1182        if (!$preserve_defaults) {
1183            $this->language_data['STYLES']['STRINGS'][$group] = $style;
1184        } else {
1185            $this->language_data['STYLES']['STRINGS'][$group] .= $style;
1186        }
1187    }
1188
1189    /**
1190     * Turns highlighting on/off for strings
1191     *
1192     * @param boolean Whether to turn highlighting for strings on or off
1193     * @since 1.0.0
1194     */
1195    function set_strings_highlighting($flag) {
1196        $this->lexic_permissions['STRINGS'] = ($flag) ? true : false;
1197    }
1198
1199    /**
1200     * Sets the styles for strict code blocks. If $preserve_defaults is
1201     * true, then styles are merged with the default styles, with the
1202     * user defined styles having priority
1203     *
1204     * @param string  The style to make the script blocks
1205     * @param boolean Whether to merge the new styles with the old or just
1206     *                to overwrite them
1207     * @param int     Tells the group of script blocks for which style should be set.
1208     * @since 1.0.8.4
1209     */
1210    function set_script_style($style, $preserve_defaults = false, $group = 0) {
1211        // Update the style of symbols
1212        if (!$preserve_defaults) {
1213            $this->language_data['STYLES']['SCRIPT'][$group] = $style;
1214        } else {
1215            $this->language_data['STYLES']['SCRIPT'][$group] .= $style;
1216        }
1217    }
1218
1219    /**
1220     * Sets the styles for numbers. If $preserve_defaults is
1221     * true, then styles are merged with the default styles, with the
1222     * user defined styles having priority
1223     *
1224     * @param string  The style to make the numbers
1225     * @param boolean Whether to merge the new styles with the old or just
1226     *                to overwrite them
1227     * @param int     Tells the group of numbers for which style should be set.
1228     * @since 1.0.0
1229     */
1230    function set_numbers_style($style, $preserve_defaults = false, $group = 0) {
1231        if (!$preserve_defaults) {
1232            $this->language_data['STYLES']['NUMBERS'][$group] = $style;
1233        } else {
1234            $this->language_data['STYLES']['NUMBERS'][$group] .= $style;
1235        }
1236    }
1237
1238    /**
1239     * Turns highlighting on/off for numbers
1240     *
1241     * @param boolean Whether to turn highlighting for numbers on or off
1242     * @since 1.0.0
1243     */
1244    function set_numbers_highlighting($flag) {
1245        $this->lexic_permissions['NUMBERS'] = ($flag) ? true : false;
1246    }
1247
1248    /**
1249     * Sets the styles for methods. $key is a number that references the
1250     * appropriate "object splitter" - see the language file for the language
1251     * you are highlighting to get this number. If $preserve_defaults is
1252     * true, then styles are merged with the default styles, with the
1253     * user defined styles having priority
1254     *
1255     * @param int     The key of the object splitter to change the styles of
1256     * @param string  The style to make the methods
1257     * @param boolean Whether to merge the new styles with the old or just
1258     *                to overwrite them
1259     * @since 1.0.0
1260     */
1261    function set_methods_style($key, $style, $preserve_defaults = false) {
1262        if (!$preserve_defaults) {
1263            $this->language_data['STYLES']['METHODS'][$key] = $style;
1264        } else {
1265            $this->language_data['STYLES']['METHODS'][$key] .= $style;
1266        }
1267    }
1268
1269    /**
1270     * Turns highlighting on/off for methods
1271     *
1272     * @param boolean Whether to turn highlighting for methods on or off
1273     * @since 1.0.0
1274     */
1275    function set_methods_highlighting($flag) {
1276        $this->lexic_permissions['METHODS'] = ($flag) ? true : false;
1277    }
1278
1279    /**
1280     * Sets the styles for regexps. If $preserve_defaults is
1281     * true, then styles are merged with the default styles, with the
1282     * user defined styles having priority
1283     *
1284     * @param string  The style to make the regular expression matches
1285     * @param boolean Whether to merge the new styles with the old or just
1286     *                to overwrite them
1287     * @since 1.0.0
1288     */
1289    function set_regexps_style($key, $style, $preserve_defaults = false) {
1290        if (!$preserve_defaults) {
1291            $this->language_data['STYLES']['REGEXPS'][$key] = $style;
1292        } else {
1293            $this->language_data['STYLES']['REGEXPS'][$key] .= $style;
1294        }
1295    }
1296
1297    /**
1298     * Turns highlighting on/off for regexps
1299     *
1300     * @param int     The key of the regular expression group to turn on or off
1301     * @param boolean Whether to turn highlighting for the regular expression group on or off
1302     * @since 1.0.0
1303     */
1304    function set_regexps_highlighting($key, $flag) {
1305        $this->lexic_permissions['REGEXPS'][$key] = ($flag) ? true : false;
1306    }
1307
1308    /**
1309     * Sets whether a set of keywords are checked for in a case sensitive manner
1310     *
1311     * @param int The key of the keyword group to change the case sensitivity of
1312     * @param boolean Whether to check in a case sensitive manner or not
1313     * @since 1.0.0
1314     */
1315    function set_case_sensitivity($key, $case) {
1316        $this->language_data['CASE_SENSITIVE'][$key] = ($case) ? true : false;
1317    }
1318
1319    /**
1320     * Sets the case that keywords should use when found. Use the constants:
1321     *
1322     *  - GESHI_CAPS_NO_CHANGE: leave keywords as-is
1323     *  - GESHI_CAPS_UPPER: convert all keywords to uppercase where found
1324     *  - GESHI_CAPS_LOWER: convert all keywords to lowercase where found
1325     *
1326     * @param int A constant specifying what to do with matched keywords
1327     * @since 1.0.1
1328     */
1329    function set_case_keywords($case) {
1330        if (in_array($case, array(
1331            GESHI_CAPS_NO_CHANGE, GESHI_CAPS_UPPER, GESHI_CAPS_LOWER))) {
1332            $this->language_data['CASE_KEYWORDS'] = $case;
1333        }
1334    }
1335
1336    /**
1337     * Sets how many spaces a tab is substituted for
1338     *
1339     * Widths below zero are ignored
1340     *
1341     * @param int The tab width
1342     * @since 1.0.0
1343     */
1344    function set_tab_width($width) {
1345        $this->tab_width = intval($width);
1346
1347        //Check if it fit's the constraints:
1348        if ($this->tab_width < 1) {
1349            //Return it to the default
1350            $this->tab_width = 8;
1351        }
1352    }
1353
1354    /**
1355     * Sets whether or not to use tab-stop width specifed by language
1356     *
1357     * @param boolean Whether to use language-specific tab-stop widths
1358     * @since 1.0.7.20
1359     */
1360    function set_use_language_tab_width($use) {
1361        $this->use_language_tab_width = (bool) $use;
1362    }
1363
1364    /**
1365     * Returns the tab width to use, based on the current language and user
1366     * preference
1367     *
1368     * @return int Tab width
1369     * @since 1.0.7.20
1370     */
1371    function get_real_tab_width() {
1372        if (!$this->use_language_tab_width ||
1373            !isset($this->language_data['TAB_WIDTH'])) {
1374            return $this->tab_width;
1375        } else {
1376            return $this->language_data['TAB_WIDTH'];
1377        }
1378    }
1379
1380    /**
1381     * Enables/disables strict highlighting. Default is off, calling this
1382     * method without parameters will turn it on. See documentation
1383     * for more details on strict mode and where to use it.
1384     *
1385     * @param boolean Whether to enable strict mode or not
1386     * @since 1.0.0
1387     */
1388    function enable_strict_mode($mode = true) {
1389        if (GESHI_MAYBE == $this->language_data['STRICT_MODE_APPLIES']) {
1390            $this->strict_mode = ($mode) ? GESHI_ALWAYS : GESHI_NEVER;
1391        }
1392    }
1393
1394    /**
1395     * Disables all highlighting
1396     *
1397     * @since 1.0.0
1398     * @todo  Rewrite with array traversal
1399     * @deprecated In favour of enable_highlighting
1400     */
1401    function disable_highlighting() {
1402        $this->enable_highlighting(false);
1403    }
1404
1405    /**
1406     * Enables all highlighting
1407     *
1408     * The optional flag parameter was added in version 1.0.7.21 and can be used
1409     * to enable (true) or disable (false) all highlighting.
1410     *
1411     * @since 1.0.0
1412     * @param boolean A flag specifying whether to enable or disable all highlighting
1413     * @todo  Rewrite with array traversal
1414     */
1415    function enable_highlighting($flag = true) {
1416        $flag = $flag ? true : false;
1417        foreach ($this->lexic_permissions as $key => $value) {
1418            if (is_array($value)) {
1419                foreach ($value as $k => $v) {
1420                    $this->lexic_permissions[$key][$k] = $flag;
1421                }
1422            } else {
1423                $this->lexic_permissions[$key] = $flag;
1424            }
1425        }
1426
1427        // Context blocks
1428        $this->enable_important_blocks = $flag;
1429    }
1430
1431    /**
1432     * Given a file extension, this method returns either a valid geshi language
1433     * name, or the empty string if it couldn't be found
1434     *
1435     * @param string The extension to get a language name for
1436     * @param array  A lookup array to use instead of the default one
1437     * @since 1.0.5
1438     * @todo Re-think about how this method works (maybe make it private and/or make it
1439     *       a extension->lang lookup?)
1440     * @todo static?
1441     */
1442    function get_language_name_from_extension( $extension, $lookup = array() ) {
1443        if ( !is_array($lookup) || empty($lookup)) {
1444            $lookup = array(
1445                '6502acme' => array( 'a', 's', 'asm', 'inc' ),
1446                '6502tasm' => array( 'a', 's', 'asm', 'inc' ),
1447                '6502kickass' => array( 'a', 's', 'asm', 'inc' ),
1448                '68000devpac' => array( 'a', 's', 'asm', 'inc' ),
1449                'abap' => array('abap'),
1450                'actionscript' => array('as'),
1451                'ada' => array('a', 'ada', 'adb', 'ads'),
1452                'apache' => array('conf'),
1453                'asm' => array('ash', 'asm', 'inc'),
1454                'asp' => array('asp'),
1455                'bash' => array('sh'),
1456                'bf' => array('bf'),
1457                'c' => array('c', 'h'),
1458                'c_mac' => array('c', 'h'),
1459                'caddcl' => array(),
1460                'cadlisp' => array(),
1461                'cdfg' => array('cdfg'),
1462                'cobol' => array('cbl'),
1463                'cpp' => array('cpp', 'hpp', 'C', 'H', 'CPP', 'HPP'),
1464                'csharp' => array('cs'),
1465                'css' => array('css'),
1466                'd' => array('d'),
1467                'delphi' => array('dpk', 'dpr', 'pp', 'pas'),
1468                'diff' => array('diff', 'patch'),
1469                'dos' => array('bat', 'cmd'),
1470                'gdb' => array('kcrash', 'crash', 'bt'),
1471                'gettext' => array('po', 'pot'),
1472                'gml' => array('gml'),
1473                'gnuplot' => array('plt'),
1474                'groovy' => array('groovy'),
1475                'haskell' => array('hs'),
1476                'html4strict' => array('html', 'htm'),
1477                'ini' => array('ini', 'desktop'),
1478                'java' => array('java'),
1479                'javascript' => array('js'),
1480                'klonec' => array('kl1'),
1481                'klonecpp' => array('klx'),
1482                'latex' => ar…

Large files files are truncated, but you can click here to view the full file