mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-29 04:47:10 -06:00
Table of contents: Replace and Remove take the heading paragraph above the field's paragraph with the table (#4039)
This commit is contained in:
@@ -338,21 +338,31 @@ fn toc_range(s: &Session) -> Option<(usize, usize)> {
|
||||
}
|
||||
|
||||
/// Removes the TOC blocks `start..=end` and returns where the TOC was. A field paragraph that ends
|
||||
/// a section stays, emptied, so its section break isn't lost (#3889).
|
||||
/// a section stays, emptied, so its section break isn't lost (#3889). A heading paragraph of its
|
||||
/// own just above the field's paragraph (Word's tables start the field after their heading) goes
|
||||
/// with the table.
|
||||
fn remove_toc(s: &mut Session, start: usize, end: usize) -> Result<usize, CmdError> {
|
||||
for i in (start + 1..=end).rev() {
|
||||
s.doc.remove_block(StoryRef::Body, &Path::top(i))?;
|
||||
}
|
||||
match s.doc.para_mut(StoryRef::Body, &Path::top(start)) {
|
||||
let at = match s.doc.para_mut(StoryRef::Body, &Path::top(start)) {
|
||||
Ok(p) if p.section.is_some() => {
|
||||
*p = Paragraph { section: p.section.take(), ..Paragraph::new() };
|
||||
Ok(start + 1)
|
||||
start + 1
|
||||
}
|
||||
_ => {
|
||||
s.doc.remove_block(StoryRef::Body, &Path::top(start))?;
|
||||
Ok(start)
|
||||
start
|
||||
}
|
||||
};
|
||||
let titled = start.checked_sub(1).and_then(|i| s.doc.body.get(i)).and_then(|b| b.as_para()).is_some_and(|p| {
|
||||
p.props.style.as_deref() == Some("TOCHeading") && p.section.is_none() && toc_field(p).is_none()
|
||||
});
|
||||
if titled {
|
||||
s.doc.remove_block(StoryRef::Body, &Path::top(start - 1))?;
|
||||
return Ok(at - 1);
|
||||
}
|
||||
Ok(at)
|
||||
}
|
||||
|
||||
/// The caret is in the table of contents (its heading or an entry), where Word's context menu
|
||||
|
||||
@@ -3421,10 +3421,14 @@ fn toc_in_columns_with_localized_styles_keeps_its_layout_through_update_table()
|
||||
// The field's paragraph ends the one-column section: replacing or removing the TOC keeps it.
|
||||
let columns = |s: &Session| s.doc.sections().iter().map(|(_, x)| x.columns.count).collect::<Vec<_>>();
|
||||
assert_eq!(columns(&s), [1, 2, 1]);
|
||||
// The heading goes with the table: one "Contents" after Replace, none after Remove.
|
||||
let titles = |s: &Session| s.doc.body.iter().filter_map(|b| b.as_para()).filter(|p| p.plain_text() == "Contents").count();
|
||||
run(&mut s, "references.toc", json!({"levels": 2}));
|
||||
assert_eq!(columns(&s), [1, 2, 1], "{}", text(&s));
|
||||
assert_eq!(titles(&s), 1, "{}", text(&s));
|
||||
run(&mut s, "references.removeToc", json!({}));
|
||||
assert_eq!(columns(&s), [1, 2, 1], "{}", text(&s));
|
||||
assert_eq!(titles(&s), 0, "{}", text(&s));
|
||||
}
|
||||
|
||||
/// #2182: with two TOCs only the one Update Table would refresh is offered Update Field; the other
|
||||
|
||||
Reference in New Issue
Block a user