---
name: docx
description: Create, read, and edit Microsoft Word (.docx) documents. Use when the user wants a Word document / .docx — reports, letters, memos, templates — or to extract, find-and-replace, restyle, or add tables/images to an existing .docx. Uses the open-source python-docx library. Not for PDF, Excel, or PowerPoint.
---

# Word (.docx) documents

Build and edit `.docx` files with the open-source **python-docx** library, run through the Bash tool. Work on absolute paths.

## Preflight — Python + the library (install on demand)
1. **Find Python.** Run `python3 --version`; if it fails, try `python --version`. Use whichever works (call it `PY`).
2. **If neither exists, don't guess — guide the user once** (in their language): this task needs Python (a one-time setup). Give the path for their OS, then wait and retry — never fabricate output:
   - **macOS:** `brew install python`, or the installer at python.org.
   - **Windows:** `winget install -e --id Python.Python.3.12`, or python.org (tick "Add python.exe to PATH").
   - **Linux:** `sudo apt install -y python3 python3-pip` (or your distro's equivalent).
3. **Ensure python-docx** (installs only if missing):
   ```bash
   PY -c "import docx" 2>/dev/null || PY -m pip install --quiet --user python-docx
   ```
   If pip is offline/blocked, say so plainly and stop.

## Create a document
```python
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

doc = Document()
doc.add_heading("Quarterly Report", level=0)      # title
doc.add_heading("Summary", level=1)
p = doc.add_paragraph("Revenue grew ")
p.add_run("18%").bold = True                        # run-level formatting
doc.add_paragraph("First point", style="List Bullet")
doc.add_paragraph("Step one", style="List Number")

table = doc.add_table(rows=1, cols=2)
table.style = "Light Grid Accent 1"
hdr = table.rows[0].cells
hdr[0].text, hdr[1].text = "Metric", "Value"
row = table.add_row().cells
row[0].text, row[1].text = "Revenue", "$1.2M"

doc.add_picture("/abs/path/chart.png", width=Inches(5))
doc.save("/abs/path/out.docx")
```
Formatting lives on **runs** (`run.bold`, `run.italic`, `run.font.size = Pt(12)`, `run.font.color.rgb = RGBColor(0x1F,0x4E,0x79)`), not on the paragraph. Paragraph controls alignment/spacing (`p.alignment = WD_ALIGN_PARAGRAPH.CENTER`).

## Edit an existing document (preserve formatting)
Open it and mutate in place; don't rebuild from scratch or you lose styles.
```python
doc = Document("/abs/path/in.docx")
for p in doc.paragraphs:
    if "OLD" in p.text:
        for run in p.runs:          # replace at run level to keep formatting
            run.text = run.text.replace("OLD", "NEW")
for t in doc.tables:
    for row in t.rows:
        for cell in row.cells:
            ...
doc.save("/abs/path/in.docx")
```
Find-and-replace caveat: a phrase may be split across several runs. If a naive per-run replace misses it, join the paragraph's runs, replace, then write the text back into the first run and clear the rest.

## Read / extract content
- Quick text dump: iterate `doc.paragraphs` and `doc.tables`.
- To Markdown (better for analysis): `pandoc in.docx -t gfm -o out.md` if pandoc is installed, else fall back to python-docx.

## Convert to PDF
Prefer LibreOffice headless when available (best fidelity):
```bash
soffice --headless --convert-to pdf --outdir /abs/dir /abs/path/out.docx
```
If not installed, say so and offer the .docx.

## Conventions
- Page numbers / headers-footers / TOC need section & field XML — set them via `doc.sections[i]` and, for a TOC, insert a `w:fldSimple` field (the user must update fields in Word, or convert via LibreOffice which resolves them).
- Always save to an absolute path and report where the file is.
- Match the output language and format chosen in the session setup.
