搭建博客之前从没想过,在文章中放入带语法着色的代码片段,是挺不容易的一件事。
因为实现起来复杂,刚开始一般都没有代码着色功能。这也就给了前端插件生存的空间,例如 Prism 和 highlight.js。
Prism 是把 HTML 中的 <code>
块里的内容替换成带有语法着色的新内容,就如同 less.js
在浏览器端把 .less
编译成 .css
文件那样。注意,Prism 看到的并不是 markdown 源文件,而是转换之后的 HTML,因为 Prism 是当网页在用户浏览器上渲染时才起作用,而不是在 markdown 转 HTML 的时候。
Prism 的使用体验很不错,只要在网页头部插入 prism.js
和 prism.css
剩下的它会自动搞定。直到有一天我发现代码的样式不对了,原来是 Hugo 自己的代码着色与 Prism 的掺和到一起了。既然 Hugo 有自带的,就研究了一下,发现完全够用。
与 Prism 的丰富相比,Hugo 显得有些简单,同时也意味着更容易上手,少一些折腾,少一些选择困难。使用 Hugo 的代码块功能,只要简单弄一下配置文件,然后在文章中使用就可以了。下面说说具体做法。
配置文件
打开项目根目录下的 config.toml
,加上这么一段
[markup.highlight]
style = 'manni' # 样式参考 https://swapoff.org/chroma/playground
就是这么简单!网上那些教程写的配置项太多太乱,我逐个试过后,把默认值就很完美的全都删掉(例如 tabWidth = 4
)只留下必要且有意义的,发现就只需要选一个自己喜欢的样式,其他啥都不用。目前可选的样式并没有太满意的,manni 也是妥协之后的选择,期待以后会有更好看的。
对于高级玩家,想在 markdown 中插入 HTML 代码的,需要打开一个默认被关闭的选项,就再添加下面这段:
[markup.goldmark.renderer]
unsafe = true # 默认值不支持在 markdown 中写 html,需改成 true 开启
上面这个配置项写的是 unsafe 看着挺吓人,但其实不必担心,因为用于个人网站的话,所有东西都是自己写的,不会有恶意代码。
markdown 里写代码块
这部分用直观的对照一个一个例子来呈现,先展示代码块渲染在页面上的样子,紧接着展示 markdown 源码怎么写。
1. 最普通的用法
渲染效果:
fn main() {
println!("Hello, world!");
}
markdown 写法:
```rust
fn main() {
println!("Hello, world!");
}
```
对于不带行号的代码块,默认的样式布局可能会显得有些局促,调整一下文章的 CSS:
/* 不带行号的代码块 */
.highlight>pre {
padding: 10px; /* 适当留出边距 */
overflow: auto; /* 代码行太长向右滚动 */
}
2. 带行号的
渲染效果:
|
|
对应的 markdown 写法:
```rust {linenos=table}
fn main() {
println!("Hello, world!");
}
```
上面代码中用到了扩展语法,也就是紧跟在 rust 后、花括号内的部分。
这里用到的参数是 lineos,有以下两种取值:
- inline:代码行号内联在代码块里,鼠标框选代码时会选中行号
- table:鼠标框选代码时不会选中行号,方便复制粘贴 table 目前有个小瑕疵就是行号和代码对不齐,需要在文章的 CSS 中设置一下 line-height:
.highlight{
/* 统一行高,让行号和代码能对齐 */
line-height: 18px;
}
3. 自定义起始行号
渲染效果:
|
|
对应的 markdown 写法:
```rust {linenos=table, linenostart=21}
fn main() {
println!("Hello, world!");
}
```
linenostart=21
表示代码块从第 21 行开始计数。典型的使用场景是,在一大段代码中单摘出一小段,为保留原有的代码行号,就可以这么来用。
4. 行高亮
我们有时候会有把某些行高亮,用来强调突出,像下面这样:
渲染效果:
|
|
对应的 markdown 写法:
```rust {linenos=table, hl_lines=[2 "5-6"]}
fn main() {
another_function(5);
}
fn another_function(x: i32) {
println!("The value of x is: {}", x);
}
```
这里 hl_lines 就表示有哪些行高亮,它的值是一个集合,上面的例子中有两部分做了高亮。首先是第 2 行,接下来是第 5-6 行,当连续多行高亮时,可以用 ”起始行号-截止行号“
的写法。其中「起始行号」和「截止行号」并非指左侧的代码行号,而是从这个代码块中的第一行开始数起。例如下面这段:
渲染效果:
|
|
对应的 markdown 写法:
```rust {linenos=table, linenostart=21, hl_lines=[2]}
fn main() {
another_function(5);
}
```
代码行号从第 21 行开始,高亮的是本代码块的第 2 行,于是实际是第 22 行高亮。