Codemirror Run Mode with Line Number

by Adi Jaya

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/mode/javascript/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/mode/css/css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/mode/htmlmixed/htmlmixed.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/mode/xml/xml.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/codemirror.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.56.0/addon/runmode/runmode.min.js"></script>
<pre class="cm-s-default"><code data-mode="html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;utf-8&quot; /&gt;
&lt;title&gt;Hello&lt;/title&gt;
&lt;style&gt;
body {
	background-color: #ffffff;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;h2&gt;Hello&lt;/h2&gt;

&lt;/body&gt;
&lt;/html&gt;</code></pre>


<pre class="cm-s-default"><code data-mode="css">/*css*/
body {
	background-color: #ffffff;
	font-size: 1em;
}

#demo {
	width: calc( 100% - 30px );
}</code></pre>


<pre class="cm-s-default"><code data-mode="js">var removeClass = function(s, e) {
    var a = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
    if (s.classList) s.classList.remove(e);
    else {
        for (var l = &quot;&quot;, r = s.className.replace(/\s+/g, &quot; &quot;).replace(a, &quot;&quot;).split(&quot; &quot;), c = 0; c &lt; r.length; c++) r[c] !== e &amp;&amp; (l += r[c] + &quot; &quot;);
        s.className = l.replace(a, &quot;&quot;)
    }
};</code></pre>

CSS

pre {
    padding: 0;
    position: relative;
    border: 1px solid #dad8d8;
    clear: both;
}

pre code {
    display: block;
    padding: 10px;
    overflow: auto;
}

.linenumber-container {
    position: relative;
    display: block;
    float: left;
    margin-right: 10px;
    background: #f1f1f1;
    padding: 10px 0;
    border-right: 1px solid #dad8d8;
}

.line {
    position: relative;
    text-decoration: none;
    color: #9e9e9e;
    display: block;
    padding: 0 10px;
    text-align: right;
}

.line:before {
    content: "";
    position: absolute;
    right: 0;
    top: 20%;
    border-radius: 4px;
    color: #ffffff;
    width: 0;
    height: 0;
    border-right: 5px solid blue;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
}

.line:after {
    content: attr(id);
    position: absolute;
    left: 100%;
    background: blue;
    padding: 2px 5px;
    top: -2px;
    border-radius: 4px;
    color: #ffffff;
}

.line:before,
.line:after {
    visibility: hidden;
}

.line:hover {
    color: blue;
}

.line:hover.line:before,
.line:hover.line:after {
    visibility: visible;
}

.linenumber-clear {
    clear: both;
    display: block;
    height: 0.1px;
}

JavaScript

var elPre = document.querySelectorAll("pre");
for (var i = 0; i < elPre.length; i++) {
    var code = elPre[i].getElementsByTagName("code")[0];
    var type = code.getAttribute("data-mode");
    var mode = "html" == type ? "text/html" : "css" == type ? "text/css" : "js" == type ? "application/typescript" : "text/plain";

    var span = document.createElement("span");
    span.className = "linenumber-container";
    var clear = document.createElement("span");
    clear.className = "linenumber-clear";

    var num = code.innerHTML.split("\n").length;

    for (var j = 0; j < num; j++) {
        var line = document.createElement("a");
        line.className = "line";
        line.href = "#code:" + (i + 1) + ":" + (j + 1);
        line.id = "code:" + (i + 1) + ":" + (j + 1);
        line.innerHTML = [j + 1];
        span.appendChild(line);
    }

    elPre[i].insertBefore(span, elPre[i].firstChild);
    elPre[i].appendChild(clear);

    var textCode = code.textContent ? code.textContent : code.innerText;
    if (typeof CodeMirror != "undefined") {
        CodeMirror.runMode(textCode, mode, code);
    } else {
        alert("Codemirror Error");
    }
}