pptx-merge

Installation
SKILL.md

pptx-merge

Splice selected slides from multiple PPTX files into a single editable deck. Each slide keeps its original native shapes (text, charts, SmartArt, pictures, tables) and its source layout, master, theme, and embedded media — fully editable in PowerPoint.

This skill is a composer for existing decks. For authoring brand-new Oracle-branded slides from a brief, use the sibling oracle-pptx skill.

When to use

Use when the user wants to:

  • Merge / combine / splice / assemble slides from multiple PPTX sources into one deck
  • Build a "best of" deck from corp / marketing / partner decks
  • Reorder selected slides from one or more sources
  • Audit an existing PPTX for PowerPoint "Repair this presentation" errors
  • Audit a deck where slides appear uneditable (one full-bleed image per slide)

Do not use this for authoring new slides from scratch — that's oracle-pptx.

What gets preserved

Preserved Notes
Native shapes (text frames, auto-shapes, freeforms, groups) Fully editable
Charts, SmartArt, tables, OLE-embedded objects Round-trip via referenced parts
Pictures and embedded media Copied byte-for-byte
Slide layout, slide master, theme Copied per source — see Caveats
Notes slides + notes master First source's notes master becomes deck-primary

What is not preserved: comments, revisions, handout master, custom XML parts, presentation-level macros.

Quick start

  1. Write a manifest.json (see reference/manifest-schema.md):

    {
      "sources": {
        "corp": "../decks/CorpPresentation.pptx",
        "product": "../decks/ProductOverview.pptx"
      },
      "slides": [
        { "source": "corp",    "slide_index": 1, "role": "Cover" },
        { "source": "product", "slide_index": 5, "role": "Architecture" },
        { "source": "corp",    "slide_index": 8, "role": "Pricing" }
      ],
      "output_pptx": "merged.pptx"
    }
    
  2. Run the merger:

    python3 scripts/merge.py manifest.json
    # override the output path:
    python3 scripts/merge.py manifest.json --output /tmp/out.pptx
    # override slide size (default is 16:9):
    python3 scripts/merge.py manifest.json --size 4:3
    python3 scripts/merge.py manifest.json --size auto      # match first source
    python3 scripts/merge.py manifest.json --size 13.33x7.5in
    
  3. Always audit the result before delivering:

    python3 scripts/audit.py merged.pptx
    

    Exit code 0 = clean. Non-zero means an issue worth investigating before you hand the deck off.

Manifest fields

Field Required Purpose
sources yes Map of key → path to source .pptx. Paths are relative to the manifest file.
slides yes Ordered list of slide entries. Each entry has source (key from sources) and slide_index (1-based).
output_pptx yes (or pass --output) Output path, relative to the manifest file.
slide_size optional Output slide size. Preset ("16:9" [default], "4:3", "16:10", "a4", "letter"), "auto" (adopt first source's size), or {"cx": <emu>, "cy": <emu>}. CLI --size overrides.
slides[].role optional Free-form description; printed in the build log.
slides[].position optional Free-form integer for human-readable ordering; not enforced.

Any extra top-level fields (deck_title, audience, version, etc.) are ignored — keep them for documentation.

Full schema: reference/manifest-schema.md.

Caveats — read before using on production decks

Read reference/caveats.md for the full list. The most important ones:

  • Multiple slide masters in the output. Each source brings its own master/theme. Valid OOXML, but the merged deck won't have a single unified visual theme. Acceptable for "best of" decks; not acceptable if the user expects one consistent look.
  • Unused layouts retained. A source's master pulls in all its layouts (often 50–100), even if only 2 are used by the slides you picked. Inflates file size.
  • Single notes master. Schema only allows one in <p:notesMasterIdLst>. The first source's notes master becomes deck-primary; other notes slides still render via per-slide rels.
  • Mixed-aspect-ratio sources. Output is one fixed slide size (default 16:9). Slides from sources with a different aspect ratio (e.g. a 4:3 source merged into a 16:9 deck) will keep their original layout coordinates and may render off-center or with letterboxing. The merger prints a warning listing any size mismatches; pick --size to match the dominant source, or use --size auto to adopt the first source's size.
  • No comments / revisions / handout master carried over.

Auditing a deck for PowerPoint errors

When the user reports "PowerPoint found a problem with content" or "slides aren't editable / they're images", run the auditor first:

python3 scripts/audit.py path/to/deck.pptx

It catches:

Failure mode Detected?
<p:notesMasterIdLst> has > 1 <p:notesMasterId> (PowerPoint corruption) yes
Missing <p:defaultTextStyle> yes
Missing presentation-level theme rel yes
Missing required ancillary parts (presProps, viewProps, tableStyles) yes
Slides flattened to a single full-bleed image (uneditable) yes

The auditor is independent of the merger — it audits any PPTX, including ones produced by other tools.

Composition with the oracle-pptx skill

A common pipeline:

  1. oracle-pptx — author new branded slides (cover, sections, value-prop, summaries, thank-you).
  2. pptx-merge — splice those new slides with extracted slides from corp / marketing / partner decks into one deliverable.

The two skills are deliberately split: oracle-pptx enforces a single brand-compliant theme; pptx-merge preserves source styling per slide. Trying to enforce brand compliance during merge would conflict with the merge's job.

Verifying after a merge

Recommended post-merge checks:

# 1. Schema audit
python3 scripts/audit.py output.pptx

# 2. Render to PDF (sanity check; LibreOffice is optional)
soffice --headless --convert-to pdf --outdir /tmp output.pptx
pdfinfo /tmp/output.pdf | grep -E '^Pages|^Page size'

# 3. Open in PowerPoint
# If PowerPoint asks to "Repair", re-run audit.py — the schema check
# is built specifically to catch the issues PowerPoint enforces.

Dependencies

  • Python ≥ 3.10
  • lxml (XML/rels manipulation)

Install: pip install lxml. No python-pptx, PptxGenJS, or LibreOffice required for the merger itself; LibreOffice is optional for the post-merge PDF render check.

Examples

See examples/manifest-example.json for a minimal 3-slide manifest. The example references examples/sources/ PPTXs which you'd substitute with real decks.

Reference

Installs
1
First Seen
8 days ago