hexo+reveal指南

hexo+reveal指南

作为一个标准学生仔,slides我做的也不少了,之前一直用WPS,但是其在理工背景下有一些弊端,比如插入公式非常麻烦,以及格式总有些奇妙缩进/空格且难以修复。前段时间从学长那里了解到了可以用markdown+js来写slides,相比之下用markdown来写内容,格式就不再是问题了。(虽然相比WPS可能会有一些单一,不过我正好懒得搞花哨的东西hhh)

首先明确一下需要做的事:

  • 找到工具可以用markdown+js来写slides
  • 将其嵌入到hexo框架下,做到渲染slides与渲染正常文章一样,不需要多余操作

Reveal.js

对于第一点,有许多选择,包括nodeppt,reveal.js等等,但是前者现在已经不维护了,支持的node.js的版本似乎也比较落后了,因此我选择使用reveal.js。

基本格式

reveal的官网在这里,其直接提供了一个js编写slides的框架。下载过程比较简单,这里略过,先简单看一下其编写的格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
<link rel="stylesheet" href="dist/reveal.css" />
<link rel="stylesheet" href="dist/theme/white.css" />
</head>
<body>
<div class="reveal">
<div class="slides">
<section>Slide 1</section>
<section>Slide 2</section>
</div>
</div>
<script src="dist/reveal.js"></script>
<script>
Reveal.initialize();
</script>
</body>
</html>
slides的主体在<body>里面,其需要两层<div>进行包裹,分别是reveal以及slides,编写的时候顺序就是reveal > slides > sections,其中每一个section里面就是一张slide。为了使用revealslides这两个class,我们需要在<head>部分提前引入。

插件引用

另外如果需要其它插件,比如高亮,或者支持markdown编写等等,需要在Reveal.initialize中添加,具体格式为

1
2
3
4
5
6
7
8
<script src=dist/reveal.js></script>
<script src=plugin/markdown/markdown.js></script>
<script src=plugin/highlight/highlight.js></script>
<script>
Reveal.initialize({
plugins: [ RevealMarkdown, RevealHighlight]
});
</script>
在前面引入对应的包,然后初始化时添加到plugins列表中。一般需要用到的功能,包括公式渲染,高亮,notes等等,对应的包都在reveal.js文件夹下,从而可以本地直接引用。当然也可以引cdn链接,比如我的reveal版本是5.2.1,那么我要highlight功能的话,引用时也可以写
1
<script src=https://cdn.jsdelivr.net/npm/reveal.js@5.2.1/plugin/highlight/highlight.js></script>
具体的包可以自己去找一下

公式渲染

公式渲染需要引用mathjax,或者KaTex,这一点可以参考官网。我按照官网指示没成功,自己引用的是mathjax3,配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.2.1/plugin/math/math.js"></script>
<script>
Reveal.initialize({
plugins: [ ..., RevealMath ],
math: {
mathjax: 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js',
tex: {
packages: ['base', 'ams'], // 这里必须显式写上 ams, 为了支持flalign等换行
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$', '$$'], ['\\[', '\\]']]
},
},
...
});
</script>

这样配置好之后一般的公式应该就能正常渲染了。写的时候跟正常也一样,行内公式用$...$,独立公式用$$...$$。但是此时对换行可能还是不支持。我一开始以为是mathjax与reveal的版本兼容问题,但是后面发现是\\被识别为\了,也就是公式中\被识别为转义符号了,那么换行时多打两个\就可以了,例子如下

1
2
3
4
5
6
$$
\begin{flalign}
5 &= 1+ 4 \\\\
&= 2 + 3
\end{flalign}
$$

markdown编写

最后是关于这个框架如何使用markdown。事实上并不需要太多操作,官网也提供了详细的说明,这里简单介绍一下。 原本每一页slide的区分依靠<section>标签,然后内部再使用js进行排版和内容编写。换成markdown的话,只需要外面包两层标签,内部就可以正常使用markdown语法了,slide之间的区分依靠---符号

