Skip to content

Instantly share code, notes, and snippets.

@gscottolson
Created January 17, 2012 21:53
Show Gist options
  • Save gscottolson/1629170 to your computer and use it in GitHub Desktop.
Save gscottolson/1629170 to your computer and use it in GitHub Desktop.
Shorten a long string of HTML to a predetermined length and append with '...'
String.prototype.shorten = function( length ) {
//shorten a string while minding the possible HTML markup within
var original = this.toString()
, length = length || 500
, tagRE = /<\/?\w+(\s+\w+="?[^>]*"?)*\s*>/g
, openTagRE = /<[^>\/]*([^\/]*>)/g
, closeTagRE = /<[\/]([^\/]*>)/g
, pipeRE = /\|/
, tag = ''
, tags = original.match( tagRE )
, tagDepth = 0
, htmlTagless = original.replace( tagRE, '|' ).replace( /\s+/g, ' ' ).replace( /(^\s|\s$)/g, '' ) //replace HTML tags with pipe, then consecutive spaces with single space, then leading and trailing spaces
, substrings = htmlTagless.match( new RegExp( '(.{' + length + '})' ) )
;
var truncated = ( substrings && substrings[ 1 ] ) ? substrings[ 1 ].replace( /\w+$/, '...' ) : original;
while( truncated.match( /\|/ ) && tags.length ) { //convert any pipes back to tags
tag = tags.shift();
if ( tag.match( openTagRE ) ) { //an open tag increases the tag depth
tagDepth++;
} else if ( tag.match( closeTagRE ) ) { //a close tag decreases the tag depth
tagDepth--;
}
truncated = truncated.replace( pipeRE, tag );
}
while ( tagDepth && tags.length ) {
tag = tags.shift();
if ( tag.match( closeTagRE ) ) {
truncated += tag;
tagDepth--;
}
}
return truncated;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment