I didn't have much luck finding a saphire specific answer to this question, so I went searching for a PHP function to help me with this and came across this post: http://stackoverflow.com/questions/1193500/php-truncate-html-ignoring-tags
Here is my end result. I'm still curious as to whether there is an easier way to achieve this?
/**
* Get a bbcode parsed summary of the blog entry
*/
function ParagraphSummary(){
if(self::$allow_wysiwyg_editing) {
return $this->printTruncated(800, $this->obj('Content')->FirstParagraph('html'));
} else {
$parser = new BBCodeParser($this->Content);
$html = new HTMLText('Content');
$html->setValue($parser->parse());
return $this->printTruncated(800, $html->FirstParagraph('html'));
}
}
/**
* Responsible for closing any tags which have been left open in the summary...
*/
public function printTruncated($maxLength, $html, $isUtf8=true)
{
$printedLength = 0;
$position = 0;
$tags = array();
$string = '';
// For UTF-8, we need to count multibyte sequences as one character.
$re = $isUtf8
? '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\x80-\xFF][\x80-\xBF]*}'
: '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}';
while ($printedLength < $maxLength && preg_match($re, $html, $match, PREG_OFFSET_CAPTURE, $position))
{
list($tag, $tagPosition) = $match[0];
// Print text leading up to the tag.
$str = substr($html, $position, $tagPosition - $position);
if ($printedLength + strlen($str) > $maxLength)
{
$string .= substr($str, 0, $maxLength - $printedLength);
$printedLength = $maxLength;
break;
}
$string .= $str;
$printedLength += strlen($str);
if ($printedLength >= $maxLength) break;
if ($tag[0] == '&' || ord($tag) >= 0x80)
{
// Pass the entity or UTF-8 multibyte sequence through unchanged.
$string .= $tag;
$printedLength++;
}
else
{
// Handle the tag.
$tagName = $match[1][0];
if ($tag[1] == '/')
{
// This is a closing tag.
$openingTag = array_pop($tags);
assert($openingTag == $tagName); // check that tags are properly nested.
$string .= $tag;
}
else if ($tag[strlen($tag) - 2] == '/')
{
// Self-closing tag.
$string .= $tag;
}
else
{
// Opening tag.
$string .= $tag;
$tags[] = $tagName;
}
}
// Continue after the tag.
$position = $tagPosition + strlen($tag);
}
// Print any remaining text.
if ($printedLength < $maxLength && $position < strlen($html))
$string .= substr($html, $position, $maxLength - $printedLength);
// Close any open tags.
while (!empty($tags))
$string .= sprintf('</%s>', array_pop($tags));
return $string;
}