Here's a little bit of code to chop strings (with html tags) around a specified length while making sure no html tags are chopped. It also prevents chopping while a tag is still open.
Note: this will only work in xhtml strict/transitional due to the checking of "/>" tags and the requirement of quotations in every value of a tag. It's also only been tested with the presence of br, img, and a tags, but it should work with the presence of any tag.
<?php
function html_substr($posttext, $minimum_length, $length_offset) {
// The approximate length you want the concatenated text to be
$minimum_length = 200;
// The variation in how long the text can be
// in this example text length will be between 200-10=190 characters
// and the character where the last tag ends
$length_offset = 10;
// Reset tag counter & quote checker
$tag_counter = 0;
$quotes_on = FALSE;
// Check if the text is too long
if (strlen($posttext) > $minimum_length) { // Reset the tag_counter and pass through (part of) the entire text
for ($i = 0; $i < strlen($posttext); $i++) { // Load the current character and the next one
// if the string has not arrived at the last character
$current_char = substr($posttext,$i,1
); if ($i < strlen($posttext) - 1
) { $next_char = substr($posttext,$i + 1
,1
); }
else {
$next_char = \"\";
}
// First check if quotes are on
if (!$quotes_on) {
// Check if it's a tag
// On a \"<\" add 3 if it's an opening tag (like <a href...)
// or add only 1 if it's an ending tag (like </a>)
if ($current_char == \"<\") {
if ($next_char == \"/\") {
$tag_counter++;
}
else {
$tag_counter = $tag_counter + 3;
}
}
// Slash signifies an ending (like </a> or ... />)
// substract 2
if ($current_char == \"/\") $tag_counter = $tag_counter - 2;
// On a \">\" substract 1
if ($current_char == \">\") $tag_counter--;
// If quotes are encountered, start ignoring the tags
// (for directory slashes)
if ($current_char == \"\"\") $quotes_on = TRUE;
}
else {
// IF quotes are encountered again, turn it back off
if ($current_char == \"\"\") $quotes_on = FALSE;
}
// Check if the counter has reached the minimum length yet,
// then wait for the tag_counter to become 0, and chop the string there
if ($i > $minimum_length - $length_offset && $tag_counter == 0) {
$posttext = substr($posttext,0
,$i + 1) . \"...\"; return $posttext;
}
}
}
return $posttext;
}
?>