# 7-29 [done][bug] markdown_edit 会把普通块 inline content 扁平化

> 发现时间：2026-05-18
>
> 状态：`[done]`
>
> 关联主线：`07-ai`

## 1. 问题定义

`mnote.doc.markdown_edit` 的 online 写回已经从“二次推导 block ops”切到 final markdown → block content，但 `build_page_content()` 仍会把普通块的 legacy `content` 统一写成扁平字符串。

这会让未修改的块也丢失原始 inline content 结构，修改过的单段落块则更容易丢失 bold / italic / link / code 等 marks。

## 2. 证据

- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs:762) 当前普通块写回直接 `obj.insert("content", json!(parsed_block.text))`。
- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs:826) 只有 `text` 和 `id` 被保留，原 inline 节点结构被覆盖。
- [7-27](/mnt/Data1T/mnote/design/07-ai/process/7-27-online-markdown-writeback-final-content-truth-v2.md:580) 已明确指出当前 `blocks_to_markdown` / 写回链会丢弃 inline marks。

## 3. 影响

- 未修改块在 `full_content` / 局部替换后也可能失去 inline 节点结构。
- 已修改块中的 bold / link / code 等 marks 可能被扁平化成普通字符串。
- 页面 AI 的正文重写与可视格式回读不一致。

## 4. 修复结果

- [doc.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/hermes_tools/doc.rs) 的 `build_page_content()` 已改为区分未变更、可安全局部替换、复杂块保留三类写回路径。
- 未变更的普通块会直接保留原始 block 结构，不再被重写成纯字符串 content。
- 已变更且原始 `content` / `contentNodes` 是单 inline text 节点的普通块，只替换该 text 节点文本，保留原 marks / attrs。
- 复杂块继续原样保留；无法证明可安全替换的已变更普通块才退回纯文本 content。

## 5. 验证证据

```bash
cargo test --manifest-path rust/Cargo.toml -p mnote-web build_page_content -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web hermes_tools_markdown_edit -- --nocapture
```

验证结果：

- `build_page_content` 定向测试通过，覆盖 full_content 不保留旧普通块、局部替换保留未变更块、单 inline text marks 保留。
- `hermes_tools_markdown_edit` 定向测试通过，覆盖 markdown edit 在线写回链路。
