Quarkdown:Markdown 的超能力进化,从想法到论文、演示、知识库的全流程工具
posts posts 2026-04-29T16:41:29+08:00Quarkdown 是一个基于 Kotlin 的 Markdown 扩展语言,支持函数调用和 Turing-complete 扩展,可编译为书籍、论文、幻灯片、网站和知识库等多种格式。技术笔记Kotlin, Markdown, 文档工具, 编译器, 知识库Quarkdown:Markdown 的超能力进化,从想法到论文、演示、知识库的全流程工具
📖 一、项目概述
1.1 Quarkdown 是什么
Quarkdown 是一个基于 Kotlin 构建的 Markdown 扩展语言,它的口号是"Markdown with superpowers"。与普通 Markdown 不同,Quarkdown 远不止是纯文本标记语法——它是一个完整的文档编译系统,能够将一份源文件编译成书籍、学术论文、幻灯片、网站和知识库等多种输出格式。
如果你厌倦了在 Markdown 里写代码示例却无法运行,想要在文档里调用函数、处理数据、生成图表,那 Quarkdown 正是为你设计的。它的扩展机制图灵完备(Turing-complete),意味着你可以在文档里写真正的程序逻辑。
1.2 核心数据
| 指标 | 数值 |
|---|---|
| Stars | 8,000+ ⭐ |
| 语言 | Kotlin 94.4%, Qotlin 4.4% |
| 最新版本 | 持续活跃开发中 |
| 许可证 | GPL v3 |
| GitHub | iamgio/quarkdown |
1.3 为什么需要 Quarkdown
传统 Markdown 的局限在于它本质上是一种静态标记语言。你写什么,就输出什么,没有计算、没有逻辑、没有动态内容。写技术文档时,你可能需要在代码块里演示一个函数的运行结果——传统做法是手动写死输出,而 Quarkdown 可以实际执行代码并把结果嵌入文档。
学术写作者面临另一个痛点:写论文需要 LaTeX 的公式能力,但 LaTeX 门槛高、排版复杂。Quarkdown 提供了两全其美的方案——用 Markdown 的简洁语法写作,编译时自动生成符合学术规范的输出。
🔬 二、原理分析
2.1 编译器架构
Quarkdown 的核心是一个基于 Kotlin 的文档编译器。它的工作流程分为三个阶段:
第一阶段:词法分析与语法解析
Quarkdown 源文件(.qmd)首先被送入词法分析器(Lexer),将文本流切分为 Token 序列。然后语法分析器(Parser)根据 Quarkdown 的语法规则构建抽象语法树(AST)。这个 AST 保留了文档的完整结构信息:标题、段落、代码块、公式、函数调用、扩展块等。
第二阶段:语义处理与执行 解析完成后,编译器遍历 AST,对不同节点执行相应的处理逻辑:
- 普通文本节点 → 直接输出
- 代码块节点 → 调用对应的解释器执行
- 函数调用节点 → 解析参数并调用 Kotlin 函数
- 扩展块 → 进入专门的处理流程(图表、公式、交互组件等)
第三阶段:输出生成 处理完语义后,编译器根据目标格式(HTML、PDF、PPT 等)选择对应的渲染器(Renderer),将处理结果转换为最终输出。
2.2 函数调用机制
Quarkdown 最强大的特性之一是函数调用。在文档中,你可以这样写:
@fun myFunction(arg1, arg2) {
// Kotlin 代码
}然后在正文中调用:
@myFunction("hello", 42)编译器会执行这段 Kotlin 代码,并将结果插入文档。这个机制的精妙之处在于:函数定义和调用都在同一个 .qmd 文件里,不需要额外的构建脚本,不需要配置文件——文档本身就是可执行的程序。
2.3 Turing-complete 扩展系统
Quarkdown 的扩展块(Extension Blocks)让文档拥有了真正的编程能力。一个扩展块以 @ 开头,后面跟着扩展名称和代码体:
@ExtensionName {
// 扩展代码
}常见的扩展包括:
@Chart— 生成交互式图表@Plot— 数据可视化@Include— 嵌入外部文件@Eval— 动态求值表达式
这些扩展不是模板替换,而是真正在编译器内部执行 Kotlin 代码。由于 Kotlin 本身是图灵完备的,Quarkdown 的扩展系统也因此获得了图灵完备性——理论上可以用 Quarkdown 文档完成任何可计算的文档处理任务。
2.4 多格式输出原理
不同输出格式的生成依赖于渲染器抽象。编译器定义了统一的渲染接口(Renderer Interface),每种输出格式都有对应的实现:
HtmlRenderer— 生成静态 HTML,适合网站和博客PdfRenderer— 生成 PDF,通过 LaTeX 中转实现高质量排版PptxRenderer— 生成 PowerPoint 幻灯片DocxRenderer— 生成 Microsoft Word 文档
这种架构设计让新增输出格式变得简单——只需要实现一个新的 Renderer,不需要改动核心编译器。
🏗️ 三、架构设计
3.1 模块划分
Quarkdown 编译器的代码库大致分为以下几个模块:
quarkdown/
├── compiler/ # 核心编译器
│ ├── lexer/ # 词法分析
│ ├── parser/ # 语法分析
│ ├── ast/ # 抽象语法树定义
│ ├── evaluator/ # 语义处理与执行
│ └── renderer/ # 多格式渲染
├── extensions/ # 官方扩展实现
│ ├── chart/ # 图表扩展
│ ├── plot/ # 绘图扩展
│ └── include/ # 文件嵌入
└── cli/ # 命令行工具这种模块化设计的优势在于关注点分离:编译器核心不依赖任何特定扩展,扩展是独立开发的。这意味着社区可以自由地为 Quarkdown 开发新的扩展,而不需要深入编译器内核。
3.2 插件系统
Quarkdown 支持插件(Plugins),允许第三方扩展编译器的功能。插件机制基于 Java 的 ServiceLoader 实现,遵循以下约定:
- 插件在
META-INF/services目录下声明实现类 - 编译器启动时扫描所有插件
- 插件通过实现特定接口来注册新的扩展和渲染器
3.3 编译上下文
编译器维护一个编译上下文(Compile Context),贯穿整个编译过程。这个上下文包含:
- 环境变量 — 定义了可在文档中访问的函数和数据
- 资源管理器 — 管理图片、数据文件等外部资源的加载
- 日志记录器 — 记录编译过程中的警告和错误
- 输出目标 — 指定输出格式和输出路径
编译上下文的生命周期从编译开始到结束,所有处理阶段都共享同一个上下文实例,确保状态一致性。
📦 四、安装与使用
4.1 环境要求
- JDK 17 或更高版本
- Gradle(构建工具,项目中包含 Gradle Wrapper)
- 支持 macOS、Linux、Windows
4.2 安装步骤
方式一:从源码编译
# 克隆仓库
git clone https://github.com/iamgio/quarkdown.git
cd quarkday
# 编译(自动下载 Gradle Wrapper)
./gradlew build
# 安装 CLI 工具
./gradlew installDist方式二:使用已发布的 JAR
从 GitHub Releases 页面下载最新的 quarkdown.jar,然后通过 Java 直接运行:
java -jar quarkday.jar --help方式三:集成到 Gradle 项目
如果你想在现有 Kotlin/Gradle 项目中使用 Quarkdown 编译器,可以添加依赖:
// build.gradle.kts
plugins {
id("io.github.iamgio.quarkdown") version "最新版本"
}
quarkdown {
outputFormat.set("html")
outputDir.set(layout.buildDirectory.dir("docs"))
}4.3 基本使用
创建一个 .qmd 文件,比如 hello.qmd:
# 我的第一篇 Quarkdown 文档
这是一段普通文本。
@Chart {
type: bar
data: [10, 20, 30, 40]
labels: ["A", "B", "C", "D"]
}
下面是一个函数调用:
@Eval { 2 + 3 * 4 } @[输出结果]编译为 HTML:
./quarkdown hello.qmd --output ./output --format html编译为 PDF:
./quarkdown hello.qmd --output ./output --format pdf4.4 生成幻灯片
Quarkdown 支持将文档编译为 PowerPoint 幻灯片。约定每个一级标题(#)生成一张新幻灯片,二级标题(##)生成子标题:
# 第一张幻灯片
这是第一张的内容
# 第二张幻灯片
这是第二张的内容./quarkdown presentation.qmd --output ./slides --format pptx💻 五、代码示例
5.1 基础函数定义与调用
# 函数调用示例
定义一个加法函数:
@fun add(a: Int, b: Int): Int {
return a + b
}
调用结果:@add(3, 5) @[]编译后,@[...] 标记的位置会被函数执行结果替换。
5.2 数据可视化
# 数据图表
@Plot {
title: "月度销售额"
type: line
data: [120, 132, 101, 134, 90, 230, 210]
xAxis: ["1月","2月","3月","4月","5月","6月","7月"]
color: "#4A90E2"
}5.3 数学公式(学术写作)
Quarkdown 支持 LaTeX 风格的数学公式渲染:
# 学术论文示例
设有一函数 $f(x) = \sum_{i=0}^{n} x_i^2$,其中:
$$
\frac{\partial f}{\partial x_i} = 2x_i
$$
上述偏导数说明了梯度下降中每个维度的更新方向。5.4 包含外部文件
# 代码示例
@Include(file="src/main/kotlin/Example.kt", lang="kotlin")5.5 条件渲染
@fun renderBadge(version: String) {
if (version == "stable") {
return "✅ 稳定版"
} else {
return "🚧 开发版"
}
}
当前版本:@renderBadge("stable") @[]📚 六、适用场景与局限性
6.1 最佳使用场景
- 技术博客与文档:需要嵌入可运行的代码示例、动态图表
- 学术论文:追求 LaTeX 质量但希望降低写作门槛
- 幻灯片制作:技术人员不想学 PowerPoint,但又需要做演示
- 知识库建设:需要输出多种格式(网站、PDF、PPT)的内容团队
- 数据报告:需要嵌入动态数据可视化的定期报告
6.2 当前局限性
- 生态尚在早期:相比 Pandoc、LaTeX 等成熟工具,插件和模板社区较小
- JVM 依赖:需要在机器上安装 JDK 17+,对于纯前端项目可能偏重
- PDF 输出依赖 LaTeX:若要生成 PDF,需要系统安装 LaTeX 环境
- 调试体验:文档内的函数出错时,错误信息可读性还有提升空间
🚀 七、快速上手建议
如果你想尝试 Quarkdown,建议从以下路径开始:
- 克隆官方示例仓库,运行几个现成的
.qmd文件感受一下输出效果 - 从一个小型幻灯片开始,体验"写 Markdown 出幻灯片"的效率提升
- 尝试嵌入代码块,感受"文档即程序"的编程式写作体验
- 阅读源码,特别是
compiler/evaluator模块,理解函数调用的执行机制
Quarkdown 代表了一种新的文档写作理念——文档不是静态文本,而是可执行的程序。对于需要频繁输出多格式技术文档的团队和个人,这是一条值得探索的技术路线。
相关资源:
- GitHub:iamgio/quarkdown
- 官方文档:项目 README 中的 Quick Start