Implementing your own reader

不用 @rho/md 库——直接从 Rho format spec 自己实现 reader。 适合:非 JS 生态(Python / Go / Rust / Swift)/ 想完全 license 自由(避开 PolyForm)/ 跟现有 reader 深度整合(Obsidian plugin / Vim plugin / etc.)。


为什么自己实现

你想…… 适合自实现?
装到 Obsidian / Bear / Typora 这类已有 reader ✅ 自实现(plugin 形式)
在 Python / Go / Rust 生态用 ✅ 自实现(@rho/md 是 JS 包)
完全避开 PolyForm Noncommercial license ✅ 自实现(spec 是 CC BY 4.0,自实现的 license 你选)
集成到 web 项目 ❌ 直接用 @rho/md(除非有特殊需求)
手写 markdown 工具学习 ✅ 自实现(学习目的)

法律 / License

  • Spec 是 CC BY 4.0 —— 你可以自由实现,不需要联系 scos-lab
  • 你的实现license 你定 —— 自由选 MIT / Apache / 商业 / 闭源
  • 唯一要求:在你的 reader 文档 / 关于页保留 attribution:"Implements Rho format spec by scos-lab"

你不能把"Rho" / "Rho format" 当 trademark 用宣传——但可以说"compatible with Rho" / "supports Rho format documents"。


实现需要的核心组件

按重要性排序:

1. Markdown parser(任何标准 CommonMark / GFM 实现)

不需要从零写——用现有 markdown parser:

  • Python: markdown / mistune / markdown-it-py
  • Go: blackfriday / goldmark
  • Rust: pulldown-cmark / comrak
  • Swift: swift-markdown / Down
  • C: cmark / md4c

需要支持:

  • Standard CommonMark
  • GFM tables / strikethrough / task lists
  • Fenced code blocks(含 lang label)
  • Blockquotes
  • 最好支持 directive containers (:::xxx);不支持的话需自己 parse

2. Rho DSL 解析器(你自己写)

按 spec 解析:

  • > [!TYPE] blockquote → callout
  • ```layout grid cols=N + :::card → layout
  • ```tabs + :::tab → tabs
  • ```stepper + :::step → stepper
  • ```modal + 内容 → modal
  • ```timeline + :::event → timeline
  • ```annotate + 正文 + --- + 标注表 → annotate
  • ```stl → STL syntax highlighting
  • ```interact + sliders/templates/computed/timer → interact

每个 DSL 输出marker class HTML(参考 Remark plugins)。

3. Inner processor(嵌套支持)

容器型 DSL(layout / tabs / stepper / modal / timeline / callout)的内容需要再跑一次完整 pipeline——参考 Inner processor.

最简实现:递归调用同一个 parser 函数,处理 inner content。

4. CSS(你自己写或借用 Rho 的)

你可以:

  • 完全自己写 CSS(参考 CSS class hooks)
  • 借用 @rho/md 的默认 CSS 文件(CC BY 4.0 文档不包括 CSS 实现 license——CSS 是 PolyForm Noncommercial。借用前请独立检查 license)
  • 或自己设计完全不同的 visual

5. Hydration(如果是 web/客户端 reader)

把静态 HTML 变成可交互组件:

  • Tabs / Stepper / Modal —— DOM event listeners
  • Interact controls —— form elements + reactive update
  • Vega-Lite chart —— 集成 vega-embed 库(任何语言都可调)
  • SVG scenes —— 内置 mini DSL evaluator(或借用现有 expression parser)
  • Timer —— setInterval / 等价的 schedule

非 web reader(如 Obsidian plugin)—— 在 Obsidian 的 view 系统里实现等价功能。

6. Mini DSL evaluator(interact 表达式)

Rho 的 mini DSL:+ - * / % ** == != < > <= >= && || ! ?: pow sqrt abs min max sin cos tan log exp pi e ...

实现选项:

  • 自己写 parser + tree-walking interpreter(~300 行)
  • 用现有表达式 lib:
    • JS: 自定义(不要用 eval!)
    • Python: simpleeval
    • Go: expr
    • Rust: evalexpr

⚠️ 关键:mini DSL 必须是纯函数 + 安全——不能 IO / 网络 / 状态修改 / eval。这是 Rho 的安全立场。

7. SVG sanitizer(用 svg template 时)

剥离危险元素 / 属性:

  • <script>, <foreignObject>
  • on* 事件属性
  • href 含 javascript:
  • 外部 URL <image href="external://...">

实现:

  • JS: 用 DOMParser + 白名单过滤
  • Python: nh3 / bleach
  • Rust: ammonia

推荐实现步骤

Step 1: 跑通 standard markdown (0.5 天)
   - 选 markdown parser
   - 让它正常输出 HTML

Step 2: 加 Callout 支持(0.5 天)
   - parse > [!TYPE] blockquote
   - 输出 marker class HTML

Step 3: 加 Layout grid + cards(1 天)
   - parse ```layout fenced + :::card directive
   - CSS Grid 布局

Step 4: 加其他静态 DSL(1 天)
   - Annotate / Timeline / STL syntax highlight

Step 5: 加交互结构 DSL(2 天)
   - Tabs / Stepper / Modal
   - 各自 hydration

Step 6: 加 interact 基础(2 天)
   - sliders / inputs / template stl
   - mini DSL evaluator

Step 7: 加 computed + namespace 共享(1 天)
   - 派生值 + 拓扑排序
   - 跨块状态共享

Step 8: 加高级 interact(3 天)
   - Vega-Lite chart 集成
   - Timer 自动播放
   - SVG scenes + sanitizer

Step 9: 加 inner processor(嵌套支持)(1 天)
   - 递归 parse

Step 10: Plain-text fallback 测试(0.5 天)
   - 确保 source 在 cat / GitHub 都可读

总计:~13 天人力。


跟 @rho/md 兼容性测试

如果你想宣称"compatible with @rho/md"——跑这个 conformance test pack:

  1. 取一份用 @rho/md 渲染的标准文档(参考 SPEC_v0.0_RENDER_TEST.md)
  2. 用你的 reader 渲染同一文档
  3. 对比输出 HTML(class names、data attributes 应该一致)
  4. 对比交互行为(slider 拖动后输出文本一致)

完整 conformance test pack 计划在 spec v1.0 发布。


已知 / 计划中的实现

Reader 状态 License
@rho/md (官方 JS reference impl) ✅ v0.1 已发布 PolyForm Noncommercial
markview desktop app (Tauri 2 + React) 🔨 v1.0 binary 准备中 PolyForm Noncommercial
cloud.rho.md (SaaS) 🔨 MVP 建设中 闭源 SaaS
Obsidian plugin 🔮 community contribution welcome 自定
Bear plugin 🔮 community contribution welcome 自定
Python python-rho 🔮 (待社区实现) 自定
Rust rho-rs 🔮 (待社区实现) 自定
Vim plugin 🔮 (待社区实现) 自定

社区实现欢迎 PR / issue 到 scos-lab/markview(仓库后续 rename)反馈兼容性问题。


See also