<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pptx on ICE-ICE-BEAR-BLOG</title><link>https://ice-ice-bear.github.io/tags/pptx/</link><description>Recent content in Pptx on ICE-ICE-BEAR-BLOG</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 29 May 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://ice-ice-bear.github.io/tags/pptx/index.xml" rel="self" type="application/rss+xml"/><item><title>Tech Log: 2026-05-29 — The AI Slide-Generation Rabbit Hole</title><link>https://ice-ice-bear.github.io/posts/2026-05-29-the-ai-slide-generation-rabbit-hole/</link><pubDate>Fri, 29 May 2026 00:00:00 +0900</pubDate><guid>https://ice-ice-bear.github.io/posts/2026-05-29-the-ai-slide-generation-rabbit-hole/</guid><description>&lt;img src="https://ice-ice-bear.github.io/" alt="Featured image of post Tech Log: 2026-05-29 — The AI Slide-Generation Rabbit Hole" /&gt;&lt;h2 id="overview"&gt;Overview
&lt;/h2&gt;&lt;p&gt;Today turned into a single-minded chase: how do you get an AI to produce a &lt;em&gt;good&lt;/em&gt; slide deck — one you can actually open and edit, not a screenshot pretending to be a presentation? The trail ran through two of my own repos, a 123-star design-pack catalog, the Marp and Slidev ecosystems, Typst and WeasyPrint as rendering backends, and a Korean dev YouTuber arguing you should ditch PowerPoint for HTML/CSS entirely. Underneath the tool sprawl there was one recurring fault line.&lt;/p&gt;
&lt;h2 id="todays-exploration-map"&gt;Today&amp;rsquo;s Exploration Map
&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TD
 Q["How to make an AI generate a *good*, editable deck?"] --&gt; CODE["Camp A: slides-as-code"]
 Q --&gt; NATIVE["Camp B: native editable .pptx"]
 CODE --&gt; MARP["Marp — Markdown to HTML/PDF/PPTX"]
 CODE --&gt; SLIDEV["Slidev — Vue-based dev slides"]
 CODE --&gt; TYPST["Typst / WeasyPrint — PDF typesetting"]
 NATIVE --&gt; DECK["deck-style — spec + python-pptx"]
 NATIVE --&gt; DIV["design-diversity — 100 design packs"]
 DECK --&gt; RULE["Shared rule: no full-bleed PNG, native objects only"]
 DIV --&gt; RULE&lt;/pre&gt;&lt;h2 id="the-fault-line-full-bleed-png-vs-native-objects"&gt;The Fault Line: Full-Bleed PNG vs Native Objects
