You are here

function _geshifilter_process_code in GeSHi Filter for syntax highlighting 5

1 call to _geshifilter_process_code()
geshifilter_filter in ./geshifilter.module
Implementation of hook_filter()

File

./geshifilter.module, line 369

Code

function _geshifilter_process_code($format, $text, $flags = '') {

  // load the GeSHi library and just return text if not successful
  if (!_geshifilter_load_geshi()) {
    return $text;
  }
  $lang_dir = variable_get('geshifilter_lang_dir', drupal_get_path('module', 'geshifilter') . '/geshi/geshi');
  $types = variable_get('geshifilter_types_' . $format, array());
  $code_container = variable_get('geshifilter_code_container', GESHI_HEADER_PRE);
  $line_numbers = variable_get('geshifilter_line_numbers', GESHI_NO_LINE_NUMBERS);
  $fancy_number = variable_get('geshifilter_fancy_number', 5);
  $start_param = variable_get('geshifilter_start_attribute', FALSE);
  $overall_style = variable_get('geshifilter_overall_style', '');
  $number_style = variable_get('geshifilter_number_style', '');
  $fancy_number_style = variable_get('geshifilter_fancy_number_style', 'font-weight: bold;');
  $code_style = variable_get('geshifilter_code_style', 'font-weight: normal;');
  $inline_code = variable_get('geshifilter_inline_code_' . $format, FALSE);
  $tags = 'blockcode' . ($inline_code ? '|code' : '');
  if (preg_match_all('/<(' . $tags . ')((?:\\s(?:.|\\s|\\z)*?)*)\\s*>((?:.|\\s|\\z)*?)<\\/\\1\\s*>/i', $text, $match)) {

    // $match[0][xx] .... fully matched string <blockcode type="language">...</blockcode>
    // $match[1][xx] .... tag
    // $match[2][xx] .... full params string type="language"...
    // $match[3][xx] .... code to highlight
    foreach ($match[3] as $key => $value) {
      preg_match_all('/(type|start)\\s*=\\s*[\\"]((?:.|\\s|\\z)*?)[\\"]/i', $match[2][$key], $param);

      //let lang and language tags for backward compatibility

      // $param[0][xx] .... fully matched string type="language"
      // $param[1][xx] .... param name
      // $param[2][xx] .... param value

      //default values
      $lang = variable_get('geshifilter_default_type_' . $format, 0);
      $start = 1;
      foreach ($param[2] as $p_key => $p_value) {

        //if lang is known, allowed and found
        if ($param[1][$p_key] == 'type' && in_array($p_value, $types) && $types[$p_value]) {
          $lang = $p_value;
        }

        //if start param has been allowed
        if (($line_numbers == GESHI_NORMAL_LINE_NUMBERS || $line_numbers == GESHI_FANCY_LINE_NUMBERS) && $start_param) {

          //if start param is found
          if ($param[1][$p_key] == 'start' && $p_value) {
            $start = $p_value;
          }
        }
      }

      // geshi will reencode these
      $matched = decode_entities($value);

      // undo nl and p formatting
      $matched = preg_replace("@<br />@", "", $matched);
      $matched = preg_replace("@<p>|</p>@", "", $matched);
      $geshi = new GeSHi($matched, $lang, $lang_dir);

      // enable usage of CSS classes instead of inline styles
      // (should be the first method of the GeSHi object to call according to
      // http://qbnz.com/highlighter/geshi-doc.html#enabling-css-classes)
      if (variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE) == GESHIFILTER_CSS_CLASSES) {
        $geshi
          ->enable_classes(TRUE);
      }
      if ($match[1][$key] == 'code') {
        $geshi
          ->set_header_type(GESHI_HEADER_NONE);
      }
      else {
        $geshi
          ->set_header_type($code_container);
      }
      if ($match[1][$key] != 'code') {
        $geshi
          ->set_overall_class('geshifilter');
      }

      //line numbers
      if ($line_numbers != GESHI_NO_LINE_NUMBERS && $match[1][$key] != 'code') {
        $geshi
          ->enable_line_numbers($line_numbers, $line_numbers == GESHI_FANCY_LINE_NUMBERS ? $fancy_number : null);
        if ($start_param) {
          $geshi
            ->start_line_numbers_at($start);
        }
      }

      //styles
      $geshi
        ->set_overall_style($overall_style);
      $geshi
        ->set_line_style($number_style, $fancy_number_style);
      $geshi
        ->set_code_style($code_style);
      if ($match[1][$key] == 'code') {
        $text = str_replace($match[0][$key], '<code class="geshifilter' . ($lang ? ' ' . $lang : '') . '">' . $geshi
          ->parse_code() . '</code>', $text);
      }
      else {
        $text = str_replace($match[0][$key], $geshi
          ->parse_code(), $text);
      }
    }
  }
  return $text;
}