Create, read, edit, template, and review Word .docx files.
70
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Create, read, edit, and template Microsoft Word .docx files with
python-docx via small CLIs. It handles text, styles, lists, tables,
images, headers/footers, {{token}} templating, tracked changes
(list/accept/reject), comments (list/add/delete), TOC and page-number
fields, and package health checks. It does not render documents itself
(PDF needs LibreOffice — see Converting to PDF) or edit legacy .doc.
.docx..docx: replace text, edit table cells,
insert/delete paragraphs, apply styles, merge fragmented runs..docx template with {{placeholders}} to fill from data..docx won't open or behaves oddly and you need corruption triage..doc (legacy), .odt, or WYSIWYG layout work.python-docx installed:
pip install python-docx (import name is docx; lxml comes with it).add uses the native API on python-docx >= 1.2 and an XML
fallback on older versions — both are automatic.All helpers live in scripts/ next to this file. Run them with the
terminal tool; each supports --help and prints JSON to stdout.
python scripts/docx_create.py spec.json out.docx
python scripts/docx_read.py out.docx --text
python scripts/docx_edit.py replace out.docx --find old --replace new
python scripts/docx_template.py tpl.docx values.json filled.docx
python scripts/docx_revisions.py list out.docx
python scripts/docx_comments.py list out.docx
python scripts/docx_validate.py out.docx| Task | Command |
|---|---|
| Create from JSON spec | docx_create.py spec.json out.docx |
| Full text (body+tables+headers/footers) | docx_read.py f.docx --text |
| Heading outline + table shapes | docx_read.py f.docx --structure |
| Styles actually used | docx_read.py f.docx --styles |
| Extract embedded images | docx_read.py f.docx --images outdir/ |
| Detect tracked changes/comments | docx_read.py f.docx --revisions |
| Find/replace (formatting kept) | docx_edit.py replace f.docx --find A --replace B -o out.docx |
| Set a table cell | docx_edit.py set-cell f.docx --table 0 --row 1 --col 2 --text X |
| Insert paragraph before index N | docx_edit.py insert f.docx --index N --text X --style Normal |
| Delete paragraph N | docx_edit.py delete f.docx --index N |
| Apply style to paragraph N | docx_edit.py style f.docx --index N --style "Heading 1" |
| Merge equal-format adjacent runs | docx_edit.py normalize f.docx -o out.docx |
| Insert TOC field before para N | docx_edit.py toc f.docx --index N -o out.docx |
| "Page X of Y" footer fields | docx_edit.py page-numbers f.docx |
Fill {{tokens}} | docx_template.py tpl.docx values.json out.docx --strict |
| List revisions (id/author/date/text) | docx_revisions.py list f.docx |
| Accept / reject all revisions | docx_revisions.py accept-all f.docx -o out.docx (or reject-all) |
| Accept / reject one revision | docx_revisions.py accept f.docx --id 3 -o out.docx |
| List comments (+anchored text) | docx_comments.py list f.docx |
| Add comment anchored to text | docx_comments.py add f.docx --target "phrase" --text "note" --author You |
| Delete comment by id | docx_comments.py delete f.docx --id 0 |
| Health-check the package | docx_validate.py f.docx (exit 1 on errors) |
write_file, then run
scripts/docx_create.py. The spec supports: page (size + margins in
mm), header/footer strings, footer_page_numbers (adds a
"Page X of Y" field footer), styles (custom paragraph styles with
font, size, bold/italic, hex color), and blocks — heading
(level 1-9), paragraph (either text or a runs list where each run
may set bold/italic/underline), bullet_list, numbered_list,
table (header row rendered bold, rows, optional built-in table
style such as Table Grid), image (path, optional width_mm),
toc (Table of Contents field), and page_break. The full spec
format is documented at the top of scripts/docx_create.py.scripts/docx_read.py with exactly one mode flag.
--text returns body paragraphs, all table cell text, and
header/footer text as JSON. --structure returns the heading outline
plus paragraph/table/section counts. --images DIR copies every file
under word/media/ out of the package.scripts/docx_edit.py. replace walks body, tables
(nested included), headers and footers, and preserves run formatting;
add --body-only to skip headers/footers. Pass -o out.docx to keep
the original; omit it to edit in place. Paragraph indices for
insert/delete/style/toc refer to --structure/--text body
order. Run normalize first on documents that came out of heavy Word
editing — it merges adjacent runs with identical formatting so later
find-replace matches reliably.docx_revisions.py list reports every w:ins
and w:del (id, author, date, affected text) anywhere in body,
tables, headers, or footers. accept-all / reject-all resolve them
in bulk; accept/reject --id N handles a single revision. Accept
keeps insertions and drops deleted text; reject does the reverse.docx_comments.py list returns each comment's id,
author, date, body text, and the document text it is anchored to.
add --target "some phrase" anchors a new comment to the first
occurrence of that phrase (runs are split as needed; formatting is
preserved). delete --id N removes the comment and its markers
without touching document text.{{name}}-style tokens in the document. Run
scripts/docx_template.py with a JSON object of values. Use
--strict to fail when tokens remain unfilled; the JSON output lists
filled counts and unfilled_tokens either way.--text or
--structure, and run docx_validate.py on anything you produced
via revision/comment surgery.No script needed. When LibreOffice is installed, convert headlessly:
soffice --headless --convert-to pdf --outdir outdir/ file.docxCheck availability first (command -v soffice || command -v libreoffice). If neither exists, tell the user PDF conversion is
unavailable in this environment rather than improvising — python-docx
cannot render PDFs, and layout fidelity requires a real renderer.
docx_edit.py normalize first
reduces fragmentation for all later edits.docx_revisions.py resolves run-level
insertions and deletions (the overwhelming majority). Paragraph-mark
and table-row revisions, format-change records, and moves are detected
by --revisions but not auto-resolved — see
references/revisions-and-comments.md and hand those to Word.commentsExtended.xml, which this skill ignores; comments it adds are
plain top-level comments.toc, page-numbers, and the
toc/footer_page_numbers spec options write field codes.
Word/LibreOffice populates the actual entries and numbers when the
file is opened (Word may prompt to update fields); python-docx never
computes them, so placeholder text shows until then.docx_validate.py verifies the zip, required parts, relationship
targets, image magic bytes, and referenced styles. It is NOT XSD
validation — a file can pass and still contain XML Word dislikes.KeyError. Built-ins like Heading 1, List Bullet,
List Number, Table Grid exist in the default template; custom
styles must be declared in the create spec first.List Number relies on Word's default
numbering; separate lists in one document may continue numbering
instead of restarting. Warn users needing precise multi-list numbering.set-cell uses cell.text = ...,
which resets runs in that cell to plain formatting.document.xml corrupts files
easily. Use patch/write_file only for the JSON inputs, never on the
.docx itself.docx_read.py out.docx --text and
check the expected strings appear (and old strings are gone).docx_revisions.py list should return [] (or
only the ids you intentionally left); after comment surgery,
docx_comments.py list should reflect the change and --text output
must be unchanged.docx_validate.py out.docx exits 0 with "ok": true on a healthy
package — run it after any revision/comment/field manipulation.--strict, or check unfilled_tokens == [].--structure should show the expected heading
outline and table shapes; --styles confirms custom styles applied.6680afb
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.