Compare commits

...
4 changed files with 22 additions and 4 deletions
+2 -1
View File
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -598,10 +598,11 @@ fn find_link(s: &Session, url: &str) -> Option<(Pos, Pos)> {
}
/// Where the body references note `id`.
fn note_ref_pos(s: &Session, id: u32) -> Option<Pos> {
pub(crate) fn note_ref_pos(s: &Session, id: u32) -> Option<Pos> {
for path in s.doc.para_paths(StoryRef::Body) {
let Some(p) = s.doc.para(StoryRef::Body, &path) else { continue };
let hit = p.object_offsets().into_iter().find(|o| matches!(p.object_at(*o), Some(InlineObject::NoteRef { id: n, .. }) if *n == id));
// One pass over the objects: `object_at` per offset counted the objects before each one.
let hit = p.objects_with_offsets().find(|(_, o)| matches!(o, InlineObject::NoteRef { id: n, .. } if *n == id)).map(|(off, _)| off);
if let Some(off) = hit {
return Some(Pos::new(StoryRef::Body, path, off));
}
+16
View File
@@ -588,3 +588,19 @@ fn citation_at_document_end_stays_closed() {
let back = wordcraft_engine::io::open_bytes("probe.docx", &bytes).unwrap();
assert_eq!(back.field_ranges(StoryRef::Body).len(), 1);
}
#[test]
fn a_note_reference_is_found_in_one_pass_over_its_paragraph() {
// 20,000 other notes' marks before the one wanted: each was counted again from the start.
let n = 20_000u32;
let mut d = Document::from_text("");
if let Some(wordcraft_doc::Block::Para(p)) = d.body.first_mut().map(std::sync::Arc::make_mut) {
p.text = OBJ.to_string().repeat(n as usize);
p.runs = vec![wordcraft_doc::para::Run { len: p.text.len(), props: Default::default() }];
p.objects = (1..=n).map(|id| InlineObject::NoteRef { kind: wordcraft_doc::para::NoteKind::Footnote, id, custom: String::new() }).collect();
}
let s = Session::new(d);
let at = crate::bridge::note_ref_pos(&s, n).expect("found");
assert_eq!(at.off, (n as usize - 1) * OBJ.len_utf8());
assert!(crate::bridge::note_ref_pos(&s, n + 1).is_none());
}
+1 -1
View File
File diff suppressed because one or more lines are too long