44 lines
3.2 KiB
Markdown
44 lines
3.2 KiB
Markdown
## 目标效果
|
||
1. **自动显隐 Markdown 标记**:光标不在当前行/当前元素时,自动隐藏 `#`、`*`、`**`、`> `、` ``` ` 等语法标记,只显示渲染后的文本;光标移入时恢复显示以便编辑。
|
||
2. **代码块所见即所得**:代码块(Fenced Code Block)显示为灰色背景的卡片块,优化字体和间距,不再只是裸露的文本。
|
||
3. **柔和样式优化**:调整行高、字号、颜色、段落间距,使其视觉上更接近渲染后的文档(Typora 风格)。
|
||
|
||
## 技术方案
|
||
### 1. 核心逻辑重构:从 `StateField` 转向 `ViewPlugin`
|
||
目前的 `liveMarkdownDecorations.js` 基于正则匹配行,无法精准处理嵌套语法(如加粗内的斜体)和光标交互。将改用 `ViewPlugin` 结合 `syntaxTree`(语法树):
|
||
- **语法树解析**:利用 `@codemirror/language` 提供的 `syntaxTree` 遍历文档节点,精准识别 `HeaderMark`(标题#)、`EmphasisMark`(*)、`CodeMark`(`)、`FencedCode`(代码块)等节点。
|
||
- **光标感知**:在 `ViewPlugin` 的 `update` 钩子中监听 `docChanged` 和 `selectionSet`。
|
||
- **动态装饰**:
|
||
- **隐藏逻辑**:如果节点的范围 **不包含** 当前光标选区,则对该节点的语法标记部分应用 `Decoration.replace({})`(完全隐藏)或 `Decoration.mark({ class: 'cm-md-hidden' })`。
|
||
- **代码块逻辑**:识别 `FencedCode` 节点,对整个范围应用 `Decoration.line({ class: 'cm-md-fenced-code' })` 添加背景色;对首尾的 `CodeMark`(```)在非聚焦时进行隐藏或弱化处理。
|
||
|
||
### 2. 样式实现细节
|
||
- **隐藏类 (`.cm-md-hidden`)**:设置为 `display: none` 或 `font-size: 0`。
|
||
- **代码块样式 (`.cm-md-fenced-code`)**:
|
||
- 背景色:`var(--app-background)` 或微调的灰色。
|
||
- 圆角与内边距:让代码块看起来像一个独立的容器。
|
||
- 字体:使用等宽字体 (`monospace`)。
|
||
- **柔和排版**:
|
||
- 增加 `line-height` (如 1.8)。
|
||
- 增加段落间距 (`margin-bottom` 效果)。
|
||
- 调整标题 (`Header`) 的 `font-weight` 和 `border-bottom`,使其更像预览模式。
|
||
|
||
## 实施步骤
|
||
1. **废弃旧逻辑**:清空或重写 `src/codemirror/liveMarkdownDecorations.js`。
|
||
2. **实现 `ViewPlugin`**:
|
||
- 引入 `syntaxTree`。
|
||
- 编写遍历逻辑,识别 Markdown 节点。
|
||
- 实现光标包含判断逻辑。
|
||
- 生成 `Decoration.replace` (隐藏) 和 `Decoration.line` (样式)。
|
||
3. **完善 CSS**:在 `LivePreviewEditor.vue` 中补充对应的 CSS 规则(`.cm-md-hidden`, `.cm-md-header`, `.cm-md-fenced-code` 等)。
|
||
4. **验证**:测试标题、加粗、代码块在光标移入/移出时的显隐效果。
|
||
|
||
## 预期节点类型 (基于 @lezer/markdown)
|
||
- `ATXHeading`: 包含 `HeaderMark` (#) 和内容。
|
||
- `Emphasis` / `StrongEmphasis`: 包含 `EmphasisMark` (*, _)。
|
||
- `FencedCode`: 包含 `CodeMark` (```), `CodeInfo` (语言), `CodeText` (内容)。
|
||
- `Blockquote`: 包含 `QuoteMark` (>)。
|
||
|
||
## 风险点
|
||
- **性能**:频繁遍历语法树可能在长文档中导致卡顿。需要利用 `RangeSetBuilder` 高效构建 Decoration,并尽量复用。
|
||
- **光标边界**:光标恰好在标记边缘时的显隐判定需要精细调整(通常光标接触即显示)。 |