Index: INSTALL.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue/INSTALL.txt,v
retrieving revision 1.6
diff -u -p -r1.6 INSTALL.txt
--- INSTALL.txt	2 Nov 2007 01:47:16 -0000	1.6
+++ INSTALL.txt	10 Dec 2007 19:57:25 -0000
@@ -24,6 +24,8 @@ New Installation
 
 8. Grant the proper access to users under admin/user/access
 
+9. Enable project issue to link filter in proper input formats at admin/settings/filters
+
 
 --------------------------------------------------------------
 Upgrading
Index: project_issue.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue/project_issue.css,v
retrieving revision 1.17
diff -u -p -r1.17 project_issue.css
--- project_issue.css	14 Nov 2007 05:57:42 -0000	1.17
+++ project_issue.css	10 Dec 2007 19:57:25 -0000
@@ -156,3 +156,12 @@ table.projects .project-project-links {
   text-align: right;
   color: #999;
 }
+
+/* Automatic issue links */
+.project-issue-status-2,
+.project-issue-status-3,
+.project-issue-status-5,
+.project-issue-status-6,
+.project-issue-status-7 {
+  text-decoration: line-through;
+}
Index: project_issue.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue/project_issue.module,v
retrieving revision 1.74
diff -u -p -r1.74 project_issue.module
--- project_issue.module	9 Dec 2007 03:17:19 -0000	1.74
+++ project_issue.module	10 Dec 2007 19:57:28 -0000
@@ -970,3 +970,148 @@ function project_issue_link_alter(&$node
     unset($links['comment_add']);
   }
 }
+
+
+/**
+ * @defgroup project_issue_filter Project Issue number to link filter
+ */
+
+/**
+ * Theme automatic Project Issue links
+ * @ingroup project_issue_filter
+ */
+function theme_project_issue_issue_link($node, $comment_id=0) {
+  if ($node->type == 'project_issue') {
+    $title = check_plain("#$node->nid: $node->title");
+    $path = "node/$node->nid";
+    $attributes = array('title' => project_issue_state($node->sid));
+    $fragment = null;
+    if($comment_id > 0) {
+      $title = check_plain("#$node->nid#comment-$comment_id: $node->title");
+      $fragment = "comment-$comment_id";
+    }
+    $output = "<span class=project-issue-status-$node->sid>";
+    $output .= l($title, $path, $attributes, null, $fragment);
+    $output .= '</span>';
+  }
+  else {
+    $output = "[#$node->nid]";
+  }
+  return $output;
+}
+
+/**
+ * Implementation of hook_form_filter_tips()
+ * @ingroup project_issue_filter
+ */
+function project_issue_filter_tips($delta, $format, $long = FALSE) {
+  if ($long) {
+    return t('References to project issues (in the form of [#1234] or [#1234#comment-1]) turn into links automatically, with the title of the issue appended. Statuses are shown on hover, issues with certain statuses are crossed out.');
+  }
+  else {
+    return t('Project issue numbers (ex. [#12345]) turn into links automatically.');
+  }
+}
+
+/**
+ * Implementation of hook_form_filter()
+ * @ingroup project_issue_filter
+ */
+function project_issue_filter($op, $delta = 0, $format = -1, $text = '') {
+  switch ($op) {
+    case 'list':
+      return array(0 => t('Project Issue to link filter'));
+    case 'description':
+      return t('Converts references to project issues (in the form of [#12345]) into links. Caching should be disabled if node access control modules are used.');
+    case 'no cache':
+      //Disable cache if there is a node access control module.
+      $grants = module_implements('node_grants');
+      if (!empty($grants)) {
+        return TRUE;
+      }
+      else {
+        return FALSE;
+      }
+    case 'prepare':
+      return $text;
+    case 'process':
+      $regex = '(?<!\w)(\[#(\d+)(#comment-(\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_id=$preg_matches[4][0];
+        $node = node_load($nid);
+        if (is_object($node) && node_access('view', $node)) {
+          $link = theme_project_issue_issue_link($node, $comment_id);
+          $text = substr_replace($text, $link, $match[1], strlen($match[0]));
+          $offset = max($offset, $match[1]+strlen($link));
+        }
+        else {
+          $offset = max($offset, $match[1]+strlen($match[0]));
+        }
+      }
+      return $text;
+  }
+}
+
+/**
+ * Implementation of hook_requirements()
+ * @ingroup project_issue_filter
+ */
+function project_issue_requirements($phase) {
+  $requirements = array();
+  $input_formats = array();
+  if ($phase == 'runtime') {
+    $no_cache = project_issue_filter('no cache',0);
+    foreach (filter_formats() as $format => $input_format) {
+      $filters = filter_list_format($format);
+      if (isset($filters['project_issue/0'])) {
+        //Put up an error when cache should be disabled but isn't.
+        if ($no_cache && filter_format_allowcache($format)) {
+          $description_names['%issuefilter'] = $filters['project_issue/0']->name;
+          $description_names['!inputformat'] = l($input_format->name, "admin/settings/filters/$format");
+          $requirements[] = array(
+            'title' => 'Project Issue to link filter',
+            'value' => t('Some module conflicts were detected.'),
+            'description' => t('%issuefilter conflicts with node access control modules when caching is enabled. Please save !inputformat input format\'s configuration again to disable its cache.', $description_names),
+            'severity' => REQUIREMENT_ERROR,
+          );
+        }
+        //List input formats with disabled cache.
+        else {
+          $input_formats[] = $input_format->name;
+        }
+        //Put up an error when some code escaping filter's weight is higher.
+        $low_filters = array('filter/0', 'filter/1', 'codefilter/0');
+        foreach ($low_filters as $lfilter) {
+          if (isset($filters[$lfilter]) && $filters['project_issue/0']->weight <= $filters[$lfilter]->weight) {
+            $description_names['%issuefilter'] = $filters['project_issue/0']->name;
+            $description_names['%lowfilter']  = $filters[$lfilter]->name;
+            $requirements[] = array(
+              'title' => 'Project Issue to link filter',
+              'value' => t('Some filter conflicts were detected.'),
+              'description' => t('%issuefilter should come after %lowfilter to prevent loss of layout and highlighting.', $description_names)
+                 .' '.l(t('Please rearange the filters.'), "admin/settings/filters/$format/order"),
+              'severity' => REQUIREMENT_ERROR,
+            );
+          }
+        }
+      }
+    }
+
+    if ($no_cache) {
+      if (!empty($input_formats)) {
+        $input_formats = implode(', ', $input_formats);
+        $requirements[] = array(
+          'title' => 'Project Issue to link filter',
+          'value' => t('Some module conflicts were detected.'),
+          'description' => t('%issuefilter conflicts with node access control modules when caching is enabled. Caching will be disabled when using these input formats: %inputformats', array('%issuefilter' => 'Project Issue to link filter', '%inputformats' => $input_formats)),
+          'severity' => REQUIREMENT_WARNING,
+        );
+      }
+    }
+  }
+  return $requirements;
+}
