这是一份用来检验 Yggdrasil 渲染管线的综合性文章:每一节对应站点的一项写作能力,包括排版、提示块、表格、多语言代码高亮、可在浏览器里运行的代码、KaTeX 与化学公式、二十余种 Mermaid 图表、脚注、图片灯箱和折叠内容。页面里任何一处显示异常,都说明对应环节出了回归。

一、标题层级

页面标题已经占用 H1,正文从 H2 开始,目录和锚点由系统自动生成。下面依次展开 H3 到 H6。

三级标题 H3

四级标题 H4

五级标题 H5
六级标题 H6

二、行内样式

粗体、斜体、粗斜体、删除线,也可以嵌套 斜体 使用。行内代码:运行 make dev 启动开发服务器,用 cargo build --release 构建发布版。

部分行内 HTML 会保留下来:快捷键 Ctrl + K 打开搜索,高亮标记用来强调,下划线、新增、删除,化学式 H2O 与 CO2,面积单位 m2,以及 漢han字ji 这样的注音。

行尾加两个空格可以强制换行,
这一行就是换行之后的内容。

三、提示块与引用

GitHub 风格的五种提示块都有各自的配色与图标:

补充说明:读者即使略读,也不会错过这里的信息。

小技巧:make dev-assets 可以在不重启服务器的情况下刷新前端资源。

关键信息:server 与 hydrate 两个 feature 互斥,不要同时启用。

风险提示:运行器镜像升级前,先确认旧容器已经退出。

危险操作:DROP TABLE 之后数据无法恢复。

普通引用块可以包含强调、链接与行内代码,也可以嵌套:

这是一级引用,里面有 粗体、行内代码 和 链接。

这是嵌套的二级引用。

引用里同样可以放列表和代码:

  1. 第一项
  2. 第二项
let answer = 42;

四、列表

无序与有序列表

  • 第一项
  • 第二项
    • 嵌套项 2.1
    • 嵌套项 2.2
      • 更深一层 2.2.1
  • 第三项
  1. 克隆仓库
  2. 安装依赖
    1. 安装 Rust 工具链
    2. 安装 Bun 与 cargo-leptos
  3. 启动服务

任务列表

  • 配置 Rust 工具链
  • 准备 PostgreSQL
  • 运行 make dev
  • 编写单元测试
  • 部署到生产环境

五、表格

对齐方式

左对齐居中对齐右对齐
LeftCenterRight
第二行第二行123.45
第三行第三行6.7

单元格里的行内元素

功能渲染位置示例
代码高亮服务端(syntect)fn main() {}
数学公式服务端(KaTeX)
脚注服务端见此处1
Mermaid浏览器,进入视口时懒加载二十余种图表
可运行代码服务端 Docker 沙箱运行器

六、代码高亮

服务端用 syntect 着色,页面不需要额外的高亮脚本,每个代码块右上角带复制按钮。没有语言标记的围栏按纯文本显示。

系统与后端语言

use std::collections::HashMap;

#[derive(Debug, Clone)]
struct Post {
    id: i64,
    title: String,
}

fn index(posts: &[Post]) -> HashMap<i64, &Post> {
    posts.iter().map(|p| (p.id, p)).collect()
}
package main

import "fmt"

type Stack[T any] struct{ items []T }

func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }

func main() {
	s := &Stack[string]{}
	s.Push("yggdrasil")
	fmt.Println(len(s.items))
}
const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, {s}!\n", .{"Zig"});
}
from dataclasses import dataclass


@dataclass
class Point:
    x: float
    y: float


def centroid(points: list[Point]) -> Point:
    n = len(points)
    return Point(sum(p.x for p in points) / n, sum(p.y for p in points) / n)

移动端与前端语言

data class User(val name: String, val age: Int)

fun main() {
    listOf(User("Alice", 30), User("Bob", 25))
        .filter { it.age >= 28 }
        .forEach { println("${it.name}: ${it.age}") }
}
struct Greeting {
    let message: String

    func say(to name: String) -> String {
        "\(message), \(name)!"
    }
}

print(Greeting(message: "Hello").say(to: "world"))
interface Todo {
  id: number;
  title: string;
  done: boolean;
}

const toggle = (todo: Todo): Todo => ({ ...todo, done: !todo.done });
import { useState } from "react";

export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount((c) => c + 1)}>clicked {count} times</button>;
}
<template>
  <button class="hello" @click="count++">{{ message }} {{ count }}</button>
</template>

<script setup lang="ts">
import { ref } from "vue";

const message = ref<string>("clicked");
const count = ref(0);
</script>

<style scoped>
.hello {
  color: #42b883;
}
</style>
<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <title>Hello</title>
  </head>
  <body>
    <p class="greeting">你好,世界</p>
  </body>
</html>
.card {
  display: grid;
  gap: 0.75rem;
  border: 1px solid color-mix(in oklab, currentColor 20%, transparent);
  border-radius: 12px;
}

@media (prefers-color-scheme: dark) {
  .card { background: #111; }
}

配置、数据与脚本

[package]
name = "yggdrasil"
edition = "2021"

[features]
default = ["server"]
hydrate = []
services:
  app:
    image: yggdrasil:latest
    environment:
      DATABASE_URL: postgres://user:pass@db:5432/yggdrasil
    ports:
      - "8080:8080"
{
  "name": "yggdrasil",
  "features": ["ssr", "markdown", "mcp"],
  "private": true
}
SELECT t.name, COUNT(*) AS posts
FROM tags t
JOIN post_tags pt ON pt.tag_id = t.id
GROUP BY t.name
ORDER BY posts DESC
LIMIT 10;
# 构建并部署
make build
docker compose up -d
docker compose logs -f app
- let timeout = 5;
+ let timeout = 10;
  run(timeout);
@fragment
fn fs_main(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
    return vec4<f32>(uv, 0.5, 1.0);
}
没有语言标记的代码块,
按纯文本显示,不做语法高亮。

七、数学公式

公式由 KaTeX 在服务端渲染成 HTML,页面不依赖 MathML,也不需要额外的脚本。

行内公式

质能方程 ,欧拉恒等式 ,黄金比例 ,排序算法的时间复杂度 。

块级公式

对齐与矩阵

项目内置的物理与集合宏

数集:、、、、。微积分:、、、、。向量与范数:、、、。

量子力学记号:、、内积 、期望 。

化学式与单位

行内化学式 、,温度 ,浓度 。

标题中的公式

勾股定理

标题和目录里的公式也应该正常渲染。

八、Mermaid 图表

站点在浏览器里渲染 Mermaid,进入视口时才加载渲染器,自动适配明暗主题,点击图表可以放大、缩放和平移。下面按用途分组展示。

流程图

是

否

用户访问文章页

命中 SSR 缓存?

返回缓存 HTML

读取数据库

渲染 Markdown

写入 SSR 缓存

返回响应

是

否

用户访问文章页

命中 SSR 缓存?

返回缓存 HTML

读取数据库

渲染 Markdown

写入 SSR 缓存

返回响应

服务端

浏览器

请求

未命中

HTML

页面 / WASM

Axum + Leptos SSR

moka 缓存

PostgreSQL

服务端

浏览器

请求

未命中

HTML

页面 / WASM

Axum + Leptos SSR

moka 缓存

PostgreSQL

时序图

Docker服务端浏览器用户Docker服务端浏览器用户通过 SSE 推送alt[校验通过][校验失败]点击「运行」1提交源码与语言2限流与白名单校验3创建只读容器并执行4stdout / stderr5流式输出6返回错误7渲染到终端8
Docker服务端浏览器用户Docker服务端浏览器用户通过 SSE 推送alt[校验通过][校验失败]点击「运行」1提交源码与语言2限流与白名单校验3创建只读容器并执行4stdout / stderr5流式输出6返回错误7渲染到终端8

类图

撰写

标记

1

*

*

*

Post

+i64 id

+String slug

+String title

+String content_md

+publish()

+trash()

User

+i64 id

+String username

Tag

+i64 id

+String name

撰写

标记

1

*

*

*

Post

+i64 id

+String slug

+String title

+String content_md

+publish()

+trash()

User

+i64 id

+String username

Tag

+i64 id

+String name

状态图

发布

撤回

删除

删除

恢复

永久删除

草稿

已发布

回收站

发布

撤回

删除

删除

恢复

永久删除

草稿

已发布

回收站

实体关系图

writes

receives

tagged

USER

POST

bigint

id

PK

text

slug

UK

text

title

text

status

COMMENT

bigint

id

PK

bigint

post_id

FK

text

status

TAG

writes

receives

tagged

USER

POST

bigint

id

PK

text

slug

UK

text

title

text

status

COMMENT

bigint

id

PK

bigint

post_id

FK

text

status

TAG

甘特图与时间线

2026-10-012026-10-032026-10-052026-10-072026-10-092026-10-112026-10-132026-10-152026-10-172026-10-192026-10-212026-10-232026-10-25功能开发 联调测试 灰度上线 全量上线 开发发布发布计划
2026-10-012026-10-032026-10-052026-10-072026-10-092026-10-112026-10-132026-10-152026-10-172026-10-192026-10-212026-10-232026-10-25功能开发 联调测试 灰度上线 全量上线 开发发布发布计划
早期v0.xDioxus 全栈v1.0全新设计语言近期v1.1迁移到 Leptosv1.2路由分包与首屏优化Yggdrasil 版本演进
早期v0.xDioxus 全栈v1.0全新设计语言近期v1.1迁移到 Leptosv1.2路由分包与首屏优化Yggdrasil 版本演进

Git 分支图

mainfeatureinitadd-runneradd-testsreleasev1.2.0
mainfeatureinitadd-runneradd-testsreleasev1.2.0

思维导图

Yggdrasil

写作

Markdown

可运行代码

公式与图表

站点

SSR

主题

视图过渡

服务

MCP

备份

代码运行器

Yggdrasil

写作

Markdown

可运行代码

公式与图表

站点

SSR

主题

视图过渡

服务

MCP

备份

代码运行器

数据图表

45%25%15%10%5%文章内容构成正文 [45]代码块 [25]数学公式 [15]图表 [10]其他 [5]
45%25%15%10%5%文章内容构成正文 [45]代码块 [25]数学公式 [15]图表 [10]其他 [5]
每月访问量1月2月3月4月5月6月1200110010009008007006005004003002001000访问量
每月访问量1月2月3月4月5月6月1200110010009008007006005004003002001000访问量
优先做规划中暂缓顺手做主题切换多语言评论审核全文搜索投入低投入高价值低价值高功能优先级
优先做规划中暂缓顺手做主题切换多语言评论审核全文搜索投入低投入高价值低价值高功能优先级
Visit 800Home 500Post 650Exit 680Comment 120
Visit 800Home 500Post 650Exit 680Comment 120

Mermaid 的桑基图词法只接受 ASCII 节点名,写中文节点会解析失败,上图因此使用英文标签。

用户旅程与看板

读者
发现
发现
读者
搜索关键词
搜索关键词
读者
点开文章
点开文章
阅读
阅读
读者
浏览目录
浏览目录
读者
运行示例代码
运行示例代码
互动
互动
读者
留下评论
留下评论
读者阅读一篇文章
读者
发现
发现
读者
搜索关键词
搜索关键词
读者
点开文章
点开文章
阅读
阅读
读者
浏览目录
浏览目录
读者
运行示例代码
运行示例代码
互动
互动
读者
留下评论
留下评论
读者阅读一篇文章

待办

进行中

已完成

设计评论审核流程

补充备份回归测试

路由分包优化

迁移到 Leptos

待办

进行中

已完成

设计评论审核流程

补充备份回归测试

路由分包优化

迁移到 Leptos

架构与块图

CDN应用PostgreSQL边缘源站
CDN应用PostgreSQL边缘源站

浏览器

服务端

数据库

路由

渲染

缓存

浏览器

服务端

数据库

路由

渲染

缓存

需求图与 C4 上下文图

需求图的元素名与关系只能用 ASCII 标识符,中文放进带引号的 text 与 type 里。

<<satisfies>>

<<contains>>

<<Requirement>>

runnable_code

ID: 1

Text: 阅读器可以执行代码块

Risk: High

Verification: Test

<<Functional Requirement>>

limits

ID: 1.1

Text: 限制 CPU、内存与超时

Risk: Medium

Verification: Inspection

<<Element>>

sandbox

Type: Docker 容器

<<satisfies>>

<<contains>>

<<Requirement>>

runnable_code

ID: 1

Text: 阅读器可以执行代码块

Risk: High

Verification: Test

<<Functional Requirement>>

limits

ID: 1.1

Text: 限制 CPU、内存与超时

Risk: Medium

Verification: Inspection

<<Element>>

sandbox

Type: Docker 容器

读者[Person]阅读文章与笔记作者[Person]写作与管理Yggdrasil[Software System]博客、笔记与 MCP 服务AI 客户端[Software System]通过 MCP 读写内容浏览管理调用 MCPYggdrasil 系统上下文
读者[Person]阅读文章与笔记作者[Person]写作与管理Yggdrasil[Software System]博客、笔记与 MCP 服务AI 客户端[Software System]通过 MCP 读写内容浏览管理调用 MCPYggdrasil 系统上下文

其他图表

源端口015目的端口1631序列号3263确认号6495
源端口015目的端口1631序列号3263确认号6495
性能可维护性体积生态学习成本方案 A方案 B三种方案对比
性能可维护性体积生态学习成本方案 A方案 B三种方案对比
站点950前端770服务端180路由分包480主包290API120运行器
站点950前端770服务端180路由分包480主包290API120运行器

九、脚注

正文里可以引用 PostgreSQL2,也可以引用渲染管线用到的 pulldown-cmark3。同一条脚注可以被引用多次2,每次引用在定义末尾都有对应的返回链接。

脚注的标签可以含空格4,也可以写成多段,续段缩进四个空格5。

十、链接与图片

链接

图片与灯箱

图片带模糊占位与延迟加载,点击进入灯箱,可以缩放和拖动。

Yggdrasil v1.0 首页,亮色主题Yggdrasil v1.0 首页,亮色主题

Yggdrasil v1.0 首页,暗色主题Yggdrasil v1.0 首页,暗色主题

分包合并效果:共享分包由 1121 个降到 262 再到 97 个分包合并效果:共享分包由 1121 个降到 262 再到 97 个

十一、可运行代码块

在围栏语言后加 runnable,阅读器就会在代码块下方挂出运行器:代码在服务端的 Docker 沙箱里执行,只读文件系统、无网络,输出以流的形式显示在终端里。每个示例都是独立的单文件程序。

Python

python可运行
未运行复制代码更多操作
-- NORMAL --i 插入 · v 选择 · ⌘↵ 运行

预期输出:the: 3、quick: 1、brown: 1。

Node.js

围栏末尾可以追加紧凑的 JSON 来调整资源,五个字段必须写全,且不能含空白:

node可运行
未运行复制代码更多操作
-- NORMAL --i 插入 · v 选择 · ⌘↵ 运行

预期输出:fib(90) = 2880067194370816120 与 1, 4, 9, 16。

TypeScript(Bun)

bun可运行
未运行复制代码更多操作
-- NORMAL --i 插入 · v 选择 · ⌘↵ 运行

预期输出:5。

Go

go可运行
未运行复制代码更多操作
-- NORMAL --i 插入 · v 选择 · ⌘↵ 运行

预期输出:[0 1 4 9 16]。

Rust

rust可运行
未运行复制代码更多操作
-- NORMAL --i 插入 · v 选择 · ⌘↵ 运行

预期输出:go: 2、python: 1、rust: 3。

运行器不提供标准输入,也不开放网络。需要联网或读取本地文件的示例,请用不带 runnable 的普通代码块展示。

十二、折叠内容

点击展开:推导 1 + 2 + … + n

把求和式倒序再写一遍,两式相加,每一列的和都是 ,一共 列:

折叠区域里可以继续使用 Markdown、行内代码,也可以放代码块:

print(sum(range(1, 101)))  # 5050
点击展开:参考答案

答案是 42。

十三、分割线与转义

上方文字


中间文字


下方文字

以下字符前加反斜杠可以原样输出:* 星号、_ 下划线、` 反引号、# 井号、[ 方括号 ]、\ 反斜杠、$ 美元符号。

十四、Unicode 与多语言

  • 中文:世界,你好!
  • 日本語:こんにちは世界
  • 한국어:안녕하세요 세계
  • العربية:مرحبا بالعالم
  • Русский:Привет, мир
  • Emoji:🚀 🦀 🌳 ✨ 📝 🔥

十五、混合排版压力测试

  1. 引用 + 有序列表 + 强调
  2. 同时包含 行内代码 与链接。

下面这段同时出现公式 、inline code、强调、超链接和脚注6:

Markdown 源码

解析

HTML

KaTeX 公式

syntect 高亮

Mermaid 占位

HTML 清理

SSR 缓存

客户端水合

Mermaid 懒加载渲染

Markdown 源码

解析

HTML

KaTeX 公式

syntect 高亮

Mermaid 占位

HTML 清理

SSR 缓存

客户端水合

Mermaid 懒加载渲染

测试结束:如果以上内容都渲染正确,说明 Markdown 管线工作正常。