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.
If you are a Linux user, you can use apt
( Debian-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">'John Doe'</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! 🍻