JSFiddle - React, Tailwind, and code Playground

HTML

<p style="color:red">This is line #1</p>
<p style="color:blue"><span style="color:yellow"><span style="color:red">This is</span> line #2</span></p>
<p style="color:blue"><span style="color:yellow"><span style="color:green">This is line #3</span></span>
<p style="color:blue"><span style="color:yellow">This is</span><span style="color:red">line #4</span></span></p>

JavaScript

[].forEach.call(document.getElementsByTagName("p"), format);
function wrap(text, color) {
   var span = document.createElement("span");
   span.style.color = color;
   span.appendChild(text);
   return span;
}
function format(p) {
    for (var cur = p.firstChild; cur != null; cur = next) {
        var next = cur.nextSibling;
        if (cur.nodeType == 3) {
            // top-level text nodes are wrapped in spans
            next = p.insertBefore(wrap(cur, p.style.color), next);
        } else {
            if (cur.childNodes.length == 1 && cur.firstChild.nodeType == 3)
               continue;
            // top-level spans are unwrapped…
            while (cur.firstChild) {
                if (cur.firstChild.nodeType == 1)
                    // with nested spans becoming unnested
                    p.insertBefore(cur.firstChild, next);
                else
                    // and child text nodes becoming wrapped again
                    p.insertBefore(wrap(cur.firstChild, cur.style.color), next);
            }
            // now empty span is removed
            next = cur.nextSibling;
            p.removeChild(cur);
        }
    }
    p.style.color = p.firstChild.style.color;
}