1
2
3
4
5
6
7
8
9
10
<section data-markdown>
<textarea data-template>
## Slide 1
A paragraph with some text and a [link](https://hakim.se).
---
## Slide 2
---
## Slide 3
</textarea>
</section>

更多的内容,包括美化,子页等操作这里略过,看官网可能更加合适。

嵌入hexo

网上关于hexo与reveal结合的教程比较少,github项目也很少,相比之下hugo框架与reveal结合的相关资源会好很多。这里使用的是github上的一个项目

安装很简单,blog目录下输入

1
npm i hexo-generator-slidehtml
即可。

之后对于slide的渲染步骤与正常文章是类似的,只要在slide的tag中添加一个slidehtml: true即可。但是此时还不能直接访问slide

比如slide渲染之后的link是https://sophilex.top/posts/418a878e/,这是与其它文章一样格式的地址,但是想访问slide,需要在后面添加slide.html,总体为https://sophilex.top/posts/418a878e/slide.html

每次都这么做可能有点麻烦,所以我在第一个link里添加了一个按钮用于跳转。blog\thems\your_theme\layout\post.ejs提供了文章展示的相关js模板,只需要在里面写一个按钮,识别到文章中slidehtmltag为true就展示即可。

1
2
3
4
5
6
7
<!-- 加个横线与文章内容区分 -->
<hr/>
<% if (page.slidehtml) { %>
<div class="mt-4 text-center">
<a href="<%= url_for(page.path) %>slide.html" class="btn btn-primary">View Slides</a>
</div>
<% } %>
这块内容放在markdown-body下面即可,也就是在展示完文章内容(如果有)之后,放上这个按钮。

slide的渲染模板在blog\node_modules\hexo-generated-slidehtml\layout\post-slide.ejs中,其内容结构与第一部分介绍的reveal模板差不多,毕竟最终html代码就由其产出。slide主体内容被嵌入在如下代码中

1
2
3
4
5
6
7
8
9
10
<div class="reveal">
<div class="slides">
<section data-markdown
data-separator="<%- config.horizontalSeparator %>"
data-separator-vertical="<%- config.verticalSeparator %>"
data-separator-notes="^Note:">
<script type="text/template"><%- page %></script>
</section>
</div>
</div>
前两层是reveal格式要求,里面是markdown格式要求,slide内容在<%- page %>中,相关结构都处理好了,因此写的时候只需要按照正常markdown内容写就好了。不过写slide之前需要加上一句 <!-- Slide Start -->用于表明接下来的内容是slide的,而前面的内容就会被正常渲染为文章页面的内容,格式如下
1
2
3
4
5
6
7
8
9
10
11
12
slide tags...

文章内容
<!-- Slide Start -->

## 标题1
123

---

## 标题2
123456

其余的reveal相关配置,参考本文第一部分,在post-slide.ejs中进行相关修改即可。这里分享一下我的配置(大部分都抄的学长的hhh)

导出PDF

有时候在线的slides有导出本地PDF文件的需求,但是直接在reveal框架渲染出的网页上按Ctrl+P进行下载的话,格式非常乱,完全不能看。这里提供两种方法

reveal官方

官方给的一个方法是在slides的url后面跟上?print-pdf,然后在对应页面按Ctrl+P进行打印。比如我的一个slide的url是https://sophilex.top/posts/ef9972ec/slide.html,加上对应后缀之后就是https://sophilex.top/posts/ef9972ec/slide.html?print-pdf,但是这个功能只能在Chrome和Chromium中使用。 至于效果,至少在我这边跟原始方法的效果没啥区别,并不具备可用性。

decktape

一个专门用来导出网页slides的工具,link。除了reveal.js,其也支持各种网页渲染框架的导出,感兴趣可以去详细了解一下。 使用方法也是非常简单,命令基本格式为

1
decktape [options] [command] <url> <filename>
其中[command]参数代表了你的slides的渲染框架,这里就写reveal即可;<url>参数就代表你要导出的slides的网址;<filename>参数代表导出文件名

其它可选项都由[optioins]参数提供,包括导出的分辨率等等,具体可以去项目里详细了解。

举个栗子,如果我想导出这份slides,我的命令应该写为

1
decktape reveal https://sophilex.top/posts/ef9972ec/slide.html hhh.pdf

导出效果实测非常nice!

总结

这种写slides的方式跟写日常写笔记差不多,但也意味着其排版比较固定(想要复杂点的,多写点css当然也可以实现,但是我懒),插入图片似乎也比较麻烦,位置大小啥的得慢慢调。不过公式编辑的便捷是一大优势,以及个人觉得很帅。(以及被迫重新学了一点前端hhh

好玩。


hexo+reveal指南
https://sophilex.github.io/posts/87c52bab/
作者
Sophilex
发布于
2025年6月12日
许可协议