Behind the scene: Syntax Highlighted Editor

Syntax highlighted editors is not a new concept in the world wide web.

Few years ago, there are some famous names that dominating the world:
FCKeditor in the early age, TinyEditor, nedit and ton of other WYSIWYG
(What you see is what you get) editors during the jQuery age,…

Nowaday, syntax highlighted editor can be found anywhere, in Wordpress, in blog engines, online code editors like C9 or Koding,… and the numbers are countless.

Most of them are very easy to integrate with your website / web app. Some just has one CSS and one JS file, all you have to do is to include them to your web page and, voilà!!!

But have you ever asked: How does it work? How it’s made?

Well… the answer is much easier than you think. You can find out yourself by
using Chrome Dev Tool or Firebug.

If you’re a lazy man, then read on, I will do it and tell you how :)

OK, no more talking, this is the basic layout of every popular syntax
highlighted editor
on the web:

 The HTML structure

Here we have 2 layers:

Our HTML structure should be like this:

<div class='code-editor'> 
    <textarea class='code-input'></textarea> 
    <pre class='code-output'></pre> 
</div>

Both layers have the same position and same size, and just overlap each other (the pre overlap on textarea), they also have the same format (font-family, font-size, line-height,…), so, every time user typing on code-input, the highlighted will be displayed on code-output.

.code-editor { 
    ... 
    position: relative; 
} 

.code-input, .code-output { 
    position: absolute; 
    top: 0; left: 0; 
    width: 100%; height: 100%; 
    font-family: 'Monaco', monospace; 
    font-size: 14px; 
    line-height: 18px; 
}

 Handling inputs

But how do we click or type to code-input when is has code-output
overlap on already? You may asked. To get through this problem, you need to set the pointer-events attribute of code-output to none in your CSS file:

.code-output { 
    ... 
    pointer-events: none; 
}

And how to make the code-output update when the text in code-input
changed? You can listen for input event of the code-input and update the
content of code-output base on that.

var codeInput = document.querySelector('.code-input'); 
var codeOutput = document.querySelector('.code-output'); 

codeInput.addEventListener('input', function(e){ 
    var charCode = (typeof e.which == "number") ? e.which : e.keyCode; 
    var newChar = String.fromCharCode(charCode); 
    codeOutput.innerHTML = codeHighlight(codeInput.value + newChar); 
});

If you don’t want to listen for input event, you can listen for keypress or
keyup, keydown, but it will take more time to handle special keys like
backspace.

Next problem is handling scroll event, you know, during coding or writing time, you have to scroll your editor, up and down. We need to make the code-output follow the scroll of code-input.

We listen for scroll event of code-input and use scrollTop to make them both scrolling.

codeInput.addEventListener('scroll', function(e) { 
    codeOutput.scrollTop = codeInput.scrollTop; 
});

 Code highlighting

Did you notice the** codeHighlight()** function in handling input part? This is where we read the inputted code, and convert them to formatted HTML content.

For example, if we look at the simple code:

// Hey yo! function sum(a, b) { return a + b; }

The formatted HTML content should be:

<span class='comment'>// Hey yo!</span> 
<span class='keyword'>function</span> sum(a, b) { 
<span class='keyword'>return</span> a <span class='operator'>+</span> b; 
}

In CSS, we can define the style to make comment, keyword and operator class be more colorful.

There are many solutions to do it, you can use RegEx to write your own
parser/converter:

output = input.replace(/function/g, '<span class="keyword"> function </span>'); 

output = input.replace(/(\+|\-|\*|\/)/g, '<span class="operator"> $1 </span>'); 

...

Or you can use some syntax highlighting libraries for time saving, there are
many for you to choose from: Prism, HighlightJS,…

output = hljs.highlight('javascript', input);

If you complete all above steps, you finished your very first code editor with
syntax highlighting support. I hope this post is helpful for you.

In the next post, I will show you how to create a live preview markdown editor base on what we get in this post.

Happy coding :)

 
1
Kudos
 
1
Kudos

Now read this

Setup free SSL with Let’s Encrypt and Nginx

If you search Google for “free SSL”, there are many companies provide you a free trial SSL for only 90 days or less. After that, you will have to pay. Now, thanks to Let’s Encrypt. It’s no longer needed. You can claim your own SSL... Continue →

Subscribe to The Full Snack Developer

Don’t worry; we hate spam with a passion.
You can unsubscribe with one click.

S9LXLa7CrucYvIzThg7