# 文档总览

从普通正文到 AI 流式回答，用同一个解析与渲染入口。

`@quirekit/incremark-core` 提供基于优化后 Lezer 的增量解析；Vue 3 与 React 19 各自提供阅读组件 `QuireMarkdown`。
直接传入 Markdown 字符串，或不断追加已收到的文本；语法、后置引用和自定义节点使用同一套解析规则。

## 从这里开始

| 你想完成的事 | 入口 |
| --- | --- |
| 在 Vue 中显示 Markdown | [快速开始](/guide/getting-started) |
| 在 React 中显示或流式渲染 Markdown | [React 接入](/guide/react) |
| 接入 AI 响应、处理停止和切换消息 | [流式接入](/guide/streaming) |
| 编辑源码并观察逐字更新 | [Playground](/playground) |
| 换链接、代码块或表格组件 | [自定义组件](/guide/components) |
| 添加业务语法与资源节点 | [自定义语法](/guide/extensions) |
| 显示卡片、表格与折叠 HTML | [HTML 与样式](/guide/html) |
| 在无框架环境解析 | [无框架解析](/guide/headless) |
| 了解与我们早期 Incremark 的区别 | [与 Incremark 比较](/guide/comparison) |

## 看看流式更新

点击开始，后置链接与脚注会在定义到达时更新前面的内容。停止保留已收到的原文。

### reading/stream.vue

```vue
<script setup lang="ts">
import { computed, onBeforeUnmount, ref } from "vue";
import { QuireMarkdown, type QuireMarkdownProps } from "@quirekit/incremark/vue";
import { QuireButton, QuireTypography } from "@quirekit/ui/vue";
import type { ExampleLocale } from "../shared/types";
import { readingSample } from "./sample";

const props = withDefaults(defineProps<{ /** Tutorial language. */ locale?: ExampleLocale }>(), { locale: "zh-CN" });
const content = ref(readingSample(props.locale)), identity = ref(0);
const status = ref<NonNullable<QuireMarkdownProps["status"]>>("complete");
const labels = computed(() => props.locale === "zh-CN"
  ? { start: "开始流式演示", stop: "停止", load: "一次性加载", reading: "流式阅读预览", receiving: "正在接收", stopped: "已停止", complete: "已完成" }
  : { start: "Start streaming", stop: "Stop", load: "Load all", reading: "Streaming reading preview", receiving: "Receiving", stopped: "Stopped", complete: "Complete" });
let timer: ReturnType<typeof setTimeout> | undefined;

/** Cancels the producer independently of QuireMarkdown's parser lifecycle. */
function cancel(): void { if (timer !== undefined) clearTimeout(timer); timer = undefined; }
/** Supplies the authoritative full text after each simulated network chunk; no parser APIs are needed. */
function start(): void {
  cancel(); identity.value++; content.value = ""; status.value = "receiving";
  const source = readingSample(props.locale);
  /** Delivers the next 20 UTF-16 code units, including arbitrary syntax boundaries. */
  function append(): void {
    content.value = source.slice(0, content.value.length + 20);
    if (content.value.length < source.length) timer = setTimeout(append, 30);
    else { timer = undefined; status.value = "complete"; }
  }
  append();
}
/** Retains the exact received prefix when the user stops delivery. */
function stop(): void { cancel(); status.value = "stopped"; }
/** Replaces the message with its complete source and a new resource identity. */
function load(): void { cancel(); identity.value++; content.value = readingSample(props.locale); status.value = "complete"; }
onBeforeUnmount(cancel);
</script>
<template>
  <div class="grid gap-4 p-qk-surface">
    <div class="flex flex-wrap items-center gap-2">
      <QuireButton size="sm" variant="outline" @click="start">{{ labels.start }}</QuireButton>
      <QuireButton size="sm" variant="ghost" :disabled="status !== 'receiving'" @click="stop">{{ labels.stop }}</QuireButton>
      <QuireButton size="sm" variant="ghost" @click="load">{{ labels.load }}</QuireButton>
      <QuireTypography as="span" variant="helper">{{ status === 'receiving' ? labels.receiving : status === 'stopped' ? labels.stopped : labels.complete }}</QuireTypography>
    </div>
    <section :aria-label="labels.reading"><QuireMarkdown :content="content" :identity="String(identity)" :status="status" :locale="locale" /></section>
  </div>
</template>

```

### shared/types.ts

```ts
/** Example host language; independent of the documentation router. */
export type ExampleLocale = "zh-CN" | "en";

```

### reading/sample.ts

````ts
import type { ExampleLocale } from "../shared/types";

/** @param locale - Tutorial language. @returns One source with late definitions, repeated footnotes and an incrementally displayed code block. */
export function readingSample(locale: ExampleLocale): string {
  const chinese = locale === "zh-CN";
  return [chinese ? "## 流式 Markdown" : "## Streaming Markdown",
    chinese ? "先收到正文和[文档][api]引用，定义会在末尾到达。这里重复引用同一脚注[^note]、[^note]。"
      : "The [documentation][api] reference arrives before its definition. This footnote is used twice[^note], [^note].",
    ...Array.from({ length: 6 }, (_, index) => chinese
      ? `第 ${index + 1} 段保留 **强调**、中文与 emoji 🙂。已收到的正文继续可读，后置定义到达时前面的链接会更新。`
      : `Paragraph ${index + 1} keeps **emphasis** and emoji 🙂. Existing text stays readable while late definitions update earlier links.`),
    "```ts\nconst message = 'hello'\nconsole.log(message)\n```",
    chinese ? "[^note]: 脚注正文也使用[文档][api]链接。" : "[^note]: The footnote also links to the [documentation][api].",
    "[api]: https://example.com/docs", "[api]: https://example.com/ignored",
  ].join("\n\n");
}

````

## 当前版本

这是工作区预览版，API 仍在演进，尚未发布到 npm。核心包、Vue 与 React 适配包均使用 **MIT** 许可。
当前提供 core、Vue 与 React；其他框架、remark/rehype 插件兼容和 MDC 模板执行不在当前支持范围。
完整能力见[语法范围](/guide/syntax)，行为与成本见[性能边界](/guide/performance)。
