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
#!/usr/bin/env python3
"""Convert a backgrounds manifest JSON into the ApplyBackgrounds spec string.
The manifest is produced by `apply-illustrations-to-deck.py --backgrounds-out`:
{"backgrounds": {"<1-based slide #>": "/abs/image", ...}}
The spec string consumed by the ApplyBackgrounds VBA macro is
`<#>=<path>;<#>=<path>...`, sorted by slide number. Paths may not contain the
`;` or `=` delimiters. This deterministic conversion is split out of
`apply-backgrounds.sh` so it can be unit-tested (the VBA side cannot run in CI).
Usage:
backgrounds-manifest-to-spec.py <manifest.json> # prints the spec to stdout
"""
import json
import sys
from pathlib import Path
def manifest_to_spec(manifest: object) -> str:
"""Return the `#=path;#=path` spec for ApplyBackgrounds, sorted by slide #.
Raises ValueError (with an actionable message) on any malformed input: a
non-object manifest, a non-object `backgrounds`, an empty manifest, a
non-integer slide key, a non-string path, or a path containing a `;`/`=`
delimiter (which would corrupt the spec the macro parses).
"""
if not isinstance(manifest, dict):
raise ValueError(
"manifest must be a JSON object like "
'{"backgrounds": {"<slide #>": "/abs/image", ...}}'
)
backgrounds = manifest.get("backgrounds", {})
if not isinstance(backgrounds, dict):
raise ValueError("manifest 'backgrounds' must be an object mapping slide # -> image path")
if not backgrounds:
raise ValueError(
"manifest has no 'backgrounds' entries — nothing to apply; skip the "
"ApplyBackgrounds pass when there are no FULL (Safe zone) slides"
)
def slide_num(key: object) -> int:
try:
return int(key)
except (TypeError, ValueError):
raise ValueError(f"slide key {key!r} is not an integer") from None
tokens = []
for key in sorted(backgrounds, key=slide_num):
path = backgrounds[key]
if not isinstance(path, str):
raise ValueError(f"image path for slide {key} must be a string, got {type(path).__name__}")
if ";" in path or "=" in path:
raise ValueError(
f"image path for slide {key} contains a reserved spec delimiter "
f"(';' or '='): {path!r} — rename the file so its path has neither"
)
tokens.append(f"{slide_num(key)}={path}")
return ";".join(tokens)
def main() -> None:
if len(sys.argv) != 2:
print("usage: backgrounds-manifest-to-spec.py <manifest.json>", file=sys.stderr)
sys.exit(2)
path = Path(sys.argv[1])
try:
raw = path.read_text()
except OSError as exc:
print(f"ERROR: cannot read manifest {path}: {exc.strerror or exc} — "
f"generate it with apply-illustrations-to-deck.py --backgrounds-out", file=sys.stderr)
sys.exit(1)
try:
manifest = json.loads(raw)
except json.JSONDecodeError as exc:
print(f"ERROR: manifest {path} is not valid JSON: {exc}", file=sys.stderr)
sys.exit(1)
try:
print(manifest_to_spec(manifest))
except ValueError as exc:
print(f"ERROR: {exc}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main().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