目录

Quarkdown:Markdown 的超能力进化,从想法到论文、演示、知识库的全流程工具

Quarkdown:Markdown 的超能力进化,从想法到论文、演示、知识库的全流程工具

📖 一、项目概述

1.1 Quarkdown 是什么

Quarkdown 是一个基于 Kotlin 构建的 Markdown 扩展语言,它的口号是"Markdown with superpowers"。与普通 Markdown 不同,Quarkdown 远不止是纯文本标记语法——它是一个完整的文档编译系统,能够将一份源文件编译成书籍、学术论文、幻灯片、网站和知识库等多种输出格式。

如果你厌倦了在 Markdown 里写代码示例却无法运行,想要在文档里调用函数、处理数据、生成图表,那 Quarkdown 正是为你设计的。它的扩展机制图灵完备(Turing-complete),意味着你可以在文档里写真正的程序逻辑。

1.2 核心数据

指标数值
Stars8,000+ ⭐
语言Kotlin 94.4%, Qotlin 4.4%
最新版本持续活跃开发中
许可证GPL v3
GitHubiamgio/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 实现,遵循以下约定:

  1. 插件在 META-INF/services 目录下声明实现类
  2. 编译器启动时扫描所有插件
  3. 插件通过实现特定接口来注册新的扩展和渲染器

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 pdf

4.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,建议从以下路径开始:

  1. 克隆官方示例仓库,运行几个现成的 .qmd 文件感受一下输出效果
  2. 从一个小型幻灯片开始,体验"写 Markdown 出幻灯片"的效率提升
  3. 尝试嵌入代码块,感受"文档即程序"的编程式写作体验
  4. 阅读源码,特别是 compiler/evaluator 模块,理解函数调用的执行机制

Quarkdown 代表了一种新的文档写作理念——文档不是静态文本,而是可执行的程序。对于需要频繁输出多格式技术文档的团队和个人,这是一条值得探索的技术路线。


相关资源: