I’ve been using the flashcard program Anki religiously to study programming concepts. It’s been even less exciting than it sounds because I haven’t had syntax highlighting; all my code has looked like this:
After a few fits and starts, I figured out a way to highlight code blocks that doesn’t rely on Anki’s add-on system, which isn’t supported by its mobile apps. This post is more synthesis than genesis - I found a lot of useful information online, but nothing that put everything together. Here’s my attempt to do so.
If you are just looking to get highlight.js
working with an Anki collection; I have a treat for you. Here’s a massive 151KB Anki export (half the size of one of the images in this post) containing a single card…and all the files you need to highlight your code. To change your theme, open the card template editor (for example, from studying a card -> Edit
-> Cards...
, click Back Template
, and modify <link rel="stylesheet" href="_nord.css">
to refer to the name of another highlight.js stylesheet (see the demo for inspiration).
If you want to learn more about how this works, read on.
highlight.js
: The hard wayhighlight.min.js
and the themes you want to use (as a tall, pale dude from the Midwest, I’m all-in on nord.css
). See the documentation to verify your target language is supported.highlight.min.js
and your css file to your Anki installation’s collection.media
directory. On Mac, this is located at ~/Library/Application Support/Anki2/User 1/collection.media
. User 1
here is my Anki username and the default username in Anki; this will change if you have updated your username in Anki. By default, Anki will consider these files unused media if a user uses Tools > Check Media
, and it will therefore suggest we remove them. We can prevent this by prefixing the files with an underscore. I suggest renaming them to _highlight.min.js
and _nord.css
(or the like).collection.media
named something like _my_highlight.js
. This file should include the following:document.querySelectorAll('pre code').forEach((block) => {
// Replace HTML <br> with newline characters
// https://stackoverflow.com/a/37815205/4738478
block.innerHTML = block.innerHTML.replace(/<br\s*\/?>/gi,'\n');
// Use highlight.js
hljs.highlightElement(block);
});
Browse -> Cards
. Edit the card to include the following:<link rel="stylesheet" href="_nord.css">
<script>
if (typeof hljs === "undefined") {
var script = document.createElement('script');
script.src = "_highlight.min.js";
script.async = false;
document.head.appendChild(script);
}
var script = document.createElement('script');
script.src = '_my_highlight.js';
script.async = false;
document.head.appendChild(script);
document.head.removeChild(script);
</script>
<pre>
<code>
{{MyCodeField}}
</code>
</pre>
Where {{MyCodeField}}
is the name of the code field on your card. (Mine is {{Solution}}
). Why does this work? I’m still figuring that out.
You should now see your rendered code in your card preview.
Congrats, that’s it! This gives you:
highlight.js
. (Languages can be set manually with class="code-python">
if you prefer)<br>
tags in my code with newlines and you may have to, too.