Jakho

Jakho

Full Stack developer.
x

Creating Anki flashcards with Markdown and implementing code highlighting

Recently, while 整理 past notes recorded during Codeing, I thought that since I got the Anki iOS client, I could extract some practical notes to create Anki flashcards. This way, I can open them anytime on my phone when I'm bored, reinforcing my memory, which could also be helpful for future interviews or interviewing others.

Since the notes are in Markdown format and often contain some code snippets, for example:

# Given a string, determine if it can be rearranged into a palindrome.md

var canPermutePalindrome = function(s) {
    const set = new Set();
    s.split('').forEach(key => {
        if (set.has(key)) {
            set.delete(key);
        } else {
            set.add(key);
        }
    });
    return set.size <= 1;
};

However, if I directly convert the content using a Markdown editor, the formatted text may not be directly pasted into Anki's editor or may not be in a usable state, for example:

image

Of course, you can directly install the official Syntax Highlighting plugin to use, but manually creating cards one by one is indeed cumbersome. As a programmer, I definitely need to use some coding skills to free my hands. As long as I write a program to convert Markdown to HTML source code and ensure the code has highlighting, I can batch convert cards through the program. Here, I provide an implementation idea using Node.js, and everyone can implement it according to their understanding and language.

In Node.js, there are many Markdown tools, such as marked and markdown-it. I am using markdown-it here; the principles are common, and you can choose different tools.

We install the markdown-it and highlight.js dependencies and import them for use:

const markdownit = require('markdown-it');
const highlightjs = require('highlight.js');

const md = markdownit({
  html: true,
  typographer: true,
  highlight: (str, lang) => {
    if (lang === undefined || lang === "") {
      lang = "bash";
    }
    if (lang && highlightjs.getLanguage(lang)) {
      try {
        const formatted = highlightjs
          .highlight(lang, str, true)
          .value.replace(/\n/g, "<br/>") // Use br for line breaks
          .replace(/\s/g, "&nbsp;") // Replace spaces with nbsp
          .replace(/span&nbsp;/g, "span "); // Fix span tag
        return '<pre class="custom"><code class="hljs">' + formatted + "</code></pre>";
      } catch (e) {
        console.log(e);
      }
    }
    return '<pre class="custom"><code class="hljs">' + md.utils.escapeHtml(str) + "</code></pre>";
  },
})

md.render(`Markdown content to be converted`)

The above code is the basic usage of the markdown-it library to convert Markdown to HTML source code. However, the content pasted directly into Anki will not have effective code highlighting because generally, these libraries add styles using classes, which require an additional CSS file to load styles on the page. However, we cannot directly add CSS styles to the cards, so we need to inject the CSS content into the HTML as inline styles to fully display the formatted content in Anki.

Here, we need to introduce a library juice, which can inline your CSS properties into the style attributes.

# pnpm i juice

const juice = require('juice');

# You can download the style files provided by highlight.js
# https://highlightjs.org/download
# After downloading, extract the necessary CSS files and load them using the juice library

// Convert markdown to HTML source code
const result = md.render(`Markdown content to be converted`); 

// Load CSS content, which can be read from a file using readFile or directly copy the file content as a variable
const defaultStyle = `CSS content...`;
const codeStyle = `CSS content...`;

// Use juice to perform inline style operations
const res = juice.inlineContent(result, defaultStyle + codeStyle, {
  inlinePseudoElements: true,
  preserveImportant: true,
});

// Get the HTML source code with inline styles
console.log(res); 

Then copy the code into the Anki software to see the effect:

image

This way, you can write some automated batch programs to convert your notes containing code into importable content, allowing for batch entry of flashcards through a CSV file.

image

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.