fix: TOC anchor navigation - remove anchor text from parsed content

- Fix parse_blocks: after extracting anchor from \\x03..\\x04 markers,
  remove the anchor text too (was contaminating display text)
- When TOC jump occurs, clear pending_anchor to prevent saved position
  from overriding the TOC navigation on first frame
- Add tests for heading with/without anchor parsing
This commit is contained in:
Developer
2026-05-22 21:03:56 +08:00
parent 1d2407098c
commit 528d70fc33
2 changed files with 27 additions and 1 deletions

View File

@@ -26,11 +26,14 @@ fn parse_blocks(raw_text: &str) -> Vec<ContentBlock> {
if let Some(anchor_end) = after_level.find('\x04') {
let anchor_str = &after_level[anchor_start + 1..anchor_end];
anchor = Some(anchor_str.to_string());
// Remove \x03<anchor>\x04 from text to prevent anchor ID contamination
let rm_start = pos + 2 + anchor_start;
let rm_end = pos + 2 + anchor_end + 1;
text.replace_range(rm_start..rm_end, "");
}
}
text.drain(pos..pos + 2);
}
text = text.replace(&['\x03', '\x04'][..], "");
text = text.replace('\x02', "");
}
let text = text.trim().to_string();
@@ -682,4 +685,26 @@ mod tests {
assert_eq!(blocks[0].text, "段一");
assert_eq!(blocks[1].text, "段二");
}
#[test]
fn test_parse_blocks_heading_with_anchor() {
// \x011\x03toc1\x04Chapter 1\x02 → heading_level=1, anchor="toc1", text="Chapter 1"
let blocks = parse_blocks("\x011\x03toc1\x04Chapter 1\x02\n\nbody text");
assert_eq!(blocks.len(), 2);
assert_eq!(blocks[0].heading_level, 1);
assert_eq!(blocks[0].anchor.as_deref(), Some("toc1"));
assert_eq!(blocks[0].text, "Chapter 1");
assert_eq!(blocks[1].heading_level, 0);
assert_eq!(blocks[1].text, "body text");
}
#[test]
fn test_parse_blocks_heading_without_anchor() {
// \x011Title\x02 → heading_level=1, anchor=None, text="Title"
let blocks = parse_blocks("\x011Title\x02");
assert_eq!(blocks.len(), 1);
assert_eq!(blocks[0].heading_level, 1);
assert_eq!(blocks[0].anchor, None);
assert_eq!(blocks[0].text, "Title");
}
}