Skip to content

Instantly share code, notes, and snippets.

@lastguest
Last active October 12, 2016 09:12
Show Gist options
  • Select an option

  • Save lastguest/10277461 to your computer and use it in GitHub Desktop.

Select an option

Save lastguest/10277461 to your computer and use it in GitHub Desktop.
Parse Style Runs from HTML string
"use strict";
var test = '<b style="color:#fff; background: red">He<i>ll</i>o </b><u>Wo<i>rld</i></u>';
function parseStyle(text){
// Patterns and temp strings
var tags_rx = /<\s*(\/?\s*[^>]+)(\s+[^>]+)?\s*>/gm,
css_rx = /([\w-]+\s*:\s*[^\n;"']+)/gm,
partial, tag, css, temp_style;
// Indexes
var last_idx = 0,
last_text_idx = 0;
// Stacks
var style = [],
style_stack = [],
clean_text = [],
css_properties = [];
// For each tag :
while ( tag = tags_rx.exec(text) ) {
// Extract the text fragment as save it
partial = text.substr(last_idx, tag.index - last_idx)
clean_text.push(partial);
// Save last clean text offset
last_text_idx += partial.length;
// Check if we are closing a tag
if (tag[1][0]=='/'){
// Get style run from temp stack
temp_style = style_stack.pop();
temp_style.length = last_text_idx - temp_style.start;
// Save style run
style.push(temp_style);
} else {
var tmp_tag = tag[1].replace(/^\s+|\s+$/,'');
// check if tag contain CSS
css = false;
css_properties = tmp_tag.match(css_rx);
for (var property in css_properties) {
css=css||{};
property = css_properties[property].split(/\s*:\s*/);
css[property[0]] = property[1];
}
// Save open style run in temp stack
temp_style = {
tag: /\s/.test(tmp_tag) ? tmp_tag.substring(0,tmp_tag.indexOf(' ')) : tmp_tag,
start: last_text_idx,
};
css ? temp_style.css = css : '' ;
style_stack.push(temp_style);
}
// Move text offset pointer
last_idx = tags_rx.lastIndex;
}
// Save last text chunk
clean_text.push(text.substr(last_idx));
// Order runs
style.sort(function(a,b){
return a.start-b.start;
});
return {
text: clean_text.join(''),
style: style
};
}
console.log(
parseStyle(test)
);
/*
{
text: 'Hello World',
style:
[
{ tag: 'b',
start: 0,
css: { color: '#fff', background: 'red' },
length: 6 },
{ tag: 'i', start: 2, length: 2 },
{ tag: 'u', start: 6, length: 5 },
{ tag: 'i', start: 8, length: 3 }
]
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment