Six-skill presentation system: ingest talks into a rhetoric vault, run interactive clarification, generate a speaker profile, create presentations that match your documented patterns, produce the deck illustrations + thumbnail visual layer, and publish talk pages to a Jekyll shownotes site. Includes a 102-entry Presentation Patterns taxonomy (91 observable, 11 unobservable go-live items) for scoring, brainstorming, and go-live preparation.
86
92%
Does it follow best practices?
Impact
86%
1.24xAverage score across 26 eval scenarios
Advisory
Suggest reviewing before use
"""Tests for apply-illustrations-to-deck.py — zone parsing, scrim, title repositioning."""
from pathlib import Path
from pptx import Presentation
from pptx.util import Inches
from conftest import make_deck
OUTLINE_WITH_ZONES = """\
### Slide 2: The Problem
- Format: **FULL**
- Image prompt: `A confused developer`
- Safe zone: upper_third (painted sky backdrop)
- Text: **The Problem**
### Slide 5: The Solution
- Format: **FULL**
- Image prompt: `A clean architecture`
- Safe zone: lower_third (flat gradient)
- Text: **The Solution**
### Slide 8: Split View
- Format: **FULL**
- Image prompt: `Side by side comparison`
- Safe zone: left_half (studio backdrop)
- Text: **Before and After**
"""
OUTLINE_NO_ZONES = """\
### Slide 1: Title
- Format: **FULL**
- Image prompt: `A title slide`
- Text: **Title**
"""
def test_parse_zones(apply_illustrations, tmp_path):
outline = tmp_path / "outline.md"
outline.write_text(OUTLINE_WITH_ZONES)
zones = apply_illustrations.parse_zones(outline)
assert zones == {2: "upper_third", 5: "lower_third", 8: "left_half"}
def test_parse_zones_empty(apply_illustrations, tmp_path):
outline = tmp_path / "outline.md"
outline.write_text(OUTLINE_NO_ZONES)
zones = apply_illustrations.parse_zones(outline)
assert zones == {}
def test_parse_zones_all_types(apply_illustrations, tmp_path):
text = """\
### Slide 1: A
- Safe zone: upper_third (sky)
### Slide 2: B
- Safe zone: middle_third (frame)
### Slide 3: C
- Safe zone: lower_third (ground)
### Slide 4: D
- Safe zone: left_half (wall)
### Slide 5: E
- Safe zone: right_half (backdrop)
"""
outline = tmp_path / "outline.md"
outline.write_text(text)
zones = apply_illustrations.parse_zones(outline)
assert len(zones) == 5
assert zones[1] == "upper_third"
assert zones[2] == "middle_third"
assert zones[3] == "lower_third"
assert zones[4] == "left_half"
assert zones[5] == "right_half"
def test_zone_layout_keys(apply_illustrations):
"""All five zones have layout entries."""
for zone in ["upper_third", "middle_third", "lower_third", "left_half", "right_half"]:
assert zone in apply_illustrations.ZONE_LAYOUT
layout = apply_illustrations.ZONE_LAYOUT[zone]
assert "top_in" in layout
assert "left_in" in layout
assert "width_in" in layout
assert "height_in" in layout
def test_scrim_shape_name_constant(apply_illustrations):
"""Scrim uses a named constant for detection."""
assert apply_illustrations.SCRIM_SHAPE_NAME == "_title_scrim"
def test_ensure_scrim_adds_shape(apply_illustrations, tmp_path):
"""ensure_scrim adds a scrim rectangle to a slide."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
# Add a textbox so the slide has text
slide.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1))
result = apply_illustrations.ensure_scrim(slide, "upper_third", "000000", 45000)
assert result == 1
# Verify a shape with the scrim name was added
scrim_shapes = [s for s in slide.shapes if s.name == "_title_scrim"]
assert len(scrim_shapes) == 1
def test_ensure_scrim_idempotent(apply_illustrations, tmp_path):
"""Running ensure_scrim twice doesn't add a second scrim."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
slide.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1))
apply_illustrations.ensure_scrim(slide, "upper_third", "000000", 45000)
result = apply_illustrations.ensure_scrim(slide, "upper_third", "000000", 45000)
assert result == 0 # Already present, not added again
scrim_shapes = [s for s in slide.shapes if s.name == "_title_scrim"]
assert len(scrim_shapes) == 1
def test_reposition_title(apply_illustrations, tmp_path):
"""Title text shapes are repositioned to the zone."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
tb = slide.shapes.add_textbox(Inches(1), Inches(1), Inches(4), Inches(1))
tb.text_frame.paragraphs[0].add_run().text = "Title"
moved = apply_illustrations.reposition_title(slide, "upper_third")
assert moved == 1
def test_reposition_title_placeholder(apply_illustrations, tmp_path):
"""Placeholder title shapes (from Title layouts) are also repositioned."""
prs = Presentation()
title_layout = prs.slide_layouts[0] # Title Slide layout
slide = prs.slides.add_slide(title_layout)
if slide.shapes.title:
slide.shapes.title.text = "Placeholder Title"
moved = apply_illustrations.reposition_title(slide, "lower_third")
# Title Slide has title + subtitle placeholders
assert moved >= 1
def test_parse_zones_no_cross_slide_match(apply_illustrations, tmp_path):
"""Safe zone from slide 5 doesn't leak into slide 4."""
text = """\
### Slide 4: No Zone Here
- Format: **FULL**
- Image prompt: `A scene`
### Slide 5: Has Zone
- Format: **FULL**
- Image prompt: `Another scene`
- Safe zone: lower_third (gradient)
"""
outline = tmp_path / "outline.md"
outline.write_text(text)
zones = apply_illustrations.parse_zones(outline)
assert 4 not in zones
assert zones.get(5) == "lower_third"
# ── IMG+TXT layout tests ─────────────────────────────────────────────
OUTLINE_MIXED_FORMATS = """\
### Slide 1: Hook
- Format: **FULL**
- Image prompt: `Opening scene`
- Safe zone: upper_third (sky)
### Slide 2: Detail
- Format: **IMG+TXT**
- Image prompt: `A diagram with explanation`
### Slide 3: Exception
- Format: **EXCEPTION** — real screenshot
- Visual: screenshot of the dashboard
### Slide 4: Both fields
- Format: **IMG+TXT**
- Safe zone: lower_third (gradient)
- Image prompt: `Mixed signals`
"""
def test_parse_img_txt_slides(apply_illustrations, tmp_path):
outline = tmp_path / "outline.md"
outline.write_text(OUTLINE_MIXED_FORMATS)
img_txt = apply_illustrations.parse_img_txt_slides(outline)
# Slide 2 is IMG+TXT only — included
assert 2 in img_txt
# Slide 1 is FULL — excluded
assert 1 not in img_txt
# Slide 3 is EXCEPTION — excluded
assert 3 not in img_txt
# Slide 4 has both Format: IMG+TXT and Safe zone — Safe zone wins, excluded
assert 4 not in img_txt
def test_parse_img_txt_slides_empty(apply_illustrations, tmp_path):
outline = tmp_path / "outline.md"
outline.write_text(OUTLINE_NO_ZONES)
img_txt = apply_illustrations.parse_img_txt_slides(outline)
assert img_txt == set()
def test_parse_zones_and_img_txt_disjoint(apply_illustrations, tmp_path):
"""A slide with both Safe zone and Format: IMG+TXT goes to zones, not img_txt."""
outline = tmp_path / "outline.md"
outline.write_text(OUTLINE_MIXED_FORMATS)
zones = apply_illustrations.parse_zones(outline)
img_txt = apply_illustrations.parse_img_txt_slides(outline)
# Slide 4 has Safe zone — it's a FULL slide via the zone path
assert zones.get(4) == "lower_third"
assert 4 not in img_txt
def test_apply_img_txt_layout_repositions_picture(apply_illustrations, tmp_path):
"""Picture in an IMG+TXT slide is moved to the left column at ~60% width."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
# Add a picture at an arbitrary position
img = tmp_path / "test.png"
# Minimal 1x1 PNG
img.write_bytes(
bytes.fromhex(
"89504e470d0a1a0a0000000d49484452000000010000000108020000"
"00907753de0000000c4944415478da6300010000000500010d0a2db40000"
"000049454e44ae426082"
)
)
slide.shapes.add_picture(str(img), Inches(2), Inches(2), Inches(4), Inches(3))
pic_moved, _ = apply_illustrations.apply_img_txt_layout(slide)
assert pic_moved == 1
pictures = [s for s in slide.shapes if s.shape_type == 13] # PICTURE
bg = pictures[0]
assert bg.left == Inches(apply_illustrations.IMGTXT_IMG_LEFT_IN)
assert bg.top == Inches(apply_illustrations.IMGTXT_IMG_TOP_IN)
assert bg.width == Inches(apply_illustrations.IMGTXT_IMG_WIDTH_IN)
assert bg.height == Inches(apply_illustrations.IMGTXT_IMG_HEIGHT_IN)
def test_apply_img_txt_layout_repositions_title(apply_illustrations):
"""Title placeholder is repositioned to the right column."""
prs = Presentation()
title_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_layout)
if slide.shapes.title:
slide.shapes.title.text = "Right Column Title"
_, text_moved = apply_illustrations.apply_img_txt_layout(slide)
assert text_moved >= 1
assert slide.shapes.title.left == Inches(apply_illustrations.IMGTXT_TEXT_LEFT_IN)
assert slide.shapes.title.top == Inches(apply_illustrations.IMGTXT_TITLE_TOP_IN)
def test_swap_or_insert_picture_inserts_when_missing(apply_illustrations, tmp_path):
"""When a slide has no picture shape, swap_or_insert_picture adds one."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
# No picture on the slide
img = tmp_path / "test.png"
img.write_bytes(
bytes.fromhex(
"89504e470d0a1a0a0000000d49484452000000010000000108020000"
"00907753de0000000c4944415478da6300010000000500010d0a2db40000"
"000049454e44ae426082"
)
)
pic = apply_illustrations.swap_or_insert_picture(slide, img)
assert pic is not None
pictures = [s for s in slide.shapes if s.shape_type == 13]
assert len(pictures) == 1
# Inserted full-bleed at slide dimensions
assert pictures[0].left == Inches(0)
assert pictures[0].top == Inches(0)
def test_swap_or_insert_picture_swaps_when_present(apply_illustrations, tmp_path):
"""When a slide already has a picture shape, swap_or_insert_picture swaps it."""
prs = Presentation()
blank = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank)
img1 = tmp_path / "before.png"
img2 = tmp_path / "after.png"
png_bytes = bytes.fromhex(
"89504e470d0a1a0a0000000d49484452000000010000000108020000"
"00907753de0000000c4944415478da6300010000000500010d0a2db40000"
"000049454e44ae426082"
)
img1.write_bytes(png_bytes)
img2.write_bytes(png_bytes)
slide.shapes.add_picture(str(img1), Inches(2), Inches(2), Inches(4), Inches(3))
pictures_before = [s for s in slide.shapes if s.shape_type == 13]
assert len(pictures_before) == 1
pic = apply_illustrations.swap_or_insert_picture(slide, img2)
pictures_after = [s for s in slide.shapes if s.shape_type == 13]
# Still exactly one picture — swapped, not added
assert len(pictures_after) == 1
# python-pptx returns fresh wrapper objects each iteration, so identity-check
# via the underlying XML element rather than the Python object.
assert pic._element is pictures_after[0]._element
# Position untouched by swap (the FULL/IMG+TXT layout repositioning happens after)
assert pic.left == Inches(2)
assert pic.top == Inches(2)
_MIN_PNG = bytes.fromhex(
"89504e470d0a1a0a0000000d49484452000000010000000108020000"
"00907753de0000000c4944415478da6300010000000500010d0a2db40000"
"000049454e44ae426082"
)
def test_apply_full_records_background_not_picture(apply_illustrations, tmp_path):
"""FULL slides are recorded for the VBA background pass, not given a picture shape."""
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
deck = tmp_path / "deck.pptx"
make_deck(3).save(str(deck))
illust_dir = tmp_path / "illustrations"
illust_dir.mkdir()
(illust_dir / "slide-02.png").write_bytes(_MIN_PNG)
outline = tmp_path / "outline.md"
outline.write_text(
"### Slide 2: The Problem\n- Format: **FULL**\n- Safe zone: upper_third (sky)\n"
)
out_deck = tmp_path / "out.pptx"
zones = apply_illustrations.parse_zones(outline)
_, backgrounds = apply_illustrations.apply(
deck, illust_dir, zones, set(), out_deck, "png", "000000", 45000,
)
# FULL slide 2 is recorded for the background pass with an absolute path…
assert backgrounds == {2: str((illust_dir / "slide-02.png").resolve())}
# …and NOT inserted as a picture shape (background fill is applied later via VBA)
slide2 = Presentation(str(out_deck)).slides[1]
pictures = [s for s in slide2.shapes if s.shape_type == MSO_SHAPE_TYPE.PICTURE]
assert pictures == []
def test_apply_imgtxt_keeps_picture_shape(apply_illustrations, tmp_path):
"""IMG+TXT slides still get a real picture shape (not a background fill)."""
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE_TYPE
deck = tmp_path / "deck.pptx"
make_deck(3).save(str(deck))
illust_dir = tmp_path / "illustrations"
illust_dir.mkdir()
(illust_dir / "slide-02.png").write_bytes(_MIN_PNG)
outline = tmp_path / "outline.md"
outline.write_text("### Slide 2: Detail\n- Format: **IMG+TXT**\n")
out_deck = tmp_path / "out.pptx"
img_txt = apply_illustrations.parse_img_txt_slides(outline)
_, backgrounds = apply_illustrations.apply(
deck, illust_dir, {}, img_txt, out_deck, "png", "000000", 45000,
)
# IMG+TXT is not a background; it stays a picture shape
assert backgrounds == {}
slide2 = Presentation(str(out_deck)).slides[1]
pictures = [s for s in slide2.shapes if s.shape_type == MSO_SHAPE_TYPE.PICTURE]
assert len(pictures) == 1
def test_imgtxt_geometry_constants_consistent(apply_illustrations):
"""IMG+TXT image + text columns + margins fit the 13.333" slide."""
img_right = (
apply_illustrations.IMGTXT_IMG_LEFT_IN
+ apply_illustrations.IMGTXT_IMG_WIDTH_IN
)
text_right = (
apply_illustrations.IMGTXT_TEXT_LEFT_IN
+ apply_illustrations.IMGTXT_TEXT_WIDTH_IN
)
assert img_right < apply_illustrations.IMGTXT_TEXT_LEFT_IN, (
"Image must finish before the text column starts"
)
assert text_right <= apply_illustrations.SLIDE_W_IN, (
"Text column must fit within the slide width"
).github
eval-resources
humor-postmortem-blind-spots
qr-bitly-slug-from-outline
qr-missing-shortener-detection
shownotes-publisher-omit-placeholder
shownotes-publisher-publish-no-date
shownotes-publisher-publish-with-date
shownotes-publisher-update-add-video
video-extraction-diagnostics
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
rules
scripts
skills
illustrations
presentation-creator
references
patterns
build
deliver
prepare
scripts
shownotes-publisher
vault-clarification
vault-ingress
vault-profile
tests