pptx — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pptx (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You already know python-pptx and PptxGenJS. This skill adds a converter that turns HTML slides into native, editable PowerPoint objects, scripts that make template work reliable, and checks that show whether a deck is valid and looks right.
<skill> is the directory containing this file. Run bundled scripts by absolute path from the user's working directory, so relative paths to their files keep working:
uv run <skill>/scripts/thumbnail.py deck.pptxRun Python you write with its dependencies declared, either uv run --with python-pptx script.py or a PEP 723 header. Run Node scripts as NODE_PATH=<skill>/node_modules node build.js; if <skill>/node_modules is missing, run npm install in <skill> once. Rendering needs LibreOffice (soffice) and poppler (pdftoppm).
| Task | Workflow |
|---|---|
| Read a deck's text | uv run --with 'markitdown[pptx]' python -m markitdown deck.pptx |
| New deck, no template | html2pptx, below. Read html2pptx.md and design.md first. |
| New deck from a template | Template workflow, below |
| Change an existing deck | python-pptx for text and shapes. Slide XML (ooxml.md) for what python-pptx can't reach. |
| Speaker notes | scripts/notes.py |
markitdown labels slides from 1 (<!-- Slide number: 1 -->); every script here counts from 0. To take on an existing deck's look, read ppt/theme/theme1.xml from the unpacked file (<a:clrScheme>, <a:fontScheme>) and look at its thumbnail grid.
design.md): palette, type scale, grid. State it in two sentences before writing code.html2pptx.md. Mark chart and table areas with class="placeholder".html2pptx() for each slide, adds charts and tables at the placeholders with PptxGenJS, and calls pptx.writeFile({ fileName }). html2pptx throws every problem on a slide at once; fix them all and rerun.uv run <skill>/scripts/thumbnail.py template.pptx grid. Look at the grid images.Never leave a placeholder empty or invent filler to occupy one.
uv run <skill>/scripts/rearrange.py template.pptx working.pptx 0,12,12,31,40inventory.json: uv run <skill>/scripts/inventory.py working.pptx inventory.json uv run <skill>/scripts/replace.py working.pptx replacements.json output.pptxinventory.json maps slide-N to shape-N, both 0-based. Shapes are ordered top to bottom, then left to right, and slide numbers are left out. Each shape has left, top, width and height in inches, and paragraphs. It also carries:
placeholder_type (TITLE, CENTER_TITLE, SUBTITLE, BODY, OBJECT, …), only for placeholdersdefault_font_size, when the layout sets oneoverflow, overlap and warnings, when it detects themParagraphs list only the properties that differ from the default.
The replacements file has the same shape, with paragraphs for each shape to fill:
{
"slide-0": {
"shape-0": {"paragraphs": [{"text": "Revenue grew 18%", "bold": true}]},
"shape-1": {"paragraphs": [
{"text": "Renewals drove two thirds of growth"},
{"text": "Churn fell to 4%", "bullet": true, "level": 0}
]}
}
}text, bold, italic, underlinefont_size, font_namecolor ("C0392B") or theme_color ("ACCENT_1")alignment (LEFT, CENTER, RIGHT, JUSTIFY)space_before, space_after, line_spacing (in points)bullet with levelRead ooxml.md first. Then unpack, edit, validate after each change, and pack:
uv run <skill>/ooxml/scripts/unpack.py deck.pptx unpacked
uv run <skill>/ooxml/scripts/validate.py unpacked --original deck.pptx
uv run <skill>/ooxml/scripts/pack.py unpacked edited.pptxuv run <skill>/scripts/notes.py deck.pptx # print {"slide-0": "…", …}
uv run <skill>/scripts/notes.py deck.pptx notes.json -o out.pptxThe JSON maps slide keys to plain text, with one paragraph per line. An empty string clears a slide's notes, and slides not listed keep theirs. In an html2pptx build, use slide.addNotes('…') instead.
A deck is done when it validates and every slide has been looked at.
uv run <skill>/ooxml/scripts/validate.py deck.pptx. For an edited deck or one built from a template, add --original template.pptx so only new problems are reported. Fix everything it lists.On duplicated slides, validate.py also reports schema errors the template already had. Compare them with the source slide before chasing them.
uv run <skill>/ooxml/scripts/render.py deck.pptx pages and read every image. Look for:thumbnail.py deck.pptx grid --outline-placeholders gives an overview, with every text box outlined.
#. '#C0392B' corrupts the file.design.md.rearrange.py.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.