@linloir/limr 0.1.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.en.md +151 -0
  2. package/README.md +80 -127
  3. package/benchmarks/results/layout.json +2593 -0
  4. package/benchmarks/results/markstream-code.json +1823 -0
  5. package/benchmarks/results/markstream-reading-repeat.json +1152 -0
  6. package/benchmarks/results/markstream.json +12486 -0
  7. package/benchmarks/results/streaming-browser.json +77 -0
  8. package/benchmarks/results/streaming.json +357 -0
  9. package/dist/base.css +93 -10
  10. package/dist/{chunk-7JF5HHVF.js → chunk-BG5QUQFR.js} +340 -72
  11. package/dist/chunk-BG5QUQFR.js.map +1 -0
  12. package/dist/chunk-BVHHOVMT.js +179 -0
  13. package/dist/chunk-BVHHOVMT.js.map +1 -0
  14. package/dist/chunk-FJZCQY2S.js +155 -0
  15. package/dist/chunk-FJZCQY2S.js.map +1 -0
  16. package/dist/chunk-FSI5OTBW.js +1 -0
  17. package/dist/{chunk-ETHLPBKQ.js → chunk-GU2RPESF.js} +238 -131
  18. package/dist/chunk-GU2RPESF.js.map +1 -0
  19. package/dist/{chunk-65V5OZ4G.js → chunk-SUAAUGAX.js} +1350 -511
  20. package/dist/chunk-SUAAUGAX.js.map +1 -0
  21. package/dist/core/index.d.ts +6 -3
  22. package/dist/core/index.js +15 -5
  23. package/dist/extensions/index.d.ts +30 -5
  24. package/dist/extensions/index.js +15 -3
  25. package/dist/index.d.ts +4 -4
  26. package/dist/index.js +31 -8
  27. package/dist/{engine-43u8B4yt.d.ts → knuth-plass-C8mgFm7W.d.ts} +67 -1
  28. package/dist/knuth-plass-layout-CHQCWKB5.js +449 -0
  29. package/dist/knuth-plass-layout-CHQCWKB5.js.map +1 -0
  30. package/dist/react/index.d.ts +7 -5
  31. package/dist/react/index.js +7 -3
  32. package/dist/styles.css +93 -10
  33. package/dist/{translations-BliabrPd.d.ts → translations-BXzSwLBJ.d.ts} +49 -4
  34. package/docs/README.md +13 -0
  35. package/docs/api.md +5 -158
  36. package/docs/assets/rendered.svg +9 -0
  37. package/docs/assets/source.svg +9 -0
  38. package/docs/en/README.md +28 -0
  39. package/docs/en/ai-skills.md +57 -0
  40. package/docs/en/annotations.md +86 -0
  41. package/docs/en/api.md +115 -0
  42. package/docs/en/architecture.md +41 -0
  43. package/docs/en/extensions.md +208 -0
  44. package/docs/en/getting-started.md +69 -0
  45. package/docs/en/integration.md +154 -0
  46. package/docs/en/modules.md +84 -0
  47. package/docs/en/performance.md +93 -0
  48. package/docs/en/plugin-packages.md +68 -0
  49. package/docs/en/styles.md +99 -0
  50. package/docs/en/syntax.md +455 -0
  51. package/docs/extensions.md +5 -306
  52. package/docs/implementation.md +5 -76
  53. package/docs/performance.md +5 -81
  54. package/docs/screenshots/blocks.png +0 -0
  55. package/docs/screenshots/dark.png +0 -0
  56. package/docs/screenshots/desktop.png +0 -0
  57. package/docs/screenshots/plugin-mobile.png +0 -0
  58. package/docs/styles.md +5 -100
  59. package/docs/visual-upgrade.md +5 -145
  60. package/docs/zh-CN/README.md +28 -0
  61. package/docs/zh-CN/ai-skills.md +57 -0
  62. package/docs/zh-CN/annotations.md +86 -0
  63. package/docs/zh-CN/api.md +115 -0
  64. package/docs/zh-CN/architecture.md +41 -0
  65. package/docs/zh-CN/extensions.md +210 -0
  66. package/docs/zh-CN/getting-started.md +69 -0
  67. package/docs/zh-CN/integration.md +154 -0
  68. package/docs/zh-CN/modules.md +84 -0
  69. package/docs/zh-CN/performance.md +93 -0
  70. package/docs/zh-CN/plugin-packages.md +68 -0
  71. package/docs/zh-CN/styles.md +99 -0
  72. package/docs/zh-CN/syntax.md +457 -0
  73. package/examples/notes.tsx +18 -11
  74. package/examples/packages/paper-theme/index.css +25 -0
  75. package/examples/packages/paper-theme/package.json +7 -0
  76. package/examples/packages/reading-tools/index.d.ts +2 -0
  77. package/examples/packages/reading-tools/index.js +25 -0
  78. package/examples/packages/reading-tools/package.json +16 -0
  79. package/package.json +17 -5
  80. package/skills/limr-plugin-development/SKILL.md +22 -0
  81. package/skills/limr-plugin-development/agents/openai.yaml +4 -0
  82. package/skills/limr-plugin-development/assets/plugin-template/README.md +30 -0
  83. package/skills/limr-plugin-development/assets/plugin-template/package.json +36 -0
  84. package/skills/limr-plugin-development/assets/plugin-template/src/index.tsx +50 -0
  85. package/skills/limr-plugin-development/assets/plugin-template/src/styles.css +9 -0
  86. package/skills/limr-plugin-development/assets/plugin-template/tsconfig.json +20 -0
  87. package/skills/limr-plugin-development/assets/plugin-template/tsup.config.ts +8 -0
  88. package/skills/limr-plugin-development/references/contract.md +51 -0
  89. package/skills/limr-use/SKILL.md +23 -0
  90. package/skills/limr-use/agents/openai.yaml +4 -0
  91. package/skills/limr-use/references/integration.md +49 -0
  92. package/skills/limr-use/references/syntax.md +20 -0
  93. package/dist/chunk-65V5OZ4G.js.map +0 -1
  94. package/dist/chunk-7JF5HHVF.js.map +0 -1
  95. package/dist/chunk-ETHLPBKQ.js.map +0 -1
  96. package/dist/chunk-V2OG4Y3F.js +0 -1
  97. /package/dist/{chunk-V2OG4Y3F.js.map → chunk-FSI5OTBW.js.map} +0 -0