&lt;/h2&gt;&lt;p&gt;Every tool I looked at today sorts into two camps, and the dividing line is not &amp;ldquo;Markdown vs GUI&amp;rdquo; — it is &lt;strong&gt;what the final artifact actually contains&lt;/strong&gt;. One camp renders a slide as a single full-bleed image (or an HTML canvas), which looks pixel-perfect but is dead on arrival the moment someone wants to fix a typo. The other camp emits &lt;em&gt;native objects&lt;/em&gt; — real text frames, shape nodes, editable tables — at the cost of design fidelity being harder to nail.&lt;/p&gt;
&lt;p&gt;This matters more for AI generation than for humans, because the failure mode of a language model asked to &amp;ldquo;make a slide&amp;rdquo; is to reach for the safe average: a gradient background, a rounded card, one sans-serif font, and — when it can — a single baked-in image per slide. That image is the trap. It demos beautifully and is useless as a deliverable.&lt;/p&gt;
&lt;p&gt;What was striking is that two repos I read today, built by different people, independently codified &lt;em&gt;the exact same rule&lt;/em&gt; to fight this: full-bleed PNG is banned, native objects are mandatory. That convergence is the real story of the day.&lt;/p&gt;
&lt;h2 id="deck-style-style-as-text-output-as-python-pptx"&gt;deck-style: Style as Text, Output as python-pptx
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/ice-ice-bear/deck-style" target="_blank" rel="noopener"
 &gt;&lt;code&gt;ice-ice-bear/deck-style&lt;/code&gt;&lt;/a&gt; is my own platform for generating editable native &lt;code&gt;.pptx&lt;/code&gt; files (기획서/planning decks and 콘티/storyboards) by distilling a reference&amp;rsquo;s design into a &lt;strong&gt;specification plus tokens&lt;/strong&gt;. The architecture is explicitly two-layer, and that split is the whole point:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Layer 1 — Style&lt;/strong&gt;: &lt;code&gt;styles/{slug}/spec.md&lt;/code&gt; + &lt;code&gt;tokens.json&lt;/code&gt;. Pure text and data. Drop it into the context of Claude, OpenAI, or Gemini and it just works — zero model dependency.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layer 2 — Engine&lt;/strong&gt;: python-pptx code. Locally a Claude Code skill writes and runs it on demand; in the app a code-execution sandbox runs it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because the style is &lt;em&gt;text&lt;/em&gt; and the engine is &lt;em&gt;code&lt;/em&gt;, the same deck definition is portable from a local Claude Code session straight into a self-hosted app on OpenAI or Gemini. The repo ships six packs across two tracks — planning decks (&lt;code&gt;planning-doc&lt;/code&gt;, &lt;code&gt;planning-dark-bold-red&lt;/code&gt;) and storyboards (&lt;code&gt;storyboard-sketch-bw&lt;/code&gt;, &lt;code&gt;storyboard-accent-orange&lt;/code&gt;, &lt;code&gt;storyboard-treatment-photo&lt;/code&gt;, &lt;code&gt;storyboard-cinematic-dark&lt;/code&gt;) — each a folder of &lt;code&gt;spec.md&lt;/code&gt;, &lt;code&gt;tokens.json&lt;/code&gt;, &lt;code&gt;preview.png&lt;/code&gt;, and a private &lt;code&gt;reference/&lt;/code&gt;. The stack is python-pptx for native generation, PyMuPDF (&lt;code&gt;fitz&lt;/code&gt;) + Pillow for extracting style out of reference PDFs.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph TD
 REF["Reference PDF / deck"] --&gt; EXTRACT["PyMuPDF + Pillow extractor"]
 EXTRACT --&gt; SPEC["spec.md + tokens.json (pure text)"]
 SPEC --&gt; INJECT["Inject into Claude / OpenAI / Gemini context"]
 INJECT --&gt; ENGINE["python-pptx engine"]
 ENGINE --&gt; PPTX["Editable native .pptx"]&lt;/pre&gt;&lt;p&gt;The interesting design decision is treating the style spec as a &lt;em&gt;prompt artifact&lt;/em&gt; rather than a code config. It means a non-engineer can paste a &lt;code&gt;spec.md&lt;/code&gt; into a chat and get the same output the local engine produces — the spec is the contract, the engine is interchangeable.&lt;/p&gt;
&lt;h2 id="design-diversity-100-packs-and-the-no-full-bleed-mandate"&gt;design-diversity: 100 Packs and the &amp;ldquo;No Full-Bleed&amp;rdquo; Mandate
&lt;/h2&gt;&lt;p&gt;&lt;a class="link" href="https://github.com/epoko77-ai/design-diversity" target="_blank" rel="noopener"
 &gt;&lt;code&gt;epoko77-ai/design-diversity&lt;/code&gt;&lt;/a&gt; (123★, 20 forks, TypeScript) attacks a different angle of the same problem: not &amp;ldquo;is it editable?&amp;rdquo; but &amp;ldquo;why does every AI deck look the &lt;em&gt;same&lt;/em&gt;?&amp;rdquo; The README&amp;rsquo;s framing is sharp — generative models converge on a safe average, so the fix is not a better model but telling it &lt;em&gt;which&lt;/em&gt; design to use. The repo distills public design systems into &lt;strong&gt;100 prompt-style design packs&lt;/strong&gt; (50 PPT + 50 web, 20 of them premium with detailed multi-page specs), exposed through a Claude Code consumer skill called &lt;code&gt;design-pick&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install the skill into a project&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp -r skills/design-pick YOUR_PROJECT/.claude/skills/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# or globally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cp -r skills/design-pick ~/.claude/skills/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You either name a pack slug directly (&lt;code&gt;web-velvet-dark-boutique&lt;/code&gt;) or describe a vibe (&amp;ldquo;a premium dark-toned deck&amp;rdquo;) and the skill recommends two or three. All 100 pack specs are bundled as &lt;code&gt;references/&lt;/code&gt; inside the skill, so it works offline after install. There is even a no-skill path: copy a pack&amp;rsquo;s &lt;code&gt;prompt.md&lt;/code&gt; into a &lt;a class="link" href="https://claude.ai" target="_blank" rel="noopener"
 &gt;claude.ai&lt;/a&gt; chat alongside your source material and ask for an editable native &lt;code&gt;.pptx&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is the convergence I flagged earlier. The recent commits show design-diversity hardening &lt;em&gt;exactly&lt;/em&gt; the rule deck-style is built around: commit &lt;code&gt;3c017ab&lt;/code&gt; (&amp;ldquo;PPT pack native .pptx output rules&amp;rdquo;) and &lt;code&gt;3127592&lt;/code&gt; (&amp;ldquo;README: native .pptx output spec notice&amp;rdquo;) codify that full-bleed PNG slides are forbidden, native objects are mandatory, and images may only be &lt;em&gt;supporting&lt;/em&gt; assets — because the model was intermittently baking entire slides as single PNGs. Two repos, same enemy, same rule written down. When independent projects converge on a constraint, that constraint is usually load-bearing.&lt;/p&gt;
