? project_issue.vmod.module
? project_issue.vnoc.module
? project_issue.vori.module
Index: project_issue.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue/project_issue.module,v
retrieving revision 1.80
diff -u -p -r1.80 project_issue.module
--- project_issue.module	26 Jan 2008 06:41:51 -0000	1.80
+++ project_issue.module	1 Feb 2008 15:27:08 -0000
@@ -1129,31 +1129,68 @@ function project_issue_filter($op, $delt
     case 'prepare':
       return $text;
     case 'process':
-      $regex = '(?<!\w)(\[#(\d+)(-(\d+))?\])(?![^<]*<\/a>|([^<]|(<(?!code)))*<\/code>|([^<]|(<(?!pre)))*<\/pre>|\w)';
-      $offset = 0;
-      while(preg_match("/$regex/", $text, $preg_matches, PREG_OFFSET_CAPTURE, $offset)) {
-        $offset++;
-        $match = $preg_matches[1];
-        $nid = $preg_matches[2][0];
-        $comment_number = $preg_matches[4][0];
-        $node = node_load($nid);
-        if (is_object($node) && node_access('view', $node) && $node->type == 'project_issue') {
-          if (!is_null($comment_number)) {
-            // Pull comment id based on the comment number.
-            $comment_id = db_result(db_query("SELECT cid FROM {comments} WHERE nid = %d AND thread = '%s'", $nid, int2vancode($comment_number) .'/'));
-            $link = theme('project_issue_issue_link', $node, $comment_id, $comment_number);
-          }
-          else {
-            $link = theme('project_issue_issue_link', $node);
+      $events = array();
+
+      // Find potential matches.
+      $regex = '(?<!\w)(\[#(\d+)(-(\d+))?\])(?!\w)';
+      preg_match_all("/$regex/", $text, $preg_matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+      foreach ($preg_matches as $preg_match) {
+        $events[$preg_match[0][1]] = array('type' => 'match', 'length' => strlen($preg_match[0][0]), 'nid' => $preg_match[2][0], 'comment_number' => $preg_match[4][0]);
+      }
+
+      // Find blocking tags.
+      $open_tags = array('<a ', '<code', '<pre', '[code');
+      $close_tags = array('</a>', '</code>', '</pre>', '[/code]');
+      foreach ($open_tags as $i => $tag) {
+        $offset=0;
+        while(($offset = strpos($text, $tag, $offset)) !== false) {
+          $events[$offset] = array('type' => 'open', 'which' => $i);
+          $offset += strlen($tag);
+        }
+      }
+
+      ksort($events);
+      $newtext = '';
+      $parsed = 0; // text was parsed from chars 0 to $parsed (exclusive)
+
+      foreach($events as $place => $event) {
+        // skip events inside blocking tag (they're already copied as is)
+        if ($place < $parsed) {
+          continue;
+        }
+        // copy plain text (with no events)
+          $newtext .= substr($text, $parsed, ($place - $parsed));
+          $parsed = $place;
+        // if a blocking tag is opened, skip to closing tag
+        if ($event['type'] == 'open') {
+          $skip = strpos($text, $close_tags[$event['which']], $place);
+          if ($skip === false) {
+            $skip = drupal_strlen($text);
           }
-          $text = substr_replace($text, $link, $match[1], strlen($match[0]));
-          $offset = max($offset, $match[1] + strlen($link));
+          $newtext .= substr($text, $parsed, ($skip - $parsed));
+          $parsed = $skip;
         }
-        else {
-          $offset = max($offset, $match[1] + strlen($match[0]));
+
+        if ($event['type'] == 'match') {
+          $comment_number = $event['comment_number'];
+          $node = node_load($event['nid']);
+          if (is_object($node) && node_access('view', $node) && $node->type == 'project_issue') {
+            if (!is_null($comment_number)) {
+              $comment_id = db_result(db_query("SELECT cid FROM {comments} WHERE nid = %d AND thread = '%s'", $event['nid'], int2vancode($comment_number) .'/'));
+              $link = theme('project_issue_issue_link', $node, $comment_id, $comment_number);
+            }
+            else {
+              $link = theme('project_issue_issue_link', $node);
+            }
+            $newtext .= $link;
+            $parsed += $event['length'];
+          }
         }
+
       }
-      return $text;
+
+      // Append remaining part
+      return $newtext . substr($text, $parsed);
   }
 }
 
