Footnote and Endnote options per section (#385) (#390)

- Model: NoteProps (pos, numFmt, numStart, numRestart) in the settings and
  each section; Document::note_options resolves section > document > defaults.
- DOCX: w:footnotePr / w:endnotePr read and written in settings and every
  w:sectPr in schema order; hostile numStart clamped (ECMA-376 §17.11).
- Layout: footnotes below the text, endnotes at the end of each section,
  numbering restarted per section or per page (from where notes land, at
  most three passes), per-section number formats.
- Commands: references.noteOptions takes kind/pos/numFmt/numStart/
  numRestart/scope; references.convertNotes (footnote/endnote/swap, one
  undo step); references.footnote/endnote take a custom mark.
- UI: Footnote and Endnote dialog from the Footnotes group launcher;
  strings in every catalog.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Valentin Klein
2026-10-11 15:10:17 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent f8f1d80c38
commit 4e710a920b
37 changed files with 1099 additions and 107 deletions
+3 -10
View File
@@ -358,16 +358,9 @@ pub fn specs() -> Vec<CommandSpec> {
}),
CommandSpec::new("insert.crossReference", "Cross-reference", "Insert › Links", cross_ref)
.params(r#"{"to": "heading|bookmark|figure|table", "target": string (text / name / number), "show"?: "text|page|number|aboveBelow"} or {} to list targets"#),
CommandSpec::new("references.noteOptions", "Footnote and Endnote", "References › Footnotes", |s, v| {
if let Some(f) = p::str(v, "footnoteFormat") {
s.doc.settings.footnote_format = wordcraft_doc::section::NumFormat::from_ooxml(f);
}
if let Some(f) = p::str(v, "endnoteFormat") {
s.doc.settings.endnote_format = wordcraft_doc::section::NumFormat::from_ooxml(f);
}
Ok(json!({"footnoteFormat": s.doc.settings.footnote_format, "endnoteFormat": s.doc.settings.endnote_format}))
})
.params(r#"{"footnoteFormat"?: "decimal|lowerRoman|upperRoman|lowerLetter|upperLetter", "endnoteFormat"?: …}"#),
CommandSpec::new("references.noteOptions", "Footnote and Endnote", "References › Footnotes", super::references::note_options).params(
r#"{"kind"?: "footnote|endnote", "pos"?: "pageBottom|beneathText" (footnotes) | "sectEnd|docEnd" (endnotes), "numFmt"?: "decimal|lowerRoman|upperRoman|lowerLetter|upperLetter|…", "numStart"?: 1-32767, "numRestart"?: "continuous|eachSect|eachPage" (each page: footnotes only), "scope"?: "document|section", "footnoteFormat"?: …, "endnoteFormat"?: …} — no settings: the options in effect at the caret"#,
),
CommandSpec::new("references.researcher", "Researcher", "References › Research", |s, _| {
s.status = "Researcher needs an online service; WordCraft keeps your documents offline.".into();
Ok(json!({"available": false}))