这是一篇样式自检页:把本站支持的 Markdown 语法和主题标签插件基本跑了一遍,
用来检查排版、配色、间距、组件样式是否正常。看完可以直接删掉,或者留着当排版参考。

顺手可查的三处:把鼠标移到标题左侧的回形针上(应从红色变蓝);
鼠标移进正文空白处,卡片阴影应变重;顶部菜单搜索框与按钮同宽。

一级标题 H1

一级标题通常留给文章标题,正文里很少用 —— 这里放一个是为了把六级都验证到。

二级标题 H2

三级标题 H3

四级标题 H4

五级标题 H5
六级标题 H6

一、文本格式

粗体、斜体、粗斜体、删除线、行内代码、HTML 高亮、下划线、
上标与下标、Ctrl + C、
HTML(鼠标悬停看全称)。

== 高亮扩展:这是高亮文字,中间是普通文字,再来 一段高亮 收尾。

中英文混排:这是 Chinese 与 English 混在一起、还有 123 数字和「中文引号」、以及标点……

转义:*这不是斜体*、`这不是代码`。

行尾两个空格可以强制换行:
这一行是强制换行后的新行。

1.1 链接

二、图片

图 1:普通图片(本地 wallpaper)

头像,带 title

内联 HTML 图片

三、引用

一级引用:里面也能写 粗体、行内代码、链接。

二级引用:嵌套一层。

  • 引用里还能放列表
  • 第二项

回到一级引用。

四、列表

4.1 无序 / 有序 / 嵌套

  • 第一层 A
    • 第二层 A-1
      • 第三层 A-1-1
    • 第二层 A-2
  • 第一层 B
  1. 有序第一项
  2. 有序第二项
    1. 嵌套有序 2.1
    2. 嵌套有序 2.2
  3. 有序第三项
  • 混合:无序里套有序
    1. 第一条
    2. 第二条

4.2 任务列表

  • 已完成的事项
  • 未完成的事项
  • 带 行内代码 的事项

五、表格

左对齐 居中对齐 右对齐
普通文本 粗体 100
代码 链接 2,048
很长很长的一段内容,用来观察窄屏下的换行与横向滚动表现 中 3
高亮 K -1

六、代码

行内代码:npm run build、git commit -m "msg"、box-shadow: 0 8px 29px -6px。

带标题的代码块:

title
1
2
3
// 主题支持在代码块第一行写 title="..."
const greet = (name) => `hello, ${name}`
console.log(greet('正弦'))
1
2
3
4
# 发布:提交推送后,Cloudflare Pages 会自动构建上线
git add -A
git commit -m "更新文章"
git push
1
2
3
4
/* 样式片段 */
.card-widget {
box-shadow: 0 8px 29px -6px rgba(0, 0, 0, 0.29);
}
1
2
没有指定语言的代码块
plain text here

长代码块(超过 height_limit: 800,用于验证收缩/滚动):

title
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// 这是一段故意写得很长的代码,用来撑破代码块的 800px 高度上限,
// 观察主题的「收缩 / 展开」按钮和内部滚动是否正常。
const PI = Math.PI

function radians(deg) {
return (deg * PI) / 180
}

function clamp(value, min, max) {
return Math.max(min, Math.min(max, value))
}

function lerp(a, b, t) {
return a + (b - a) * clamp(t, 0, 1)
}

