From a0ca5362c09584445685d46b84a53021c62f6e30 Mon Sep 17 00:00:00 2001 From: Steven Wittens Date: Tue, 12 Dec 2006 08:35:30 +0000 Subject: #73910: Teaser length should be a maximum as the description says, not a minimum. --- modules/node/node.module | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'modules/node/node.module') diff --git a/modules/node/node.module b/modules/node/node.module index 52e4ed6ae..ef78d89db 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -173,19 +173,36 @@ function node_teaser($body, $format = NULL) { 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('

' => 4, '
' => 0, '
' => 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('

' => 0, '
' => 6, '
' => 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); } /** -- cgit v1.2.3