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]);
    }
  }
  
 ...