Skip to content

Markdown

@astryxdesign/core v0.7.1 · Markdown

Markdown#

粗体、斜体 和 代码。
  • 标题、列表按设计规范排版
  • 链接自动识别外链
引用也会缩进显示

使用方法 ​

Markdown 把 Markdown 源码渲染成正文。标题、段落、强调、链接、行内代码、代码块、引用、列表、任务列表、表格、分隔线和图片都可以用。表格、删除线和任务列表按 GFM 处理。尖括号里的网址和邮箱一直是链接。裸网址、www. 开头的主机名和裸邮箱,要等 autolink 设为 gfm 才变成链接。句末的标点留在链接外面。

从独立入口导入,结构样式会随组件加载。主题在应用入口引入一次:

ts
import '@astryx-vue/themes/neutral.css'
vue
<script setup lang="ts">
import { Markdown } from '@astryx-vue/core/Markdown'
</script>

<template>
  <Markdown content="## 标题\n\n一段 **说明**。" />
</template>

content 没传时,默认插槽里的文本会当作源码。插槽只读取文本,不接受已经渲染好的节点。

链接会去掉控制字符。javascript:、vbscript: 和 data:text/html 不会变成可点击的地址,只留下链接文字。图片另外拒绝所有 data: 地址。原始 HTML 不会执行,标签会按普通文字显示。

代码块交给已有的 CodeBlock,引用交给 Blockquote,标题交给 Heading,链接交给 Link。列表和表格用语义元素,因为现有的 List 和表格组件是界面控件,不是正文排版。

components 可以换掉某一类节点的渲染。自定义组件通过 props 拿到节点数据,有内容的节点还会收到默认插槽。

components 里放的是组件定义,不需要是响应式的。直接写成普通对象就行。如果放进了 ref() 或 reactive(),Vue 会把组件定义也变成响应式对象,开发模式下控制台会出现 Vue received a Component that was made a reactive object 的警告。渲染结果不受影响,只是多了不必要的开销。要避免它,用下面任意一种:

ts
import { markRaw, ref, shallowRef } from 'vue'

// 普通对象,不包响应式
const components = { paragraph: MyParagraph }

// 需要整体替换时,用 shallowRef(或 shallowReactive)
const swappable = shallowRef({ paragraph: MyParagraph })

// 或者给每个组件套 markRaw,外层再用 ref 也不会警告
const marked = ref({ paragraph: markRaw(MyParagraph) })

plugins 挂在解析之后的语法树上。transform 拿到根节点,返回下一棵树;没有改动时把原来的根返回去,流式渲染才能继续复用已经稳定的块。render 画出 type 为 extension、并且 plugin 等于这个名字的节点。inlinePlugins 只在普通文本里做匹配,pattern 要带 g。列表里靠前的先匹配,同一位置重叠时前面的赢。行内代码和围栏代码不会被碰到。replace 返回替换进去的节点,返回 null 就跳过这次匹配。扩展节点如果带了 name,就由同名插件的 render 来画;返回一个普通的 link 节点时,走原来的链接渲染。

defineMarkdownPlugin 把插件对象原样返回,用来收窄类型。isMarkdownExtensionNode 用来确认一个节点是不是某个插件的扩展节点。

传入 sources 后,正文里的 [id] 和 【id】 会画成引用芯片。citationStyle 默认 label,芯片上是来源标题。设成 number 后变成带序号的小徽章,同一个 id 共用一个序号。

标题会生成可聚焦的锚点,href 指向标题 id,并带有 aria-label。嵌套列表的记号按层循环:无序是圆点、圆圈、方块,有序是数字、小写字母、小写罗马数字。

正文里的字符实体会解码,&amp; 显示成 &,&copy; 显示成 ©。围栏代码里的 &copy; 保持原文。

围栏代码默认折行。一行超过容器宽度时,代码元素带 data-wrapped="true"。

围栏信息是 diff 或 diff-ts 这种时,默认的代码块会打开差异层。换掉 components.code 时,语言字符串仍原样传进去。

markdownSourceLinesPlugin 从 @astryx-vue/core/Markdown/plugins 引入,放进 plugins 后,标题、段落、列表项、引用、代码块外层、表格外层和分隔线会带上 data-source-line 与 data-source-line-end。不传这个插件时没有这些属性。

