simple syntax highlighting

by Ben Gillbanks

HTML

<pre id="code-editor" contenteditable="true" spellcheck="false">var x = 5;
function foo() {
  if (x > 10) {
    console.log("x is greater than 10");
  } else {
    console.log("x is less than or equal to 10");
  }
}</pre>

CSS

mark {
    background: black;
}
pre {
    font-family: courier-new, monospace;
    color: grey;
}

.keyword {
 color: blue;
 font-weight:bold;
}

JavaScript

var highlight = function() {
  storeCursorPosition();
  var code = editor.innerText;
  var keywords = ["var", "function", "if", "else", "console"];

  // Split the code into individual lines
  var lines = code.split("\n");

  // Loop through each line
  for (var i = 0; i < lines.length; i++) {
    // Loop through each keyword
    for (var j = 0; j < keywords.length; j++) {
      var keyword = keywords[j];
      var keywordRegex = new RegExp("\\b" + keyword + "\\b", "g");
      lines[i] = lines[i].replace(keywordRegex, "<span class='keyword'>" + keyword + "</span>");
    }
  }
  // Join the lines back together
  code = lines.join("\n");
  editor.innerHTML = code;
//  restoreCursorPosition();
}


// Store the cursor position and highlighted code
var storeCursorPosition = function() {
console.log(document.getSelection());
    var range = document.getSelection().getRangeAt(0);
    console.log(range);
    var highlightedCode = range.extractContents();
    var placeholder = document.createElement("mark");
    placeholder.appendChild(highlightedCode);
    range.insertNode(placeholder);
}

// Restore the cursor position and highlighted code
var restoreCursorPosition = function() {
    var placeholders = document.getElementsByTagName("mark");
    while (placeholders.length > 0) {
        var placeholder = placeholders[0];
        while (placeholder.firstChild) {
            placeholder.parentNode.insertBefore(placeholder.firstChild, placeholder);
        }
        placeholder.parentNode.removeChild(placeholder);
    }
}

var editor = document.getElementById("code-editor");
editor.addEventListener("input", highlight );
highlight();