#!/usr/bin/env python3
"""
Generate a test EPUB for
section-break rendering.
Tests that a bare
element between paragraphs produces a visible blank-line
gap (section separator), while a
inside a paragraph only produces a line
break with no extra spacing.
Cases covered:
1. Standalone
between paragraphs (section break — must show gap).
2.
with a CSS class (calibre-style section break).
3. Multiple consecutive
elements (each adds one line of spacing).
4. Inline
inside a
(line break only — no extra gap).
5.
at start of chapter (no gap before first paragraph).
6.
following a heading.
Visual verification instructions are embedded as the first paragraph of each
chapter so a human tester can confirm the expected result on device.
"""
import os
import zipfile
from pathlib import Path
OUTPUT_DIR = Path(__file__).parent.parent / "test" / "epubs"
OUTPUT_PATH = OUTPUT_DIR / "test_br_section_break.epub"
FILLER = (
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
"tempor incididunt ut labore et dolore magna aliqua."
)
CSS = """\
body { margin: 0; padding: 0; }
p { margin-top: 1pt; margin-bottom: 0; text-indent: 1em; text-align: justify; }
h1 { text-align: center; margin-top: 0.5em; margin-bottom: 0.5em; }
h2 { text-align: center; margin-top: 0.5em; margin-bottom: 0.5em; }
.section-br { display: block; }
"""
def xhtml(title, body):
return f"""\
PASS: A visible blank-line gap should appear between the two sections below.
{FILLER}
{FILLER}
PASS: The gap above should be roughly one line tall (same as a blank line).
""") # --------------------------------------------------------------------------- # Chapter 2 —PASS: A blank-line gap should appear between the two sections below, identical to Ch 1, even though the <br> carries a CSS class.
{FILLER}
{FILLER}
""") # --------------------------------------------------------------------------- # Chapter 3 — multiple consecutivePASS: Two blank lines should appear between the sections (one per <br>).
{FILLER}
{FILLER}
PASS: Three blank lines should appear below.
{FILLER}
{FILLER}
""") # --------------------------------------------------------------------------- # Chapter 4 — inlinePASS: The two lines below should be adjacent with NO extra gap between them. The <br> is inside the paragraph and must only break the line.
First line of the paragraph.
Second line of the paragraph — directly below, no gap.
PASS: Above should look like two closely-spaced lines, not like two paragraphs separated by a blank line.
""") # --------------------------------------------------------------------------- # Chapter 5 —PASS: There should be a blank-line gap between the heading above and this paragraph.
{FILLER}
PASS: There should be a blank-line gap between the section heading and this paragraph.
""") # --------------------------------------------------------------------------- # Chapter 6 —PASS: This heading should appear near the top of the page with no large blank area above it despite the <br> being the very first element.
{FILLER}
""") CHAPTERS = [ ("ch1", "chapter1.xhtml", "Chapter 1: Standalone br", ch1), ("ch2", "chapter2.xhtml", "Chapter 2: Classed br", ch2), ("ch3", "chapter3.xhtml", "Chapter 3: Multiple br", ch3), ("ch4", "chapter4.xhtml", "Chapter 4: Inline br", ch4), ("ch5", "chapter5.xhtml", "Chapter 5: br after heading", ch5), ("ch6", "chapter6.xhtml", "Chapter 6: br at start", ch6), ] def build_epub(path): os.makedirs(os.path.dirname(path), exist_ok=True) with zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED) as epub: # mimetype must be first and uncompressed epub.writestr("mimetype", "application/epub+zip", compress_type=zipfile.ZIP_STORED) epub.writestr("META-INF/container.xml", """\