[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> geshi.php (source)

   1  <?php
   2  /**
   3   * GeSHi - Generic Syntax Highlighter
   4   *
   5   * The GeSHi class for Generic Syntax Highlighting. Please refer to the
   6   * documentation at http://qbnz.com/highlighter/documentation.php for more
   7   * information about how to use this class.
   8   *
   9   * For changes, release notes, TODOs etc, see the relevant files in the docs/
  10   * directory.
  11   *
  12   *   This file is part of GeSHi.
  13   *
  14   *  GeSHi is free software; you can redistribute it and/or modify
  15   *  it under the terms of the GNU General Public License as published by
  16   *  the Free Software Foundation; either version 2 of the License, or
  17   *  (at your option) any later version.
  18   *
  19   *  GeSHi is distributed in the hope that it will be useful,
  20   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22   *  GNU General Public License for more details.
  23   *
  24   *  You should have received a copy of the GNU General Public License
  25   *  along with GeSHi; if not, write to the Free Software
  26   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  27   *
  28   * @package    geshi
  29   * @subpackage core
  30   * @author     Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
  31   * @copyright  (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
  32   * @license    http://gnu.org/copyleft/gpl.html GNU GPL
  33   *
  34   */
  35  
  36  //
  37  // GeSHi Constants
  38  // You should use these constant names in your programs instead of
  39  // their values - you never know when a value may change in a future
  40  // version
  41  //
  42  
  43  /** The version of this GeSHi file */
  44  define('GESHI_VERSION', '1.0.8');
  45  
  46  // Define the root directory for the GeSHi code tree
  47  if (!defined('GESHI_ROOT')) {
  48      /** The root directory for GeSHi */
  49      define('GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
  50  }
  51  /** The language file directory for GeSHi
  52      @access private */
  53  define('GESHI_LANG_ROOT', GESHI_ROOT . 'geshi' . DIRECTORY_SEPARATOR);
  54  
  55  
  56  // Line numbers - use with enable_line_numbers()
  57  /** Use no line numbers when building the result */
  58  define('GESHI_NO_LINE_NUMBERS', 0);
  59  /** Use normal line numbers when building the result */
  60  define('GESHI_NORMAL_LINE_NUMBERS', 1);
  61  /** Use fancy line numbers when building the result */
  62  define('GESHI_FANCY_LINE_NUMBERS', 2);
  63  
  64  // Container HTML type
  65  /** Use nothing to surround the source */
  66  define('GESHI_HEADER_NONE', 0);
  67  /** Use a "div" to surround the source */
  68  define('GESHI_HEADER_DIV', 1);
  69  /** Use a "pre" to surround the source */
  70  define('GESHI_HEADER_PRE', 2);
  71  /** Use a pre to wrap lines when line numbers are enabled or to wrap the whole code. */
  72  define('GESHI_HEADER_PRE_VALID', 3);
  73  /**
  74   * Use a "table" to surround the source:
  75   *
  76   *  <table>
  77   *    <thead><tr><td colspan="2">$header</td></tr></thead>
  78   *    <tbody><tr><td><pre>$linenumbers</pre></td><td><pre>$code></pre></td></tr></tbody>
  79   *    <tfooter><tr><td colspan="2">$footer</td></tr></tfoot>
  80   *  </table>
  81   *
  82   * this is essentially only a workaround for Firefox, see sf#1651996 or take a look at
  83   * https://bugzilla.mozilla.org/show_bug.cgi?id=365805
  84   * @note when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE
  85   */
  86  define('GESHI_HEADER_PRE_TABLE', 4);
  87  
  88  // Capatalisation constants
  89  /** Lowercase keywords found */
  90  define('GESHI_CAPS_NO_CHANGE', 0);
  91  /** Uppercase keywords found */
  92  define('GESHI_CAPS_UPPER', 1);
  93  /** Leave keywords found as the case that they are */
  94  define('GESHI_CAPS_LOWER', 2);
  95  
  96  // Link style constants
  97  /** Links in the source in the :link state */
  98  define('GESHI_LINK', 0);
  99  /** Links in the source in the :hover state */
 100  define('GESHI_HOVER', 1);
 101  /** Links in the source in the :active state */
 102  define('GESHI_ACTIVE', 2);
 103  /** Links in the source in the :visited state */
 104  define('GESHI_VISITED', 3);
 105  
 106  // Important string starter/finisher
 107  // Note that if you change these, they should be as-is: i.e., don't
 108  // write them as if they had been run through htmlentities()
 109  /** The starter for important parts of the source */
 110  define('GESHI_START_IMPORTANT', '<BEGIN GeSHi>');
 111  /** The ender for important parts of the source */
 112  define('GESHI_END_IMPORTANT', '<END GeSHi>');
 113  
 114  /**#@+
 115   *  @access private
 116   */
 117  // When strict mode applies for a language
 118  /** Strict mode never applies (this is the most common) */
 119  define('GESHI_NEVER', 0);
 120  /** Strict mode *might* apply, and can be enabled or
 121      disabled by {@link GeSHi->enable_strict_mode()} */
 122  define('GESHI_MAYBE', 1);
 123  /** Strict mode always applies */
 124  define('GESHI_ALWAYS', 2);
 125  
 126  // Advanced regexp handling constants, used in language files
 127  /** The key of the regex array defining what to search for */
 128  define('GESHI_SEARCH', 0);
 129  /** The key of the regex array defining what bracket group in a
 130      matched search to use as a replacement */
 131  define('GESHI_REPLACE', 1);
 132  /** The key of the regex array defining any modifiers to the regular expression */
 133  define('GESHI_MODIFIERS', 2);
 134  /** The key of the regex array defining what bracket group in a
 135      matched search to put before the replacement */
 136  define('GESHI_BEFORE', 3);
 137  /** The key of the regex array defining what bracket group in a
 138      matched search to put after the replacement */
 139  define('GESHI_AFTER', 4);
 140  /** The key of the regex array defining a custom keyword to use
 141      for this regexp's html tag class */
 142  define('GESHI_CLASS', 5);
 143  
 144  /** Used in language files to mark comments */
 145  define('GESHI_COMMENTS', 0);
 146  
 147  /** Used to work around missing PHP features **/
 148  define('GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, '4.3.3') === 1));
 149  
 150  /** make sure we can call stripos **/
 151  if (!function_exists('stripos')) {
 152      // the offset param of preg_match is not supported below PHP 4.3.3
 153      if (GESHI_PHP_PRE_433) {
 154          /**
 155           * @ignore
 156           */
 157          function stripos($haystack, $needle, $offset = null) {
 158              if (!is_null($offset)) {
 159                  $haystack = substr($haystack, $offset);
 160              }
 161              if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
 162                  return $match[0][1];
 163              }
 164              return false;
 165          }
 166      }
 167      else {
 168          /**
 169           * @ignore
 170           */
 171          function stripos($haystack, $needle, $offset = null) {
 172              if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
 173                  return $match[0][1];
 174              }
 175              return false;
 176          }
 177      }
 178  }
 179  
 180  /** some old PHP / PCRE subpatterns only support up to xxx subpatterns in
 181      regular expressions. Set this to false if your PCRE lib is up to date
 182      @see GeSHi->optimize_regexp_list()
 183      TODO: are really the subpatterns the culprit or the overall length of the pattern?
 184      **/
 185  define('GESHI_MAX_PCRE_SUBPATTERNS', 500);
 186  
 187  //Number format specification
 188  /** Basic number format for integers */
 189  define('GESHI_NUMBER_INT_BASIC', 1);        //Default integers \d+
 190  /** Enhanced number format for integers like seen in C */
 191  define('GESHI_NUMBER_INT_CSTYLE', 2);       //Default C-Style \d+[lL]?
 192  /** Number format to highlight binary numbers with a suffix "b" */
 193  define('GESHI_NUMBER_BIN_SUFFIX', 16);           //[01]+[bB]
 194  /** Number format to highlight binary numbers with a prefix % */
 195  define('GESHI_NUMBER_BIN_PREFIX_PERCENT', 32);   //%[01]+
 196  /** Number format to highlight binary numbers with a prefix 0b (C) */
 197  define('GESHI_NUMBER_BIN_PREFIX_0B', 64);        //0b[01]+
 198  /** Number format to highlight octal numbers with a leading zero */
 199  define('GESHI_NUMBER_OCT_PREFIX', 256);           //0[0-7]+
 200  /** Number format to highlight octal numbers with a suffix of o */
 201  define('GESHI_NUMBER_OCT_SUFFIX', 512);           //[0-7]+[oO]
 202  /** Number format to highlight hex numbers with a prefix 0x */
 203  define('GESHI_NUMBER_HEX_PREFIX', 4096);           //0x[0-9a-fA-F]+
 204  /** Number format to highlight hex numbers with a suffix of h */
 205  define('GESHI_NUMBER_HEX_SUFFIX', 8192);           //[0-9][0-9a-fA-F]*h
 206  /** Number format to highlight floating-point numbers without support for scientific notation */
 207  define('GESHI_NUMBER_FLT_NONSCI', 65536);          //\d+\.\d+
 208  /** Number format to highlight floating-point numbers without support for scientific notation */
 209  define('GESHI_NUMBER_FLT_NONSCI_F', 131072);       //\d+(\.\d+)?f
 210  /** Number format to highlight floating-point numbers with support for scientific notation (E) and optional leading zero */
 211  define('GESHI_NUMBER_FLT_SCI_SHORT', 262144);      //\.\d+e\d+
 212  /** Number format to highlight floating-point numbers with support for scientific notation (E) and required leading digit */
 213  define('GESHI_NUMBER_FLT_SCI_ZERO', 524288);       //\d+(\.\d+)?e\d+
 214  //Custom formats are passed by RX array
 215  
 216  // Error detection - use these to analyse faults
 217  /** No sourcecode to highlight was specified
 218   * @deprecated
 219   */
 220  define('GESHI_ERROR_NO_INPUT', 1);
 221  /** The language specified does not exist */
 222  define('GESHI_ERROR_NO_SUCH_LANG', 2);
 223  /** GeSHi could not open a file for reading (generally a language file) */
 224  define('GESHI_ERROR_FILE_NOT_READABLE', 3);
 225  /** The header type passed to {@link GeSHi->set_header_type()} was invalid */
 226  define('GESHI_ERROR_INVALID_HEADER_TYPE', 4);
 227  /** The line number type passed to {@link GeSHi->enable_line_numbers()} was invalid */
 228  define('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
 229  /**#@-*/
 230  
 231  
 232  /**
 233   * The GeSHi Class.
 234   *
 235   * Please refer to the documentation for GeSHi 1.0.X that is available
 236   * at http://qbnz.com/highlighter/documentation.php for more information
 237   * about how to use this class.
 238   *
 239   * @package   geshi
 240   * @author    Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
 241   * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
 242   */
 243  class GeSHi {
 244      /**#@+
 245       * @access private
 246       */
 247      /**
 248       * The source code to highlight
 249       * @var string
 250       */
 251      var $source = '';
 252  
 253      /**
 254       * The language to use when highlighting
 255       * @var string
 256       */
 257      var $language = '';
 258  
 259      /**
 260       * The data for the language used
 261       * @var array
 262       */
 263      var $language_data = array();
 264  
 265      /**
 266       * The path to the language files
 267       * @var string
 268       */
 269      var $language_path = GESHI_LANG_ROOT;
 270  
 271      /**
 272       * The error message associated with an error
 273       * @var string
 274       * @todo check err reporting works
 275       */
 276      var $error = false;
 277  
 278      /**
 279       * Possible error messages
 280       * @var array
 281       */
 282      var $error_messages = array(
 283          GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',
 284          GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',
 285          GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',
 286          GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'
 287      );
 288  
 289      /**
 290       * Whether highlighting is strict or not
 291       * @var boolean
 292       */
 293      var $strict_mode = false;
 294  
 295      /**
 296       * Whether to use CSS classes in output
 297       * @var boolean
 298       */
 299      var $use_classes = false;
 300  
 301      /**
 302       * The type of header to use. Can be one of the following
 303       * values:
 304       *
 305       * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.
 306       * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.
 307       * - GESHI_HEADER_NONE: No header is outputted.
 308       *
 309       * @var int
 310       */
 311      var $header_type = GESHI_HEADER_PRE;
 312  
 313      /**
 314       * Array of permissions for which lexics should be highlighted
 315       * @var array
 316       */
 317      var $lexic_permissions = array(
 318          'KEYWORDS' =>    array(),
 319          'COMMENTS' =>    array('MULTI' => true),
 320          'REGEXPS' =>     array(),
 321          'ESCAPE_CHAR' => true,
 322          'BRACKETS' =>    true,
 323          'SYMBOLS' =>     false,
 324          'STRINGS' =>     true,
 325          'NUMBERS' =>     true,
 326          'METHODS' =>     true,
 327          'SCRIPT' =>      true
 328      );
 329  
 330      /**
 331       * The time it took to parse the code
 332       * @var double
 333       */
 334      var $time = 0;
 335  
 336      /**
 337       * The content of the header block
 338       * @var string
 339       */
 340      var $header_content = '';
 341  
 342      /**
 343       * The content of the footer block
 344       * @var string
 345       */
 346      var $footer_content = '';
 347  
 348      /**
 349       * The style of the header block
 350       * @var string
 351       */
 352      var $header_content_style = '';
 353  
 354      /**
 355       * The style of the footer block
 356       * @var string
 357       */
 358      var $footer_content_style = '';
 359  
 360      /**
 361       * Tells if a block around the highlighted source should be forced
 362       * if not using line numbering
 363       * @var boolean
 364       */
 365      var $force_code_block = false;
 366  
 367      /**
 368       * The styles for hyperlinks in the code
 369       * @var array
 370       */
 371      var $link_styles = array();
 372  
 373      /**
 374       * Whether important blocks should be recognised or not
 375       * @var boolean
 376       * @deprecated
 377       * @todo REMOVE THIS FUNCTIONALITY!
 378       */
 379      var $enable_important_blocks = false;
 380  
 381      /**
 382       * Styles for important parts of the code
 383       * @var string
 384       * @deprecated
 385       * @todo As above - rethink the whole idea of important blocks as it is buggy and
 386       * will be hard to implement in 1.2
 387       */
 388      var $important_styles = 'font-weight: bold; color: red;'; // Styles for important parts of the code
 389  
 390      /**
 391       * Whether CSS IDs should be added to the code
 392       * @var boolean
 393       */
 394      var $add_ids = false;
 395  
 396      /**
 397       * Lines that should be highlighted extra
 398       * @var array
 399       */
 400      var $highlight_extra_lines = array();
 401  
 402      /**
 403       * Styles of lines that should be highlighted extra
 404       * @var array
 405       */
 406      var $highlight_extra_lines_styles = array();
 407  
 408      /**
 409       * Styles of extra-highlighted lines
 410       * @var string
 411       */
 412      var $highlight_extra_lines_style = 'background-color: #ffc;';
 413  
 414      /**
 415       * The line ending
 416       * If null, nl2br() will be used on the result string.
 417       * Otherwise, all instances of \n will be replaced with $line_ending
 418       * @var string
 419       */
 420      var $line_ending = null;
 421  
 422      /**
 423       * Number at which line numbers should start at
 424       * @var int
 425       */
 426      var $line_numbers_start = 1;
 427  
 428      /**
 429       * The overall style for this code block
 430       * @var string
 431       */
 432      var $overall_style = 'font-family:monospace;';
 433  
 434      /**
 435       *  The style for the actual code
 436       * @var string
 437       */
 438      var $code_style = 'font-family: monospace; font-weight: normal; font-style: normal; margin:0; padding:0; background:inherit;';
 439  
 440      /**
 441       * The overall class for this code block
 442       * @var string
 443       */
 444      var $overall_class = '';
 445  
 446      /**
 447       * The overall ID for this code block
 448       * @var string
 449       */
 450      var $overall_id = '';
 451  
 452      /**
 453       * Line number styles
 454       * @var string
 455       */
 456      var $line_style1 = 'font-weight: normal;';
 457  
 458      /**
 459       * Line number styles for fancy lines
 460       * @var string
 461       */
 462      var $line_style2 = 'font-weight: bold;';
 463  
 464      /**
 465       * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
 466       * @var string
 467       */
 468      var $table_linenumber_style = 'width:1px;font-weight: normal;text-align:right;margin:0;padding:0 2px;';
 469  
 470      /**
 471       * Flag for how line numbers are displayed
 472       * @var boolean
 473       */
 474      var $line_numbers = GESHI_NO_LINE_NUMBERS;
 475  
 476      /**
 477       * Flag to decide if multi line spans are allowed. Set it to false to make sure
 478       * each tag is closed before and reopened after each linefeed.
 479       * @var boolean
 480       */
 481      var $allow_multiline_span = true;
 482  
 483      /**
 484       * The "nth" value for fancy line highlighting
 485       * @var int
 486       */
 487      var $line_nth_row = 0;
 488  
 489      /**
 490       * The size of tab stops
 491       * @var int
 492       */
 493      var $tab_width = 8;
 494  
 495      /**
 496       * Should we use language-defined tab stop widths?
 497       * @var int
 498       */
 499      var $use_language_tab_width = false;
 500  
 501      /**
 502       * Default target for keyword links
 503       * @var string
 504       */
 505      var $link_target = '';
 506  
 507      /**
 508       * The encoding to use for entity encoding
 509       * NOTE: Used with Escape Char Sequences to fix UTF-8 handling (cf. SF#2037598)
 510       * @var string
 511       */
 512      var $encoding = 'utf-8';
 513  
 514      /**
 515       * Should keywords be linked?
 516       * @var boolean
 517       */
 518      var $keyword_links = true;
 519  
 520      /**
 521       * Currently loaded language file
 522       * @var string
 523       * @since 1.0.7.22
 524       */
 525      var $loaded_language = '';
 526  
 527      /**
 528       * Wether the caches needed for parsing are built or not
 529       *
 530       * @var bool
 531       * @since 1.0.8
 532       */
 533      var $parse_cache_built = false;
 534  
 535      /**
 536       * Work around for Suhosin Patch with disabled /e modifier
 537       *
 538       * Note from suhosins author in config file:
 539       * <blockquote>
 540       *   The /e modifier inside <code>preg_replace()</code> allows code execution.
 541       *   Often it is the cause for remote code execution exploits. It is wise to
 542       *   deactivate this feature and test where in the application it is used.
 543       *   The developer using the /e modifier should be made aware that he should
 544       *   use <code>preg_replace_callback()</code> instead
 545       * </blockquote>
 546       *
 547       * @var array
 548       * @since 1.0.8
 549       */
 550      var $_kw_replace_group = 0;
 551      var $_rx_key = 0;
 552  
 553      /**
 554       * some "callback parameters" for handle_multiline_regexps
 555       *
 556       * @since 1.0.8
 557       * @access private
 558       * @var string
 559       */
 560      var $_hmr_before = '';
 561      var $_hmr_replace = '';
 562      var $_hmr_after = '';
 563      var $_hmr_key = 0;
 564  
 565      /**#@-*/
 566  
 567      /**
 568       * Creates a new GeSHi object, with source and language
 569       *
 570       * @param string The source code to highlight
 571       * @param string The language to highlight the source with
 572       * @param string The path to the language file directory. <b>This
 573       *               is deprecated!</b> I've backported the auto path
 574       *               detection from the 1.1.X dev branch, so now it
 575       *               should be automatically set correctly. If you have
 576       *               renamed the language directory however, you will
 577       *               still need to set the path using this parameter or
 578       *               {@link GeSHi->set_language_path()}
 579       * @since 1.0.0
 580       */
 581      function GeSHi($source = '', $language = '', $path = '') {
 582          if (!empty($source)) {
 583              $this->set_source($source);
 584          }
 585          if (!empty($language)) {
 586              $this->set_language($language);
 587          }
 588          $this->set_language_path($path);
 589      }
 590  
 591      /**
 592       * Returns an error message associated with the last GeSHi operation,
 593       * or false if no error has occured
 594       *
 595       * @return string|false An error message if there has been an error, else false
 596       * @since  1.0.0
 597       */
 598      function error() {
 599          if ($this->error) {
 600              //Put some template variables for debugging here ...
 601              $debug_tpl_vars = array(
 602                  '{LANGUAGE}' => $this->language,
 603                  '{PATH}' => $this->language_path
 604              );
 605              $msg = str_replace(
 606                  array_keys($debug_tpl_vars),
 607                  array_values($debug_tpl_vars),
 608                  $this->error_messages[$this->error]);
 609  
 610              return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
 611          }
 612          return false;
 613      }
 614  
 615      /**
 616       * Gets a human-readable language name (thanks to Simon Patterson
 617       * for the idea :))
 618       *
 619       * @return string The name for the current language
 620       * @since  1.0.2
 621       */
 622      function get_language_name() {
 623          if (GESHI_ERROR_NO_SUCH_LANG == $this->error) {
 624              return $this->language_data['LANG_NAME'] . ' (Unknown Language)';
 625          }
 626          return $this->language_data['LANG_NAME'];
 627      }
 628  
 629      /**
 630       * Sets the source code for this object
 631       *
 632       * @param string The source code to highlight
 633       * @since 1.0.0
 634       */
 635      function set_source($source) {
 636          $this->source = $source;
 637          $this->highlight_extra_lines = array();
 638      }
 639  
 640      /**
 641       * Sets the language for this object
 642       *
 643       * @note since 1.0.8 this function won't reset language-settings by default anymore!
 644       *       if you need this set $force_reset = true
 645       *
 646       * @param string The name of the language to use
 647       * @since 1.0.0
 648       */
 649      function set_language($language, $force_reset = false) {
 650          if ($force_reset) {
 651              $this->loaded_language = false;
 652          }
 653  
 654          //Clean up the language name to prevent malicious code injection
 655          $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
 656  
 657          $language = strtolower($language);
 658  
 659          //Retreive the full filename
 660          $file_name = $this->language_path . $language . '.php';
 661          if ($file_name == $this->loaded_language) {
 662              // this language is already loaded!
 663              return;
 664          }
 665  
 666          $this->language = $language;
 667  
 668          $this->error = false;
 669          $this->strict_mode = GESHI_NEVER;
 670  
 671          //Check if we can read the desired file
 672          if (!is_readable($file_name)) {
 673              $this->error = GESHI_ERROR_NO_SUCH_LANG;
 674              return;
 675          }
 676  
 677          // Load the language for parsing
 678          $this->load_language($file_name);
 679      }
 680  
 681      /**
 682       * Sets the path to the directory containing the language files. Note
 683       * that this path is relative to the directory of the script that included
 684       * geshi.php, NOT geshi.php itself.
 685       *
 686       * @param string The path to the language directory
 687       * @since 1.0.0
 688       * @deprecated The path to the language files should now be automatically
 689       *             detected, so this method should no longer be needed. The
 690       *             1.1.X branch handles manual setting of the path differently
 691       *             so this method will disappear in 1.2.0.
 692       */
 693      function set_language_path($path) {
 694          if ($path) {
 695              $this->language_path = ('/' == $path[strlen($path) - 1]) ? $path : $path . '/';
 696              $this->set_language($this->language);        // otherwise set_language_path has no effect
 697          }
 698      }
 699  
 700      /**
 701       * Sets the type of header to be used.
 702       *
 703       * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This
 704       * means more source code but more control over tab width and line-wrapping.
 705       * GESHI_HEADER_PRE means that a "pre" is used - less source, but less
 706       * control. Default is GESHI_HEADER_PRE.
 707       *
 708       * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code
 709       * should be outputted.
 710       *
 711       * @param int The type of header to be used
 712       * @since 1.0.0
 713       */
 714      function set_header_type($type) {
 715          //Check if we got a valid header type
 716          if (!in_array($type, array(GESHI_HEADER_NONE, GESHI_HEADER_DIV,
 717              GESHI_HEADER_PRE, GESHI_HEADER_PRE_VALID, GESHI_HEADER_PRE_TABLE))) {
 718              $this->error = GESHI_ERROR_INVALID_HEADER_TYPE;
 719              return;
 720          }
 721  
 722          //Set that new header type
 723          $this->header_type = $type;
 724      }
 725  
 726      /**
 727       * Sets the styles for the code that will be outputted
 728       * when this object is parsed. The style should be a
 729       * string of valid stylesheet declarations
 730       *
 731       * @param string  The overall style for the outputted code block
 732       * @param boolean Whether to merge the styles with the current styles or not
 733       * @since 1.0.0
 734       */
 735      function set_overall_style($style, $preserve_defaults = false) {
 736          if (!$preserve_defaults) {
 737              $this->overall_style = $style;
 738          } else {
 739              $this->overall_style .= $style;
 740          }
 741      }
 742  
 743      /**
 744       * Sets the overall classname for this block of code. This
 745       * class can then be used in a stylesheet to style this object's
 746       * output
 747       *
 748       * @param string The class name to use for this block of code
 749       * @since 1.0.0
 750       */
 751      function set_overall_class($class) {
 752          $this->overall_class = $class;
 753      }
 754  
 755      /**
 756       * Sets the overall id for this block of code. This id can then
 757       * be used in a stylesheet to style this object's output
 758       *
 759       * @param string The ID to use for this block of code
 760       * @since 1.0.0
 761       */
 762      function