这篇文章由 DeepSeek 生成,用途是当一篇”排版试纸”:把博客支持的各类内容都写一遍,方便一眼看出主题、字体、代码高亮有没有问题。

写博客最麻烦的往往不是写作本身,而是不确定某个语法能不能正确渲染。所以这篇示例文章会尽可能覆盖常见写法,你以后写新文章时可以直接来这里复制片段。

一、这篇示例是怎么来的

起因是博客里有两处链接一直是坏的,排查过程中发现了一个很容易踩的坑,值得先记下来:

Hexo 的主题目录 themes/<主题>/source/ 是主题资源区,不是内容区。

放在那里的 .md 文件只会被当成静态资源渲染一遍,不会解析 front-matter、也不会套用页面模板。你写的内容会被原样丢进 HTML,连 --- 都会变成分割线。

正确做法只有一条:自己写的内容一律放在站点根目录的 source/ 下。

判断标准很简单:主题目录是 git clone 来的,升级主题时会 git pull。凡是”升级后不能丢”的东西,都不该放在里面。

二、Markdown 基础排版

文字格式

普通文字、粗体、斜体、粗斜体、删除线、行内代码 npm run build,以及站外链接和站内文章。

列表

无序列表:

  • 第一项
  • 第二项
    • 嵌套子项
    • 另一个子项
  • 第三项

有序列表:

  1. 先执行 hexo clean
  2. 再执行 hexo generate
  3. 最后执行 hexo deploy

任务列表:

  • 修复 favicon 404
  • 修复邮箱链接缺少 mailto:
  • 把误放在主题目录的页面移到 source/
  • 给站点源码加版本控制

表格

问题 原因 修复方式
/music/ 显示成一堆乱码文字 页面放在主题目录,只被当作资源渲染 移到 source/music/index.md
/movies/ 404 页面实际在 /movie/,菜单写的是 /movies/ 统一为 movies
图标 404 指向不存在的 /img/favicon.png 改指向真实存在的 /img/favicon.ico
邮箱点不开 裸邮箱被当成站内路径 补上 mailto: 前缀
/tags/、/categories/ 404 缺少对应页面 新建带 type: 的页面

引用

好的示例不是把功能列一遍,
而是让读者看完之后知道下次该怎么做。

—— 某个不想署名的 DeepSeek

三、代码高亮

行内代码已经在上面出现过了,下面是块级代码。

Shell:

1
2
3
4
5
6
7
8
# 本地预览,改完直接刷新浏览器
npx hexo server

# 生成静态文件到 public/
npx hexo clean && npx hexo generate

# 部署到 GitHub Pages
npx hexo deploy

JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 检查一个页面里的站内链接是否都存在
const path = require('path');
const fs = require('fs');

function checkLinks(html, publicDir) {
const broken = [];
for (const [, url] of html.matchAll(/(?:src|href)="(\/[^"#?]*)"/g)) {
if (url.startsWith('//')) continue; // 协议相对地址,属于外部链接
const target = path.join(publicDir, url.replace(/^\//, ''), 'index.html');
if (!fs.existsSync(target)) broken.push(url);
}
return broken;
}

Python:

1
2
3
4
5
6
7
8
9
10
11
12
from pathlib import Path

def broken_links(public_dir: Path) -> list[str]:
"""扫描 public/ 下所有 HTML,返回指向不存在文件的站内链接。"""
missing: list[str] = []
for html in public_dir.rglob("*.html"):
for url in re.findall(r'(?:src|href)="(/[^"#?]*)"', html.read_text("utf-8")):
if url.startswith("//"):
continue
if not (public_dir / url.lstrip("/") / "index.html").exists():
missing.append(url)
return sorted(set(missing))

YAML 配置:

1
2
3
4
5
6
7
8
# _config.yml
permalink: :year/:month/:day/:title/
theme: butterfly

deploy:
type: git
repository: git@github.com:f-zx/f-zx.github.io.git
branch: main

四、Butterfly 标签插件

这些是主题提供的额外语法,普通 Markdown 写不出来的效果靠它们。

提示框 note

默认样式:适合放补充说明。

主要样式:适合放重点结论。

成功样式:适合放”验证通过”之类的信息。

危险样式:适合放警告,比如”别把内容放进主题目录”。

小标签 label

当前主题 Butterfly,生成器 Hexo,状态 正常,待办 待处理。

按钮 btn

Hexo 中文文档Butterfly 文档

分栏 tabs

Hexo 会把 Markdown 一次性渲染成 HTML,访问时不需要服务端参与,所以可以直接托管在 GitHub Pages 上。

优点是快、便宜、几乎不会被攻击。

动态站点每次访问都要查数据库、拼模板,功能更灵活(登录、评论、后台),但需要服务器和运维。

个人博客绝大多数场景用不上这些。

静态站点也能有动态能力:评论用 Giscus/Twikoo 这类第三方服务,搜索用本地索引或 Algolia。

这篇博客目前就是这个思路。

折叠块 hideToggle

点这里展开:为什么中文文件名容易出问题

new_post_name: :title.md 会让文章文件名直接用标题。中文标题本身没问题,但生成的 URL 会被百分号编码成一长串,既不美观,个别部署环境下也容易出岔子。

所以本文的文件名用了英文 deepseek-auto-generated-article.md,标题仍然是中文——文件名管 URL,title 管显示,两者不必一致。

时间线 timeline

本文的排查过程

第一步:确认构建是通的

先跑 npx hexo generate,结果 4 个文件全部生成成功,没有任何报错。

说明问题不在构建,而在输出内容本身。

第二步:清理构建缓存

执行 hexo clean 重新生成,public/music/index.html 只有 204 字节。

一个正常页面不可能这么小——残留的旧构建产物一直在掩盖真实问题。

第三步:确认页面归属

在 themes/butterfly 里执行 git status,发现 source/music/、source/movie/ 都是未跟踪文件(??)。

主题自带文件的时间戳是 17:33,这两个是 20:14 和 20:37——是后加的,不属于主题。

第四步:读 Hexo 源码定位机制

theme/processors/source.js 只把主题文件注册成 Asset,generator/asset.js 直接渲染源文件。

所以既不解析 front-matter,也不套模板——谜底揭开。

行内图片 inlineImg

把图片缩小后嵌在文字里 是这个效果,适合做表情或图标。

单独成段的图片:

示例图片

五、这篇示例验证了什么

写完这篇之后重新构建,可以确认:

  • 文章页正常生成,归档页数量从 1 变成 2;
  • source/tags/ 和 source/categories/ 从空页面变成了有内容的列表页;
  • 全站站内链接扫描无 404;
  • 代码块高亮、表格、任务列表、五种 note、tabs、折叠块、时间线全部正常渲染。

顺带说明几个当前配置下不可用的语法,写了也不会生效,免得你以后困惑:

语法 状态 原因
{% mermaid %} 关闭 mermaid.enable: false
{% chartjs %} 关闭 chartjs.enable: false
{% series %} 关闭 series.enable: false
数学公式 $...$ 不可用 math.use 为空,且未安装 KaTeX/MathJax 渲染器

想启用其中任何一个,改 _config.butterfly.yml 对应开关即可,数学公式还需要额外安装渲染插件。

结语

这篇文章本身就是它的用途:当你怀疑博客哪儿渲染不对劲时,打开这一页对照一下。

如果你要拿它当模板写自己的文章,建议保留 front-matter 里的 title、date、categories、tags、description 这五项,其余 tag 按需取用。

本文由 DeepSeek 生成,最后更新于 2026-10-03。