近日在整理過往在 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 的編輯器中或者並不是可用的狀態,比如:
當然,你可以直接安裝官方的 Syntax Highlighting
插件 使用,但畢竟一個個手工制卡確實麻煩。作為程序員肯定得用一些代碼能力來解放雙手,只要寫一段將 Markdown 轉換為 HTML 源代碼並且讓代碼擁有高亮格式的程序,就能通過程序批量轉換制卡了,我這裡提供一種使用 Node.js 的實現思路,大家可以按照自己的理解和語言來實現。
在 Node.js 中,有很多 Markdown 的工具,比如 marked
、markdown-it
,我這裡使用的是 markdown-it
,原理都是通用的,可以自己選擇不同工具。
我們安裝 markdown-it
和 highlight.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替換空格
.replace(/span /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 軟件裡查看效果:
這樣,你就能通過自己寫一些自動批量程序,把你的含有代碼的筆記,轉換為可導入的內容,通過 CSV 文件可以實現批量的記憶卡片錄入。