@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
package/README.en.md ADDED
@@ -0,0 +1,151 @@
1
+ # LiMR
2
+
3
+ [![package version](https://img.shields.io/badge/version-1.0.1-blue.svg)](package.json)
4
+
5
+ [简体中文](README.md) · **English**
6
+
7
+ **Linloir’s limr Is a Markdown Renderer.** A React Markdown renderer for long documents and streaming output. Body text, navigation, reference cards, selections, and highlights share one document state, and can also be composed into your own interface.
8
+
9
+ [Live Playground](https://linloir.github.io/LiMR/) · [English docs](docs/en/README.md) · [中文文档](docs/zh-CN/README.md) · [AI Skills](docs/en/ai-skills.md)
10
+
11
+ ## Install and use
12
+
13
+ ```sh
14
+ npm install @linloir/limr
15
+ # or pnpm add @linloir/limr
16
+ ```
17
+
18
+ ```tsx
19
+ import { Reader } from '@linloir/limr';
20
+ import '@linloir/limr/styles.css';
21
+ import '@linloir/limr/math.css';
22
+
23
+ const source = '# Start reading\n\nSupports **Markdown** and $E = mc^2$.';
24
+
25
+ export default function Article() {
26
+ return <Reader source={source} />;
27
+ }
28
+ ```
29
+
30
+ Requires React / React DOM **18.3 or 19**, Node.js **20+**, and an ESM-capable build tool. Interactive features target modern browsers; Node SSR is supported. UI labels default to English; pass the exported `chinese` locale for Chinese labels. Import `math.css` when using formulas.
31
+
32
+ Render just the body, or a growing response:
33
+
34
+ ```tsx
35
+ import { Markdown } from '@linloir/limr';
36
+
37
+ export function Answer({ text, generating }: { text: string; generating: boolean }) {
38
+ return <Markdown source={text} streaming={generating} followOutput />;
39
+ }
40
+ ```
41
+
42
+ `source` is the complete accumulated string. Set `streaming` to `false` when generation ends. `followOutput` is off by default and pauses when the reader scrolls up. `Markdown` does not include navigation, a sidebar, or a selection toolbar.
43
+
44
+ ## Capabilities
45
+
46
+ | Scenario | Features |
47
+ | --- | --- |
48
+ | Reading | CommonMark, GFM tables/tasks, math, Shiki code highlighting, Mermaid diagrams |
49
+ | Rich content | Images, figure groups, captions, video, definitions, exercises, nested quotes and Obsidian callouts, citations, original/translated/parallel text |
50
+ | Interaction | Responsive contents, annotation sidebar/overlays, complete atomic copying, four highlight styles, `==highlights==` and footnote cards |
51
+ | Layout and streaming | Standard, Knuth–Plass, justified; incomplete-syntax states, increment fades, stable selections |
52
+ | Integration | Controlled annotations, original UTF-16 offsets, isolated readers, nested scroll containers, SSR |
53
+ | Extensions | Custom syntax, conditional renderer replacement, annotation types, selection actions, streaming effects, parameters, CSS theme packages |
54
+
55
+ Defaults include `citation` and Markdown footnote cards. `highlight` supports editable application annotations; `==text==` creates read-only source highlights. `[^id]` and `^[body]` use comment markers with sidebar/overlay cards, including immediately after highlights. Notes, questions, and chat annotations belong to application plugins; `question()` renders exercises. See the [syntax reference](docs/en/syntax.md).
56
+
57
+ ```markdown
58
+ <definition title="Definition">
59
+
60
+ Use **Markdown** inside custom blocks.
61
+
62
+ </definition>
63
+
64
+ This passage has a source<ref id="paper" />.
65
+
66
+ <citation id="paper" title="Reference" url="https://example.com/paper" summary="Short summary" />
67
+ ```
68
+
69
+ Default modules also support `::` directives: for example, `::definition{title="Definition"}` followed by its body and a standalone closing `::`. Tags and `:::` containers remain supported. Mermaid accepts `mermaid` code fences or `::mermaid`; diagram mode supports zoom, drag panning, and keyboard/wheel navigation.
70
+
71
+ ## Typography and streaming
72
+
73
+ `typography` accepts `standard` (default), `knuth-plass`, or `justify`. KP uses TeX's box/glue/penalty paragraph optimization and Knuth–Liang English hyphenation, caches measurements and prepared breakpoints, and retains typeset nodes while scrolling. Browser font measurements do not guarantee pixel-identical TeX PDF output. The [performance report](docs/en/performance.md) includes Scikit Learn scroll/resize comparisons and measurement boundaries.
74
+
75
+ Streaming defers incomplete syntax markers. Default modules can show loading states, while code and math display usable intermediate content. New text and special blocks fade in through opacity; existing controls and selections stay stable. Plugins can customize `streaming.Loading` and `streaming.effect`; hosts can override the animation with `streamEffect` or disable it with `false`.
76
+
77
+ Formulas and diagrams select as atomic units. Selection-toolbar copying retains their complete original source and delimiters, including both `$` signs around inline math. A single block anchors its toolbar below it; copy feedback and button width use nonlinear transitions. See [annotations and selection](docs/en/annotations.md) and [styles](docs/en/styles.md).
78
+
79
+ ## Composition and extensions
80
+
81
+ `Reader` provides a complete layout. Use `DocumentProvider` with `Markdown`, `TableOfContents`, `AnnotationSidebar`, `AnnotationOverlay`, and `SelectionToolbar` for your own layout. See [application integration](docs/en/integration.md).
82
+
83
+ ```tsx
84
+ import { Reader, defineBlock } from '@linloir/limr';
85
+
86
+ const plugins = [defineBlock({
87
+ name: 'notice',
88
+ component: ({ children }) => <aside className="notice">{children}</aside>,
89
+ })];
90
+
91
+ export function Notice() {
92
+ return <Reader source={'<notice>\n\n**Custom content**\n\n</notice>'} plugins={plugins} />;
93
+ }
94
+ ```
95
+
96
+ `plugins` appends to the defaults. `extensions` replaces the entire list; `extensions={[]}` uses basic CommonMark. Replace a named extension explicitly with `replaceExtension()`. Keep configuration references stable.
97
+
98
+ To replace only a content renderer, use `rendererOverrides` with `type`, `component`, and `when` to restrict by language, ancestors, or streaming state. Host rules take precedence. This scopes rendering rules; it is not a security sandbox for third-party code.
99
+
100
+ Plugins can own the complete card UI (`overlay.Card`), collapsed sidebar summary (`sidebar.Preview`), async loading, and selection actions. Use the [plugin development Skill](skills/limr-plugin-development/SKILL.md) or [package guide](docs/en/plugin-packages.md) to build an installable extension and add it through `plugins`. Examples cover [notes](examples/notes.tsx), a [streaming assistant](examples/assistant.tsx), a [standalone plugin](examples/packages/reading-tools/index.js), and a [CSS theme](examples/packages/paper-theme/index.css). The `@limr-example/*` packages are unpublished local examples.
101
+
102
+ ## AI Skills
103
+
104
+ | Skill | Purpose |
105
+ | --- | --- |
106
+ | [limr-use](skills/limr-use/SKILL.md) | Integrate LiMR, author content, configure interaction, and install existing plugins |
107
+ | [limr-plugin-development](skills/limr-plugin-development/SKILL.md) | Build standalone module packages with a TypeScript / ESM / CSS starter and validation guidance |
108
+
109
+ Skills ship in the npm package and can also be downloaded from this repository. Copy the entire skill directory to keep references and templates together. See [download, installation, and invocation](docs/en/ai-skills.md) for Codex project and user scopes.
110
+
111
+ ## Styles and runtime
112
+
113
+ - `styles.css` includes light/dark styling and local Maple code fonts. `styles/base.css` provides the same styling without loading Maple. Font assets remain in the npm download. Choose one stylesheet.
114
+ - `appearance` scopes CSS themes across the reader and portalled controls. Applications or system fonts supply body typography.
115
+ - Code highlighting, math, Mermaid, and KP load on demand. Mermaid draws on the client; unclosed streamed diagrams show loading first. Video loads near the viewport by default, with a click-to-load option. Remote media may contact its source site.
116
+ - The full DOM remains available for browser search, native selection, and printing. Appends and eligible finalization reuse stable prefixes; definition changes, middle edits, or document-scoped transforms can still require a full parse.
117
+ - Unregistered HTML is displayed as text. Markdown-supplied JavaScript expressions are never executed. Custom renderers own their data and remote requests.
118
+
119
+ See [styles and fonts](docs/en/styles.md), [API](docs/en/api.md), and [performance and limits](docs/en/performance.md).
120
+
121
+ ## Local development
122
+
123
+ ```sh
124
+ pnpm install
125
+ pnpm dev
126
+ pnpm check
127
+ pnpm test:docs
128
+ pnpm exec playwright install chromium
129
+ pnpm test:browser
130
+ ```
131
+
132
+ Local development uses Python 3 to generate downloadable Skill archives. The header switches between Playground and LiMR-rendered, bilingual Docs.
133
+
134
+ Refreshing the Playground restores the default document and standard typography, without automatically restoring the previous document or edits. Save explicitly stores a draft; use Load saved text to reopen it. Language preference is retained separately. The typography dropdown offers all three modes; the streaming demo adds up to five UTF-16 units every 90ms.
135
+
136
+ The local Playground runs at `http://127.0.0.1:4173`. Use `@linloir/limr/core` for parsing without React/DOM. Other entry points are `@linloir/limr/react` and `@linloir/limr/extensions`.
137
+
138
+ ## Build and publish Pages
139
+
140
+ `main` contains source; `pages` contains only generated files. GitHub Pages uses **Deploy from a branch → pages → /(root)**. Pushing `main` does not automatically build the site.
141
+
142
+ ```sh
143
+ pnpm test:docs
144
+ pnpm build:playground
145
+ pnpm preview:playground --port 4174
146
+ # http://127.0.0.1:4174/LiMR/
147
+ ```
148
+
149
+ The output is `demo-dist/`, including `.nojekyll`, bilingual Docs, examples, and updated Skill ZIPs. After verification, sync that directory into a separate `pages` worktree, commit, and push both source and artifact branches. Change the build/preview `--base` when deploying under another repository name. README and docs describe repository source; check your installed npm version's exports/types, or use `pnpm pack` to consume the current source.
150
+
151
+ [MIT License](LICENSE). Developed with Codex.
package/README.md CHANGED
@@ -1,198 +1,151 @@
1
1
  # LiMR
2
2
 
3
- **Linloir’s limr Is a Markdown Renderer.**
3
+ [![package version](https://img.shields.io/badge/version-1.0.1-blue.svg)](package.json)
4
4
 
5
- 一个可以独立使用,也可以组合成完整阅读界面的 React Markdown 渲染包。正文、目录、角注和选区使用同一份文档状态,面向长文阅读和 AI 流式输出。
5
+ **简体中文** · [English](README.en.md)
6
6
 
7
- ## 使用
7
+ **Linloir’s limr Is a Markdown Renderer.** 面向长文阅读和流式输出的 React Markdown 渲染器。正文、目录、引用卡片、选区和高亮共享文档状态,也可以拆开组合到自己的界面中。
8
+
9
+ [在线 Playground](https://linloir.github.io/LiMR/) · [中文文档](docs/zh-CN/README.md) · [English docs](docs/en/README.md) · [AI Skills](docs/zh-CN/ai-skills.md)
10
+
11
+ ## 安装与使用
8
12
 
9
13
  ```sh
10
- pnpm add @linloir/limr
14
+ npm install @linloir/limr
15
+ # 或 pnpm add @linloir/limr
11
16
  ```
12
17
 
13
18
  ```tsx
14
- import { Reader } from '@linloir/limr';
19
+ import { Reader, chinese } from '@linloir/limr';
15
20
  import '@linloir/limr/styles.css';
16
- import '@linloir/limr/math.css'; // 使用公式时导入;字体随包提供
21
+ import '@linloir/limr/math.css';
22
+
23
+ const source = '# 开始阅读\n\n支持 **Markdown** 与 $E = mc^2$。';
17
24
 
18
- <Reader source={markdown} />
25
+ export default function Article() {
26
+ return <Reader source={source} locale={chinese} />;
27
+ }
19
28
  ```
20
29
 
21
- 需要 React 18.3 / 19、现代浏览器和支持 ESM 的构建工具。npm 包名为 `@linloir/limr`;源码可用 `pnpm pack` 构建并生成本地安装包。
30
+ 需要 React / React DOM **18.3 或 19**、Node.js **20+** 和支持 ESM 的构建工具。交互功能面向现代浏览器;支持 Node SSR。默认界面语言为英文,中文界面传入 `chinese`。`math.css` 在使用公式时引入。
22
31
 
23
- 只显示正文:
32
+ 只显示正文,或显示持续生成的回答:
24
33
 
25
34
  ```tsx
26
35
  import { Markdown } from '@linloir/limr';
27
36
 
28
- <Markdown source={markdown} />
29
- // source 是持续增长的完整字符串;生成结束时设为 false。
30
- <Markdown source={answer} streaming={generating} followOutput />
37
+ export function Answer({ text, generating }: { text: string; generating: boolean }) {
38
+ return <Markdown source={text} streaming={generating} followOutput />;
39
+ }
31
40
  ```
32
41
 
33
- `followOutput` 默认关闭。开启后只在用户保持在底部附近时跟随输出。用户向上阅读时暂停跟随。
42
+ `source` 是累计的完整字符串,生成结束时把 `streaming` 设为 `false`。`followOutput` 默认关闭;开启后在读者向上滚动时暂停跟随。`Markdown` 不自带目录、侧栏或选区工具栏。
34
43
 
35
- ## 组件
44
+ ## 支持什么
36
45
 
37
- | 组件 | 职责 |
46
+ | 场景 | 能力 |
38
47
  | --- | --- |
39
- | `Markdown` | 正文、原文坐标、标题和选区信息;不包含工具菜单 |
40
- | `DocumentProvider` | 给组合组件提供同一份文档和交互状态 |
41
- | `Reader` | 开箱即用的响应式组合,窄屏自动使用角注浮层 |
42
- | `TableOfContents` | 固定标题、自动换行、隐藏滚动条、跟随 active 项 |
43
- | `AnnotationSidebar` | 与正文角标对齐的卡片、避让、独立列表或自定义定位 |
44
- | `AnnotationOverlay` | 鼠标预览、点击/触摸展开、键盘退出和焦点恢复 |
45
- | `SelectionToolbar` | 独立的选区操作和自定义 UI 槽位 |
46
- | `AnnotationMarkdown` | 在卡片内复用渲染能力,隔离文档和选区作用域 |
47
-
48
- 例如,在自己的三栏布局里组合:
49
-
50
- ```tsx
51
- <DocumentProvider source={markdown}>
52
- <div className="reading-columns">
53
- <TableOfContents />
54
- <Markdown />
55
- <AnnotationSidebar />
56
- </div>
57
- <AnnotationOverlay />
58
- <SelectionToolbar actions={actions} />
59
- </DocumentProvider>
60
- ```
61
-
62
- `reading-columns` 的样式由应用提供。对齐侧栏和正文应位于**同一个滚动容器**,侧栏保持正常文档流中的相对定位。窗口滚动无需配置;内部滚动容器用 `scrollRoot={element}` 指定。常规布局直接用 `Reader` 即可。详见 [组合和布局约定](docs/api.md#布局和定位)。
63
-
64
- ## 默认能力与扩展
48
+ | 文档阅读 | CommonMark、GFM 表格/任务列表、数学公式、Shiki 代码高亮、Mermaid 图表 |
49
+ | 富内容 | 图片与图组、图注、视频、释义、练习题、嵌套注释与 Obsidian callout、引用、原文/译文/对照 |
50
+ | 阅读交互 | 响应式目录、标注侧栏/窄屏浮层、完整原子内容复制、四种高亮样式、`==高亮==` 与脚注卡片 |
51
+ | 排版与流式 | 标准、Knuth–Plass、两端对齐;未闭合语法中间态、增量淡入和稳定选区 |
52
+ | 应用集成 | 受控标注、原始 UTF-16 坐标、多个独立阅读器、内部滚动容器、SSR |
53
+ | 扩展 | 自定义语法、按条件替换渲染组件、标注类型、选区动作、流式效果、参数与 CSS 主题包 |
65
54
 
66
- 默认包含 GFM、公式、代码高亮、响应式图片/图组与图注、视频、释义、问题正文区块、拓展阅读、ref 引用和分段译文。每一种特殊语法都是使用公开接口实现的独立模块。`translations` 支持原文、译文与对照,可通过 `parameters.translationMode` 统一控制;[图组与译文语法](docs/extensions.md#图片与论文图组)包含完整示例。
55
+ 默认模块包括 `citation` 和 Markdown 脚注卡片;`highlight` 支持应用创建的可编辑高亮,`==文字==` 则生成只读源码高亮。`[^id]` 与 `^[正文]` 显示评论角标及侧栏/浮层,也可紧接在高亮后面。笔记、提问和聊天标注由应用插件提供,`question()` 是练习题正文模块。完整写法见[语法手册](docs/zh-CN/syntax.md)。
67
56
 
68
- **默认角注只有 citation/ref;高亮单独提供。** 提问、注记、聊天等应用角注由插件注册。`question()` 是问题正文区块,与问答角注无关。
69
-
70
- ```tsx
71
- import { standard, defineBlock, replaceExtension, codeHighlight } from '@linloir/limr';
72
-
73
- const extensions = [
74
- ...replaceExtension(standard(), codeHighlight({ languages: ['typescript', 'python'] })),
75
- defineBlock({
76
- name: 'notice',
77
- component: ({ children }) => <aside className="notice">{children}</aside>,
78
- }),
79
- ];
80
-
81
- <Reader source={'<notice>\n\n**自定义内容**\n\n</notice>'} extensions={extensions} />
82
- ```
57
+ ```markdown
58
+ <definition title="定义">
83
59
 
84
- 同一模块也支持 `:::notice` 指令语法。`extensions` 是完整的扩展列表;传入 `[]` 得到基础 CommonMark。可以用 `.filter()` 移除默认模块,或 `replaceExtension()` 替换同名模块。保持配置引用稳定,例如在模块外定义或使用 `useMemo`。
60
+ 在特殊区块中继续使用 **Markdown**。
85
61
 
86
- 安装第三方扩展时,用 `plugins` **追加**到默认模块;样式包通过 CSS 导入和 `appearance` 选择:
62
+ </definition>
87
63
 
88
- ```tsx
89
- import { readingTools } from '@limr-example/reading-tools';
90
- import '@linloir/limr/styles.css';
91
- import '@limr-example/paper-theme';
64
+ 这段内容有参考来源<ref id="paper" />。
92
65
 
93
- const plugins = [readingTools()];
94
- <Reader source={markdown} plugins={plugins} appearance="paper" />
66
+ <citation id="paper" title="参考资料" url="https://example.com/paper" summary="简短摘要" />
95
67
  ```
96
68
 
97
- 这里的两个 `@limr-example` 包是仓库内的可打包示例,尚未发布。实际社区包可以使用同样的结构。见 [扩展打包](docs/extensions.md#作为独立包分发) 和 [样式指南](docs/styles.md)。
69
+ 默认模块也支持 `::` 指令:例如 `::definition{title="定义"}` 与独立一行的 `::` 包围正文;原有标签与 `:::` 写法继续可用。Mermaid 使用 `mermaid` 代码围栏或 `::mermaid`,图像模式支持缩放、拖拽平移和键盘/滚轮移动。
98
70
 
99
- 常用标签:
71
+ ## 排版与流式行为
100
72
 
101
- ```markdown
102
- <definition title="定义">
73
+ `typography` 支持 `standard`(默认)、`knuth-plass`、`justify`。KP 使用 TeX 的 box/glue/penalty 段落优化和 Knuth–Liang 英文断词,缓存测量及断行准备结果,滚动保留已排版节点。浏览器字体测量与 TeX PDF 不保证逐像素相同;[性能报告](docs/zh-CN/performance.md)包含 Scikit Learn 滚动/窗口变化对照及测量边界。
103
74
 
104
- 支持 **Markdown** 的内容。
75
+ 流式输出暂缓不完整的语法标记;默认模块可显示 loading,代码和公式可直接展示可用中间态。新增文字和特殊块只做透明度淡入,既有控件和选区保持稳定。插件可通过 `streaming.Loading`、`streaming.effect` 自定义行为,宿主可用 `streamEffect` 覆盖动画或设为 `false`。
105
76
 
106
- </definition>
77
+ 公式、图表等原子内容按整体选择,选区工具栏复制保留原始源码和分隔符(包括行内公式两侧的 `$`)。单个块的工具栏位于块下方;复制反馈与按钮宽度使用非线性过渡。详见[标注与选区](docs/zh-CN/annotations.md)和[样式](docs/zh-CN/styles.md)。
107
78
 
108
- 引用一段文字<ref id="paper" />。
79
+ ## 组合与扩展
109
80
 
110
- <citation id="paper" title="论文" url="https://example.com" description="支持 **富文本** 描述。" />
111
- ```
112
-
113
- 也支持 `cite-id`、`cite-from-ids`、`desc` 等原有属性。未知 HTML 按原文显示,标签中的 JavaScript 表达式不执行。更多模块和 parser 接口见 [扩展指南](docs/extensions.md)。
114
-
115
- ## 高亮、选区和应用插件
81
+ `Reader` 提供完整布局;自定义布局可用 `DocumentProvider` 组合 `Markdown`、`TableOfContents`、`AnnotationSidebar`、`AnnotationOverlay` 和 `SelectionToolbar`。详见[项目集成](docs/zh-CN/integration.md)。
116
82
 
117
83
  ```tsx
118
- import { Reader, copyText, highlightPalette, highlightSelection, deleteAnnotations, chinese } from '@linloir/limr';
84
+ import { Reader, defineBlock } from '@linloir/limr';
119
85
 
120
- const actions = [
121
- highlightPalette(),
122
- highlightSelection(),
123
- copyText({ label: '复制文字' }),
124
- copyText({ label: '复制 Markdown', format: 'syntax' }),
125
- deleteAnnotations(),
126
- ];
86
+ const plugins = [defineBlock({
87
+ name: 'notice',
88
+ component: ({ children }) => <aside className="notice">{children}</aside>,
89
+ })];
127
90
 
128
- <Reader source={markdown} locale={chinese} actions={actions} />
91
+ export function Notice() {
92
+ return <Reader source={'<notice>\n\n**自定义内容**\n\n</notice>'} plugins={plugins} />;
93
+ }
129
94
  ```
130
95
 
131
- 工具菜单默认提供色块、高亮、复制和删除。悬浮左侧色块可调整颜色与样式,添加高亮直接生效;同一文本片段可以同时拥有高亮、旁注、提问等多个 annotation。高亮统一存为 `type: 'highlight'` 的 annotation,通过 `annotations` / `onAnnotationsChange` 管理。右侧删除操作移除该片段关联的所有 annotation,隐藏高亮则保留注释。上面的 `actions` 可替换默认列表。
96
+ `plugins` 追加到默认扩展;`extensions` 替换整个扩展列表,`extensions={[]}` 使用基础 CommonMark。同名扩展使用 `replaceExtension()` 显式替换。配置应保持引用稳定。
132
97
 
133
- 选区同时提供 `raw`、`syntax`、`blocks` 三种结果,所有范围都指向**未经改写的原始输入**,使用 UTF-16 偏移、右端不包含。`quality` 区分精确映射、公式等原子节点和无法精确映射的内容。默认高亮和脚注使用 `syntax`,仅吸附选区两端紧邻的标准 Markdown 标记,不扩大未选中的文字,也不吸附特殊块的外层标签。行内及围栏代码支持部分选择、高亮与角标;公式保持整体选择。
98
+ 只替换某类内容的呈现时,可用 `rendererOverrides` 的 `type`、`component` 和 `when`,按语言、祖先或流式状态限定范围;宿主规则优先。它是渲染范围约束,不是第三方代码安全沙箱。
134
99
 
135
- 插件可以在一个 `defineExtension()` 中提供 `actions`、`annotationTypes` 和语法模块。动作拿到选区、文档、`addAnnotation` / `updateAnnotation` / `activateAnnotation` 等命令和取消信号。卡片可以使用任意 React 组件,也可以用 `AnnotationMarkdown` 持续渲染 Markdown 回答。
100
+ 插件可以拥有完整卡片 UI(`overlay.Card`)、侧栏摘要(`sidebar.Preview`)、异步加载和选区操作。使用 [AI 插件开发 Skill](skills/limr-plugin-development/SKILL.md) 或[独立插件包指南](docs/zh-CN/plugin-packages.md)创建可安装的包,再通过 `plugins` 引入。仓库提供[笔记](examples/notes.tsx)、[流式助手](examples/assistant.tsx)、[独立插件](examples/packages/reading-tools/index.js)和 [CSS 主题](examples/packages/paper-theme/index.css)示例;`@limr-example/*` 是未发布的本地示例包。
136
101
 
137
- [助手插件](examples/assistant.tsx) 和 [旁注编辑插件](examples/notes.tsx) 演示了这条路径。运行 `pnpm dev` 后即可在同一 playground 页面选中文字,使用问答、旁注、笔记、提问和脚注;新注释会直接进入桌面侧栏或手机卡片的编辑态。顶部“编辑/保存”切换写作与阅读,返回阅读时保存文本与注释到浏览器。“加载”包含全部预设、已保存文本与文件导入导出,“插件”下拉菜单支持多选。预设包含 Express / Axios README、文学作品及 scikit-learn 原论文的 Markdown 转写,来源与许可随文本保留。流式演示始终使用当前文本,主题切换独立保留。问答示例使用本地模拟传输;实际 Codex 连接、认证、会话管理由应用适配器实现,LiMR 不预设服务端协议。
102
+ ## AI Skills
138
103
 
139
- ## 渲染与资源
104
+ | Skill | 用途 |
105
+ | --- | --- |
106
+ | [limr-use](skills/limr-use/SKILL.md) | 指导 AI 在项目中接入 LiMR、编写内容、配置交互和引入已有插件 |
107
+ | [limr-plugin-development](skills/limr-plugin-development/SKILL.md) | 指导 AI 开发独立模块包,附带 TypeScript / ESM / CSS 模板及验证步骤 |
140
108
 
141
- - 流式追加会重新解析尚未稳定的末尾区块,复用前面的区块;后到的引用定义会触发完整语义校正。结束时进行最终完整解析。
142
- - 自定义 transform 默认按全文处理。只有声明 `scope: 'local'` 且满足局部性约定的模块才参与尾部增量解析。
143
- - 代码高亮接近视口时加载 Shiki、所需语言和主题;流式代码暂停更新后才重新高亮。公式按需加载 KaTeX。视频点击播放前不请求播放器。
144
- - 角注数据在卡片显示时才加载,同一阅读器内请求复用、取消和有限缓存;不同阅读器资源隔离。
145
- - 不注入第三方 CDN。默认样式附带本地 Maple Mono NF CN 代码字体,按字形范围加载 WOFF2 子集,加载前使用系统等宽字体。正文衬线字体使用应用/系统回退,Playground 自行提供 Noto Serif SC。可使用不带字体的 `@linloir/limr/styles/base.css`。缓存和覆盖方式见 [样式指南](docs/styles.md)。
146
- - 默认保留完整 DOM,支持原生查找、选择和打印;不使用会破坏这些行为的默认虚拟列表。
109
+ Skills 随 npm 包分发,也可以从仓库下载。复制完整目录即可保留引用文件和模板;[下载、安装与调用说明](docs/zh-CN/ai-skills.md)包含 Codex 项目级与用户级配置。
147
110
 
148
- SSR 支持 Node 环境。`renderToString` 中未加载的公式先输出源码回退;如需首次 HTML 包含完整公式,先 `await preloadMath()`,或者使用 React 流式 SSR。Shiki 高亮在客户端补充,代码文本会直接出现在 SSR HTML 中。使用 Next.js 等区分服务端/客户端组件的框架时,在应用的客户端边界内导入这些交互组件。
111
+ ## 样式与运行方式
149
112
 
150
- [性能测量](docs/performance.md) 包含数据、等价功能配置和限制。数据针对固定硬件和夹具,不代表所有 Markdown、插件或设备。
113
+ - `styles.css` 包含默认浅色/深色样式和本地 Maple 代码字体;`styles/base.css` 提供相同样式但不加载 Maple。字体资产仍包含在 npm 包中。两者选一即可。
114
+ - `appearance` 为 CSS 主题提供作用域,也会传播到 portal 中的工具栏和浮层。正文中文字体由应用或系统提供。
115
+ - 代码高亮、公式、Mermaid 和 KP 按需加载。Mermaid 在客户端绘图,未闭合的流式图表先显示 loading。视频默认接近视口时加载,可以配置为点击加载;远程媒体仍可能访问其来源站点。
116
+ - 保留全文 DOM,支持浏览器查找、原生选择与打印。流式追加和可局部处理的收尾复用稳定前缀;定义变化、中间编辑或全文 transform 仍可能触发全文解析。
117
+ - 未注册的 HTML 显示为原文,Markdown 中的 JavaScript 表达式不执行。自定义组件负责自己的数据和远程请求。
151
118
 
152
- ## 开发
119
+ 详见[样式与字体](docs/zh-CN/styles.md)、[API](docs/zh-CN/api.md)和[性能与限制](docs/zh-CN/performance.md)。
153
120
 
154
- [在线 Playground](https://linloir.github.io/LiMR/)
121
+ ## 本地开发
155
122
 
156
123
  ```sh
157
124
  pnpm install
158
125
  pnpm dev
159
126
  pnpm check
127
+ pnpm test:docs
160
128
  pnpm exec playwright install chromium
161
129
  pnpm test:browser
162
- NODE_ENV=production pnpm bench
163
130
  ```
164
131
 
165
- ### npm 发布
132
+ 本地开发需要 Python 3 生成 Skill 下载归档。标题栏可切换 Docs / Playground,Docs 由 LiMR 渲染,可切换语言。
166
133
 
167
- `pnpm test:package` 会构建并打包当前版本,在独立的 React 18/19 项目中验证类型、SSR、浏览器交互及样式资源,然后将通过验证的安装包保存到 `artifacts/`。
134
+ Playground 刷新后回到默认文档与标准排版,不自动恢复上次打开的文档或编辑。编辑后的“保存”写入本地草稿,可从“加载已保存文本”手动打开;语言偏好独立保留。排版菜单提供三种模式,流式演示每 90ms 增加最多 5 个 UTF-16 单元。
168
135
 
169
- ```sh
170
- pnpm check
171
- pnpm test:package
172
- npm login --auth-type=web --registry=https://registry.npmjs.org
173
- npm publish ./artifacts/linloir-limr-0.1.0.tgz --access public --registry=https://registry.npmjs.org
174
- ```
175
-
176
- 发布账号需要拥有 `@linloir` scope 的权限并完成 npm 要求的双重认证。后续发布先更新 `package.json` 的版本,再重新打包,并将命令中的文件名替换为新版本。
136
+ 本地 Playground 位于 `http://127.0.0.1:4173`。纯解析场景使用 `@linloir/limr/core`,不依赖 React/DOM;其他入口为 `@linloir/limr/react` 和 `@linloir/limr/extensions`。
177
137
 
178
- ### GitHub Pages 预览
138
+ ## 构建与发布 Pages
179
139
 
180
- `main` 保存源码,独立的 `pages` 分支保存 Playground 构建后的静态产物,通过 SSH 推送到 GitHub。`pages` 分支由构建生成,无需手工合并源码。预览地址为 <https://linloir.github.io/LiMR/>。
181
-
182
- 首次部署在仓库 **Settings → Pages → Build and deployment** 中设置 **Source: Deploy from a branch**、**Branch: pages**、目录 **/(root)**,然后保存。后续推送 `pages` 分支会更新站点。
183
-
184
- 本地检查与线上相同的 `/LiMR/` 路径:
140
+ `main` 保存源码;`pages` 只保存构建产物。GitHub Pages 设置为 **Deploy from a branch → pages → /(root)**;推送 `main` 不会自动构建站点。
185
141
 
186
142
  ```sh
143
+ pnpm test:docs
187
144
  pnpm build:playground
188
- pnpm preview:playground
189
- # 打开 http://127.0.0.1:4173/LiMR/
145
+ pnpm preview:playground --port 4174
146
+ # http://127.0.0.1:4174/LiMR/
190
147
  ```
191
148
 
192
- 构建输出为 `demo-dist/`,包含跳过 Jekyll 处理的 `.nojekyll` 文件。更新预览时,重新构建并将该目录的内容提交、推送到 `pages` 分支。`pnpm dev` 仍使用本地根路径。部署到其他仓库名时,需要同步修改两个 Playground 脚本中的 `--base`。
193
-
194
- 其他入口:`@linloir/limr/core`(无 React/DOM 运行时依赖)、`@linloir/limr/react`、`@linloir/limr/extensions`。详细 props、hooks、受控状态和主题配置见 [API 指南](docs/api.md)。
195
-
196
- MIT License.
149
+ 构建输出 `demo-dist/`,包含 `.nojekyll`、双语 Docs、示例和更新后的 Skill ZIP。验证后,将该目录内容同步到独立的 `pages` 工作树,提交并推送源码与产物分支。部署其他仓库名时需修改构建/预览的 `--base`。README 和文档以仓库实现为准;核对 npm 安装版本的导出和类型,必要时用 `pnpm pack` 消费当前源码。
197
150
 
198
- Developed with Codex.
151
+ [MIT License](LICENSE). Developed with Codex.