&lt;h2 id="the-slides-as-code-camp-marp-slidev-typst"&gt;The Slides-as-Code Camp: Marp, Slidev, Typst
&lt;/h2&gt;&lt;p&gt;The other half of the day was the Markdown-first camp. &lt;a class="link" href="https://github.com/marp-team/marp" target="_blank" rel="noopener"
 &gt;&lt;code&gt;marp-team/marp&lt;/code&gt;&lt;/a&gt; (11.8k★) is the entrance to the &amp;ldquo;Markdown Presentation Ecosystem&amp;rdquo; — you write CommonMark with directives and it exports to &lt;strong&gt;HTML, PDF, and PowerPoint&lt;/strong&gt;, with a pluggable architecture (Marp Core, the Marpit framework, Marp CLI, the VS Code extension). &lt;a class="link" href="https://sli.dev" target="_blank" rel="noopener"
 &gt;Slidev&lt;/a&gt; takes the same Markdown-native idea but aims squarely at developers, leaning on a Vue component model for interactive, code-friendly decks.&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://weasyprint.org" target="_blank" rel="noopener"
 &gt;WeasyPrint&lt;/a&gt; and Typst showed up as the &lt;em&gt;rendering backends&lt;/em&gt; for this camp — the question of how Markdown/HTML becomes a print-quality PDF. The thread I kept pulling was the trade-off triangle: Marp/Slidev give you HTML fidelity and animation but a weaker &lt;code&gt;.pptx&lt;/code&gt; export; python-pptx gives you true editable PowerPoint but you hand-build layout; Typst gives gorgeous PDF typesetting with a Markdown-like syntax but no native PowerPoint. I also poked at &lt;a class="link" href="https://ko.libreoffice.org" target="_blank" rel="noopener"
 &gt;LibreOffice&lt;/a&gt; as a headless &lt;code&gt;.pptx&lt;/code&gt;→PDF converter and concluded it is too heavy a dependency to lean on — which, foreshadowing, was the exact conclusion I reached in today&amp;rsquo;s Creative Agent Studio work too.&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;graph LR
 MD["Markdown source"] --&gt; MARP2["Marp / Slidev"]
 MARP2 --&gt; HTML["HTML deck (high fidelity, animated)"]
 MARP2 --&gt; PDFA["PDF / weak .pptx export"]
 SPEC2["spec.md + tokens"] --&gt; PPTXENG["python-pptx"]
 PPTXENG --&gt; EDIT["Fully editable .pptx (hand-built layout)"]
 MD --&gt; TYPST2["Typst / WeasyPrint"]
 TYPST2 --&gt; PDFB["Print-quality PDF (no native .pptx)"]&lt;/pre&gt;&lt;h2 id="코딩애플-just-code-the-slides-in-htmlcss"&gt;코딩애플: &amp;ldquo;Just Code the Slides in HTML/CSS&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;The Korean dev channel &lt;a class="link" href="https://www.youtube.com/watch?v=2kdo2ZLTG_E" target="_blank" rel="noopener"
 &gt;코딩애플&lt;/a&gt; (&amp;ldquo;PPT you can show off&amp;rdquo;) makes the slides-as-code argument in its purest form: a slide is just a document for presenting data nicely, so escape the PowerPoint fixation and have an AI code the slides in HTML/CSS. His points line up exactly with the Marp/Slidev pitch — higher animation freedom, easy and varied charts (he explicitly tells the model to use &lt;strong&gt;Chart.js&lt;/strong&gt; for line and pie charts), real-time interactive inputs, even 3D models and simulations, with page-snap and browser full-screen making it indistinguishable from PowerPoint in delivery. The honest caveats he raises are the same ones I keep hitting: the model doesn&amp;rsquo;t know your Korean fonts unless you specify them, and once you add images you have to hand-direct layout and color. That is the editability tax again, viewed from the HTML side.&lt;/p&gt;
