API reference

@rho/md 全部公开 API surface——build-time exports、runtime exports、辅助工具、类型。


总览

import {
  // === Build-time: Remark plugins ===
  remarkPlugins,            // 数组(7 个 plugin 的合集)
  remarkCallout,
  remarkLayout,
  remarkAnnotate,
  remarkTabs,
  remarkStepper,
  remarkTimeline,
  remarkModal,

  // === Build-time: Inner processor (nested DSL) ===
  registerInnerPlugin,
  registerAllInnerPlugins,
  parseInner,

  // === Runtime: Hydration ===
  hydrateAll,
  renderInteractBlocks,
  renderTabsBlocks,
  renderStepperBlocks,
  renderModalBlocks,

  // === Highlight.js / lowlight grammar ===
  stlLanguage,
} from '@rho/md';

// === CSS ===
import '@rho/md/css';

Build-time API

remarkPlugins

类型:Array<RemarkPlugin>

7 个 Rho remark plugin 组成的数组——一次注册全部最简单:

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import { remarkPlugins } from '@rho/md';

const processor = unified().use(remarkParse);
remarkPlugins.forEach((p) => processor.use(p));

等价于:

processor
  .use(remarkCallout)
  .use(remarkLayout)
  .use(remarkAnnotate)
  .use(remarkTabs)
  .use(remarkStepper)
  .use(remarkTimeline)
  .use(remarkModal);

remarkCallout / remarkLayout / remarkAnnotate / remarkTabs / remarkStepper / remarkTimeline / remarkModal

类型:RemarkPlugin

单独引用每个 remark plugin。每个负责一种 DSL:

Plugin DSL 触发
remarkCallout Callout > [!INFO] blockquote
remarkLayout Layout ```layout grid cols=N fenced block
remarkAnnotate Annotate ```annotate fenced block
remarkTabs Tabs ```tabs fenced block
remarkStepper Stepper ```stepper fenced block
remarkTimeline Timeline ```timeline fenced block
remarkModal Modal ```modal fenced block

