domains / documents / docx-manipulation / docx
The four copies are not simple reproductions of one procedure. The anthropics/skills copy is the canonical upstream skill focused on docx-js creation, raw XML editing, merge_runs, validation, and tracked changes. The Vibe-Skills and awesome-llm-skills copies share a different workflow: mandatory reading of docx-js.md/ooxml.md, a Python Document library, unpack/pack scripts, and a redlining workflow; Vibe-Skills additionally adds scientific schematics. The skillsbench copy is a narrow python-docx template-filling skill centered on split placeholders, headers/footers, nested tables, and conditional sections. Each contains material steps or constraints the others lack, so crowning one would hide real alternatives.
| Repository | Path |
|---|---|
| anthropics/skills | skills/docx/SKILL.md |
| foryourhealth111-pixel/Vibe-Skills | bundled/skills/document-skills/docx/SKILL.md |
| Prat011/awesome-llm-skills | document-skills/docx/SKILL.md |
| benchflow-ai/skillsbench | tasks/offer-letter-generator/environment/skills/docx/SKILL.md |
| Role | Repository | Path |
|---|---|---|
| peer | anthropics/skills | skills/docx/SKILL.md |
| peer | foryourhealth111-pixel/Vibe-Skills | bundled/skills/document-skills/docx/SKILL.md |
| peer | Prat011/awesome-llm-skills | document-skills/docx/SKILL.md |
| peer | benchflow-ai/skillsbench | tasks/offer-letter-generator/environment/skills/docx/SKILL.md |
| inferior | davepoon/buildwithclaude | plugins/all-skills/skills/docx/SKILL.md |
| inferior | LeoYeAI/openclaw-master-skills | skills/bettafish-opinion-analysis/subskills/docx/SKILL.md |
| inferior | ComposioHQ/awesome-claude-skills | document-skills/docx/SKILL.md |
| inferior | FreedomIntelligence/OpenClaw-Medical-Skills | skills/docx/SKILL.md |
| adapter | foryourhealth111-pixel/Vibe-Skills | bundled/skills/docx/SKILL.md |
| adapter | LeoYeAI/openclaw-master-skills | skills/docx/SKILL.md |
| adapter | benchflow-ai/skillsbench | tasks/organize-messy-files/environment/skills/docx/SKILL.md |
---
name: docx
description: "Use this skill for creating, reading, editing, or manipulating Word documents (.docx) and templates (.dotx). Covers docx-js creation, raw XML editing, python-docx template filling, tracked changes, comments, and content extraction."
---
# DOCX creation, editing, and analysis
A `.docx` is a ZIP archive of XML files. Choose the approach by task.
## Conflicts
- **anthropics/skills** says `docx` (npm) is preinstalled; write the script and `require('docx')` directly. **Vibe-Skills** and **Prat011/awesome-llm-skills** require reading `docx-js.md` completely before creating a document and note dependencies may need installation.
- **anthropics/skills** edits existing documents by `unzip`, `merge_runs.py`, editing `word/document.xml`, `zip`, and `validate.py`. **Vibe-Skills** and **Prat011/awesome-llm-skills** use a Python Document library with `ooxml/scripts/unpack.py` and `pack.py`.
- **Vibe-Skills** adds a scientific-schematics step for new documents; the other copies do not.
- **benchflow-ai/skillsbench** uses `python-docx` for template filling and does not describe docx-js or raw XML redlining.
## Reading and analyzing content
### Text extraction
Convert to markdown with pandoc:
```bash
pandoc --track-changes=all path-to-file.docx -o output.md
# Options: --track-changes=accept/reject/all
```
### Raw XML access
Unpack the document to inspect or edit XML:
```bash
# anthropics/skills approach
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete
python scripts/merge_runs.py unpacked/
# Vibe-Skills / awesome-llm-skills approach
python ooxml/scripts/unpack.py <office_file> <output_directory>
```
Key files:
- `word/document.xml` — main content
- `word/comments.xml` — comments
- `word/media/` — embedded images
- Tracked changes use `<w:ins>` and `<w:del>` tags
## Creating a new Word document
### Using docx-js (JavaScript/TypeScript)
**anthropics/skills:** `docx` is preinstalled; `require('docx')` directly. Only if that fails: `npm install docx`.
**Vibe-Skills / awesome-llm-skills:** MANDATORY — read `docx-js.md` completely before proceeding.
Create a script using `Document`, `Paragraph`, `TextRun` components. Export with `Packer.toBuffer()`.
Gotchas (from anthropics/skills):
- Page size defaults to A4. For US Letter set `page: { size: { width: 12240, height: 15840 } }`.
- Landscape: pass portrait dimensions and `orientation: PageOrientation.LANDSCAPE`.
- Tables need dual widths: `columnWidths` on the table AND `width` on every cell, both in `WidthType.DXA`.
- Table shading: use `ShadingType.CLEAR`, never `SOLID`.
- Lists: use a `numbering` config with `LevelFormat.BULLET`, never literal `•`.
- `ImageRun` requires `type:`.
- `PageBreak` must be inside a `Paragraph`.
- Never use `\n` — use separate `Paragraph` elements.
- TOC: headings must use built-in `HeadingLevel.*`.
- Don't use a table as a horizontal rule — use a paragraph bottom border.
- Dot-leader: use `PositionalTab` inside a `TextRun`.
**Vibe-Skills only:** Consider adding scientific schematics via `python scripts/generate_schematic.py "description" -o figures/output.png`.
### Verify the output
```bash
python scripts/office/soffice.py --headless --convert-to pdf output.docx
pdftoppm -jpeg -r 100 output.pdf page
ls page-*.jpg
```
## Editing an existing Word document
### Raw XML editing (anthropics/skills)
```bash
unzip -q doc.docx -d unpacked/
find unpacked -type l -delete
python scripts/merge_runs.py unpacked/
# edit unpacked/word/document.xml in place — do NOT reformat
(cd unpacked && rm -f ../out.docx && zip -Xr ../out.docx .)
python scripts/office/validate.py out.docx --original doc.docx
```
Legacy `.doc` files: convert first with `python scripts/office/soffice.py --headless --convert-to docx file.doc`.
### Python Document library (Vibe-Skills / awesome-llm-skills)
MANDATORY — read `ooxml.md` completely before proceeding.
```bash
python ooxml/scripts/unpack.py <office_file> <output_directory>
# Create and run a Python script using the Document library
python ooxml/scripts/pack.py <input_directory> <office_file>
```
### python-docx template filling (benchflow-ai/skillsbench)
Use `python-docx` for template-based documents. Critical issue: Word splits placeholder text across multiple XML runs. Use paragraph-level search and rebuild:
```python
import re
from docx import Document
def replace_all_placeholders(doc, data):
def replace_in_paragraph(para):
text = para.text
pattern = r'\{\{([A-Z_]+)\}\}'
matches = re.findall(pattern, text)
if not matches:
return
new_text = text
for key in matches:
placeholder = '{{' + key + '}}'
if key in data:
new_text = new_text.replace(placeholder, str(data[key]))
if new_text != text:
runs = para.runs
if runs:
runs[0].text = new_text
for run in runs[1:]:
run.text = ''
for para in doc.paragraphs:
replace_in_paragraph(para)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
replace_in_paragraph(para)
for nested_table in cell.tables:
for nested_row in nested_table.rows:
for nested_cell in nested_row.cells:
for para in nested_cell.paragraphs:
replace_in_paragraph(para)
for section in doc.sections:
for para in section.header.paragraphs:
replace_in_paragraph(para)
for para in section.footer.paragraphs:
replace_in_paragraph(para)
```
Also handle nested tables recursively and conditional sections (`{{IF_CONDITION}}...{{END_IF_CONDITION}}`).
## Tracked changes and redlining
### Redlining workflow (Vibe-Skills / awesome-llm-skills)
1. Get markdown representation: `pandoc --track-changes=all path-to-file.docx -o current.md`
2. Identify and group changes into batches of 3-10.
3. Principle: Minimal, Precise Edits — only mark text that actually changes. Break replacements into: [unchanged text] + [deletion] + [insertion] + [unchanged text]. Preserve the original run's RSID for unchanged text.
4. Implement changes in OOXML using `<w:ins>`/`<w:del>` with `w:id`, `w:author`, `w:date` attributes. Inside `<w:del>`, use `<w:delText>`, not `<w:t>`.
5. Validate with `--author "<name>"` to check every edit is tracked.
### Accepting changes (anthropics/skills)
`python scripts/accept_changes.py in.docx out.docx`
Note: accepting a deleted paragraph mark should join that paragraph to the one below. `pandoc --track-changes=accept` never joins paragraphs. `accept_changes.py` joins them correctly except when followed by an empty spacer paragraph.
## Comments
Comments require six cross-linked files. Use the helper script (anthropics/skills) or the Document library (Vibe-Skills / awesome-llm-skills).