Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2550067f3 | ||
|
|
ffc7dd8162 |
Binary file not shown.
@@ -22,6 +22,55 @@ and layouts exactly as designed.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## WORKFLOW — ALWAYS FOLLOW THIS PROCESS
|
||||||
|
|
||||||
|
Before generating any slides, complete these 3 steps **in order**. Do not skip straight to generating.
|
||||||
|
|
||||||
|
### Step 1: Brief the presentation
|
||||||
|
|
||||||
|
Ask the user these questions **in a single message** before doing anything else:
|
||||||
|
|
||||||
|
1. **Doel** — Wat is het doel van deze presentatie? (informeren / overtuigen / updaten / inspireren)
|
||||||
|
2. **Kernboodschap** — Als het publiek één ding onthoudt, wat moet dat zijn?
|
||||||
|
3. **Publiek** — Voor wie is dit? (intern team, MT, externe partner, all-hands)
|
||||||
|
4. **Taal** — Nederlands of Engels?
|
||||||
|
5. **Beschikbare bronnen** — Welke databronnen mogen we gebruiken voor de inhoud?
|
||||||
|
|
||||||
|
For the last question, check which connectors/MCPs are active and mention them explicitly as options:
|
||||||
|
- **Slack** → recente updates, team-aankondigingen, discussies ophalen
|
||||||
|
- **Gmail** → e-mails, klantcommunicatie, recente updates
|
||||||
|
- **Google Drive** → documenten, rapporten, bestaand materiaal
|
||||||
|
- **Ahrefs / GSC** → SEO data, keyword performance, traffic metrics
|
||||||
|
- **Contentful** → productcontent, beschrijvingen
|
||||||
|
- **Datadog / analytics** → performance data en metrics
|
||||||
|
|
||||||
|
### Step 2: Propose a slide structure
|
||||||
|
|
||||||
|
Based on the brief, **propose a numbered slide plan** and wait for approval before generating anything. Example format:
|
||||||
|
|
||||||
|
```
|
||||||
|
Voorgestelde opzet:
|
||||||
|
1. Titelslide
|
||||||
|
2. Agenda
|
||||||
|
3. Sectie-divider — Q1 Financiën
|
||||||
|
4. Big number — Omzethighlight
|
||||||
|
5. Chart KPI cards — Financieel overzicht
|
||||||
|
6. Section-divider — AI & Automation
|
||||||
|
7. Before/after — Contentproductie
|
||||||
|
8. Impact statement
|
||||||
|
9. Afsluiting
|
||||||
|
|
||||||
|
Klopt deze opzet? Wil je slides toevoegen, weglaten of verplaatsen?
|
||||||
|
```
|
||||||
|
|
||||||
|
**Do not generate until the user approves the structure.**
|
||||||
|
|
||||||
|
### Step 3: Generate
|
||||||
|
|
||||||
|
Only after approval: set up the generator, build the slide plan, and run `generate()`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## SETUP (run once per session)
|
## SETUP (run once per session)
|
||||||
|
|
||||||
Before generating, ensure the generator and baseline are available:
|
Before generating, ensure the generator and baseline are available:
|
||||||
@@ -70,7 +119,7 @@ generate([
|
|||||||
("Team Strategy & Leadership", "Author Name / Team"),
|
("Team Strategy & Leadership", "Author Name / Team"),
|
||||||
]),
|
]),
|
||||||
("closing", []),
|
("closing", []),
|
||||||
], "/Users/derkdissselhof/Library/Application Support/Claude/local-agent-mode-sessions/a2d0567c-5a2d-4037-a100-87a5e74b9a55/3f471e31-d031-4ffe-bb3a-282799a05800/local_0cbc5cf3-74a0-4400-80d7-33c648a960dc/outputs/MyPresentation.pptx")
|
], "/sessions/brave-bold-cerf/mnt/outputs/MyPresentation.pptx")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -221,7 +270,7 @@ Light gray background with 4 equal feature/USP cards.
|
|||||||
| `Vier redenen om voor ons te kiezen` | Slide title |
|
| `Vier redenen om voor ons te kiezen` | Slide title |
|
||||||
| `Laagste prijs` | Card title line 1 (all 4 cards identical in baseline) |
|
| `Laagste prijs` | Card title line 1 (all 4 cards identical in baseline) |
|
||||||
| `garantie` | Card title line 2 (all 4 cards identical in baseline) |
|
| `garantie` | Card title line 2 (all 4 cards identical in baseline) |
|
||||||
| `All-inclusive prijzen zonder verborgen kosten...` | Card body (all 4 identical in baseline) |
|
| `All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.` | Card body (all 4 identical in baseline) |
|
||||||
| `30%` | Card stat (all 4 identical in baseline) |
|
| `30%` | Card stat (all 4 identical in baseline) |
|
||||||
| `goedkoper dan traditioneel` | Card stat label (all 4 identical in baseline) |
|
| `goedkoper dan traditioneel` | Card stat label (all 4 identical in baseline) |
|
||||||
|
|
||||||
@@ -235,19 +284,19 @@ cards share identical placeholder text, pass `n=1..4` to target each card indivi
|
|||||||
# Card 1
|
# Card 1
|
||||||
("Laagste prijs", "Armeense lunch", 1),
|
("Laagste prijs", "Armeense lunch", 1),
|
||||||
("garantie", "Tolma & Ghapama", 1),
|
("garantie", "Tolma & Ghapama", 1),
|
||||||
("All-inclusive prijzen zonder verborgen kosten...", "Sona nodigde iedereen uit voor een Armeense lunch op 10 april.", 1),
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.", "Sona nodigde iedereen uit voor een Armeense lunch op 10 april.", 1),
|
||||||
# Card 2
|
# Card 2
|
||||||
("Laagste prijs", "Paas taart", 2),
|
("Laagste prijs", "Paas taart", 2),
|
||||||
("garantie", "van Marte", 2),
|
("garantie", "van Marte", 2),
|
||||||
("All-inclusive prijzen zonder verborgen kosten...", "Marte verraste het team met een zelfgemaakte paastaart.", 2),
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.", "Marte verraste het team met een zelfgemaakte paastaart.", 2),
|
||||||
# Card 3
|
# Card 3
|
||||||
("Laagste prijs", "Chinese snacks", 3),
|
("Laagste prijs", "Chinese snacks", 3),
|
||||||
("garantie", "van Irene", 3),
|
("garantie", "van Irene", 3),
|
||||||
("All-inclusive prijzen zonder verborgen kosten...", "Irene bracht authentieke Chinese snacks mee voor het hele kantoor.", 3),
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.", "Irene bracht authentieke Chinese snacks mee voor het hele kantoor.", 3),
|
||||||
# Card 4
|
# Card 4
|
||||||
("Laagste prijs", "Boek tip", 4),
|
("Laagste prijs", "Boek tip", 4),
|
||||||
("garantie", "van Dennis", 4),
|
("garantie", "van Dennis", 4),
|
||||||
("All-inclusive prijzen zonder verborgen kosten...", "Dennis deelde zijn favoriete boek: Zero to One van Peter Thiel.", 4),
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.", "Dennis deelde zijn favoriete boek: Zero to One van Peter Thiel.", 4),
|
||||||
# Remove stat elements (replace with empty or relevant values)
|
# Remove stat elements (replace with empty or relevant values)
|
||||||
("30%", ""),
|
("30%", ""),
|
||||||
("goedkoper dan traditioneel", ""),
|
("goedkoper dan traditioneel", ""),
|
||||||
@@ -319,12 +368,15 @@ White slide comparing two states side by side (gray left panel, dark right panel
|
|||||||
| `nodig` | Left stat 3 label |
|
| `nodig` | Left stat 3 label |
|
||||||
| `Geautomatiseerd` | Right panel title |
|
| `Geautomatiseerd` | Right panel title |
|
||||||
| `Claude Skills handelen keyword research, copy generation en Contentful publishing af. Mens reviewt alleen het eindresultaat.` | Right panel body |
|
| `Claude Skills handelen keyword research, copy generation en Contentful publishing af. Mens reviewt alleen het eindresultaat.` | Right panel body |
|
||||||
| `15min` | Right stat 1 |
|
| `15min` | Right stat 1 number |
|
||||||
| `500+` | Right stat 2 |
|
| `per product per markt` | Right stat 1 label (**appears twice** — the global replacement above also covers this) |
|
||||||
|
| `500+` | Right stat 2 number |
|
||||||
| `producten per week` | Right stat 2 label |
|
| `producten per week` | Right stat 2 label |
|
||||||
| `0.5 FTE` | Right stat 3 |
|
| `0.5 FTE` | Right stat 3 number |
|
||||||
| `menselijke review` | Right stat 3 label |
|
| `menselijke review` | Right stat 3 label |
|
||||||
|
|
||||||
|
> **Important:** `per product per markt` is used as the label for **both** left stat 1 and right stat 1. A single global replacement `("per product per markt", "your new label")` updates both sides at once. If you want different labels per side, replace right stat 1 first with a unique temporary value, then do the global replacement.
|
||||||
|
>
|
||||||
> Note: `⬤ VOORHEEN` and `⬤ NU MET AI SKILLS` are colored dot labels — best left as-is.
|
> Note: `⬤ VOORHEEN` and `⬤ NU MET AI SKILLS` are colored dot labels — best left as-is.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -495,7 +547,7 @@ plan = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# 3. Generate
|
# 3. Generate
|
||||||
generate(plan, "/Users/derkdissselhof/Library/Application Support/Claude/local-agent-mode-sessions/a2d0567c-5a2d-4037-a100-87a5e74b9a55/3f471e31-d031-4ffe-bb3a-282799a05800/local_0cbc5cf3-74a0-4400-80d7-33c648a960dc/outputs/MyPresentation.pptx")
|
generate(plan, "/sessions/brave-bold-cerf/mnt/outputs/MyPresentation.pptx")
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -266,6 +266,11 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
{slide_order[i][1] for i in range(total) if i not in wanted}
|
{slide_order[i][1] for i in range(total) if i not in wanted}
|
||||||
)
|
)
|
||||||
used_media = collect_used_media(src, drop_paths)
|
used_media = collect_used_media(src, drop_paths)
|
||||||
|
# Also add media from copy sources (they reference same files as originals)
|
||||||
|
# (already captured above since originals' rels are not in drop_paths)
|
||||||
|
|
||||||
|
# Collect media for copied slides (same source rels → same media)
|
||||||
|
# Already included in used_media since source slides are in keep_paths.
|
||||||
|
|
||||||
out_buf = BytesIO()
|
out_buf = BytesIO()
|
||||||
with zipfile.ZipFile(out_buf, 'w', zipfile.ZIP_DEFLATED) as dst:
|
with zipfile.ZipFile(out_buf, 'w', zipfile.ZIP_DEFLATED) as dst:
|
||||||
@@ -307,6 +312,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
if item == 'ppt/presentation.xml':
|
if item == 'ppt/presentation.xml':
|
||||||
data = src.read(item).decode('utf-8')
|
data = src.read(item).decode('utf-8')
|
||||||
|
|
||||||
|
# Extract existing sldId elements → map rId → element
|
||||||
rid_to_elem = {}
|
rid_to_elem = {}
|
||||||
existing_ids = []
|
existing_ids = []
|
||||||
for m in re.finditer(r'<p:sldId\b[^/]*/>', data):
|
for m in re.finditer(r'<p:sldId\b[^/]*/>', data):
|
||||||
@@ -319,6 +325,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
|
|
||||||
next_sld_id = max(existing_ids, default=256) + 1
|
next_sld_id = max(existing_ids, default=256) + 1
|
||||||
|
|
||||||
|
# Build sldId elements for copies
|
||||||
for copy_rid, (src_info, _, _, copy_num) in copies.items():
|
for copy_rid, (src_info, _, _, copy_num) in copies.items():
|
||||||
elem = (
|
elem = (
|
||||||
f'<p:sldId id="{next_sld_id}"'
|
f'<p:sldId id="{next_sld_id}"'
|
||||||
@@ -327,6 +334,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
rid_to_elem[copy_rid] = elem
|
rid_to_elem[copy_rid] = elem
|
||||||
next_sld_id += 1
|
next_sld_id += 1
|
||||||
|
|
||||||
|
# Reorder sldIdLst to match plan_order
|
||||||
ordered = ''.join(
|
ordered = ''.join(
|
||||||
rid_to_elem[rid] for rid in plan_order if rid in rid_to_elem
|
rid_to_elem[rid] for rid in plan_order if rid in rid_to_elem
|
||||||
)
|
)
|
||||||
@@ -342,6 +350,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
if item == 'ppt/_rels/presentation.xml.rels':
|
if item == 'ppt/_rels/presentation.xml.rels':
|
||||||
data = src.read(item).decode('utf-8')
|
data = src.read(item).decode('utf-8')
|
||||||
|
|
||||||
|
# Remove unwanted slide rels
|
||||||
def keep_rel(m):
|
def keep_rel(m):
|
||||||
rid = re.search(r'Id="([^"]+)"', m.group(0))
|
rid = re.search(r'Id="([^"]+)"', m.group(0))
|
||||||
rtype = re.search(r'Type="([^"]+)"', m.group(0))
|
rtype = re.search(r'Type="([^"]+)"', m.group(0))
|
||||||
@@ -350,6 +359,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
return m.group(0)
|
return m.group(0)
|
||||||
data = re.sub(r'<Relationship[^>]*/>', keep_rel, data)
|
data = re.sub(r'<Relationship[^>]*/>', keep_rel, data)
|
||||||
|
|
||||||
|
# Add relationships for copied slides
|
||||||
copy_rels = ''.join(
|
copy_rels = ''.join(
|
||||||
f'<Relationship Id="{copy_rid}" '
|
f'<Relationship Id="{copy_rid}" '
|
||||||
f'Type="{SLIDE_REL}" '
|
f'Type="{SLIDE_REL}" '
|
||||||
@@ -364,6 +374,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
if item == '[Content_Types].xml':
|
if item == '[Content_Types].xml':
|
||||||
data = src.read(item).decode('utf-8')
|
data = src.read(item).decode('utf-8')
|
||||||
|
|
||||||
|
# Remove unwanted slide overrides
|
||||||
def keep_ct(m):
|
def keep_ct(m):
|
||||||
ct_type = re.search(r'ContentType="([^"]+)"', m.group(0))
|
ct_type = re.search(r'ContentType="([^"]+)"', m.group(0))
|
||||||
part = re.search(r'PartName="([^"]+)"', m.group(0))
|
part = re.search(r'PartName="([^"]+)"', m.group(0))
|
||||||
@@ -374,6 +385,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
return m.group(0)
|
return m.group(0)
|
||||||
data = re.sub(r'<Override[^>]*/>', keep_ct, data)
|
data = re.sub(r'<Override[^>]*/>', keep_ct, data)
|
||||||
|
|
||||||
|
# Add content types for copied slides
|
||||||
copy_cts = ''.join(
|
copy_cts = ''.join(
|
||||||
f'<Override PartName="/ppt/slides/slide{copy_num}.xml"'
|
f'<Override PartName="/ppt/slides/slide{copy_num}.xml"'
|
||||||
f' ContentType="{SLIDE_CT}"/>'
|
f' ContentType="{SLIDE_CT}"/>'
|
||||||
@@ -388,8 +400,8 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
|
|
||||||
# ── Write copied slide files ──────────────────────────────────────
|
# ── Write copied slide files ──────────────────────────────────────
|
||||||
for copy_rid, (src_info, replacements, template, copy_num) in copies.items():
|
for copy_rid, (src_info, replacements, template, copy_num) in copies.items():
|
||||||
src_path = src_info[0]
|
src_path = src_info[0] # e.g. ppt/slides/slide12.xml
|
||||||
src_rels = src_info[1]
|
src_rels = src_info[1] # e.g. ppt/slides/_rels/slide12.xml.rels
|
||||||
dest_path = f'ppt/slides/slide{copy_num}.xml'
|
dest_path = f'ppt/slides/slide{copy_num}.xml'
|
||||||
dest_rels = f'ppt/slides/_rels/slide{copy_num}.xml.rels'
|
dest_rels = f'ppt/slides/_rels/slide{copy_num}.xml.rels'
|
||||||
|
|
||||||
@@ -400,6 +412,7 @@ def generate(slide_plan, output_path, media=None, page_numbers=True):
|
|||||||
dst.writestr(dest_path, data)
|
dst.writestr(dest_path, data)
|
||||||
print(f" ✓ {template:30s} (copy → slide{copy_num}.xml)")
|
print(f" ✓ {template:30s} (copy → slide{copy_num}.xml)")
|
||||||
|
|
||||||
|
# Copy the rels file too (same media references)
|
||||||
if src_rels in src.namelist():
|
if src_rels in src.namelist():
|
||||||
dst.writestr(dest_rels, src.read(src_rels))
|
dst.writestr(dest_rels, src.read(src_rels))
|
||||||
|
|
||||||
@@ -449,73 +462,80 @@ if __name__ == '__main__':
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
("process-timeline", [
|
("process-timeline", [
|
||||||
("WORKFLOW", "MAART → APRIL 2026"),
|
("WORKFLOW", "MAART \u2192 APRIL 2026"),
|
||||||
("Van ontwerp tot levering", "Een maand vol events en verbinding"),
|
("Van ontwerp tot levering", "Een maand vol events en verbinding"),
|
||||||
("Upload", "Ronald McDonald"),
|
("Upload", "Ronald McDonald"),
|
||||||
("Upload je ontwerp of gebruik onze online editor.",
|
("Upload je ontwerp of gebruik onze online editor.",
|
||||||
"Team kookte op 25 maart voor gezinnen bij het Ronald McDonald Huis."),
|
"Team kookte op 25 maart voor gezinnen bij het Ronald McDonald Huis."),
|
||||||
("Designcheck", "HelloBoxing"),
|
("Designcheck", "HelloBoxing"),
|
||||||
("Automatische controle op resolutie, afloop en kleuren.",
|
("Automatische controle op resolutie, afloop en kleuren.",
|
||||||
"Bokslessen hernomen — bi-weekly op donderdag, start 16 april."),
|
"Bokslessen hernomen \u2014 bi-weekly op donderdag, start 16 april."),
|
||||||
("Productie", "CEO Bezoek"),
|
("Productie", "CEO Bezoek"),
|
||||||
("We matchen je order aan de beste supplier.",
|
("We matchen je order aan de beste supplier.",
|
||||||
"17 CEO's aanwezig op 2 april voor Michael's AI-talk in the living."),
|
"17 CEO\u2019s aanwezig op 2 april voor Michael\u2019s AI-talk in the living."),
|
||||||
("Levering", "Strategy Days"),
|
("Levering", "Strategy Days"),
|
||||||
("Track & trace tot aan je deur. Gemiddeld 5 werkdagen.",
|
("Track & trace tot aan je deur. Gemiddeld 5 werkdagen.",
|
||||||
"Twee dagen strategische afstemming op 14 & 15 april."),
|
"Twee dagen strategische afstemming op 14 & 15 april."),
|
||||||
("Gemiddelde levertijd: ", "Keynote: "),
|
("Gemiddelde levertijd: ", "Keynote: "),
|
||||||
("5 werkdagen in NL/BE", "vrijdag 17 april om 16:30"),
|
("5 werkdagen in NL/BE", "vrijdag 17 april om 16:30"),
|
||||||
("Express: 2 werkdagen →", "Met de laatste strategy updates →"),
|
("Express: 2 werkdagen \u2192", "Met de laatste strategy updates \u2192"),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
("big-number", [
|
("big-number", [
|
||||||
("Q1 HIGHLIGHT", "CEO BEZOEK"),
|
("Q1 HIGHLIGHT", "CEO BEZOEK"),
|
||||||
("+42%", "17"),
|
("+42%", "17"),
|
||||||
("Year-over-year growth in new customer acquisition",
|
("Year-over-year growth in new customer acquisition",
|
||||||
"CEO's aanwezig bij Michael's AI-talk in de Rotterdam living"),
|
"CEO\u2019s aanwezig bij Michael\u2019s AI-talk in the Rotterdam living"),
|
||||||
("Driven by marketplace expansion into 3 new markets and a 28% improvement in organic search visibility across all locales.",
|
("Driven by marketplace expansion into 3 new markets and a 28% improvement in organic search visibility across all locales.",
|
||||||
"Op 2 april verwelkomde het Rotterdam kantoor 17 CEO's voor een sessie over AI en de toekomst van ons vak."),
|
"Op 2 april verwelkomde het Rotterdam kantoor 17 CEO\u2019s voor een sessie over AI en de toekomst van ons vak."),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
# USP cards — each card now has individual content (nth-occurrence targeting)
|
||||||
("usp-4-cards", [
|
("usp-4-cards", [
|
||||||
("WAAROM HELLOPRINT", "MENSEN & CULTUUR"),
|
("WAAROM HELLOPRINT", "MENSEN & CULTUUR"),
|
||||||
("Vier redenen om voor ons te kiezen",
|
("Vier redenen om voor ons te kiezen",
|
||||||
"Community moments deze maand"),
|
"Community moments deze maand"),
|
||||||
|
# Card 1 — Armeense lunch
|
||||||
("Laagste prijs", "Armeense lunch", 1),
|
("Laagste prijs", "Armeense lunch", 1),
|
||||||
("garantie", "Tolma & Ghapama", 1),
|
("garantie", "Tolma & Ghapama", 1),
|
||||||
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
||||||
"Sona nodigde iedereen uit voor een Armeense lunch op 10 april.", 1),
|
"Sona nodigde iedereen uit voor een Armeense lunch op 10 april.", 1),
|
||||||
("30%", "10 apr", 1),
|
("30%", "10 apr", 1),
|
||||||
("goedkoper dan traditioneel", "Armeens lunchen", 1),
|
("goedkoper dan traditioneel", "Armeens lunchen", 1),
|
||||||
|
# Card 2 — Easter cake
|
||||||
("Laagste prijs", "Easter Cake", 2),
|
("Laagste prijs", "Easter Cake", 2),
|
||||||
("garantie", "Carrot Cake", 2),
|
("garantie", "Carrot Cake", 2),
|
||||||
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
||||||
"Saskia bakte een worteltaart voor Pasen — op beiden verdiepingen!", 2),
|
"Saskia bakte een worteltaart voor Pasen \u2014 op beiden verdiepingen!",2),
|
||||||
("30%", "2 apr", 2),
|
("30%", "2 apr", 2),
|
||||||
("goedkoper dan traditioneel", "Paastraktatie", 2),
|
("goedkoper dan traditioneel", "Paastraktatie", 2),
|
||||||
|
# Card 3 — Chinese snacks
|
||||||
("Laagste prijs", "Chinese Snacks", 3),
|
("Laagste prijs", "Chinese Snacks", 3),
|
||||||
("garantie", "Sachima & Mahua", 3),
|
("garantie", "Sachima & Mahua", 3),
|
||||||
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
||||||
"Yaqi bracht traditionele Chinese snacks mee van haar vakantie.", 3),
|
"Yaqi bracht traditionele Chinese snacks mee van haar vakantie.", 3),
|
||||||
("30%", "16 apr", 3),
|
("30%", "16 apr", 3),
|
||||||
("goedkoper dan traditioneel", "Internationaal genieten", 3),
|
("goedkoper dan traditioneel", "Internationaal genieten", 3),
|
||||||
|
# Card 4 — Dennis' book
|
||||||
("Laagste prijs", "Kinderboek Launch", 4),
|
("Laagste prijs", "Kinderboek Launch", 4),
|
||||||
("garantie", "My New Parents", 4),
|
("garantie", "My New Parents", 4),
|
||||||
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
("All-inclusive prijzen zonder verborgen kosten. Vind je het goedkoper? Wij matchen het.",
|
||||||
"Dennis' vrouw lanceerde haar eerste kinderboek — met de hand geschreven en getekend!", 4),
|
"Dennis\u2019 vrouw lanceerde haar eerste kinderboek \u2014 met de hand geschreven en getekend!",
|
||||||
|
4),
|
||||||
("30%", "9 apr", 4),
|
("30%", "9 apr", 4),
|
||||||
("goedkoper dan traditioneel", "NL & EN editie", 4),
|
("goedkoper dan traditioneel", "NL & EN editie", 4),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
("testimonial", [
|
("testimonial", [
|
||||||
("Helloprint heeft ons de flexibiliteit gegeven om snel te schakelen. Van 500 visitekaartjes tot 50.000 brochures — alles wordt op tijd en perfect geleverd.",
|
("Helloprint heeft ons de flexibiliteit gegeven om snel te schakelen. Van 500 visitekaartjes tot 50.000 brochures \u2014 alles wordt op tijd en perfect geleverd.",
|
||||||
"Rolling dolma boosts productivity by 89%. No proof... but worth testing! Kom naar boven om mee te helpen met Tolma en Ghapama voor de Armeense lunch."),
|
"Rolling dolma boosts productivity by 89%. No proof\u2026 but worth testing! Kom naar boven om mee te helpen met Tolma en Ghapama voor de Armeense lunch."),
|
||||||
("Martine Verhoeven", "Sona Hovhannisyan"),
|
("Martine Verhoeven", "Sona Hovhannisyan"),
|
||||||
("Marketing Director — TechCorp BV",
|
("Marketing Director \u2014 TechCorp BV",
|
||||||
"People & Culture — Helloprint Rotterdam"),
|
"People & Culture \u2014 Helloprint Rotterdam"),
|
||||||
("MV", "SH"),
|
("MV", "SH"),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
# Second section-divider — duplicate template, now supported
|
||||||
("section-divider", [
|
("section-divider", [
|
||||||
("02", "02"),
|
("02", "02"),
|
||||||
("Financial Performance", "Upcoming"),
|
("Financial Performance", "Upcoming"),
|
||||||
@@ -527,4 +547,4 @@ if __name__ == '__main__':
|
|||||||
]
|
]
|
||||||
|
|
||||||
print("Generating: Office Rotterdam — Maandoverzicht\n")
|
print("Generating: Office Rotterdam — Maandoverzicht\n")
|
||||||
generate(plan, "/Users/derkdissselhof/Library/Application Support/Claude/local-agent-mode-sessions/a2d0567c-5a2d-4037-a100-87a5e74b9a55/3f471e31-d031-4ffe-bb3a-282799a05800/local_0cbc5cf3-74a0-4400-80d7-33c648a960dc/outputs/OfficeRotterdam_Maandoverzicht_Apr2026.pptx")
|
generate(plan, "/sessions/brave-bold-cerf/mnt/outputs/OfficeRotterdam_Maandoverzicht_Apr2026.pptx")
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Reference in New Issue
Block a user