/** * Automatically generate a teaser for a node body. * * If the end of the teaser is not indicated using the delimiter * then we try to end it at a sensible place, such as the end of a paragraph, * a line break, or the end of a sentence (in that order of preference). * * @param $body * The content for which a teaser will be generated. * @param $format * The format of the content. If the content contains PHP code, we do not * split it up to prevent parse errors. If the line break filter is present * then we treat newlines embedded in $body as line breaks. * @return * The generated teaser. */ function node_teaser($body, $format = NULL) { $size = variable_get('teaser_length', 600); // Find where the delimiter is in the body $delimiter = strpos($body, ''); // If the size is zero, and there is no delimiter, the entire body is the teaser. if ($size == 0 && $delimiter === FALSE) { return $body; } // If a valid delimiter has been specified, use it to chop off the teaser. if ($delimiter !== FALSE) { return substr($body, 0, $delimiter); } // We check for the presence of the PHP evaluator filter in the current // format. If the body contains PHP code, we do not split it up to prevent // parse errors. if (isset($format)) { $filters = filter_list_format($format); if (isset($filters['filter/1']) && strpos($body, '' => 0); // If no complete paragraph then treat line breaks as paragraphs. $line_breaks = array('
' => 6, '
' => 4); // Newline only indicates a line break if line break converter // filter is present. if (isset($filters['filter/2'])) { $line_breaks["\n"] = 1; } $break_points[] = $line_breaks; // If the first paragraph is too long, split at the end of a sentence. $break_points[] = array('. ' => 1, '! ' => 1, '? ' => 1, '?' => 0, '? ' => 1); // Iterate over the groups of break points until a break point is found. foreach ($break_points as $points) { // Look for each break point, starting at the end of the teaser. foreach ($points as $point => $offset) { // The teaser is already reversed, but the break point isn't. $rpos = strpos($reversed, strrev($point)); if ($rpos !== FALSE) { $min_rpos = min($rpos + $offset, $min_rpos); } } // If a break point was found in this group, slice and return the teaser. if ($min_rpos !== $max_rpos) { // Don't slice with length 0. Length must be <0 to slice from RHS. return ($min_rpos === 0) ? $teaser : substr($teaser, 0, 0 - $min_rpos); } } // If a break point was not found, still return a teaser. return $teaser; }