@@ -0,0 +1,68 @@
1
+ # 插件模块包
2
+
3
+ > 阅读提示:本文包含 LiMR 扩展语法和交互示例。部分内容在 GitHub 等普通 Markdown 阅读器中无法完整展示;前往 [GitHub Pages 文档](https://linloir.github.io/LiMR/#/docs/zh-CN/plugin-packages) 可获得最佳阅读体验。
4
+
5
+ [文档目录](README.md) · [English](../en/plugin-packages.md)
6
+
7
+ 一个插件包导出返回 RendererExtension 的工厂,消费者安装后通过 plugins 追加。插件可同时提供语法、标注、动作和参数,CSS 独立导出。它不需要修改 LiMR 源码。
8
+
9
+ ## 可复制模板
10
+
11
+ 完整模板位于 [plugin-template](../../skills/limr-plugin-development/assets/plugin-template/README.md),包含 TypeScript 源码、类型构建、CSS、package.json 和 tsup 配置。它演示 reading-tip 区块、example:note 卡片和保存选区动作。
12
+
13
+ 安装 LiMR 后,在应用目录执行:
14
+
15
+ ```sh
16
+ mkdir -p packages/limr-reading-tools
17
+ cp -R node_modules/@linloir/limr/skills/limr-plugin-development/assets/plugin-template/. packages/limr-reading-tools/
18
+ cd packages/limr-reading-tools
19
+ npm install
20
+ npm run typecheck
21
+ npm run build
22
+ npm pack
23
+ ```
24
+
25
+ 源码仓库中的对应路径为 skills/limr-plugin-development/assets/plugin-template。替换模板的 @example 包名、扩展名、类型名和动作 ID,再实现业务数据与 UI;模板的 private: true 用于防止示例名被误发布,不影响本地打包。
26
+
27
+ ## 包契约
28
+
29
+ | 字段 | 要求 |
30
+ | --- | --- |
31
+ | type | module |
32
+ | exports["."] | import 指向 ESM,types 指向 .d.ts |
33
+ | exports["./styles.css"] | 插件需要 CSS 时显式导出 |
34
+ | files | 包含构建输出与使用说明 |
35
+ | sideEffects | CSS 使用 ["**/*.css"],避免被构建工具移除 |
36
+ | peerDependencies | @linloir/limr、react;直接依赖 react-dom API 时再声明 react-dom |
37
+ | 构建 external | LiMR、React、react/jsx-runtime,以及使用到的 React DOM 入口 |
38
+
39
+ LiMR 或 React 的第二份内置副本会破坏上下文/Hook 共享。不要打包宿主依赖,不要深度导入 LiMR 内部文件。参数声明合并必须随导出的类型分发。
40
+
41
+ ## 在应用中引入
42
+
43
+ 下方 @example 包来自模板,并未发布到 npm。先安装本地打出的归档;生成文件名以 npm pack 输出为准:
44
+
45
+ ```sh
46
+ npm install ./packages/limr-reading-tools/example-limr-reading-tools-0.1.0.tgz
47
+ ```
48
+
49
+ ```tsx
50
+ import { Reader } from '@linloir/limr';
51
+ import { readingTools } from '@example/limr-reading-tools';
52
+ import '@linloir/limr/styles.css';
53
+ import '@example/limr-reading-tools/styles.css';
54
+
55
+ const plugins = [readingTools({ label: '阅读笔记' })];
56
+
57
+ export function Article({ source }: { source: string }) {
58
+ return <Reader source={source} plugins={plugins} />;
59
+ }
60
+ ```
61
+
62
+ 真实第三方包使用它的包名和 peer 版本约束。改写已存在的默认模块使用 extensions + replaceExtension,不要重复注册同一标签。字体、公式样式、持久化和应用服务仍由宿主配置。
63
+
64
+ ## 验证可分发性
65
+
66
+ 本地类型检查通过后,还需把真实 tgz 安装到独立消费者中:检查公开导入、SSR、CSS 资源、默认模块仍可用和新增交互。支持 React 18/19 的包应分别验证两种宿主。语法插件检查流式结束与一次性解析等价;交互插件检查桌面侧栏、窄屏浮层、键盘、异步取消和两种主题。
67
+
68
+ LiMR 仓库的 [reading-tools](../../examples/packages/reading-tools/index.js) 和 [paper-theme](../../examples/packages/paper-theme/index.css) 是另一组可打包示例。AI 可使用[插件开发 Skill](ai-skills.md),其中的模板可独立复制,引用文件无需依赖本仓库路径。
@@ -0,0 +1,99 @@
1
+ # 样式与字体
2
+
3
+ > 阅读提示:本文包含 LiMR 扩展语法和交互示例。部分内容在 GitHub 等普通 Markdown 阅读器中无法完整展示;前往 [GitHub Pages 文档](https://linloir.github.io/LiMR/#/docs/zh-CN/styles) 可获得最佳阅读体验。
4
+
5
+ [文档目录](README.md) · [English](../en/styles.md)
6
+
7
+ ## 基础样式和主题
8
+
9
+ 默认 CSS 在 `@layer limr` 中,宿主普通 CSS 可覆盖。选择 styles.css(带 Maple)或 styles/base.css(不加载 Maple);公式另加 math.css。
10
+
11
+ ```tsx
12
+ import { Reader } from '@linloir/limr';
13
+ import '@linloir/limr/styles/base.css';
14
+ import './paper.css';
15
+
16
+ export function Paper({ source }: { source: string }) {
17
+ return <Reader source={source} appearance="paper" theme="auto" />;
18
+ }
19
+ ```
20
+
21
+ paper.css 示例:
22
+
23
+ ```css
24
+ [data-limr-appearance='paper'] {
25
+ --limr-font-text: Georgia, 'Noto Serif SC', serif;
26
+ --limr-content-width: 820px;
27
+ --limr-accent: #8b6548;
28
+ }
29
+ [data-limr-appearance='paper'][data-limr-theme='dark'] {
30
+ --limr-accent: #d1ab84;
31
+ }
32
+ ```
33
+
34
+ appearance 会传给 portal 中的浮层/工具栏;不要只用 `.limr-reader .your-selector` 匹配这些元素。theme: auto 通过系统偏好选择内置主题;自定义 auto 深色覆盖还需对应 prefers-color-scheme 媒体规则。独立 CSS 包示例见 [paper-theme](../../examples/packages/paper-theme/index.css)。
35
+
36
+ ## 常用变量
37
+
38
+ | 变量 | 用途 |
39
+ | --- | --- |
40
+ | --limr-font-text / --limr-font-code | 正文 / 代码字体 |
41
+ | --limr-font-size / --limr-line-height | 基础排版 |
42
+ | --limr-font-features | 正文默认 normal,保留中文全角标点;可显式设置 'palt' 1 启用比例标点 |
43
+ | --limr-punctuation-spacing | 默认 space-all,保留连续中文标点的全角空白 |
44
+ | --limr-emphasis-spacing / --limr-list-item-gap | 斜体末尾 / 列表间距 |
45
+ | --limr-text / --limr-heading / --limr-secondary / --limr-muted | 文字层次 |
46
+ | --limr-background / --limr-surface / --limr-border | 背景和边框 |
47
+ | --limr-link / --limr-accent / --limr-selection | 链接、激活、选区 |
48
+ | --limr-content-width / --limr-reader-width | 正文 / 总宽,默认 900px / 1800px |
49
+ | --limr-toc-width / --limr-sidebar-width / --limr-column-gap | 侧栏宽度与列间隔 |
50
+ | --limr-sticky-top | 吸顶偏移 |
51
+ | --limr-reader-bottom-space / --limr-reader-min-height | 短正文高度与底部预留 |
52
+ | --limr-sidebar-padding-inline / --limr-sidebar-reference-gap | 侧栏内容统一留白(10px)和关联区间隔(1px) |
53
+ | --limr-overlay-duration / --limr-overlay-morph-duration | 浮层进退(560ms)和预览/展开转换(480ms) |
54
+ | --limr-overlay-z / --limr-toolbar-z | 浮层层级 |
55
+ | --limr-overflow-fade-size | 溢出渐隐,默认 24px,0px 关闭 |
56
+ | --limr-toolbar-panel-max-height | 工具栏面板高度上限 |
57
+ | --limr-tool-icon-size / --limr-mark-size | 工具图标 / 正文角标尺寸 |
58
+ | --limr-mermaid-max-height | 图表视口最大高度;默认 min(70vh, 36rem) |
59
+ | --limr-mermaid-scrollbar | 图表细滚动条颜色;默认 #87837866 |
60
+
61
+ runtime 测量的 --limr-toolbar-available-height、--limr-toolbar-panel-height、--limr-toc-available-height 是布局输出,不应由主题覆盖。sidebar 的局部颜色通常由 AnnotationType.sidebar 配置提供,见[扩展开发](extensions.md)。
62
+
63
+ ## 字体和资源体积
64
+
65
+ Maple Mono NF CN v7.9 的本地 WOFF2 子集随包分发,衍生字体名为 LiMR Maple Mono NF CN,OFL 许可证随资源提供。unicode-range 和 font-display: swap 限制运行时按需请求,但完整字体资产仍约 31MB,base.css 只避免浏览器加载,不减少 npm 安装体积。
66
+
67
+ 正文不自动加载中文字体;可使用系统回退、自托管或宿主选定的字体服务。Playground 的 Noto Serif SC 是演示项目依赖。不要假定任何字体覆盖所有文字。
68
+
69
+ 默认字体/公式样式不依赖外部 CDN。带哈希的字体资源可由宿主设置长期 immutable 缓存;库无法替服务器设置 HTTP 缓存头。远程图片、视频和插件请求由内容和宿主决定。
70
+
71
+ ## 布局与交互约定
72
+
73
+ 同步侧栏的高度由阅读区域决定,不能用所有卡片总高撑大页面。模块只控制自己的内容,骨架负责灰色关联区、摘要与卡片外壳;避免重复 padding 或空段落补偿。大卡片从预览位置过渡,减少动态效果设置会关闭动画。
74
+
75
+ 密集的文末引用在静止时向上借用空余空间。悬浮或激活时优先对齐当前条目,允许邻项在边缘裁切;角标悬浮时可压缩可选摘要,为关联区和标题留出空间。展开内容受可见阅读区域高度限制,并可在卡片内滚动。侧栏条目即使被向上收拢,也会反向对齐正文。取消激活后按当前卡片高度平滑回位,使用 `--limr-motion-slow` 和 `--limr-ease`,保持卡片间距与页面高度。
76
+
77
+ 选区保留原生浏览器范围与键盘行为,绘制层只计算可见片段。代码支持局部高亮,公式整体选择,图片高亮使用边框。单个整块选区的工具栏定位在块下方。打印隐藏绘制层并保留正文。移动端自动化检查不等于 iOS/Android 原生拖动手柄和真机验收。
78
+
79
+ 选区工具栏的复制反馈使用淡入淡出与轻微缩放。按钮文字宽度随当前状态增长或收缩,均通过 `--limr-ease` 非线性过渡;减少动态效果设置会关闭这些过渡。
80
+
81
+ Mermaid 图像支持拖拽平移、触摸和触控板滚动、方向键、Page Up/Down、Home/End,以及 Shift+滚轮横向移动;单击或 Enter 整块选择,拖动不会选中内部文字。缩放仅改变有限高度视口内的内容。共享磨砂工具栏在悬浮或获得焦点时显示,触屏常显;按钮只做背景淡入,不缩放。源码模式保留正常顶部内边距。主题和插件可在 Reader 或图表块上覆盖最大高度与滚动条变量。
82
+
83
+ ## 仅 CSS 的独立主题
84
+
85
+ 包可导出 CSS,files 包含 CSS,sideEffects 为 `["**/*.css"]`;不需要 React 或解析器运行时依赖。规则用独立 appearance 名隔离,覆盖浅色、深色、auto 和 portal,并在同页两个不同主题 Reader 中检查。
86
+
87
+ 展开工具栏面板使用工具栏的全部可用宽度。宽度由当前操作按钮行与可用视口决定,展开内容不参与工具栏的固有宽度计算,不会反向撑大工具栏。高亮样式按钮按文字自然宽度排列,空间不足时整项换行并左对齐。多行下划线需要保持内部 span 为 inline,不把它直接作为 flex 子项。
88
+
89
+ ## 段落排版与流式效果
90
+
91
+ `typography="standard"` 为默认模式;`justify` 使用浏览器两端对齐;`knuth-plass` 使用 TeX 的 box/glue/penalty 动态规划:四种适配类别、整数 badness、独立平方惩罚、连续与末行断词惩罚,以及 pretolerance、tolerance、emergency 多轮求解。整段求最优解,不使用 beam search 或段落长度截断。默认英文断词采用 Knuth–Liang 模式,Unicode 断行规则同时处理中文标点。字形由浏览器测量,因此不承诺与 TeX PDF 逐像素相同。
92
+
93
+ `knuthPlass` 可配置 `pretolerance`、`tolerance`、`linePenalty`、`hyphenPenalty`、`adjacentDemerits`、`doubleHyphenDemerits`、`finalHyphenDemerits`、`emergencyStretch`(CSS 像素)、`looseness` 和 `hyphenate`(`false` 或返回单词分段的函数)。核心段落参数沿用 TeX 常用默认值,额外提供 16px 应急伸展量;浏览器适配器默认按字号换算为 3em,仅参与断行评估,可用 `knuthPlass.emergencyStretch` 显式覆盖。`pretty` / `normal` 保留为可选的旧版 CSS 模式。
94
+
95
+ KP 按需加载,对视口附近的稳定段落排版;离开视口后保留 DOM,宽度变化时复用测量结果与前缀和,更新前保护原生选区。窗口缩小时,屏外缓存行暂时裁切横向溢出,进入视口后完成精确排版;仍被选中的段落暂时允许换行并保留原生选区。流式尾段稳定后再排版,不改变源码、标注位置或复制内容。滚动和缩放对照见[性能](performance.md),算法依据见 [TeX 源码](https://github.com/TeX-Live/texlive-source/blob/trunk/texk/web2c/tex.web)。测量准备与断行分离的设计也参考了 [Typst 的增量排版实现](https://github.com/typst/typst/tree/main/crates/typst-layout/src/inline)。
96
+
97
+ 默认 loading 使用固定 32×32 viewBox、22px 显示尺寸、粗轨道和伸缩弧线;旋转、增长、收缩均为非线性缓动,围绕固定圆心运动,颜色跟随 `--limr-secondary`。新增文字与特殊块只做透明度淡入,不增加背景色,段落结束时不再次播放出现动画。插件可用 `streaming.effect` 替换共享动画,Reader 可用 `streamEffect` 单独覆盖。
98
+
99
+ 源码高亮的默认蓝色由 `--limr-inline-highlight` 控制,也可通过 `inlineHighlights({ color })` 替换模块。默认只读工具栏的说明可用 `locale.inlineHighlightHint` 本地化。
@@ -0,0 +1,457 @@
1
+ # 默认语法
2
+
3
+ > 阅读提示:本文包含 LiMR 扩展语法和交互示例。部分内容在 GitHub 等普通 Markdown 阅读器中无法完整展示;前往 [GitHub Pages 文档](https://linloir.github.io/LiMR/#/docs/zh-CN/syntax) 可获得最佳阅读体验。
4
+
5
+ [文档目录](README.md) · [English](../en/syntax.md)
6
+
7
+ **模块**是为 LiMR 增加一组能力的配置对象,例如公式、视频或引用。下面的“创建函数”在应用代码中调用,返回模块对象;“模块名”是对象的 `name` 字段,用于替换和移除;“标签 / 指令”才是写在 Markdown 正文中的语法。完整概念和配置方式见[内置模块](modules.md)。
8
+
9
+ `@linloir/limr` 随包提供以下默认模块。`Reader`、独立 `Markdown` 和 `DocumentProvider` 默认通过 `standard()` 全部启用;纯核心 `createDocument()` 默认只有 CommonMark。下面每节给出源码和实际效果,交互示例由 LiMR 自己渲染。
10
+
11
+ ## 模块清单
12
+
13
+ | 创建函数(应用代码) | 模块名(name) | 默认能力 | 注册的特殊标签 / 指令 |
14
+ | --- | --- | --- | --- |
15
+ | `gfm()` | `gfm` | 表格、删除线、任务列表、自动链接、标准脚注 | `::gfm` |
16
+ | `math()` | `math` | 行内与块级公式 | `$…$`、`$$…$$`、`::math` |
17
+ | `codeHighlight()` | `code-highlight` | Shiki 围栏代码高亮 | 标准代码围栏、`::code` / `::code-highlight` |
18
+ | `definition()` | `definition` | 释义 | 标签 / 指令 `definition`、`title`、`content` |
19
+ | `question()` | `question` | 练习题与答案 | 标签 / 指令 `question` 及下文子标签 |
20
+ | `extras()` | `extras` | 拓展阅读 | 标签 / 指令 `extras`、`extra` |
21
+ | `video()` | `video` | 原生视频、YouTube、Bilibili | 标签 / 指令 `video`、`md-video` |
22
+ | `figures()` | `figures` | 图组与图注 | 标签 / 指令 `figures`、`figure`、`figcaption`、`caption`、`img` |
23
+ | `citation()` | `citation` | 引用定义与角标 | 标签 / 指令 `citation`、`ref` |
24
+ | `translations()` | `translations` | 原文、译文与对照 | 标签及指令 `translations`、`origin`、`translation` |
25
+ | `mermaid()` | `mermaid` | 流程图等 Mermaid 图表 | Mermaid 围栏、`::mermaid` |
26
+ | `callout()` | `callout` | 有类型、标题、折叠状态的注释块 | `> [!type]`、`::callout` |
27
+ | `inlineHighlights()` | `inline-highlights` | 源码内嵌高亮 | `==文字==`、`::highlight` |
28
+ | `footnotes()` | `footnotes` | 评论角标和脚注卡片 | `[^id]`、`^[正文]`、`::footnote`、`::footnote-ref` |
29
+
30
+ 这些是 Markdown 中允许的静态标签,不是任意 MDX/HTML 执行环境。使用字符串属性,如 `multi="true"`、`answer="[0,2]"`;不要使用 `answer={[0,2]}`、事件函数或展开属性。未注册 HTML 按文本显示;表达式不执行并可能产生诊断。嵌套块的标签和正文之间保留空行。
31
+
32
+ ## CommonMark 与 GFM
33
+
34
+ ````markdown
35
+ # 标题
36
+
37
+ **粗体**、*斜体*、~~删除线~~、[链接](https://example.com)、`行内代码`。
38
+
39
+ > 引用块,默认界面标题为 Note / 注释。
40
+
41
+ - 普通列表
42
+ - [x] 已完成
43
+ - [ ] 未完成
44
+
45
+ | 名称 | 说明 |
46
+ | --- | --- |
47
+ | LiMR | Markdown renderer |
48
+
49
+ ```typescript
50
+ const value = 42;
51
+ ```
52
+
53
+ 标准脚注[^note]。
54
+
55
+ [^note]: 以角标和侧栏 / 窄屏卡片显示的脚注内容。
56
+ ````
57
+
58
+ 实际效果(可交互):
59
+
60
+ #### 标题示例
61
+
62
+ **粗体**、*斜体*、~~删除线~~、[链接](https://example.com)、`行内代码`。
63
+
64
+ > 引用块,默认界面标题为 Note / 注释。
65
+
66
+ - 普通列表
67
+ - [x] 已完成
68
+ - [ ] 未完成
69
+
70
+ | 名称 | 说明 |
71
+ | --- | --- |
72
+ | LiMR | Markdown renderer |
73
+
74
+ ```typescript
75
+ const value = 42;
76
+ ```
77
+
78
+ 标准脚注[^syntax-note]。
79
+
80
+ [^syntax-note]: 以角标和侧栏 / 窄屏卡片显示的脚注内容。
81
+
82
+ 默认 `[^note]` 显示脚注角标和卡片;移除 `footnotes` 模块后,GFM 仍可渲染传统文末脚注。图片 `![说明](/image.png)` 由普通 Markdown 支持。原始 HTML 不透传到 DOM;需要自定义外观时注册扩展或覆盖 `components`。
83
+
84
+ ## 公式与代码
85
+
86
+ ```markdown
87
+ 行内公式:$E = mc^2$。
88
+
89
+ $$
90
+ \int_0^1 x^2\,dx = \frac{1}{3}
91
+ $$
92
+ ```
93
+
94
+ 实际效果(可交互):
95
+
96
+ 行内公式:$E = mc^2$。
97
+
98
+ $$
99
+ \int_0^1 x^2\,dx = \frac{1}{3}
100
+ $$
101
+
102
+ 公式需要导入 `@linloir/limr/math.css`;支持通过 `math({ macros, strict })` 配置。代码围栏语言用于 Shiki 高亮。默认接近视口才加载高亮,流式代码等待语法闭合,且原生选区离开代码后再应用高亮;超过默认 100,000 字符、未支持或未在允许列表中的语言保留可读源码。`codeHighlight({ languages, lightTheme, darkTheme, eager, maxLength })` 可配置。
103
+
104
+ ## 释义
105
+
106
+ ```markdown
107
+ <definition title="熵">
108
+
109
+ 表示不确定性的量:$H(X)$。
110
+
111
+ </definition>
112
+ ```
113
+
114
+ 实际效果(可交互):
115
+
116
+ <definition title="熵">
117
+
118
+ 表示不确定性的量:$H(X)$。
119
+
120
+ </definition>
121
+
122
+ 富文本标题和指定正文可以使用子标签:
123
+
124
+ ```markdown
125
+ <definition>
126
+
127
+ <title>**Entropy** / 熵</title>
128
+
129
+ <content>
130
+
131
+ 正文支持 Markdown。
132
+
133
+ </content>
134
+
135
+ </definition>
136
+ ```
137
+
138
+ `title` 属性按文字渲染;富文本用子标签。也可以写 `:::definition{title="熵"}`,以 `:::` 结束。
139
+
140
+ ## 练习题
141
+
142
+ ```markdown
143
+ <question title="哪些是偶数?">
144
+
145
+ <question-content>请选择所有正确选项。</question-content>
146
+
147
+ <question-sel-grp multi="true" answer="[0,2]">
148
+
149
+ <question-sel>2</question-sel>
150
+
151
+ <question-sel>3</question-sel>
152
+
153
+ <question-sel>4</question-sel>
154
+
155
+ </question-sel-grp>
156
+
157
+ <question-hint>考虑能否被 2 整除。</question-hint>
158
+
159
+ <question-answer>2 和 4 是偶数。</question-answer>
160
+
161
+ </question>
162
+ ```
163
+
164
+ 实际效果(可交互):
165
+
166
+ <question title="哪些是偶数?">
167
+
168
+ <question-content>请选择所有正确选项。</question-content>
169
+
170
+ <question-sel-grp multi="true" answer="[0,2]">
171
+
172
+ <question-sel>2</question-sel>
173
+
174
+ <question-sel>3</question-sel>
175
+
176
+ <question-sel>4</question-sel>
177
+
178
+ </question-sel-grp>
179
+
180
+ <question-hint>考虑能否被 2 整除。</question-hint>
181
+
182
+ <question-answer>2 和 4 是偶数。</question-answer>
183
+
184
+ </question>
185
+
186
+ 答案索引从 **0** 开始。`multi` 默认关闭;`answer` 可以是 JSON 数组或单个索引的字符串。属性优先读取选择组,其次读取 `question`。提示和答案可以单独展开,有答案索引时支持提交、判分和重试。它不连接 AI,也不创建问答标注。
187
+
188
+ ## 拓展阅读
189
+
190
+ ```markdown
191
+ <extras>
192
+
193
+ <extra title="继续阅读" url="https://example.com/article" desc="背景和补充材料。" />
194
+
195
+ </extras>
196
+ ```
197
+
198
+ 实际效果(可交互):
199
+
200
+ <extras>
201
+
202
+ <extra title="内置模块" url="https://linloir.github.io/LiMR/#/docs/zh-CN/modules" desc="背景和补充材料。" />
203
+
204
+ </extras>
205
+
206
+ `extra` 使用 `title`、`url`、`desc`。链接经过内置 URL 过滤。
207
+
208
+ ## 引用卡片
209
+
210
+ ```markdown
211
+ 一个来源<ref id="a" />,或一组来源<ref ids='["a","b"]' />。
212
+
213
+ <ref id="a">带引用的 **原文**</ref>
214
+
215
+ <citation id="a" title="资料 A" url="https://example.com/a" description="完整的 **Markdown** 说明。" summary="收起时的简短摘要。" />
216
+
217
+ <citation cite-id="b" title="资料 B" url="https://example.com/b" desc="兼容属性名。" />
218
+ ```
219
+
220
+ 实际效果(可交互):
221
+
222
+ 一个来源<ref id="a" />,或一组来源<ref ids='["a","b"]' />。
223
+
224
+ <ref id="a">带引用的 **原文**</ref>
225
+
226
+ <citation id="a" title="资料 A" url="https://example.com/a" description="完整的 **Markdown** 说明。" summary="收起时的简短摘要。" />
227
+
228
+ <citation cite-id="b" title="资料 B" url="https://example.com/b" desc="兼容属性名。" />
229
+
230
+ `citation` 的 ID 读取 `cite-id`,其次 `id`;说明读取 `desc`,其次 `description`。`ref` 读取 `cite-from-ids`、`ids`、`id`,支持 JSON 数组或逗号分隔字符串。定义本身不占正文位置,同一个定义可以被多个角标引用。
231
+
232
+ Citation 默认不提供展开大卡片,点击固定预览;摘要按 `summary → description → 安全 URL → title` 回退,去掉 Markdown 标记。正文显示 `description`,没有时显示 `summary`。悬浮或激活时临时高亮引用所在的最近文本块(段落、标题、列表项或表格单元格),不写入已保存高亮;外部范围标注使用绑定范围。配置与存储见[标注与选区](annotations.md)。
233
+
234
+ ## 图片、图组与图注
235
+
236
+ ```markdown
237
+ <figures columns="2" min-width="220" max-width="560" max-height="480">
238
+
239
+ <figure src="/figures/a.png" alt="实验 A" caption="(a) 实验 A" />
240
+
241
+ <figure id="experiment-b">
242
+
243
+ ![实验 B](/figures/b.png)
244
+
245
+ <figcaption>**(b)** 支持 Markdown 的图注。</figcaption>
246
+
247
+ </figure>
248
+
249
+ <figcaption>图 1 · 两个实验。</figcaption>
250
+
251
+ </figures>
252
+ ```
253
+
254
+ 实际效果(可交互):
255
+
256
+ <figures columns="2" min-width="220" max-width="560" max-height="480">
257
+
258
+ <figure src="../assets/source.svg" alt="实验 A" caption="(a) 实验 A" />
259
+
260
+ <figure id="experiment-b">
261
+
262
+ ![实验 B](../assets/rendered.svg)
263
+
264
+ <figcaption>**(b)** 支持 Markdown 的图注。</figcaption>
265
+
266
+ </figure>
267
+
268
+ <figcaption>图 1 · 两个实验。</figcaption>
269
+
270
+ </figures>
271
+
272
+ `figure` 可独立使用。图片可以来自 `src` / `url` 属性、内部 Markdown 图片或 `<img src="…" alt="…" />`。每个 figure 放一张图;多张图用 figures。图注可用 `caption` 属性或 `figcaption` / `caption` 子标签,富文本使用子标签。`id` 可作为页内链接目标。
273
+
274
+ | 属性 | 默认值 | 说明 |
275
+ | --- | --- | --- |
276
+ | `min-width` / `min-height` | 220 / 120 | 决定何时增加列,窄容器优先适应宽度 |
277
+ | `max-width` / `max-height` | 560 / 480 | 保持比例的图片上限;`none` / `false` 取消上限 |
278
+ | `columns` / `cols` | 自动 | 指定列数,最多 24 |
279
+ | `rows` | 自动 | 未指定列数时由图数推导列数 |
280
+ | `responsive` | true | 容器不足时降低显式列数;false 保留列数 |
281
+ | `gap` | 16 | 图组间距,像素 |
282
+
283
+ 尺寸接受非负数字或 `px`。图组限制由子图继承,子图可以覆盖。对应工厂参数为驼峰命名,例如 `figures({ maxHeight: 360, maxWidth: false })`。图片不变形、不裁切图注。单图复制按钮复制图片 URL;图组复制按钮复制 Markdown 源码,不下载图片二进制。
284
+
285
+ 指令示例:
286
+
287
+ ```markdown
288
+ :::figures{columns="2"}
289
+ ::figure{src="/a.png" caption="A"}
290
+ ::figure{src="/b.png" caption="B"}
291
+ :::
292
+ ```
293
+
294
+ ## 视频
295
+
296
+ ```markdown
297
+ <video src="/demo.mp4" provider="native" title="演示" />
298
+
299
+ <md-video url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" loading="click" />
300
+
301
+ <video url="https://www.bilibili.com/video/BV1xx411c7mD/?p=2" />
302
+ ```
303
+
304
+ `url` 优先于 `src`;`provider` 默认 `auto`,还可以是 `native`、`youtube`、`bilibili`。YouTube 支持 watch、短链接、embed、shorts、live 和起始时间;Bilibili 支持 BV/av 与分 P。支持 `title` 和 `loading`。
305
+
306
+ **默认 `loading="visible"`**:在视口附近 200px 挂载播放器,不自动播放。`click` 等待点击,`eager` 立即挂载。可以用 `video({ loading: 'click' })` 设置模块默认值。平台、网络和嵌入权限仍会影响真实播放;不能把本地 iframe 测试当作远程播放保证。自定义平台通过 `video({ resolveUrl })` 接入。
307
+
308
+ 点击加载的视频示例(点击前不创建播放器):
309
+
310
+ <video url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" loading="click" title="视频示例" />
311
+
312
+ ## 分段译文
313
+
314
+ ```markdown
315
+ <translations default="both">
316
+
317
+ <origin>
318
+
319
+ Original **Markdown**.
320
+
321
+ </origin>
322
+
323
+ <translation>
324
+
325
+ 翻译后的 **Markdown**。
326
+
327
+ </translation>
328
+
329
+ </translations>
330
+ ```
331
+
332
+ 实际效果(可交互):
333
+
334
+ <translations default="both">
335
+
336
+ <origin>
337
+
338
+ Original **Markdown**.
339
+
340
+ </origin>
341
+
342
+ <translation>
343
+
344
+ 翻译后的 **Markdown**。
345
+
346
+ </translation>
347
+
348
+ </translations>
349
+
350
+ `default` 为 `origin`、`translation` 或 `both`,未指定时默认 `origin`(可用工厂 `defaultMode` 改写)。角标依次切换原文、译文、对照;对照时译文在前。流式输入只有一侧时先显示已有内容。模块不提供自动翻译服务。
351
+
352
+ 全局 `parameters.translationMode` 覆盖各块;传 `onTranslationModeChange` 接受角标发出的更改请求,否则全局模式锁定。设回 `undefined` 恢复各块的本地选择。见[项目集成](integration.md)。
353
+
354
+ ## 选择与替换
355
+
356
+ 工具栏创建的高亮存为 annotation;`==高亮==` 由源码定义,只提供复制工具栏。默认模块的全部已注册标签都支持同名 `::` 指令。自定义标签需注册插件。使用完整清单配置或替换默认模块,见[扩展开发](extensions.md)。
357
+
358
+ ## 双冒号组件写法
359
+
360
+ 所有默认模块都支持 [CoMark 的组件写法](https://comark.dev/syntax/components),包括嵌套、标量属性和 Markdown 正文:
361
+
362
+ ```md
363
+ ::definition{title="定义"}
364
+ 支持 **富文本** 的正文。
365
+ ::
366
+
367
+ ::question{title="一道题"}
368
+ ::question-content
369
+ 题目内容。
370
+ ::
371
+ ::question-answer
372
+ 答案内容。
373
+ ::
374
+ ::
375
+ ```
376
+
377
+ 可用名称包括 `gfm`、`definition`、`title`、`content`、`question` 及其已有子标签、`extras`、`extra`、`video`、`md-video`、`figures`、`figure`、`figcaption`、`caption`、`img`、`citation`、`ref`、`translations`、`origin`、`translation`、`code`(别名 `code-highlight`)、`math`、`mermaid`、`callout`、`highlight`、`footnote`、`footnote-ref`。`::code{lang="typescript"}` 与 `::math` 的正文保持字面量。
378
+
379
+ 标准 Markdown 围栏、JSX、单冒号行内指令和原有三冒号容器继续可用。最终文档中没有配对闭合的双冒号行,保留原有 leaf directive 语义。这里兼容的是组件语法,不包含 CoMark 的 YAML 属性、命名插槽和 frontmatter。
380
+
381
+ 流式过程中,半截头部、链接、行内代码/强调/公式符号和表头会暂缓显示;已识别但未闭合的组件携带 `incomplete`,由模块选择 loading 或渐进内容。代码围栏和块公式可在闭合前展示。结束时设置 `streaming={false}` 或调用 `finish()`,恢复普通 Markdown 的最终解释。所有范围始终对应未改写的原始输入。
382
+
383
+ ## Mermaid 图表
384
+
385
+ ````markdown
386
+ ```mermaid
387
+ flowchart LR
388
+ A[开始] --> B{准备好了吗}
389
+ B --> C[继续阅读]
390
+ ```
391
+ ````
392
+
393
+ 也可使用 `::mermaid`。流式闭合前显示 loading,完成后异步加载 Mermaid 并淡入图像。背景与公式块一致,右上角共用圆角工具栏提供复制源码、放大、缩小、源码 / 图像切换。选区、高亮和角标以整张图为单位;源码视图不改变这个原子选择约定。图表使用 Mermaid strict 模式,不执行图中的交互回调。
394
+
395
+ 实际效果:
396
+
397
+ ```mermaid
398
+ flowchart LR
399
+ A[开始] --> B{准备好了吗}
400
+ B --> C[继续阅读]
401
+ ```
402
+
403
+ 图像模式支持拖动平移、方向键、Page Up/Down、Home/End 和滚轮,Shift + 滚轮横向移动;点击或 Enter 整块选择,选区工具栏位于块下方。放大后的内容在最大高度内滚动,`--limr-mermaid-max-height` 默认 `min(70vh, 36rem)`。操作栏“复制”获取图表正文,选区工具栏及浏览器复制保留完整围栏或指令。详见[样式与字体](styles.md)和[整体复制](annotations.md)。
404
+
405
+ ## Callout 与嵌套注释
406
+
407
+ ```markdown
408
+ > [!tip]+ 自定义标题
409
+ > 提示正文。
410
+ >
411
+ > > 普通的嵌套注释。
412
+ > >
413
+ > > > [!warning]- 可折叠的提醒
414
+ > > > 支持 **Markdown**。
415
+ ```
416
+
417
+ 默认类型为 `note`、`abstract`、`info`、`todo`、`tip`、`success`、`question`、`warning`、`failure`、`danger`、`bug`、`example`、`quote`,别名对齐 Obsidian:summary/tldr、hint/important、check/done、help/faq、caution/attention、fail/missing、error、cite。大小写不敏感,未知类型沿用 note 外观。`+` 初始展开,`-` 初始折叠;不写符号时为普通块。另支持 `::callout{type="tip" title="标题" fold="-"}`。
418
+
419
+ 实际效果,可展开内部的提醒:
420
+
421
+ > [!tip]+ 自定义标题
422
+ > 提示正文。
423
+ >
424
+ > > 普通的嵌套注释。
425
+ > >
426
+ > > > [!warning]- 可折叠的提醒
427
+ > > > 支持 **Markdown**。
428
+
429
+ ## 源码高亮与脚注
430
+
431
+ ```markdown
432
+ ==默认蓝色高亮==,点击后只能复制。
433
+
434
+ ==有脚注的高亮==[^note]
435
+
436
+ ==内联脚注==^[这里可以写 **Markdown**。]
437
+
438
+ [^note]: 脚注正文。
439
+
440
+ 脚注的第二段。
441
+ ```
442
+
443
+ 高亮支持内部富文本,转义字符、代码和公式中的 `==` 保持字面量。高亮颜色可由 CSS `--limr-inline-highlight` 或 `inlineHighlights({ color })` 覆盖。工具栏只提供复制按钮和单行提示“Markdown 内嵌高亮,不支持编辑”。
444
+
445
+ 脚注显示圆润评论角标;宽屏为侧栏 item,窄屏为悬浮卡片,标题是“脚注”。紧邻高亮的脚注引用这段高亮,独立脚注引用所在段落;命名脚注可重复引用。`::highlight`、`::footnote{id="note"}` 和 `::footnote-ref{id="note"}` 可表达相同模块的容器形式。移除 `footnotes` 模块可恢复 GFM 的上标和文末脚注。
446
+
447
+ 实际效果,点击高亮或评论角标:
448
+
449
+ ==默认蓝色高亮==,点击后只能复制。
450
+
451
+ ==有脚注的高亮==[^syntax-source-highlight]
452
+
453
+ ==内联脚注==^[这里可以写 **Markdown**。]
454
+
455
+ [^syntax-source-highlight]: 脚注正文。
456
+
457
+ 脚注的第二段。