How to Add Syntax Highlighting to Your Website

If you have a programming blog, like me, or your website contains code examples and explanatory content, you may want to support syntax highlighting on your pages. There are many solutions and workarounds available, but the most flexible, to me, is using Chroma.

 

What’s Chroma

Chroma is an open-source library written in Go allowing to have syntax highlighting for many different languages. Chroma is based on Pygments which is a generic syntax highlighter, written in Python.

github.com/alecthomas/chroma 🔗    pygments.org 🔗

 

Chroma CLI

While you can write Go scripts to use Chroma in your website, an easier way is to use Chroma CLI. To install it, first, you need to install Go.

golang.org/dl/ 🔗

If you are a Linux user, you can use aptDebian-based operating systems ) or brew to install it:

🚀 ~ sudo apt install golang
🚀 ~ brew install go

Then, verify the installation by running go version in the terminal.

Important! Chroma depends on a Go package called bits which was introduced in go1.9, so be sure you have go >= 1.9 .

 

To install the Chroma CLI, run:

🚀 ~ go get -u -v github.com/alecthomas/chroma/cmd/chroma

Then, to make it available globally:

🚀 ~ sudo cp ./bin/chroma /usr/bin

or

🚀 ~ sudo cp ~/go/bin/chroma /usr/bin # When $GOPATH is not specified

Run chroma --version to verify your installation.

 

How to use

Chroma is based on concepts of lexers, formatters, and styles. Lexers, generally speaking, are responsible for making lexical analysis of the input and understanding what language it uses. Formatters do the necessary operations to structure the output in a given format. And styles set the appearance of the output.

More simply, lexers determine the input type, formatters define the output type, and styles style the output.

To see the list of available lexers, formatters and styles, we run:

🚀 ~ chroma --list

 

Let’s say we want to highlight the syntax of the JavaScript code below using the monokai color scheme.

  // greeting.js
  let fullname = 'John Doe';
  const greeting = `Hello, ${fullname}`;
  console.log(greeting);
🚀 ~ chroma --lexer js --formatter html --style monokai --html-inline-styles --html-only greeting.js > output.html 

Here, the flag --html-inline-styles tells Chroma to use inline styles instead of classnames, and the flag --html-only omits the default html tags: <html> and <body>.

Chroma is smart and can autodetect the lexer. In most cases, you don’t need to specify it explicitly.

🚀 ~ chroma --html --style monokai --html-inline-styles --html-only greeting.js > output.html 

Now, you just have to copy the contents of output.html to your code. 🙂

<pre style="color:#f8f8f2;background-color:#272822"><span style="color:#75715e">// greeting.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">let</span> <span style="color:#a6e22e">fullname</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;John Doe&#39;</span>;
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">greeting</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">`Hello, </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">fullname</span><span style="color:#e6db74">}</span><span style="color:#e6db74">`</span>;
<span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">greeting</span>);
</pre>

 

The flexibility

While being incredibly useful, Chroma is also very flexible. You can generate a standalone CSS file and combine it with your website styles.

🚀 ~ chroma --html --style monokai --html-styles greeting.js > output.css
🚀 ~ chroma --html --style monokai --html-only greeting.js > output.html 

The above-generated output.html and output.css will use corresponding classnames.

 

To avoid any conflicts between the classnames generated by Chroma and classnames used in your website, you can use prefixes, for example:

🚀 ~ chroma --html --style monokai --html-prefix c5h1_ greeting.js > output.html 

Important! In the current version of Chroma (0.8.2), there’s a bug when using both --html-styles and --html-prefix flags together. If you want to have a standalone CSS with prefixed classnames, you need to manually copy the styles from output.html.

 

By the way, Chroma has an online playground where you can visually test different color schemes.

swapoff.org/chroma/playground/

 

Have fun. Cheers! 🍻