Index: aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.306
diff -u -r1.306 aggregator.module
--- aggregator.module	17 Sep 2006 19:14:15 -0000	1.306
+++ aggregator.module	12 Oct 2006 02:43:48 -0000
@@ -204,6 +204,13 @@
   $items = array(0 => t('none')) + drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items');
   $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
 
+  $form['aggregator_truncate_description'] = array(
+    '#title' => t('Maxiumum Description Length'),
+    '#type' => 'textfield',
+    '#description' => t('Set this variable to have aggregator clip off rss content that is longer than this value. Set to <em>0</em> to have aggregator <strong><em>not</em></strong> truncate rss content.'),
+    '#default_value' => variable_get('aggregator_truncate_description', '0')
+  );
+
   $form['aggregator_allowed_html_tags'] = array(
     '#type' => 'textfield', '#title' => t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255,
     '#default_value' => variable_get('aggregator_allowed_html_tags', '<a> <b> <br> <dd> <dl> <dt> <em> <i> <li> <ol> <p> <strong> <u> <ul>'),
@@ -888,6 +895,66 @@
       $item['DESCRIPTION'] = $item['SUMMARY'];
     }
 
+    /**
+     * Truncate the description if the truncate variable is set
+     */
+    $truncate = variable_get('aggregator_truncate_description', 0);
+    if($truncate) {
+      if(strlen($item['DESCRIPTION'] > $truncate)) {
+        /**
+         * We want to truncate nicley in case we are in the middle of an HTML tag
+         * so we'll use a good 'ol stack and walk the description.
+         */
+        $new_description = "";
+        $description = $item['DESCRIPTION'];
+        $in_tag = FALSE;
+        $current_tag = '';
+        $closing_tag = FALSE;
+        $p = 0;
+        while($p <= $truncate - 1 || count($tag_stack) != 0) {
+          $c = $description[$p++];
+          if($p == $truncate - 1) {
+            $closing_tags = '';
+            while(count($tag_stack) != 0) {
+              $closing_tags .= '</' . array_pop($tag_stack) . '>';
+            }
+            $item['DESCRIPTION'] = substr($description, 0, $truncate - 3 - strlen($current_tag)) . $closing_tags . '&hellip';
+          }
+          
+          if($in_tag || $c == '<') { 
+            if($c == ' ') {
+              $in_tag = FALSE;
+              $current_tag = '';
+            }
+            else if($c == '<') {
+              $in_tag = 'TRUE';
+              $closing_tag = FALSE;
+            }
+            else if($c == '/') {
+              $closing_tag = TRUE;
+            }
+            else if($c == '>') {
+              if($closing_tag) {
+                array_pop($tag_stack);
+                $tag_count--;
+                $last_tag = $tag_stack[$tag_count - 1];
+              }
+              else {
+                $tag_stack[] = $current_tag;
+                $last_tag = $current_tag; # No "array_peak" function in PHP
+                $tag_count++;
+              }
+              $current_tag = '';
+              $in_tag = FALSE;
+            }
+            else {
+              $current_tag .= $c;
+            }
+          }
+        }
+      }
+    }
+
     /*
     ** Try to resolve and parse the item's publication date. If no
     ** date is found, we use the current date instead.

