PrismJS is a great option for code syntax highlighting. It's used by Stripe, along with many other companies that deeply value documentation.
It supports a vast array of plugins and the total script weighs in at just 2k, gziped. Extra programming languages add 0.3-0.5KB each and themes are around 1KB. All in all, it's a lot of functionality for very little cost to your page load times!
This is a quick guide to get it set up on Phoenix (or just about any back-end framework that takes an agnostic approach towards JS). The code shown in this post, as well as on Alchemist Camp uses this setup.
This guide starts from a fresh Phoenix app. It should work with just about any standard app.
Install Prism
First, cd
into your assets
directory and then install the following two libraries. If you're using yarn:
yarn add prismjs
yarn add babel-plugin-prismjs
Or, if you're using npm:
npm install prismjs
npm install babel-plugin-prismjs
Next, to include it in your front-end, add the following to the top of your main app.js
file:
import Prism from "prismjs"
Adding support for more languages
Prism supports syntax highlighting for well over a hundred languages, but it doesn't load them all by default. We can configure which languages load and pick a theme by creating a .babelrc
file in our assets directory. Here's an example file:
{
"presets": ["@babel/preset-env"],
"plugins": [
[
"prismjs",
{
"languages": [
"elixir",
"erlang",
"css",
"javascript",
"markdown",
"markup",
"ruby",
"scss",
"toml"
],
// themes can be found in this directory:
// assets/node_modules/prismjs/themes
"theme": "okaidia",
"css": true
}
]
]
}
Customizing the theme
I wanted the styling from the okaidia theme for blocks of pre-formated code, but wanted my own styles to control inline code. So I commented out the theme line above, copied the theme file from its directory into the /assets/css
directory where Phoenix puts stylesheets. Then removed the styles I didn't want and re-wrote it to match my specific needs. All the Prism themes are is CSS, so you can adjust them without concern about breaking anything else.
How Prism works
Prism will add syntax highlighting to inline code
tags and to pre
blocks with code
inside them. The language of highlighting applied is determined by the class of the element. If the class is language-javascript
, the highlighting will be for JavaScript, a class of language-elixir
will apply Elixir highlighting, and so on. For the full list, refer to Prism's supported language chart.
You can also set a default language by setting a class on a parent element, such as the body
tag.
Add code to a page
Phoenix apps come with an index.html.eex
template for the /
page. Try replacing yours to the following:
<% code = ~s"""
defmodule MyModule do
#stuff
end
"""%>
<section class="row">
<article class="column">
<code class="language-elixir">Enum.at([:a, :b, :c], 1) |> IO.puts()</code>
<pre><code class="language-elixir"><%= code %></code></pre>
</article>
</section>
(The top line is just saving our block of code in a variable code
, using a HEREDOC string so we don't have to worry about new lines or indentation inside the pre
block!)
Here's the result:
Integrating with Earmark
If you're using Earmark to convert Markdown to HTML (as this site does), then you'll need to pass in a code_class_prefix
option to generate the appropriate classes on your code blocks. E.g:
Earmark.as_html!(
%Earmark.Options{
code_class_prefix: "lang-",
smartypants: false
}
)
Then you can declare the language of your code blocks in Markdown like so:
```ruby
8 ** 3
```