在 Markdown 中书写伪代码

在 Markdown 中书写伪代码

0. 想法来源

最近上算法课需要书写伪代码, 但伪代码一般都是通过 Latex 书写的, 但我又不想专门为了它去写 Latex, 所以就开始考虑如何在 Markdown 中书写伪代码.

根据 “Atwood’s Law” 原则:

Any application that can be written in JavaScript, will eventually be written in JavaScript.

任何可以用 JavaScript 来写的应用, 最终都将用 JavaScript 来写.

我再次将目光投向前端, 寻找符合前端思想的解决方案.

最终我选定了 VSCode + Markdown Preview Enhanced + pseudocode.js 的组合.

(缺点是不能在 VSCode 中实时预览, 这个问题的主要原因是我不想再次魔改和维护别人写的插件了.)

大概效果:

1. 环境要求

环境要求很简单, 你只需要安装好 VSCode 和 Markdown Preview Enhanced 插件, 这部分十分简单, 就不多说了.

2. 修改配置

这部分是最核心最重要的, 我们要给 Markdown Preview Enhanced 插件加点魔改配置.

按下快捷键 Ctrl + Shift + P, 打开 VSCode 命令窗口, 输入 Markdown Preview Enhanced: Extend Parser 命令并回车运行.

可以看见原来的代码长这样:

我们用这些代码将原来的代码 Ctrl + ACtrl + V 完整替换成以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module.exports = {
onWillParseMarkdown: function(markdown) {
return new Promise((resolve, reject)=> {
return resolve(markdown)
})
},
onDidParseMarkdown: function(html, {cheerio}) {
return new Promise((resolve, reject)=> {
return resolve(`
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.js"
integrity="sha256-F/Xda58SPdcUCr+xhSGz9MA2zQBPb0ASEYKohl8UCHc=" crossorigin="anonymous">
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.css">
<script src="https://cdn.jsdelivr.net/npm/pseudocode@latest/build/pseudocode.min.js">
</script>
` + html + `
<script>
elements = document.getElementsByClassName("pseudocode");
for (var i = 1; i <= elements.length; i++) {
setTimeout(function() {
var element = document.getElementsByClassName("pseudocode")[0];
pseudocode.renderElement(element, { lineNumber: element.getAttribute("lineNumber") == "true" });
}, i * 100);
}
</script>`)
})
},
onWillTransformMarkdown: function (markdown) {
return new Promise((resolve, reject) => {
return resolve(markdown);
});
},
onDidTransformMarkdown: function (markdown) {
return new Promise((resolve, reject) => {
return resolve(markdown);
});
}
}

最后, Ctrl + S 保存这个配置文件.

3. 写伪代码

然后我们就可以在 Markdown 中写伪代码了, 你可以用下面这段代码测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<pre class="pseudocode">
% This quicksort algorithm is extracted from Chapter 7, Introduction to Algorithms (3rd edition)
\begin{algorithm}
\caption{Quicksort}
\begin{algorithmic}
\PROCEDURE{Quicksort}{$A, p, r$}
\IF{$p < r$}
\STATE $q = $ \CALL{Partition}{$A, p, r$}
\STATE \CALL{Quicksort}{$A, p, q - 1$}
\STATE \CALL{Quicksort}{$A, q + 1, r$}
\ENDIF
\ENDPROCEDURE
\PROCEDURE{Partition}{$A, p, r$}
\STATE $x = A[r]$
\STATE $i = p - 1$
\FOR{$j = p$ \TO $r - 1$}
\IF{$A[j] < x$}
\STATE $i = i + 1$
\STATE exchange
$A[i]$ with $A[j]$
\ENDIF
\STATE exchange $A[i]$ with $A[r]$
\ENDFOR
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>

如果你需要加入 行号 功能, 可以像下面这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<pre class="pseudocode" lineNumber="true">
% This quicksort algorithm is extracted from Chapter 7, Introduction to Algorithms (3rd edition)
\begin{algorithm}
\caption{Quicksort with lineNumber}
\begin{algorithmic}
\PROCEDURE{Quicksort}{$A, p, r$}
\IF{$p < r$}
\STATE $q = $ \CALL{Partition}{$A, p, r$}
\STATE \CALL{Quicksort}{$A, p, q - 1$}
\STATE \CALL{Quicksort}{$A, q + 1, r$}
\ENDIF
\ENDPROCEDURE
\PROCEDURE{Partition}{$A, p, r$}
\STATE $x = A[r]$
\STATE $i = p - 1$
\FOR{$j = p$ \TO $r - 1$}
\IF{$A[j] < x$}
\STATE $i = i + 1$
\STATE exchange
$A[i]$ with $A[j]$
\ENDIF
\STATE exchange $A[i]$ with $A[r]$
\ENDFOR
\ENDPROCEDURE
\end{algorithmic}
\end{algorithm}
</pre>

语法基本类同 Latex 的 algorithmic 包, 语法详情参考 这里.

4. 查看方式

前面我也提到, 用这种奇葩的方式, 在 VSCode 的 MPE 插件中是不能实时预览的, 需要用浏览器打开.

最后打印, 输出成 PDF 格式即可.

使用搜索:谷歌必应百度