How to write a function that can cut a string with HTML tags to an N-length string without breaking HTML tags while doing it.
The returned string doesn\'t need to b
function trimHtml(html, options) {
options = options || {};
var limit = options.limit || 100,
preserveTags = (typeof options.preserveTags !== 'undefined') ? options.preserveTags : true,
wordBreak = (typeof options.wordBreak !== 'undefined') ? options.wordBreak : false,
suffix = options.suffix || '...',
moreLink = options.moreLink || '';
var arr = html.replace(//g, ">\n")
.replace(/\n\n/g, "\n")
.replace(/^\n/g, "")
.replace(/\n$/g, "")
.split("\n");
var sum = 0,
row, cut, add,
tagMatch,
tagName,
tagStack = [],
more = false;
for (var i = 0; i < arr.length; i++) {
row = arr[i];
// count multiple spaces as one character
rowCut = row.replace(/[ ]+/g, ' ');
if (!row.length) {
continue;
}
if (row[0] !== "<") {
if (sum >= limit) {
row = "";
} else if ((sum + rowCut.length) >= limit) {
cut = limit - sum;
if (row[cut - 1] === ' ') {
while(cut){
cut -= 1;
if(row[cut - 1] !== ' '){
break;
}
}
} else {
add = row.substring(cut).split('').indexOf(' ');
// break on halh of word
if(!wordBreak) {
if (add !== -1) {
cut += add;
} else {
cut = row.length;
}
}
}
row = row.substring(0, cut) + suffix;
if (moreLink) {
row += '»';
}
sum = limit;
more = true;
} else {
sum += rowCut.length;
}
} else if (!preserveTags) {
row = '';
} else if (sum >= limit) {
tagMatch = row.match(/[a-zA-Z]+/);
tagName = tagMatch ? tagMatch[0] : '';
if (tagName) {
if (row.substring(0, 2) !== '') {
tagStack.push(tagName);
row = '';
} else {
while (tagStack[tagStack.length - 1] !== tagName && tagStack.length) {
tagStack.pop();
}
if (tagStack.length) {
row = '';
}
tagStack.pop();
}
} else {
row = '';
}
}
arr[i] = row;
}
return {
html: arr.join("\n").replace(/\n/g, ""),
more: more
};
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = trimHtml;
}
usage
var html = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
';
var trim = trimHtml(html, { limit: 200 });
// **returns object**
{
html: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut...
',
more: true // indicates if limit is reached
}
WORKING EXAMPLE