Spec for three cover generation improvements: omit obituaries from headlines, increase font size, and use pixel-width truncation. Made-with: Cursor
3.2 KiB
Cover Refinements Design
Date: 2026-04-06 Scope: Three targeted changes to the weekly newspaper cover generation
Context
The cover is a 480×800 JPEG with a masthead bar at the top and a translucent headline strip at the bottom. Headlines are currently rendered at font size 14 and truncated by character count (45 chars), which doesn't correspond to actual pixel width — causing text to be cut short before filling the available space. Obituary articles also appear in the headline list, which is undesirable.
Changes
1. Omit Obituaries from Cover Headlines
Problem: Obituary articles appear as cover headlines alongside news stories.
Solution: Filter articles whose categories JSON array contains "Obituaries" when building the headlines list. This applies at the three call sites that construct headlines before calling generate_cover:
src/routes/publish.py— manual publishsrc/routes/issues.py— regenerate issue coversrc/scheduler.py— auto-publish
Each site already iterates articles to build categories_list for AI prompt selection. The obituary filter will be applied when building both headlines and categories_list (excluding "Obituaries" from the prompt category pool is harmless since it has no matching prompt entry).
Identification: Category string match on "Obituaries" (case-sensitive, matching the RSS feed tag).
2. Increase Headline Font Size
Problem: Font size 14 is too small to read comfortably on the cover.
Solution: In _draw_text_overlays in src/cover.py:
- Headline font:
_get_font(14)→_get_font(18) - Line spacing:
22px→26px - Strip height formula:
28 + max_headlines * 22→28 + max_headlines * 26
3. Dynamic Pixel-Width Truncation
Problem: Character-count truncation (len(text) > 45) doesn't account for variable-width font glyphs. Headlines get truncated well before reaching the edge of the 480px canvas.
Solution: Replace character-count truncation with pixel-width measurement using Pillow's textbbox:
- Compute
max_width = width - 32(16px left padding + 16px right margin) - For each headline string (with bullet prefix), measure its rendered width via
draw.textbbox((0, 0), text, font=headline_font) - If it exceeds
max_width, find the longest prefix that fits (iterating from the end) and append"…" - The ellipsis itself must be included in the width measurement
This makes truncation adapt to actual font metrics and canvas dimensions automatically.
Files Modified
| File | Change |
|---|---|
src/cover.py |
Font size 14→18, line spacing 22→26, strip height formula, replace char truncation with pixel-width truncation |
src/routes/publish.py |
Filter obituaries from headlines list |
src/routes/issues.py |
Filter obituaries from headlines list |
src/scheduler.py |
Filter obituaries from headlines list |
tests/test_cover.py |
Update tests for new truncation behavior |
Testing
- Existing cover generation tests updated to reflect new font/spacing values
- Verify pixel-width truncation produces headlines that fill available width without overflow
- Verify obituary articles are excluded from cover headlines