--- node.module.orig	2006-12-12 05:48:57.000000000 -0700
+++ node.module	2006-12-12 10:05:36.000000000 -0700
@@ -180,19 +180,36 @@ function node_teaser($body, $format = NU
     return $body;
   }
 
-  // In some cases, no delimiter has been specified (e.g. when posting using
-  // the Blogger API). In this case, we try to split at paragraph boundaries.
-  // When even the first paragraph is too long, we try to split at the end of
-  // the next sentence.
-  $breakpoints = array('</p>' => 4, '<br />' => 0, '<br>' => 0, "\n" => 0, '. ' => 1, '! ' => 1, '? ' => 1, '。' => 3, '؟ ' => 1);
-  foreach ($breakpoints as $point => $charnum) {
-    if ($length = strpos($body, $point, $size)) {
-      return substr($body, 0, $length + $charnum);
+  // The teaser may not be longer than maximum length specified. Initial slice.
+  $teaser = truncate_utf8($body, $size);
+  $position = 0;
+  // Cache the reverse of the teaser.
+  $reversed = strrev($teaser);
+
+  // In some cases, no delimiter has been specified. In this case, we try to
+  // split at paragraph boundaries.
+  $breakpoints = array('</p>' => 0, '<br />' => 6, '<br>' => 4, "\n" => 1);
+  // We use strpos on the reversed needle and haystack for speed.
+  foreach ($breakpoints as $point => $offset) {
+    $length = strpos($reversed, strrev($point));
+    if ($length !== FALSE) {
+      $position = - $length - $offset;
+      return ($position == 0) ? $teaser : substr($teaser, 0, $position);
     }
   }
 
-  // If all else fails, we simply truncate the string.
-  return truncate_utf8($body, $size);
+  // When even the first paragraph is too long, we try to split at the end of
+  // the last full sentence.
+  $breakpoints = array('. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1);
+  $min_length = strlen($reversed);
+  foreach ($breakpoints as $point => $offset) {
+    $length = strpos($reversed, strrev($point));
+    if ($length !== FALSE) {
+      $min_length = min($length, $min_length);
+      $position = 0 - $length - $offset;
+    }
+  }
+  return ($position == 0) ? $teaser : substr($teaser, 0, $position);
 }
 
 function _node_names($op = '', $node = NULL) {
