Files
Umbraformat/docs/OLD_Book_formatting_spec.md.old
bm 0c32168231 Apply updated spec compliance and establish git/docker baseline
- Spec §4.1: running headers carry titles only (recto: chapter/section
  title; verso: author name + book title); page-number fields removed
  from headers.
- Spec §4.2: page numbers centered in the footer on both verso and recto
  pages; front-matter display pages (copyright, dedication, epigraph,
  TOC) show their Roman numeral on the opening page too.
- Spec §2.2: lowercase Roman numbering visible from the copyright page
  through the front matter; Chapter 1 restarts at Arabic 1.
- Chapter/back-matter sections keep running matter on body pages; only
  the first page of each chapter is suppressed (spec §4.3).
- Drop titlePg on single-page front-matter display sections so footer
  page numbers render in LibreOffice and Word alike.
- Preserve <<<>>> scene-break cues (centered, 12pt before/after) and
  first-word-only capitalization of chapter openers.
- UI: remove the obsolete "Page Numbers" selector; footer_mode is
  accepted-but-ignored for backward compatibility.
- Tests updated to the new spec behavior (51 pass).
2026-09-22 19:06:03 -07:00

405 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UmbraFormat — Book Formatting Specification
## 1. Overview
UmbraFormat is a manuscript formatting tool that converts tagged `.docx` manuscripts into print-ready trade paperback documents. It implements the **B.D. Murphy General Book Formatting Specification**, enforcing consistent page layout, styles, headers, footers, and page numbering across all output.
**Version:** 1.1.0
**Tech Stack:** Python 3.12, Flask, python-docx, LibreHeadless (PDF conversion)
---
## 2. System Architecture
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Web UI │────▶│ Analyzer │────▶│ Formatter │
│ (Flask) │ │ (analyzer) │ │ (formatter) │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
┌──────▼───────┐
│ LibreOffice │
│ (PDF conv.) │
└──────────────┘
```
### Modules
| Module | File | Lines | Responsibility |
|--------|------|-------|----------------|
| `app.py` | `umbraformat/app.py` | 187 | Flask routes, file upload, API endpoints |
| `analyzer.py` | `umbraformat/analyzer.py` | 332 | DOCX analysis against spec |
| `formatter.py` | `umbraformat/formatter.py` | 1062 | Two-pass document reconstruction engine |
---
## 3. Input Specification
### 3.1 File Format
- **Type:** `.docx` (Office Open XML)
- **Max size:** 50 MB
- **Encoding:** UTF-8 (implicit in OOXML)
### 3.2 Structural Tags
All tags must appear on their own line, with no surrounding content.
| Tag | Purpose |
|-----|---------|
| `[book start]` | Beginning of the manuscript (title page) |
| `[chapter]` | Marks the start of each new chapter |
| `[font]` / `[/font]` | Passthrough block — original formatting preserved verbatim |
| `[copyright]` | Copyright page content follows |
| `[TOC]` | Table of contents placeholder |
| `[back matter]` | Back matter section (verbatim copy) |
| `[Req review]` | Review request page (verbatim copy) |
| `[about author]` | About the author page (verbatim copy) |
| `<<<>>>` | Scene break marker within chapters |
### 3.3 Manuscript Structure
```
[book start]
Title: The Book Title
Subtitle: A Subtitle
Author: Author Name
Imprint: Publisher Name
[optional images]
[chapter]
Chapter 1: Chapter Title
Paragraph text...
Paragraph text...
<<<>>>
Scene break...
[font]
[verbatim block]
[/font]
[chapter]
Chapter 2: Chapter Title
...
[copyright]
Copyright page text...
[TOC]
Table of contents...
[back matter]
Back matter content...
[Req review]
Review request text...
[about author]
Author bio text...
```
---
## 4. Output Specification
### 4.1 Page Layout
| Property | Value |
|----------|-------|
| Page size | 5.5 × 8.5 inches (trade paperback) |
| Orientation | Portrait |
| Mirror margins | Yes |
| Different first page | Yes |
### 4.2 Margins
| Margin | Value |
|--------|-------|
| Top | 0.35 inches |
| Bottom | 0.25 inches |
| Inside (configurable) | 0.375 – 0.875 inches (default: 0.55) |
| Outside | 0.40 inches |
**Inner margin reference by page count:**
| Page Count | Inner Margin |
|------------|--------------|
| < 100 | 0.375 inches |
| 100–200 | 0.50 inches |
| 200–400 | 0.625 inches |
| 400–600 | 0.75 inches |
| > 600 | 0.875 inches |
### 4.3 Headers
| Section Type | Header Behavior |
|--------------|-----------------|
| Title page (Section 0) | No header |
| Front matter | No header |
| Chapter sections | Alternating: odd = book title, even = author name |
| Back matter / verbatim | No header |
- Header distance: 0.50 inches from page edge
- Enabled via `evenAndOddHeaders` in document settings
### 4.4 Footers
| Section Type | Footer Behavior |
|--------------|-----------------|
| Title page | No footer |
| Front matter | PAGE field (Roman numerals, centered) |
| Chapter sections | PAGE field (Arabic numerals, centered) |
| Back matter / verbatim | PAGE field (Arabic, centered) |
- Footer distance: 0.50 inches from page edge
### 4.5 Page Numbering
| Section | Numbering |
|---------|-----------|
| Front matter (copyright, TOC) | Lower Roman (i, ii, iii...) |
| Chapters onward | Decimal (1, 2, 3...), starting at 1 |
---
## 5. Typography & Styles
### 5.1 Named Styles
#### `WA Chapter` — Chapter Title
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 18 pt |
| Alignment | Center |
| Spacing before | 24 pt |
| Spacing after | 0 pt |
| Line spacing | Single |
#### `WA Nrml Pgr` — Normal Paragraph
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 12 pt |
| First-line indent | 0.30 inches |
| Line spacing | 15 pt (exactly) |
| Spacing after | 0 pt |
#### `WA NChp Pgr` — First Paragraph of Chapter (No Indent)
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 12 pt |
| First-line indent | 0 inches |
| Line spacing | 14 pt (exactly) |
| Spacing after | 0 pt |
| First letter handling | Uppercase, drop-cap ready |
#### `WA Section` — Section Heading
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 16 pt |
| Alignment | Left |
| Spacing before | 18 pt |
| Spacing after | 6 pt |
#### `WA Scene Break` — Scene Break
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 14 pt |
| Alignment | Center |
| Content | `<<<>>>` rendered as decorative break |
#### `WA Thkng` — Internal Thought (Character Style)
| Property | Value |
|----------|-------|
| Font | Caladea |
| Size | 12 pt |
| Italic | Yes |
### 5.2 Title Page Typography
| Element | Font | Size | Alignment |
|---------|------|------|-----------|
| Book title | Caladea | 48 pt | Center |
| Subtitle | Caladea | 18 pt | Center |
| Author name | Caladea | 36 pt | Center |
| Imprint / Publisher | Caladea | 18 pt | Center |
Title page includes 24 empty spacer paragraphs to push content into vertical center.
### 5.3 Images
- Title page images are placed side-by-side using tab stops
- Image relationships (`r:embed`) are remapped during document reconstruction
- Deep-copies drawing XML to preserve original image data
---
## 6. Formatting Pipeline
### 6.1 Pass 1 — Content Assembly
1. **Tag scanning:** `_find_tags()` locates all structural markers
2. **Title extraction:** Parses title, subtitle, author, imprint, images from `[book start]` block
3. **Chapter extraction:** `_extract_chapters()` groups paragraphs by `[chapter]` tags, tracks `[font]`/`[/font]` passthrough blocks, detects `<<<>>>` scene breaks
4. **Verbatim extraction:** Back matter, review request, about author sections copied with raw XML deep-copy (preserves hyperlinks, images, formatting)
5. **Document creation:** New `.docx` built from scratch with:
- Section 0: Title page (spacer layout)
- Section 1: Copyright + TOC (with PAGEREF fields)
- Sections 2+: Chapters (each in its own section)
- Final sections: Verbatim content
### 6.2 Pass 2 — Section Properties
1. **Settings update:** Enable `evenAndOddHeaders`
2. **Per-section configuration:**
- Page size (5.5 × 8.5")
- Margins (mirror, configurable inner)
- Header/footer content (PAGE fields, alternating headers)
- Page numbering format (Roman vs. Arabic)
3. **OOXML schema reordering:** `w:sectPr` children reordered for Word compatibility
### 6.3 PDF Conversion
- Uses LibreOffice headless: `libreoffice --headless --convert-to pdf`
- Timeout: 120 seconds
- Output: same filename with `.pdf` extension
---
## 7. API Specification
### 7.1 Endpoints
| Method | Route | Description |
|--------|-------|-------------|
| `GET` | `/` | Home page |
| `GET` | `/format` | Upload/format page |
| `POST` | `/api/analyze` | Upload and analyze a `.docx` |
| `POST` | `/api/format` | Format an analyzed document |
| `GET` | `/api/download/<filename>` | Download formatted `.docx` |
| `GET` | `/api/download/<filename>/pdf` | Download formatted `.pdf` |
| `GET` | `/api/diag/<name>` | Download diagnostic output |
| `GET` | `/api/version` | Return version JSON |
### 7.2 Analysis Response (`/api/analyze`)
```json
{
"page_setup": {
"width": 5.5,
"height": 8.5,
"orientation": "PORTRAIT"
},
"margins": {
"top": 0.35,
"bottom": 0.25,
"inside": 0.55,
"outside": 0.40,
"mirror_margins": true
},
"sections": [],
"styles_found": {
"WA Nrml Pgr": {
"properties": {},
"issues": [],
"count": 150
}
},
"styles_missing": [],
"paragraph_count": 300,
"paragraphs_by_style": {},
"issues": [],
"warnings": [],
"chapter_word_count": 45000,
"upload_id": "uuid-string",
"original_filename": "manuscript.docx"
}
```
### 7.3 Format Request (`/api/format`)
```json
{
"upload_id": "uuid-string",
"font": "Caladea",
"fontSize": 12,
"innerMargin": 0.55
}
```
### 7.4 File Storage
- **Uploads:** `umbraformat/uploads/<uuid>.docx` + `<uuid>_analysis.json`
- **Formatted output:** `umbraformat/formatted/<uuid>_formatted.docx` + `<uuid>_formatted.pdf`
- **Name mapping:** `umbraformat/formatted/<uuid>_formatted.name` (maps UUID to original filename)
---
## 8. Configuration
### 8.1 Application Limits
| Setting | Value |
|---------|-------|
| Max upload size | 50 MB |
| Allowed extensions | `.docx` only |
| Server host | `0.0.0.0` |
| Server port | `5001` |
### 8.2 Docker
- Base image: `python:3.12-slim`
- LibreOffice installed for PDF conversion
- Volumes: `uploads/`, `formatted/`
---
## 9. Testing
### 9.1 Current State
No automated test suite exists. Manual testing performed through the web UI with output artifacts in `formatted/`:
| Artifact | Purpose |
|----------|---------|
| `test_stage_a.docx` – `test_stage_e.docx` | Incremental feature tests |
| `test_feat_full.docx` | Full feature integration |
| `test_feat_toc.docx` | Table of contents |
| `test_feat_pageref.docx` | Page reference fields |
| `test_feat_bookmarks.docx` | Bookmarks |
| `diag_minimal.docx` | Diagnostic output |
### 9.2 Recommended Test Coverage
- **Unit tests:** Tag parsing, style generation, margin calculations
- **Integration tests:** Full pipeline with sample manuscripts
- **Regression tests:** Document comparison against known-good outputs
- **Edge cases:** Empty chapters, missing tags, oversized images, 34+ chapters
---
## 10. Known Constraints & Limitations
1. **No undo/history:** Formatting is destructive — original file is not modified, but formatted output replaces previous version
2. **Single-user:** No concurrent session management; stateless file-based storage
3. **Tag-dependent:** Manuscript must use exact tag syntax; malformed tags cause silent failures
4. **Fixed page size:** 5.5 × 8.5 inches hardcoded; not configurable for other trim sizes
5. **Font-limited:** Only Caladea (body) and Georgia (headings) defined in spec
6. **No database:** All state stored on filesystem; no persistence across container restarts unless volumes mounted
7. **LibreOffice dependency:** PDF conversion requires LibreOffice headless, adding ~300 MB to Docker image
---
## 11. Future Considerations
- Automated test suite with pytest
- Support for additional trim sizes (6×9, 5×8)
- Custom font configuration
- Batch processing (multiple manuscripts)
- Version history / rollback
- Database-backed project tracking
- Webhook notifications on format completion
- Pre-flight checks for common manuscript issues (missing tags, inconsistent styles)