# Notebooklm Pdf To Ppt

> Convert image-based NotebookLM slide PDFs/PPTX exports into editable PowerPoint decks. Use when the user wants PDF/PPT image slides reconstructed as editable PPTX with clean backgrounds and editable text, separate from NotebookLM content generation.

- **Type:** Skill
- **Install:** `agentstack add skill-chemny-notebooklm-pdf-to-ppt-notebooklm-pdf-to-ppt`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [chemny](https://agentstack.voostack.com/s/chemny)
- **Installs:** 0
- **Category:** [Content & Media](https://agentstack.voostack.com/c/content-and-media)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [chemny](https://github.com/chemny)
- **Source:** https://github.com/chemny/notebooklm-pdf-to-ppt

## Install

```sh
agentstack add skill-chemny-notebooklm-pdf-to-ppt-notebooklm-pdf-to-ppt
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# NotebookLM PDF To PPT

Use this skill for the **editable reconstruction** problem: converting flattened NotebookLM slide exports, PDFs, or image-based PPTX files into editable PowerPoint decks.

This skill is separate from `notebooklm-course-studio`:

- `notebooklm-course-studio` owns NotebookLM content workflow: source import, content generation, artifact revision, and export.
- `notebooklm-pdf-to-ppt` owns post-export reconstruction: parse pages, clean backgrounds, rebuild editable PPTX, and diagnose fidelity problems.

Do not use this skill to ask NotebookLM to generate course content, podcasts, study guides, or new slide artifacts. Use it only after a PDF/PPTX/image export already exists or when the user explicitly asks for editable reconstruction.

## Current Status

This skill is under active development. The default path is now a small, inspectable PDF-to-editable-PPTX tool rather than the older multi-model fusion stack. It can run representative-page experiments, but it is not yet a reliable 90%+ full-deck converter.

Known current conclusions:

- PaddleOCR is the only OCR engine in the default main flow. Representative tests showed the removed secondary OCR path did not change final text, geometry, or PPTX output; it only added rejected candidates and maintenance noise.
- Preferred PaddleOCR models are the official PP-OCRv6 small models: `PP-OCRv6_small_det` for text detection and `PP-OCRv6_small_rec` for text recognition. If the installed PaddleOCR runtime does not register v6 small models, fall back to official `PP-OCRv5_mobile_det` and `PP-OCRv5_mobile_rec`. Keep official model names exactly as published by PaddleOCR; do not rename or alias local model identifiers.
- Do not use a secondary OCR fallback for top-band heading repair in the default flow. Wrong section numerals are worse than missing numerals; handle heading numbering only when PaddleOCR or another reliable evidence source provides it.
- When OCR splits a short CJK tail onto the next row inside the same visual text container, merge it into one editable text box and preserve the original visible row break. Do not leave the tail as an independent text object, and do not force a single long CJK line that PowerPoint may fail to wrap.
- Font fitting is conservative for body text: do not enlarge body text during render-fit, do not switch body Latin text to serif fonts just because a width score looks better, and reject low-confidence font-fit candidates instead of committing bad typography to layout JSON.
- CJK body font-fit must preserve readability. Do not shrink CJK body text below a conservative floor merely to match rendered width; let the final fit-to-box cap handle overflow.
- PPTX renderer differences are secondary. When structure, text, coordinates, or grouping are wrong, the root cause is the layout/fusion layer, not the PPTX renderer.
- Visual section-prefix repair must clean the entire prefix cell, not only the detected horizontal strokes. If OCR misses a top-band prefix such as `一、`, the recovered editable text and the background text-removal mask must cover the numeral plus punctuation area together.
- Title OCR repairs are allowed only for narrow, evidence-preserving fixes such as duplicated characters inside known section-title terms (`重重点` -> `重点`). Preserve the original bbox and style fields, and record the repair in `layout_repairs`; do not use this as a broad content rewrite layer.
- Local-clean must flag high-risk pages instead of silently treating them as successful. If text removal uses diffusion/inpaint on textured, illustrated, dark, or large non-uniform regions, write `localCleanRisk=review` into QA so the page can be routed to model-clean.

## Operating Principle

The user should interact by chat. Internally, run scripts and models as needed, but present the result as output paths and concise diagnoses.

Always separate the two failure domains:

- **OCR / parsing / fusion** owns text content, reading order, grouping, coordinates, font size, color, style evidence, and whether text should be editable.
- **PPTX rebuild** owns unit conversion, font substitution, text-box margins, line spacing, paragraph spacing, and renderer-specific output.

Do not let one layer compensate for the other. If OCR is wrong, fix OCR/parsing/fusion. If layout JSON is right but PPTX output is wrong, fix the renderer.

### Core reconstruction principles

OCR returns only text, boxes, and confidence. Everything else — color, font
size, weight, family, and what counts as a paragraph — is **reconstructed** by
this skill. Most fidelity bugs come from reconstructing via a fixed assumption
instead of measuring. Follow these three principles for any new rule:

1. **Reconstruct by measuring, not by assuming — and stay polarity-agnostic.**
   Recover color and size from the actual pixels of the text region, never from
   a baked-in assumption like "dark text on a light background" or "font size =
   bbox height × constant". Light text on a dark background is normal. The shared
   probe `scripts/style_probe.py` separates foreground from background by
   luminance distance and is the single source for color, ink height, and ink
   density; route new style recovery through it rather than re-deriving pixels.

2. **Base decisions on stable geometry, not on derived values.** Bounding-box
   height and position are stable; a font size estimated from ink varies between
   sibling lines (ascenders/descenders). Paragraph/grouping decisions must key
   off bbox geometry, not the estimated font size.

3. **Every recovered size must fit its box; segment by structure.** OCR boxes are
   tight to one ink line, so any recovered font size must be reconciled with the
   box (shrink-to-fit) or it overflows and overlaps. A sentence is ONE flowing
   segment (let word-wrap reflow it; do not freeze OCR's visual row breaks with
   hard newlines), but a glossary/table row is NOT a paragraph — distinguish a
   table row (a short, cross-column translation pair on the same y) from stacked
   sentence lines (same column, different y) and never vertically merge the former.

These reconstructions interact (enlarging size causes overflow; ink-based size
causes sibling-line divergence), so each new rule needs a safety check and must
be validated on rendered output, not just on the layout JSON. OCR has a hard
ceiling (mis-read phonetics, very thin numerals); do not try to fix engine-level
recognition errors in post-processing — diagnose, state the limit, and stop.

## Default Workflow

Use `scripts/run_simple.py` as the default entrypoint for normal PDF-to-PPTX conversion tests. It launches `scripts/pdf_to_ppt_simple.py` through a stable wrapper because direct script startup can stall on this local macOS Python environment.

Default command shape (use `python3`; `python` may be absent). `--background`
defaults to **`auto`** (per-page routing, see below), so a bare run already picks
the right cleanup per page:

```bash
PYTHONDONTWRITEBYTECODE=1 python3 scripts/run_simple.py \
  --pdf /path/to/source.pdf \
  --pages 1,2 \
  --output-dir /path/to/output \
  --ocr auto \
  --background auto
```

To force one mode for the whole deck, pass `--background local-clean` or
`--background model-clean`. Use `local-clean` only for white, flat, or simple
backgrounds where sampled fills are visually invisible. For illustrated,
textured, image-heavy, speech-bubble, diagram, or mixed pages, the default
quality strategy is AI/model background cleanup, not local Python fill.

For `model-clean`, the default provider in Codex is **`codex-image`**: the agent
should use Codex's built-in image capability to edit the original slide image
directly. This means: first load the local source slide PNG into the conversation
with `view_image`, then call the built-in `image_gen` tool in edit mode against
that visible image. Do not treat the lack of an `image_path` parameter on
`image_gen` as permission to switch backends. `view_image` is only the
load/inspection step; `image_gen` is the edit operation. Third-party image
backends are not the Codex default. Use them only when the user explicitly
selects one, or when a pre-authorized third-party fallback is configured and the
Codex source-image edit is unavailable, fails, or fails QA.

The script cannot call Codex's built-in image tool by itself, so it writes a
`codex_image_request` package for the page and then follows
`--model-clean-fallback` for unattended runs. In an interactive Codex session,
execute each request by opening `source_image` with `view_image`, then using
the built-in `image_gen` tool to edit that visible image. If the current Codex
image tool cannot use the visible source image as the edit target, stop and
report the limitation; do not substitute a prompt-only image generation result.
If the user has not pre-authorized a third-party image-edit fallback, ask before
switching providers. Any fallback must also edit the original source image; never
use prompt-only text-to-image generation as a clean background.
When the edited clean backgrounds have been saved to each request's
`expected_output`, run `scripts/apply_codex_image_edits.py --work-dir `
to validate the images, update layout JSON, and rebuild the PPTX.

For fully automated CLI/API runs, explicitly select a real image-edit API
backend and model supported by that environment:

```bash
PYTHONDONTWRITEBYTECODE=1 python3 scripts/run_simple.py \
  --pdf /path/to/source.pdf --pages 1,2 --output-dir /path/to/output \
  --ocr auto --background model-clean \
  --model-provider openai-image --model-clean-model  \
  --model-clean-fallback fail
```

This default path is intentionally simple:

1. Render selected PDF pages into PNGs. **Cached**: existing `slide_NNN.png` is reused.
2. OCR text lines and coordinates with PaddleOCR worker by default (`.venv-paddleocr`). By default (`--ocr-batch-size 0`) one worker handles all selected pages so the model loads once; set a smaller batch size such as `3` or `1` only when a machine hits OCR memory limits.
3. Recover style (color/size/weight) per region via `scripts/style_probe.py`, group/segment text, fit each text size to its box, then clean the background. With `--background auto` each page is routed to local-clean or model-clean automatically. **model-clean is cached**: an existing cleaned background for a page+model is reused (no re-billing).
4. **Always** strip the NotebookLM watermark from the cleaned background (`strip_watermark_from_background`), then rebuild a PPTX with the clean background and editable text boxes.
5. The maintained flow writes the editable PPTX plus layout and QA JSON. It does not render PPTX images.

Background modes:

- `auto` (**default, recommended**): per-page routing. `text_background_is_uniform`
  measures the luminance spread of the background AROUND each text box; pages
  whose text sits on a uniform/light background go to `local-clean` (fast, no
  model call), pages with textured/dark/illustrated text backgrounds go to
  `model-clean`. Solves the all-or-nothing trade-off: a mostly-white deck mostly
  uses local-clean (e.g. a 15-page deck dropped from ~15 min to ~4 min) while
  still model-cleaning the few hard pages. Bias is safe — when unsure it picks
  model-clean. This does not mean Python cleanup is the default for complex
  pages; complex pages should route to AI/model cleanup. If a page initially
  routes to `local-clean` but the local-clean QA marks `localCleanRisk=review`,
  `auto` must escalate that page to `model-clean`.
- `original`: keep the original page image as background and overlay editable text.
- `local-clean`: fast local background cleanup by covering text regions with sampled neighboring colors. Stable, no model call. **Safe-cover rule**: it only covers a region that has a surviving editable text replacement (`_has_replacement`); a region OCR'd into the mask but dropped from final `texts` (e.g. a big decorative number) is left in the background so it is never erased-without-replacement. Can still leave faint pale blocks where text sits on a textured/illustrated background.
- `model-clean`: high-quality background cleanup through an image-editing backend. In Codex chat, default to `codex-image`: load the original page image with `view_image`, edit that visible source image with built-in `image_gen`, and reject regenerated similar scenes. For unattended CLI/API runs, use `openai-image` or `gemini-native` explicitly.

Follow `references/editable-ppt-workflow.md` for the broader staged process and `references/editable-ppt-rules.md` for quality rules.

Use `references/development-roadmap.md` for the current development direction and promotion criteria. When an experiment regresses visually, stop and diagnose the responsible layer before trying another prompt or model.

Practical execution order:

1. **Input and scope**
   - Accept a PDF, flattened PPTX, or slide image set.
   - Create a work directory under the user's project output folder.
   - Record source path, selected pages, model names, and output paths.

2. **Representative pages first**
   - Do not start with a full deck.
   - Pick pages by visual type and complexity.
   - Use a small set such as `1,2`, `3,4`, `5,6`, or `9,10` depending on the current test.

3. **Render source pages**
   - Render pages to PNG.
   - Keep the original image pixel coordinate space as the layout coordinate system.

4. **OCR before rebuild**
   - Run OCR before background cleanup or PPTX rebuild.
   - Extract text, confidence, bbox, estimated font size, font family policy, color, and mask boxes.
   - Keep the layout JSON as the source of truth for rebuild.

5. **OCR / visual accuracy gate**
   - Verify text content, grouping, x/y/width/height, font size, and color before rebuild.
   - If these fields are wrong, stop and fix OCR/parsing first.
   - Merge adjacent same-baseline OCR fragments into one editable line when they share font policy and vertical overlap.
   - Same-baseline OCR fragments may have overlapping boxes because OCR over-expands glyph regions. If the second fragment still advances in reading direction and shares style/vertical overlap, treat the negative gap as bbox overlap and merge it in OCR normalization.
   - Filter footer/watermark brand text from editable text and text masks.
   - Apply renderer-calibrated OCR font-size estimates before PPTX generation.
   - Classify text role (`title`, `body`, `label`) before font and size normalization.
   - Use style-appropriate fonts only from the approved pool or explicit playful classroom fallbacks.
   - Do not call a secondary OCR engine as a top-band OCR repair in the default flow. In representative tests it added rejected candidates but did not improve final text, geometry, or PPTX output.
   - Missing section numerals should not be guessed. Add or repair section numbers only from reliable primary OCR evidence or a future dedicated numbering module.
   - When primary OCR splits a top heading into adjacent fragments, merge those fragments by x-order into one heading before typography and rebuild. Record this deterministic repair in `layout_repairs`.
   - When OCR splits a continuous paragraph into multiple visible rows inside the same visual region, column, card, bubble, or panel, rebuild it as one editable paragraph while preserving the original visible row breaks. Record `paragraphGroup`, `textSource=ocr_paragraph_group`, and `lineBreakSource=ocr_visible_rows`.
   - When OCR splits a CJK sentence into a normal line plus a very short continuation tail, such as `...什么工` + `作?`, merge them into one editable text box before paragraph grouping. Preserve the visible row break (`lineBreakSource=ocr_visible_rows`) because PowerPoint may not wrap continuous CJK text reliably.
   - Paragraph grouping must be column/region aware, not only global reading-order based. Interleaved text from another column must not prevent same-region continuation lines from being grouped.
   - Do not merge titles, table c

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [chemny](https://github.com/chemny)
- **Source:** [chemny/notebooklm-pdf-to-ppt](https://github.com/chemny/notebooklm-pdf-to-ppt)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-chemny-notebooklm-pdf-to-ppt-notebooklm-pdf-to-ppt
- Seller: https://agentstack.voostack.com/s/chemny
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
