mirror of
https://github.com/storytold/wordcraft.git
synced 2026-11-03 17:04:43 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a8694d254 |
+2
-1
File diff suppressed because one or more lines are too long
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user