Jakho

Jakho

Full Stack developer.
x

Markdown 製作Anki 記憶卡並實現程式碼高亮

近日在整理過往在 Codeing 時記錄的一些知識片段筆記,想着因為入手了 Anki 的 IOS 客戶端,能不能把這些筆記抽出來一些比較實用的做成 Anki 記憶卡片,偶爾在手機上無聊的時候隨時可以點開看看,加深記憶,這樣在往後面試或者面試他人的時候也能有幫助。

因為筆記都是 Markdown 格式,並且往往裡面都會夾雜一些代碼片段,比如:

# 給定一個字符串,判定其能否排列成回文串.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;
};

但是如果直接把內容通過 Markdown 編輯器去轉換,轉換得到的格式文本可能無法直接粘貼到 Anki 的編輯器中或者並不是可用的狀態,比如:

image

當然,你可以直接安裝官方的 Syntax Highlighting 插件 使用,但畢竟一個個手工制卡確實麻煩。作為程序員肯定得用一些代碼能力來解放雙手,只要寫一段將 Markdown 轉換為 HTML 源代碼並且讓代碼擁有高亮格式的程序,就能通過程序批量轉換制卡了,我這裡提供一種使用 Node.js 的實現思路,大家可以按照自己的理解和語言來實現。

在 Node.js 中,有很多 Markdown 的工具,比如 markedmarkdown-it,我這裡使用的是 markdown-it,原理都是通用的,可以自己選擇不同工具。

我們安裝 markdown-ithighlight.js依賴包,並且引入使用:

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/>") // 換行用br表示
          .replace(/\s/g, "&nbsp;") // 用nbsp替換空格
          .replace(/span&nbsp;/g, "span "); // span標籤修復
        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 內容`)

上面這段代碼就是這個 markdown-it 庫將 Markdown 轉換為 HTML 源代碼的基礎使用方法,但是轉換後的內容直接粘貼進 Anki 中也是無法生效代碼高亮的,原因在於:一般這些庫轉換後的 HTML 代碼都是使用 class 添加樣式的,需要在頁面額外引入 css 文件進行樣式加載的。但是,我們又沒辦法為卡片直接添加 css 樣式,因此,我們需要把 css 內容注入到 HTML 裡,作為內聯的 style 樣式,這樣才能讓 Anki 完整顯示格式內容。

這裡我們需要引入一個庫 juice,它可以將你的 CSS 屬性內聯到 style 屬性中。

# pnpm i juice

const juice = require('juice');

# 可以將 highlight.js 提供的樣式文件下載
# https://highlightjs.org/download
# 下載後提取需要用到的 css 文件,使用 juice 庫進行加載

// 將 markdown 轉為 HTML 源代碼
const result = md.render(`需要轉換的 markdown 內容`); 

// 加載 css 內容,可以通過 readFile 讀取文件或者直接複製文件內容作為變量
const defaultStyle = `CSS 內容...`;
const codeStyle = `CSS 內容...`;

// 使用 juice 執行內聯樣式操作
const res = juice.inlineContent(result, defaultStyle + codeStyle, {
  inlinePseudoElements: true,
  preserveImportant: true,
});

// 獲得內聯樣式後的 HTML 源代碼
console.log(res); 

然後將代碼複製進 Anki 軟件裡查看效果:

image

這樣,你就能通過自己寫一些自動批量程序,把你的含有代碼的筆記,轉換為可導入的內容,通過 CSV 文件可以實現批量的記憶卡片錄入。

image

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。