@astryx-vue/core/Markdown/parser 提供 parseMarkdownAst、parseInlineAst、decodeMarkdownCharacterReferences,以及旧的块列表 parseMarkdown 和行内 parseInline。组件自己用的 parseMarkdown 仍返回语法树根,不返回那份块列表。math: true 不会产生数学节点。parseInlineAst 和 parseInline 只读行内内容:# h 仍是文字,围栏读成一个行内代码。

isStreaming 打开流式模式。内容只在末尾追加时,已经闭合的块保持原来的节点,只重新解析最后一个还没写完的块。新出现的文字用 --astryx-duration-fast-max 淡入。系统开启「减少动态效果」时不播放淡入。

isStreaming 不做逐字平滑。字符级揭示用 useStreamingText,再把返回的字符串交给 content。组件不会把这段字符串再平滑一次。模拟模型输出时,把累积的原文交给 content,并在输出结束前保持 isStreaming 即可。

这一版不渲染数学公式。

解剖

部分说明
文档块级或行内 Markdown 内容的根容器。
标题渲染出的语义标题。自定义标题渲染会换掉内置的这一部分。
段落渲染出的段落。自定义段落渲染会换掉默认的这一部分。
列表由 Markdown 项渲染出的有序、无序或任务列表。
代码块围栏代码块。自定义代码渲染会换掉默认的这一部分。
引用引用块。自定义引用渲染会换掉默认的这一部分。
表格由 Markdown 的行和列渲染出的表格。里面的 Table 负责横向滚动。
分隔线水平线。自定义 hr 渲染会换掉默认的这一部分。
图片块级图片;地址不安全时改为回退。自定义图片渲染会换掉安全情况下的默认图片。

最佳实践 ​

指引实践
推荐用它排模型回复、文档摘录和说明文字。
推荐流式输出时只追加文本,结束时把 isStreaming 设回 false。
推荐需要逐字揭示时,只调用一次 useStreamingText,把结果交给 content。isStreaming 负责分块解析和淡入,不会再平滑。
推荐需要限制行宽时设置 contentWidth。不设置时正文跟容器一样宽。
避免把用户提供的 HTML 塞进源码,指望它被执行。组件会把它当成文字。
避免在 isStreaming 为 true 时整段替换已经显示的内容。缓存按「只追加」设计。

示例 ​

示例和 Astryx Markdown 的 Examples 一一对应,顺序相同。总览卡片用英文短文,不带按钮或状态。

Markdown — Cited Content

Tokyo Overview#

Tokyo is the capital of Japan with a population of over 14 millionTokyo - Wikipedia. It's the most populous metropolitan area in the worldJapan Statistics Bureau - PopulationWorld Population Review.
Key Facts#

紧凑密度,标题从 h3 起。正文里的 [id] 变成引用来源芯片。

Markdown — 序号引用

Tokyo is the capital of Japan1.
The metro area is larger still21.

同一批来源改用序号徽章。同一个 id 再次出现时,序号不变。

Markdown — 插件

a bare URL keeps its trailing period outside the link.

块级插件把 Note 段画成提示,行内插件把 @名字 变成链接,autolink 打开裸网址。

Markdown — Compact AI Response

Design Tokens#

Tokens are the shared language between design and code.
    
typescript
const tokens = {
primary: '#0066FF',
spacing: '8px',
};
  • Composable — small pieces
  • Accessible — built-in a11y
Opinionated enough for consistency, flexible enough for edge cases.

紧凑密度,标题从 h3 起。包含代码块、列表和引用。

Markdown — Data Table

Comparison Table#

FeatureReactVueSvelte
Virtual DOMYesYesNo
Bundle Size~40KB~30KB~2KB
TypeScriptNativePluginNative
Learning CurveMediumEasyEasy

列对齐按 GFM 标记。表头是次要色,只有行分隔线。

Markdown — Rich Content

Markdown Demo#

Renders markdown with Astryx styling.

Features#

Fish & chips © 2026
  • Bold, italic, code
    1. Nested number
      • Nested square
    
typescript
interface User {name: string;}
  • 已完成
    Parser
  • 未完成
    Stories

标题、强调、列表、链接、代码块和任务列表。