diff -ru geshifilter.orig/geshifilter.module geshifilter/geshifilter.module
--- geshifilter.orig/geshifilter.module	2009-07-12 15:00:28 +0000
+++ geshifilter/geshifilter.module	2010-03-30 09:52:03 +0000
@@ -21,6 +21,7 @@
 define('GESHIFILTER_ATTRIBUTE_LINE_NUMBERING', 'linenumbers');
 define('GESHIFILTER_ATTRIBUTE_LINE_NUMBERING_START', 'start');
 define('GESHIFILTER_ATTRIBUTE_FANCY_N', 'fancy');
+define('GESHIFILTER_ATTRIBUTE_TITLE', 'title');
 
 define('GESHIFILTER_BRACKETS_ANGLE', 1);
 define('GESHIFILTER_BRACKETS_SQUARE', 2);
diff -ru geshifilter.orig/geshifilter.pages.inc geshifilter/geshifilter.pages.inc
--- geshifilter.orig/geshifilter.pages.inc	2010-02-01 00:31:45 +0000
+++ geshifilter/geshifilter.pages.inc	2010-03-30 14:09:32 +0000
@@ -25,6 +25,7 @@
   $lang = NULL;
   $line_numbering = NULL;
   $linenumbers_start = NULL;
+  $title = "";
 
   // Get the possible tags and languages.
   list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
@@ -32,7 +33,7 @@
   $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)
+    array(GESHIFILTER_ATTRIBUTE_LINE_NUMBERING, GESHIFILTER_ATTRIBUTE_LINE_NUMBERING_START, GESHIFILTER_ATTRIBUTE_FANCY_N, GESHIFILTER_ATTRIBUTE_TITLE)
   ));
   $enabled_languages = _geshifilter_get_enabled_languages();
 
@@ -40,7 +41,7 @@
   // $attribute_matches[0][xx] .... fully matched string, e.g. 'language="python"'
   // $attribute_matches[1][xx] .... param name, e.g. 'language'
   // $attribute_matches[2][xx] .... param value, e.g. 'python'
-  preg_match_all('#('. $attributes_preg_string .')="?([^\s"]*)"?#', $attributes, $attribute_matches);
+  preg_match_all('#('. $attributes_preg_string .')="?([^"]*)"?#', $attributes, $attribute_matches);
 
   foreach ($attribute_matches[1] as $a_key => $att_name) {
     // get attribute value
@@ -88,9 +89,12 @@
       }
       $linenumbers_start = (int)($att_value);
     }
+    elseif ($att_name == GESHIFILTER_ATTRIBUTE_TITLE) {
+      $title = $att_value;
+    }
   }
   // Return parsed results.
-  return array('language' => $lang, 'line_numbering' => $line_numbering, 'linenumbers_start' => $linenumbers_start);
+  return array('language' => $lang, 'line_numbering' => $line_numbering, 'linenumbers_start' => $linenumbers_start, 'title' => $title);
 }
 
 /**
@@ -245,6 +249,7 @@
   $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;
+  $title = "";
 
   // Determine language based on tag name if possible.
   list($generic_code_tags, $language_tags, $tag_to_lang) = _geshifilter_get_tags($format);
@@ -267,6 +272,9 @@
   if (isset($settings['linenumbers_start'])) {
     $linenumbers_start = $settings['linenumbers_start'];
   }
+  if (isset($settings['title'])) {
+    $title = $settings['title'];
+  }
 
   if ($lang == GESHIFILTER_DEFAULT_DONOTHING) {
     // Do nothing, and return the original.
@@ -278,7 +286,7 @@
   }
   $inline_mode = (strpos($source_code, "\n") === FALSE);
   // process and return
-  return geshifilter_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode);
+  return geshifilter_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode, $title);
 }
 
 /**
@@ -297,21 +305,21 @@
 /**
  * General geshifilter processing function
  */
-function geshifilter_process($source_code, $lang, $line_numbering=0, $linenumbers_start=1, $inline_mode=FALSE) {
+function geshifilter_process($source_code, $lang, $line_numbering=0, $linenumbers_start=1, $inline_mode=FALSE, $title = "") {
   // process
   if ($lang == 'php' && variable_get('geshifilter_use_highlight_string_for_php', FALSE)) {
     return geshifilter_highlight_string_process($source_code, $inline_mode);
   }
   else {
     // process with GeSHi
-    return geshifilter_geshi_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode);
+    return geshifilter_geshi_process($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode, $title);
   }
 }
 
 /**
  * geshifilter wrapper for GeSHi processing.
  */
-function geshifilter_geshi_process($source_code, $lang, $line_numbering=0, $linenumbers_start=1, $inline_mode=FALSE) {
+function geshifilter_geshi_process($source_code, $lang, $line_numbering=0, $linenumbers_start=1, $inline_mode=FALSE, $title = "") {
   // load GeSHi library (if not already)
   $geshi_library = _geshifilter_check_geshi_library();
   if (!$geshi_library['loaded']) {
@@ -322,7 +330,7 @@
    // Check for a cached version of this source code and return it if available.
    // @todo: Use a dedicated table instead of using cache_filter? If so,
    // also take care of the flushing in _geshifilter_clear_filter_cache().
-  $cache_id = "geshifilter:$lang:$line_numbering:$line_numbering:$inline_mode" . md5($source_code);
+  $cache_id = "geshifilter:$lang:$line_numbering:$line_numbering:$inline_mode" . md5($title . $source_code);
   if ($cached = cache_get($cache_id, 'cache_filter')) {
     return $cached->data;
   }
@@ -348,7 +356,7 @@
     // commit 1610), we use both the language and overall_class for the class,
     // to mimic the 1.0.8 behavior, which is backward compatible.
     $code_class = "{$geshi->language} {$geshi->overall_class}";
-    $source_code = '<span class="geshifilter"><code class="'. $code_class .'">'. $geshi->parse_code() .'</code></span>';
+    $source_code = '<span class="geshifilter" title="'. $title .'"><code class="'. $code_class .'">'. $geshi->parse_code() .'</code></span>';
   }
   else {
     // block source code mode
@@ -361,7 +369,13 @@
       $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>';
+    if (!empty($title)) {
+      $source_code = '<div class="geshifilter-title">'. $title .'</div>';
+    }
+    else {
+      $source_code = '';
+    }
+    $source_code .= '<div class="geshifilter">'. $geshi->parse_code() .'</div>';
   }
 
   // Store in cache with a minimum expiration time of 1 day.
