Index: wordfilter.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wordfilter/wordfilter.module,v
retrieving revision 1.7.2.9.2.13
diff -b -u -p -r1.7.2.9.2.13 wordfilter.module
--- wordfilter.module	14 Apr 2009 08:15:49 -0000	1.7.2.9.2.13
+++ wordfilter.module	14 Apr 2009 09:20:15 -0000
@@ -338,10 +338,36 @@ function wordfilter_filter_process($text
       $replacement = ($word->replacement) ? $word->replacement : variable_get('wordfilter_default_replacement', '[filtered word]');
       
       if ($word->standalone) {
-        $text = preg_replace("/(\W)". preg_quote($word->words, '/') ."(\W)/i". ($utf8 ? 'u' : ''), "$1". $replacement ."$2", $text);
+        $pattern = '/(\W)'. preg_quote($word->words, '/') .'(\W)/i';
       }
       else {
-        $text = preg_replace('/'. preg_quote($word->words, '/') .'/i'. ($utf8 ? 'u' : ''), $replacement, $text);
+        $pattern = '/'. preg_quote($word->words, '/') .'/i';
+      }
+      if ($utf8) {
+        $pattern .= 'u';
+      }
+
+      $split_text = preg_split('/(<a\s+.+?>[^<]*?<\/a>)/i', substr($text, 1, -1), -1, PREG_SPLIT_DELIM_CAPTURE);
+      $split_text = array_values(array_filter($split_text));
+      if (count($split_text) > 1) {
+        $new_string = '';
+        foreach ($split_text as $index => $part) {
+          if ($index % 2 == 0) {
+            $new_string .= preg_replace($pattern, $replacement, $part);
+          }
+          else {
+            $new_string .= _wordfilter_filter_process_links($part, $pattern, $replacement);
+          }
+        }
+        $text = ' '. $new_string .' ';
+      }
+      else {
+        if (preg_match('/<a\s+.+?>[^<]*?<\/a>/i', $split_text[0])) {
+          $text = ' '. _wordfilter_filter_process_links($split_text[0], $pattern, $replacement) .' ';
+        }
+        else {
+          $text = preg_replace($pattern, $replacement, $text);
+        }
       }
     }
   }
@@ -351,6 +377,19 @@ function wordfilter_filter_process($text
 }
 
 /**
+ * Filter link text without touching link tag attributes such as href.
+ */
+function _wordfilter_filter_process_links($link, $pattern, $replacement) {
+  return preg_replace_callback(
+    '/(<a\s+.+?>)([^<]*?)(<\/a>)/i',
+    create_function(
+      "\$matches, \$p = '$pattern', \$r = '$replacement'",
+      'return $matches[1] . preg_replace($p, $r, $matches[2]) . $matches[3];'
+    ),
+    $link);
+}
+
+/**
  * Query to get the list of words to filter in the
  * filter processing stage. Does not use a pager.
  */
