JSFiddle - React, Tailwind, and code Playground
by evan
HTML
<div id="output"></div>
<textarea id="markup"></textarea>
CSS
textarea {
width: 400px;
height: 100px;
}
Babel + JSX
var raw = {
"entityMap": {},
"blocks": [{
"key": "a30dm",
"text": "We're just three MCs and one D.J.",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [{
"offset": 11,
"length": 9,
"style": "BOLD"
}, {
"offset": 25,
"length": 8,
"style": "BOLD"
}, {
"offset": 17,
"length": 11,
"style": "ITALIC"
}],
"entityRanges": []
}]
};
var styles = {
BOLD: ['<strong>', '</strong>'],
ITALIC: ['<em>', '</em>']
};
var text = raw.blocks[0].text;
var styleStack = [];
// values in haystack must be unique
function containsSome(haystack, needles) {
return haystack.length > _.difference(haystack, needles).length;
}
function relevantStyles(offset, styleRanges) {
var styles = _.filter(styleRanges, function(range) {
return (offset >= range.offset && offset < (range.offset + range.length));
});
return _.pluck(styles, 'style');
}
var outputText = [];
var styleStack = [];
for (var i = 0; i < text.length; i++) {
var characterStyles = relevantStyles(i, raw.blocks[0].inlineStyleRanges);
var nextCharacterStyles = relevantStyles(i + 1, raw.blocks[0].inlineStyleRanges);
// calculate styles to add and remove
// add
var stylesToAdd = _.difference(characterStyles, styleStack);
var stylesToRemove = _.difference(characterStyles, nextCharacterStyles);
if (stylesToAdd.length > 0) {
// add the styles
//console.log(i, 'add styles: ', stylesToAdd);
stylesToAdd.forEach(style => {
console.log('adding %s', style);
styleStack.push(style);
outputText.push(styles[style][0]);
});
}
outputText.push(text.substr(i, 1));
console.log('adding char %s, stack is', text.substr(i, 1), styleStack);
// remove
if (stylesToRemove.length > 0) {
while (containsSome(styleStack, stylesToRemove)) {
var toRemove = styleStack.pop();
console.log('removing %s', toRemove, styleStack);
outputText.push(styles[toRemove][1]);
}
}
...