&lt;h2 id="aside-googles-product-launch"&gt;Aside: Google&amp;rsquo;s Product Launch
&lt;/h2&gt;&lt;p&gt;The same channel&amp;rsquo;s &lt;a class="link" href="https://www.youtube.com/watch?v=xmxq-y2-26s" target="_blank" rel="noopener"
 &gt;Google launch recap&lt;/a&gt; was off today&amp;rsquo;s deck theme but worth a note: Gemini Omni framed as a &lt;em&gt;world model&lt;/em&gt; (a physics-aware video model) stitched to a video generator, enabling targeted edits where everything but one region stays fixed; an official self-cloning feature (face/voice upload to generate yourself in video); the retirement of Gemini CLI in favor of Antigravity 2.0; and AI search mode crossing a billion monthly users, with Google moving to swap the default search box for the AI one. The presenter&amp;rsquo;s sharp closing worry: if AI summarizes everything above the fold, purely informational content gets read only by AIs.&lt;/p&gt;
&lt;h2 id="quick-links"&gt;Quick Links
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://marp.app" target="_blank" rel="noopener"
 &gt;marp.app&lt;/a&gt; — the Marp website, with live Markdown→deck examples&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://design-diversity.vercel.app" target="_blank" rel="noopener"
 &gt;design-diversity.vercel.app&lt;/a&gt; — visual catalog of all 100 design packs&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ice-ice-bear/harnesskit" target="_blank" rel="noopener"
 &gt;ice-ice-bear/harnesskit&lt;/a&gt; — a Claude Code plugin managing zero-based version workflows (revisited today, 22 visits)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/ice-ice-bear/log-blog" target="_blank" rel="noopener"
 &gt;ice-ice-bear/log-blog&lt;/a&gt; — the blog-automation tool that wrote this post&lt;/li&gt;
&lt;li&gt;Two AI chats (a Gemini thread on naming the storyboard-gen repo, a Claude thread on splitting files by content) could not be enriched this run — the Gemini fetch hit a login-wall stub and the Claude fetch returned HTTP 403.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="insights"&gt;Insights
&lt;/h2&gt;&lt;p&gt;The day&amp;rsquo;s surface was a dozen tools, but the substance was a single decision repeated everywhere: &lt;strong&gt;does the artifact stay editable?&lt;/strong&gt; Both my deck-style repo and the unrelated design-diversity project independently wrote down the same prohibition — no full-bleed PNG, native objects only — which is strong evidence that this is &lt;em&gt;the&lt;/em&gt; failure mode of AI-generated decks, not a niche annoyance. The slides-as-code camp (Marp, Slidev, the 코딩애플 HTML/CSS pitch) solves editability by making the source &lt;em&gt;be&lt;/em&gt; code, trading away clean PowerPoint export; the native-pptx camp (deck-style, design-diversity, python-pptx) keeps PowerPoint as the target and pays in hand-built layout. The cleanest synthesis I keep circling back to is deck-style&amp;rsquo;s two-layer split: keep the &lt;em&gt;style&lt;/em&gt; as model-agnostic text and let the &lt;em&gt;engine&lt;/em&gt; be swappable, so the same intent renders through whatever backend fits — python-pptx today, maybe Typst tomorrow. The most reusable lesson is meta: when two independent codebases converge on the same hard constraint, stop treating it as a preference and treat it as a law of the domain.&lt;/p&gt;</description></item></channel></rss>