View source  
  <?php
require_once 'geshifilter.inc';
function _geshifilter_parse_attributes($attributes, $format) {
  
  $lang = NULL;
  $line_numbering = NULL;
  $linenumbers_start = NULL;
  
  list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
  $language_attributes = _geshifilter_whitespace_explode(GESHIFILTER_ATTRIBUTES_LANGUAGE);
  $attributes_preg_string = implode('|', array_merge($language_attributes, array(
    GESHIFILTER_ATTRIBUTE_LINE_NUMBERING,
    GESHIFILTER_ATTRIBUTE_LINE_NUMBERING_START,
    GESHIFILTER_ATTRIBUTE_FANCY_N,
  )));
  $enabled_languages = _geshifilter_get_enabled_languages();
  
  preg_match_all('#(' . $attributes_preg_string . ')="?([^\\s"]*)"?#', $attributes, $attribute_matches);
  foreach ($attribute_matches[1] as $a_key => $att_name) {
    
    $att_value = $attribute_matches[2][$a_key];
    
    if (in_array($att_name, $language_attributes)) {
      
      if (in_array($att_value, $language_tags)) {
        $att_value = $tag_to_lang[$att_value];
      }
      
      if (array_key_exists($att_value, $enabled_languages)) {
        $lang = $att_value;
      }
    }
    elseif ($att_name == GESHIFILTER_ATTRIBUTE_LINE_NUMBERING) {
      switch (strtolower($att_value)) {
        case "off":
          $line_numbering = 0;
          break;
        case "normal":
          $line_numbering = 1;
          break;
        case "fancy":
          $line_numbering = 5;
          break;
      }
    }
    elseif ($att_name == GESHIFILTER_ATTRIBUTE_FANCY_N) {
      $att_value = (int) $att_value;
      if ($att_value >= 2) {
        $line_numbering = $att_value;
      }
    }
    elseif ($att_name == GESHIFILTER_ATTRIBUTE_LINE_NUMBERING_START) {
      if ($line_numbering < 1) {
        $line_numbering = 1;
      }
      $linenumbers_start = (int) $att_value;
    }
  }
  
  return array(
    'language' => $lang,
    'line_numbering' => $line_numbering,
    'linenumbers_start' => $linenumbers_start,
  );
}
function _geshifilter_prepare($format, $text) {
  
  list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
  $tags = array_merge($generic_code_tags, $language_tags);
  
  $tags = preg_replace('#(\\+|\\#)#', '\\\\$1', $tags);
  $tags_string = implode('|', $tags);
  
  switch (_geshifilter_brackets($format)) {
    case GESHIFILTER_BRACKETS_ANGLE:
      $pattern = '#(<)(' . $tags_string . ')((\\s+[^>]*)*)(>)(.*?)(</\\2\\s*>|$)#s';
      break;
    case GESHIFILTER_BRACKETS_SQUARE:
      $pattern = '#(\\[)(' . $tags_string . ')((\\s+[^\\]]*)*)(\\])(.*?)(\\[/\\2\\s*\\]|$)#s';
      break;
    case GESHIFILTER_BRACKETS_BOTH:
      $pattern = '#([<\\[])(' . $tags_string . ')((\\s+[^>\\]]*)*)([>\\]])(.*?)(\\1/\\2\\s*\\5|$)#s';
      break;
  }
  
  $text = preg_replace_callback($pattern, create_function('$match', "return _geshifilter_prepare_callback(\$match, {$format});"), $text);
  if (_geshifilter_php_delimeters($format)) {
    
    $text = preg_replace_callback('#[\\[<](\\?php|\\?PHP|%)(.+?)((\\?|%)[\\]>]|$)#s', '_geshifilter_prepare_php_callback', $text);
  }
  return $text;
}
function _geshifilter_prepare_callback($match, $format) {
  
  $tag_name = $match[2];
  $tag_attributes = $match[3];
  $content = $match[6];
  
  $lang = variable_get('geshifilter_default_highlighting', GESHIFILTER_DEFAULT_PLAINTEXT);
  if ($lang == GESHIFILTER_DEFAULT_DONOTHING) {
    
    $enabled_languages = _geshifilter_get_enabled_languages();
    
    list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
    if (isset($tag_to_lang[$tag_name]) && isset($enabled_languages[$tag_to_lang[$tag_name]])) {
      $lang = $tag_to_lang[$tag_name];
    }
    else {
      
      $settings = _geshifilter_parse_attributes($tag_attributes, $format);
      if ($settings['language'] && isset($enabled_languages[$settings['language']])) {
        $lang = $settings['language'];
      }
    }
    
    if ($lang == GESHIFILTER_DEFAULT_DONOTHING) {
      return $match[0];
    }
  }
  
  return '[geshifilter-' . $tag_name . $tag_attributes . ']' . str_replace(array(
    "\r",
    "\n",
  ), array(
    '',
    '
',
  ), check_plain($content)) . '[/geshifilter-' . $tag_name . ']';
}
function _geshifilter_prepare_php_callback($match) {
  return '[geshifilter-questionmarkphp]' . str_replace(array(
    "\r",
    "\n",
  ), array(
    '',
    '
',
  ), check_plain($match[2])) . '[/geshifilter-questionmarkphp]';
}
function _geshifilter_process($format, $text) {
  
  $geshi_library = _geshifilter_check_geshi_library();
  if (!$geshi_library['success']) {
    drupal_set_message($geshi_library['message'], 'error');
    return $text;
  }
  
  list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
  if (_geshifilter_php_delimeters($format)) {
    $language_tags[] = 'questionmarkphp';
    $tag_to_lang['questionmarkphp'] = 'php';
  }
  $tags = array_merge($generic_code_tags, $language_tags);
  
  $tags = preg_replace('#(\\+|\\#)#', '\\\\$1', $tags);
  $tags_string = implode('|', $tags);
  
  $pattern = '#\\[geshifilter-(' . $tags_string . ')([^\\]]*)\\](.*?)(\\[/geshifilter-\\1\\])#s';
  $text = preg_replace_callback($pattern, create_function('$match', "return _geshifilter_replace_callback(\$match, {$format});"), $text);
  return $text;
}
function _geshifilter_replace_callback($match, $format) {
  
  $complete_match = $match[0];
  $tag_name = $match[1];
  $tag_attributes = $match[2];
  $source_code = $match[3];
  
  $source_code = decode_entities($source_code);
  
  $lang = variable_get('geshifilter_default_highlighting', GESHIFILTER_DEFAULT_PLAINTEXT);
  $line_numbering = variable_get('geshifilter_default_line_numbering', GESHIFILTER_LINE_NUMBERS_DEFAULT_NONE);
  $linenumbers_start = 1;
  
  list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
  if (variable_get('geshifilter_enable_php_delimiters', FALSE)) {
    $language_tags[] = 'questionmarkphp';
    $tag_to_lang['questionmarkphp'] = 'php';
  }
  if (isset($tag_to_lang[$tag_name])) {
    $lang = $tag_to_lang[$tag_name];
  }
  
  $settings = _geshifilter_parse_attributes($tag_attributes, $format);
  if (isset($settings['language'])) {
    $lang = $settings['language'];
  }
  if (isset($settings['line_numbering'])) {
    $line_numbering = $settings['line_numbering'];
  }
  if (isset($settings['linenumbers_start'])) {
    $linenumbers_start = $settings['linenumbers_start'];
  }
  if ($lang == GESHIFILTER_DEFAULT_DONOTHING) {
    
    return $complete_match;
  }
  if ($lang == GESHIFILTER_DEFAULT_PLAINTEXT) {
    
    $lang = 'text';
  }
  $inline_mode = strpos($source_code, "\n") === FALSE;
  
  return geshifilter_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode);
}
function _geshifilter_override_geshi_defaults(&$geshi, $langcode) {
  
  $geshi
    ->set_line_style('font-family: monospace; font-weight: normal;', 'font-family: monospace; font-weight: bold; font-style: italic;');
  $geshi
    ->set_code_style('font-family: monospace; font-weight: normal; font-style: normal');
  
  $geshi
    ->set_overall_class('geshifilter-' . $langcode);
  
  $geshi
    ->enable_keyword_links(variable_get('geshifilter_enable_keyword_urls', TRUE));
}
function geshifilter_process($source_code, $lang, $line_numbering = 0, $linenumbers_start = 1, $inline_mode = FALSE) {
  
  if ($lang == 'php' && variable_get('geshifilter_use_highlight_string_for_php', FALSE)) {
    return geshifilter_highlight_string_process($source_code, $inline_mode);
  }
  else {
    
    return geshifilter_geshi_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode);
  }
}
function geshifilter_geshi_process($source_code, $lang, $line_numbering = 0, $linenumbers_start = 1, $inline_mode = FALSE) {
  
  $geshi_library = _geshifilter_check_geshi_library();
  if (!$geshi_library['loaded']) {
    drupal_set_message($geshi_library['message'], 'error');
    return $source_code;
  }
  
  $source_code = trim($source_code, "\n\r");
  
  $geshi = _geshifilter_geshi_factory($source_code, $lang);
  
  $ccs_mode = variable_get('geshifilter_css_mode', GESHIFILTER_CSS_INLINE);
  if ($ccs_mode == GESHIFILTER_CSS_CLASSES_AUTOMATIC || $ccs_mode == GESHIFILTER_CSS_CLASSES_ONLY) {
    $geshi
      ->enable_classes(TRUE);
  }
  _geshifilter_override_geshi_defaults($geshi, $lang);
  
  if ($inline_mode) {
    
    $geshi
      ->set_header_type(GESHI_HEADER_NONE);
    $source_code = '<span class="geshifilter"><code class="' . $geshi->overall_class . '">' . $geshi
      ->parse_code() . '</code></span>';
  }
  else {
    
    $geshi
      ->set_header_type((int) variable_get('geshifilter_code_container', GESHI_HEADER_PRE));
    if ($line_numbering == 1) {
      $geshi
        ->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
      $geshi
        ->start_line_numbers_at($linenumbers_start);
    }
    elseif ($line_numbering >= 2) {
      $geshi
        ->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, $line_numbering);
      $geshi
        ->start_line_numbers_at($linenumbers_start);
    }
    $source_code = '<div class="geshifilter">' . $geshi
      ->parse_code() . '</div>';
  }
  return $source_code;
}
function geshifilter_highlight_string_process($source_code, $inline_mode) {
  
  $text = trim($source_code);
  if (substr($text, 0, 5) != '<?php') {
    $source_code = '<?php' . $source_code;
  }
  if (substr($text, -2) != '?>') {
    $source_code = $source_code . '?>';
  }
  
  $container = $inline_mode ? 'span' : 'div';
  
  $text = '<' . $container . ' class="codeblock geshifilter">' . highlight_string($source_code, TRUE) . '</' . $container . '>';
  
  $text = str_replace("\n", '', $text);
  return $text;
}