function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`
}

function debounce(fn, wait = 200) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), wait)
}
}

function throttle(fn, wait = 200) {
let last = 0
return function (...args) {
const now = Date.now()
if (now - last >= wait) {
last = now
fn.apply(this, args)
}
}
}

function deepClone(obj, seen = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj
if (seen.has(obj)) return seen.get(obj)
if (Array.isArray(obj)) {
const arr = []
seen.set(obj, arr)
obj.forEach((item) => arr.push(deepClone(item, seen)))
return arr
}
const out = {}
seen.set(obj, out)
Object.keys(obj).forEach((key) => { out[key] = deepClone(obj[key], seen) })
return out
}

function uniqueBy(list, key) {
const seen = new Set()
return list.filter((item) => {
const k = item[key]
if (seen.has(k)) return false
seen.add(k)
return true
})
}

function groupBy(list, key) {
return list.reduce((acc, item) => {
const k = item[key]
if (!acc[k]) acc[k] = []
acc[k].push(item)
return acc
}, {})
}

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}

async function retry(fn, times = 3, delay = 500) {
for (let i = 0; i < times; i++) {
try {
return await fn()
} catch (err) {
if (i === times - 1) throw err
await sleep(delay)
}
}
}

function once(fn) {
let called = false
let result
return function (...args) {
if (called) return result
called = true
result = fn.apply(this, args)
return result
}
}

function memoize(fn) {
const cache = new Map()
return function (arg) {
if (cache.has(arg)) return cache.get(arg)
const result = fn(arg)
cache.set(arg, result)
return result
}
}

const fib = memoize((n) => (n < 2 ? n : fib(n - 1) + fib(n - 2)))

function pipe(...fns) {
return (value) => fns.reduce((acc, fn) => fn(acc), value)
}

const toUpper = (s) => s.toUpperCase()
const trim = (s) => s.trim()
const exclaim = (s) => `${s}!`

const shout = pipe(trim, toUpper, exclaim)

// 底部再放一个模块导出示意,把行数凑到足够长
export {
radians,
clamp,
lerp,
formatBytes,
debounce,
throttle,
deepClone,
uniqueBy,
groupBy,
retry,
once,
memoize,
fib,
shout
}

七、分隔线与脚注

下面是分隔线:


脚注示例:这句话带两个脚注,一个是数字[1],一个是文字[2],点角标可跳到文末对应条目。

八、主题标签插件

8.1 提示框 note

default:默认色调

primary:主要信息

info:普通信息

success:成功

warning:警告

danger:危险

8.2 小标签 label

默认 蓝 粉 红 紫 橙 绿

8.3 按钮 btn

返回首页 去导航页

8.4 分栏 tabs

第一栏的内容,Markdown 照常生效。

1
console.log('tabs 里的代码块')

第二栏的内容。

  • 列表项
  • 再来一条

8.5 折叠 hideToggle / hideInline

点我展开折叠内容

折叠里的内容,也能写 Markdown:

  • 第一项
  • 第二项

行内折叠:这是被藏起来的内容

8.7 时间线 timeline

2026-09-17

买了服务器和域名,开始折腾静态博客。

2026-09-21

换成 Twikoo 评论框、自建阅读量计数器、修 Lenis 滚动。

2026-09-22

侧栏卡片调整、导航毛玻璃、回形针配色、阴影微调。

8.8 流程图 mermaid

8.9 图表 chartjs

近四个月的阅读量柱状图。

九、数学公式(KaTeX)

行内公式:质能方程 $E = mc^2$,还有求和 $\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$。

块级公式(写成单行 $$...$$,别把 $$ 单独成行 —— 会被 Markdown 渲染器搞乱):

$$ a^2 + b^2 = c^2 $$

$$\int_0^\infty e^{-x},dx = 1$$

(KaTeX 资源已自托管,只在 katex: true 的页面加载。)

十、HTML 原生标签

点开看内容(HTML 原生 details / summary)

这里是 details 里的内容。这个标签浏览器原生支持,但主题没做美化,样式会比较素。

十一、仍有局限的写法

  • 定义列表(术语 + 缩进解释):Markdown 标准里没有,用列表或 <dl> 代替。
  • 脚注、==高亮==、数学公式、Mermaid、Chart.js 已通过本站脚本 / 自托管资源启用,见上文。

  1. 这是数字脚注的内容,里面可以写 粗体 和 行内代码。 ↩

  2. 这是文字脚注的内容。 ↩