Install
openclaw skills install @j3ffyang/pptx-extractExtract a PowerPoint deck into full-data, page-delimited Markdown — every text run, table, speaker note, and image — with unextractable data (vector metafiles, charts, OLE embeds) skipped but visibly noted on its slide, then prove losslessness with a 5-point machine audit. Use when the user asks to extract/convert a PPTX to Markdown, add a new deck to an extraction project, or regenerate a stale extraction. Related terms: PPT, PowerPoint, PPTX, slide extraction, 提取.
openclaw skills install @j3ffyang/pptx-extractTurn a PowerPoint deck into one full-data Markdown file, and prove that nothing was lost. This skill is self-contained: it bundles the two tools it needs under scripts/, so it runs from anywhere and requires only a target project with a source/ folder.
source/ folder holding the .pptx decks (read-only); outputs land in <project>/extracted/.python-pptx (the system python3 may not have it).scripts/extract_pptx.py and scripts/audit_pptx.py.Set three variables and use them in every command below:
SKILL_DIR=.opencode/skills/pptx-extract # this skill's folder (its base directory)
PROJECT=/path/to/extraction-project # folder holding source/ and receiving extracted/
PY=/path/to/venv/bin/python # any Python 3 with python-pptx
The tools take --project and anchor to it, so they run from any working directory. A bare deck stem is resolved inside $PROJECT/source/, and output always lands in $PROJECT/extracted/.
<project>/extracted/<stem>.md; images at <project>/extracted/assets/<stem>/sNN-MM.<ext> (NN = slide number, MM = picture index within the slide, document order).<!-- slide: NN --> (zero-padded, deck order); each slide is headed ## Slide NN.<!-- deck: <file> | slides: N | tool: extract_pptx.py -->.<br>.Notes: after the slide content..emf/.wmf) and charts/OLE embeds are skipped rather than embedded, but each is disclosed in a visible note on that slide (> Unextractable data on this slide: ...).target — a deck stem or a .pptx path. A bare stem is resolved inside $PROJECT/source/; if ambiguous, list $PROJECT/source/*.pptx and ask.$PROJECT/extracted/<stem>.md — one file per deck, split at <!-- slide: NN --> markers$PROJECT/extracted/assets/<stem>/sNN-MM.<ext> — every extractable image, in slide orderPreflight — report what the deck contains before touching it:
unzip -l "$PROJECT/source/<stem>.pptx" | grep -c -E 'ppt/slides/slide[0-9]+\.xml$'
unzip -l "$PROJECT/source/<stem>.pptx" | grep -c 'ppt/media/'
unzip -l "$PROJECT/source/<stem>.pptx" | grep -c -E 'ppt/(charts/chart[0-9]+|diagrams/data[0-9]+|embeddings/)'
unzip -l "$PROJECT/source/<stem>.pptx" | grep -c -E 'ppt/notesSlides/notesSlide[0-9]+\.xml$'
Slides / media / charts+smartart+embeds / notes. Any non-zero charts+embeds → tell the user up front: those become visible "unextractable" notes, not data.
Extract — run this skill's bundled extractor:
"$PY" "$SKILL_DIR/scripts/extract_pptx.py" --project "$PROJECT" "<stem>"
Output always lands in $PROJECT/extracted/, regardless of the current directory.
Audit — run this skill's bundled 5-point losslessness proof (exit 1 on any hard failure):
"$PY" "$SKILL_DIR/scripts/audit_pptx.py" --project "$PROJECT" "<stem>"
The first four checks are hard gates: slide markers == slide count, unexplained media blobs == 0, unresolvable image references == 0, missing <a:t> strings == 0. The fifth is reported for review (the count of visible "unextractable" notes). On FAIL, investigate before declaring success — never report a partial extraction as done.
Spot-check — read the 2–3 densest slides in the .md (bullets nested, tables real, Notes: verbatim) and confirm the first line is the deck header.
Report — slide count, images, tables, notes, and every exclusion with its reason (chrome / metafile / OLE / chart). If any exclusion is unexpected for this deck, surface it to the user.
audit_pptx.py exits 0 (all checks OK)..md opens cleanly in a Markdown viewer with no broken images or garbled content..ppt (pre-2007): python-pptx cannot read it. Convert first with soffice --headless --convert-to pptx into a temp directory, then extract the converted file; the .md/assets/ still land in $PROJECT/extracted/ under the original stem.notes: 0 but notesSlides exist in the zip: legitimate — check the notes XML; a slide-number placeholder is not real content. Only flag it if the notes carry actual text.$PROJECT/source/. If a source must be converted or altered, work on a copy in a temp directory and leave the original untouched.