powerpoint

Create, read, edit .pptx decks with python-pptx.

  • pptx
  • powerpoint
  • presentations
  • slides
  • office
  • python-pptx

Declared platforms: linux · macos · windows

Install
npx skills add 'https://github.com/NousResearch/hermes-agent/tree/main/skills/productivity/powerpoint'
Download bundle ↓
main · 24fd22bScanned 2026-09-15

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗
View on GitHub
---name: powerpointdescription: Create, read, edit .pptx decks with python-pptx.version: 1.1.0author: Nous Researchlicense: MITplatforms: [linux, macos, windows]metadata:  hermes:    tags: [pptx, powerpoint, presentations, slides, office, python-pptx]    category: productivity    related_skills: [docx, xlsx, pdf]--- # Powerpoint Skill Create, inspect, and edit PowerPoint (.pptx) presentations using thepython-pptx library. Five helper scripts cover deck creation from a JSONspec, structured read-back, in-place edits, template-driven brand decks,and slide rendering — all offline, no PowerPoint installation required. ## When to Use - The user asks to build a slide deck, report presentation, or pitch deck.- You need to extract text, notes, tables, chart data, or images from a  .pptx someone shared.- You need to update an existing deck: replace text, refresh or patch  chart data, swap a logo, duplicate/remove/reorder slides, set  backgrounds, footers, hyperlinks, or speaker notes.- You must produce an on-brand deck from a company .pptx template.- Do NOT use this for .ppt (legacy binary) files — convert them first with  `soffice --convert-to pptx old.ppt` if LibreOffice is available. ## Prerequisites - Python 3.10+ with `python-pptx` installed  (`pip install python-pptx`).- Optional: LibreOffice (`soffice`) plus poppler (`pdftoppm` or  `pdftocairo`) for rendering slides to PNGs and for PDF export.  `pptx_render.py` detects both with `shutil.which` and degrades  gracefully (reports `{"rendered": false, "missing": [...]}`, exit 0)  when absent — all create/read/edit operations work without them.- Check availability via `terminal`:  `python -c "import pptx; print(pptx.__version__)"` and `which soffice pdftoppm`. ## How to Run All scripts live in `scripts/`, take `--help`, print JSON to stdout, andexit non-zero on failure. Run them with `terminal`: ```bashpython scripts/pptx_create.py deck.json out.pptxpython scripts/pptx_read.py deck.pptx --outline      # full JSON outlinepython scripts/pptx_read.py deck.pptx --notes        # speaker notespython scripts/pptx_read.py deck.pptx --images ./img # export picturespython scripts/pptx_edit.py deck.pptx --replace-text "Old Corp" "New Corp"python scripts/pptx_edit.py deck.pptx --chart-data update.jsonpython scripts/pptx_edit.py deck.pptx --duplicate-slide 2python scripts/pptx_edit.py deck.pptx --remove-slide 3 --move-slide 2 0python scripts/pptx_from_template.py brand.pptx out.pptx --values vals.jsonpython scripts/pptx_render.py deck.pptx --outdir ./render  # slide PNGs``` Author JSON specs with `write_file`; inspect script output and generatedJSON with `read_file`. ## Quick Reference | Task | Command ||---|---|| New deck from spec | `pptx_create.py spec.json out.pptx` || 16:9 vs 4:3 | `"slide_size": "16:9"` or `"4:3"` in the spec || Outline as JSON | `pptx_read.py deck.pptx --outline` || Export images | `pptx_read.py deck.pptx --images DIR` || Replace text | `pptx_edit.py deck.pptx --replace-text OLD NEW` || Replace chart data | `pptx_edit.py deck.pptx --chart-data spec.json` || Patch one series | same flag, spec with `"ops"` (see below) || Swap picture | `pptx_edit.py deck.pptx --swap-image N NAME new.png` || Duplicate slide | `pptx_edit.py deck.pptx --duplicate-slide N` || Remove slide | `pptx_edit.py deck.pptx --remove-slide N` || Reorder slide | `pptx_edit.py deck.pptx --move-slide FROM TO` || Slide background | `pptx_edit.py deck.pptx --set-background N RRGGBB` || Hyperlink runs | `pptx_edit.py deck.pptx --hyperlink N TEXT URL` || Slide number on | `pptx_edit.py deck.pptx --enable-slide-number N` || Footer text | `pptx_edit.py deck.pptx --set-footer N TEXT` || Set notes | `pptx_edit.py deck.pptx --set-notes N TEXT` || Append notes | `pptx_edit.py deck.pptx --append-notes N TEXT` || Fill template | `pptx_from_template.py tpl.pptx out.pptx --values v.json` || Render slide PNGs | `pptx_render.py deck.pptx --outdir DIR` | ## Procedure ### 1. Create a deck Write a JSON spec (see `pptx_create.py --help` for the full format), thenrun `pptx_create.py`. Per slide you can set: `layout` (title,title_content, section, two_content, title_only, blank), `title`,`subtitle`, `bullets` (strings, or dicts with `level` 0-4, `size` pt,`bold`, `italic`, `font`, `color` hex, `link` URL for a hyperlink),`background` (solid hex), `footer` (text; enables the layout's footerplaceholder), `slide_number` (true; enables the layout's slide-numberplaceholder), `images` (path + left/top/width/height in inches), `tables`(`rows` as list-of-lists), `shapes` (rectangle, rounded_rectangle, oval,diamond, right_arrow, chevron, with `fill` hex + optional `text`),`charts` (bar, bar_h, line, pie with `categories` + `series`), and`notes` (speaker notes). ### 2. Read a deck `pptx_read.py deck.pptx --outline` returns slide size, layout inventory,and per slide: layout name, all shape texts, table cells, image inventory(filename/ext/bytes), chart categories/series/values, and speaker notes.Use `--images DIR` to dump embedded pictures to files, then`vision_analyze` on any exported image if you need to see its content. ### 3. Edit a deck `pptx_edit.py` combines operations in one pass; use `--output` to keep theoriginal. Text replacement scans slide shapes, table cells, and notes.Image swap retargets the picture's relationship id so position and sizeare preserved. Slide removal drops the relationship and the `<p:sldId>`entry; reorder moves the `<p:sldId>` element within `<p:sldIdLst>`(python-pptx has no public API for either — the script does the XML-levelwork). `--duplicate-slide N` appends an independent deep copy of slide N:shape XML plus image/media/hyperlink relationships are cloned and rIdsremapped, so editing the copy never touches the original. Chart slidesare refused (see Pitfalls). `--set-notes`/`--append-notes` edit speakernotes; `--set-background`, `--hyperlink`, `--enable-slide-number`, and`--set-footer` handle deck polish. Chart updates take a JSON spec via `--chart-data`. Full replace:`{"slide": 0, "chart": 0, "categories": [...], "series": {...}}`. Forsurgical edits, pass `"ops"` instead — a list of`{"op": "update_series", "name": ..., "values": [...]}`,`add_series`, `remove_series`, `rename_category` (`from`/`to` or`index`), and `set_title`. python-pptx can only swap a chart's entiredataset (`replace_data`), so ops are implemented as read-existing →modify → replace; the per-part UX is a wrapper, and any chart data notexpressible as categories + numeric series will be normalized by theround-trip. ### 4. Build from a template `pptx_from_template.py` opens a brand .pptx, replaces every`{{token}}` from a values JSON across slides/tables/notes, and can appendnew slides that use the template's own layouts (by layout name or index)so they inherit the master's fonts and colors. Tip: to start from atemplate with zero slides, delete existing ones afterward with`pptx_edit.py --remove-slide`. ### 5. Visual verification `pptx_render.py deck.pptx --outdir ./render` converts the deck to PDFwith `soffice --headless` and splits it into one PNG per slide with`pdftoppm` (or `pdftocairo`). Output JSON lists the PNG paths — revieweach with `vision_analyze`. When either tool is missing the script exits0 with `{"rendered": false, "missing": [...]}` and guidance; fall back tothe JSON outline from `pptx_read.py`, which verifies content andstructure, just not visuals. ## Converting to PDF If LibreOffice is installed, export the finished deck to PDF directly: ```bashsoffice --headless --convert-to pdf --outdir ./out deck.pptx``` The output lands at `./out/deck.pdf`. Fonts not installed on the host aresubstituted, so render-verify (Procedure step 5) before shipping the PDF.There is no offline pure-Python .pptx→PDF path; if `soffice` is absent,say so rather than approximating. ## Pitfalls - **Run splitting**: PowerPoint fragments paragraph text into runs at  spell-check and edit boundaries. `--replace-text` first merges adjacent  runs whose formatting is identical, so matches split across such runs  are replaced with formatting fully preserved. Only when a match spans  *genuinely differently-formatted* runs is the paragraph rewritten with  the first run's formatting — verify those slides after replacement.- **Chart slides cannot be duplicated**: each chart relationship embeds a  separate XLSX workbook part; cloning that graph reliably is not  supported, so `--duplicate-slide` refuses chart slides cleanly instead  of corrupting the deck. Rebuild the chart on a new slide instead.  External-hyperlink and image/media rels are carried over; layout and  notes rels are recreated fresh.- **Chart ops are a wrapper**: python-pptx replaces the whole dataset;  `"ops"` round-trips existing plot data through `replace_data`, and  changing chart *type* is not possible.- **Reordering is XML-level**: python-pptx has no supported reorder API.  `--move-slide` manipulates `<p:sldIdLst>` directly; safe for ordinary  decks but re-read the deck afterward to confirm.- **Copying slides between decks is unsupported** — duplication works  only within one deck, where layouts and masters are shared.- Footer/slide-number enablement copies the placeholder from the slide's  layout; on layouts without those placeholders, `--set-footer` fails  with a clear message (add a textbox instead).- Hyperlinks apply to whole runs; `--hyperlink` links every run  containing the given text on that slide.- The default python-pptx template is 4:3; the create script sets 16:9  unless the spec says otherwise. Custom templates keep their own size.- Layout indexes vary by template. For brand templates, list layout names  first: `pptx_read.py template.pptx --outline` (`layouts_available`).- `slide.shapes.title` is None on blank layouts — the create script  handles this, but remember it when writing ad-hoc python-pptx code.- Always pass `encoding="utf-8"` when writing spec files; tokens like  `{{city}}` may be filled with non-ASCII values. ## Verification 1. After any create/edit, run `pptx_read.py OUT.pptx --outline` and check   slide count, texts, tables, notes, and chart values match intent.2. `--images DIR` then file-size check confirms pictures embedded.3. Render every slide with `pptx_render.py deck.pptx --outdir ./render`   and review each PNG with `vision_analyze` — this catches overlapping   shapes, truncated text, and color problems the outline cannot. If the   render tools are missing, the script says so; rely on the outline.4. The bundled test suite is the full contract:   `python -m pytest tests/ -q` (requires python-pptx + pytest). 
Discovery context

Discovered by repository scan. No exact path reference found in the snapshot’s root AGENTS.md.