function plugin_trim_by_characters_with_html( $text, $length = 400, $append = ' …', $allowable_tags = '' ) { $length = (int) $length; $text = trim( strip_tags( $text, $allowable_tags ) ); $in_quote = false; // if the length without tags is less than our target we are done if ( strlen( strip_tags( $text ) ) <= $length ) return $text; // count forward to find the $length character in unstripped $text not counting tags for ($i = 0, $j = 0, $l = strlen( $text ), $in_tag = false; $i < $l && ( $in_tag || $j < $length ); $i++) : switch ( $text[$i] ) : case '<': $in_tag = true; break; case '>': $in_tag = false; break; case '"': $in_quote = ! $in_quote; default : if ( ! $in_tag ) $j++; endswitch; endfor; // Step forward one and check for whitespace. If none, go back and find the last place we ended a word or html tag if ( isset( $text[$i] ) ) while ( ' ' != $text[$i] && '>' != $text[$i - 1] ) $i--; // don't end with non-final punctuation if ( isset( $text[--$i] ) ) while ( $i > 0 && in_array( $text[$i], array( ',', ':', ';', '(', '$', '&', '-' ), true ) ) $i--; // if ending at end of sentance we don't need continuation marking (i.e. …) if ( in_array( $text[$i], array( '.', '!', '?' ) ) ) return balanceTags( substr( $text, 0, $i+1 ), true ); // finally if we have a quotation mark, make sure it is final if ( '"' == $text[$i] && $in_quote ) $i--; return balanceTags( substr( $text, 0, $i+1 ), true ) . $append; }