Interact / Vega-Lite / SVG / Computed / Timer 不在 remark plugin 列表——它们在 hydration 阶段处理(fenced ```interact 块在 build-time 输出 marker class,runtime 接管)。

详见 Remark plugins.


Build-time: Inner processor

registerInnerPlugin(plugin)

类型:(plugin: RemarkPlugin) => void

把一个 remark plugin 注册给 inner processor——嵌套 DSL 解析时会被调用。

import { registerInnerPlugin, remarkCallout } from '@rho/md';
registerInnerPlugin(remarkCallout);

→ 之后 layout / tabs / stepper 等容器内的 > [!INFO] 才会被识别为 callout。

registerAllInnerPlugins()

类型:() => void

一次注册所有 7 个 plugin。最常用:

import { registerAllInnerPlugins } from '@rho/md';
registerAllInnerPlugins();

集成 @rho/md 时几乎总是要调一次——除非你明确知道不会用嵌套 DSL。

parseInner(content, options?)

类型:(content: string, options?: ParseInnerOptions) => string

供高级用户使用——手动调 inner processor 解析一段嵌套内容。普通集成不需要。

详见 Inner processor.


Runtime: Hydration

hydrateAll(container)

类型:(container: HTMLElement) => void

扫 container 内的所有 Rho marker class,把静态 HTML 变成可交互组件。最常用 hydration API:

import { hydrateAll } from '@rho/md';

const container = document.getElementById('root');
container.innerHTML = await renderRho(markdownSource);
hydrateAll(container);

幂等——多次调用只会 hydrate 一次(每个块标记后续跳过)。

等价于:

renderInteractBlocks(container);
renderTabsBlocks(container);
renderStepperBlocks(container);
renderModalBlocks(container);

renderInteractBlocks(container)

类型:(container: HTMLElement) => void

只 hydrate interact 块(slider / input / select / toggle / button / template / computed / timer / svg / vega-lite)。

适合精细控制 hydration 时机——例如 lazy-load 重 chart:

container.innerHTML = html;
renderTabsBlocks(container);   // 立即 hydrate 静态结构
// ... 用户滚到 chart 时再 ...
renderInteractBlocks(container);

renderTabsBlocks(container) / renderStepperBlocks(container) / renderModalBlocks(container)

类型同上。各自只 hydrate 对应类型的容器。

Layout / Callout / Annotate / Timeline 是纯静态——不需 hydrate,直接 HTML 即可。

详见 Hydration utilities.


Highlight.js / lowlight grammar

stlLanguage

类型:(hljs: HLJSApi) => Language

STL 语法 grammar——给 highlight.js 或 lowlight 用:

highlight.js

import hljs from 'highlight.js';
import { stlLanguage } from '@rho/md';

hljs.registerLanguage('stl', stlLanguage);

// 之后 ```stl 代码块自动 6 色高亮

lowlight (server-side / build-time)

import { common } from 'lowlight';
import { stlLanguage } from '@rho/md';
import rehypeHighlight from 'rehype-highlight';

unified()
  // ... markdown pipeline ...
  .use(rehypeHighlight, {
    plainText: ['mermaid', 'vega-lite', 'vega', 'interact', 'tabs', 'stepper', 'timeline', 'modal', 'layout', 'annotate'],
    languages: { ...common, stl: stlLanguage },
  });

plainText: [...] 数组重要——告诉 rehype-highlight 不要给 Rho 的 fenced block lang label 着色(避免双重处理)。

详见 STL syntax highlighting (writer side).


CSS

import '@rho/md/css'

引入 Rho 的内置 CSS。包含:

  • 所有 DSL 的样式(callout / layout / tabs / stepper / etc.)
  • CSS variables 支持主题化
  • .markdown-body container class(GitHub 兼容惯例)
  • Light + dark theme 支持
import '@rho/md/css';

或:

<link rel="stylesheet" href="path/to/@rho/md/css/stl-md.css">

CSS variables(主题化)

.markdown-body {
  --bg-color: #ffffff;
  --text-color: #1a1a2e;
  --code-bg: #f8f8f8;
  --border-color: #e5e7eb;
  --accent-blue: #2563eb;
  --accent-red: #dc2626;
  --accent-green: #16a34a;
  --accent-yellow: #ca8a04;
  --accent-purple: #9333ea;
  --accent-gray: #6b7280;
}

.markdown-body[data-theme="dark"] {
  --bg-color: #0f1115;
  --text-color: #e8ecf1;
  /* ... */
}

详见 CSS theming.


TypeScript 类型

Public types

import type {
  // Plugin types
  RemarkPlugin,           // 标准 unified plugin signature
  ProcessorOptions,       // 集成层 options

  // Hydration types
  HydrationOptions,       // hydrate 调用的可选 config
  HydrationResult,        // hydrate 返回信息

  // Inner processor
  InnerPluginOptions,
} from '@rho/md';

自定义 hydrate hook

import type { HydrationOptions } from '@rho/md';

const options: HydrationOptions = {
  onBlockHydrated: (block, type) => {
    console.log(`Hydrated ${type} block`, block);
  },
  errorBoundary: (block, error) => {
    console.error('Hydration failed:', error);
    block.innerHTML = '<p>Render error</p>';
  },
};

hydrateAll(container, options);

完整集成 reference

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkGfm from 'remark-gfm';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeHighlight from 'rehype-highlight';
import { common } from 'lowlight';

import {
  registerAllInnerPlugins,
  remarkPlugins,
  hydrateAll,
  stlLanguage,
} from '@rho/md';
import '@rho/md/css';

// === Build-time setup ===
registerAllInnerPlugins();

const processor = unified()
  .use(remarkParse)
  .use(remarkGfm);

remarkPlugins.forEach((p) => processor.use(p));

processor
  .use(remarkRehype, { allowDangerousHtml: true })
  .use(rehypeHighlight, {
    plainText: ['interact', 'tabs', 'stepper', 'timeline', 'modal', 'layout', 'annotate'],
    languages: { ...common, stl: stlLanguage },
  })
  .use(rehypeStringify, { allowDangerousHtml: true });

// === Render ===
async function renderRho(markdown: string): Promise<string> {
  const result = await processor.process(markdown);
  return String(result);
}

// === Browser hydration ===
function mount(container: HTMLElement, html: string) {
  container.innerHTML = html;
  hydrateAll(container);
}

// === 用法 ===
const html = await renderRho('# Hello\n\n> [!INFO]\n> Test');
mount(document.getElementById('root')!, html);

不导出 / 内部 API

⚠️ 以下不是公开 API —— 不要依赖:

  • _internal* 命名的任何东西
  • dist/ 内深路径 import(如 @rho/md/dist/internal/foo)
  • 没在本页文档化的方法

公开稳定 API 只有上面列的那些。


See also