Page-break between chapters and numeric title fallback
Every chapter after the first now starts on a new page via a Chapter_20_Break heading style (fo:break-before="page"); the first chapter keeps the plain heading so there is no blank leading page. Chapter titles now resolve as: manual override > "# Title:" header > the chapter's 1-based position in the left pane (e.g. "3."). The old "# heading" / filename fallbacks are replaced by this numbering, and the same logic drives the chapter-title hint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+28
-3
@@ -389,6 +389,9 @@ fn styles_xml() -> String {
|
||||
<style:text-properties fo:font-size="14pt" fo:font-weight="bold"/>
|
||||
</style:style>
|
||||
{headings}
|
||||
<style:style style:name="Chapter_20_Break" style:display-name="Chapter Break" style:family="paragraph" style:parent-style-name="Heading_20_1" style:next-style-name="Text_20_body" style:default-outline-level="1">
|
||||
<style:paragraph-properties fo:break-before="page"/>
|
||||
</style:style>
|
||||
<style:style style:name="Chapter_20_Caption" style:display-name="Chapter Caption" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
|
||||
<style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.2in"/>
|
||||
<style:text-properties fo:font-style="italic" fo:font-size="12pt" fo:color="#666666"/>
|
||||
@@ -447,11 +450,17 @@ fn styles_xml() -> String {
|
||||
|
||||
fn content_xml(chapters: &[Chapter]) -> String {
|
||||
let mut body = String::new();
|
||||
for chapter in chapters {
|
||||
for (i, chapter) in chapters.iter().enumerate() {
|
||||
// Chapter heading (always level 1); the document's own headings are
|
||||
// shifted down by one so they nest beneath it.
|
||||
// shifted down by one so they nest beneath it. Every chapter after the
|
||||
// first starts on a new page via a heading style with a page break.
|
||||
let heading_style = if i == 0 {
|
||||
"Heading_20_1"
|
||||
} else {
|
||||
"Chapter_20_Break"
|
||||
};
|
||||
body.push_str(&format!(
|
||||
"<text:h text:style-name=\"Heading_20_1\" text:outline-level=\"1\">{}</text:h>",
|
||||
"<text:h text:style-name=\"{heading_style}\" text:outline-level=\"1\">{}</text:h>",
|
||||
esc(&chapter.title)
|
||||
));
|
||||
if let Some(slug) = chapter.slug.as_deref().map(str::trim).filter(|s| !s.is_empty()) {
|
||||
@@ -593,10 +602,26 @@ Done.";
|
||||
.unwrap();
|
||||
assert!(content.contains(">Chapter One</text:h>"));
|
||||
assert!(content.contains(">Chapter Two</text:h>"));
|
||||
// The first chapter uses the plain heading; later chapters get a page break.
|
||||
assert!(content.contains(
|
||||
"<text:h text:style-name=\"Heading_20_1\" text:outline-level=\"1\">Chapter One</text:h>"
|
||||
));
|
||||
assert!(content.contains(
|
||||
"<text:h text:style-name=\"Chapter_20_Break\" text:outline-level=\"1\">Chapter Two</text:h>"
|
||||
));
|
||||
// The slug renders as an italic caption paragraph under the first chapter.
|
||||
assert!(content.contains(
|
||||
"<text:p text:style-name=\"Chapter_20_Caption\">\
|
||||
<text:span text:style-name=\"T_italic\">the opening</text:span></text:p>"
|
||||
));
|
||||
|
||||
// The page-break style is defined in styles.xml.
|
||||
let mut styles = String::new();
|
||||
zip.by_name("styles.xml")
|
||||
.unwrap()
|
||||
.read_to_string(&mut styles)
|
||||
.unwrap();
|
||||
assert!(styles.contains("style:name=\"Chapter_20_Break\""));
|
||||
assert!(styles.contains("fo:break-before=\"page\""));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user