docx
Capabilities
Full read/write coverage for .docx: simple paragraphs/tables through bookmarks, cross-document links, track changes, comments, and complex styling.
| Area | Support |
|---|---|
| Read | Paragraphs, tables, images, revisions, comments, styles; pandoc or unpack ingestion |
| Author | Build from scratch (docx-js) with headings, lists, tables, images, TOC, headers/footers, page sizes |
| Edit | Text substitution, table edits, insert/delete paragraphs, images, find/replace |
| Bookmarks & links | Paragraph/run bookmarks, internal anchors, cross-document hyperlinks |
| Revisions & comments | <w:ins> / <w:del> track changes, standardized comment bodies |
| Highlighting | Keyword hits with run splitting |
| Validation | docx_validator checks ZIP integrity, bookmark pairs, r:id vs. rels consistency |
Two toolchains: python-docx first, XML when required
Rule of thumb: stick to python-docx until you hit a limitation; only then unpack → edit XML → repack.
| Need | python-docx | XML route |
|---|---|---|
| Paragraphs / tables / images | ✅ straightforward | ✅ supported |
| Styles / rich formatting | ⚠️ partial | ✅ full fidelity |
| Bookmarks / hyperlinks | ❌ | ✅ via docx_link_engine |
| Track changes / comments | ❌ | ✅ XML mandatory |
Core modules (ragbase_skills.docx)
| Module | Role |
|---|---|
docx_utils | Paragraph walks (skip TOC), safe text edits, highlights, in-place inserts |
keyword_locator | Keyword search with para_range, table fallback, disambiguation |
docx_link_engine | Bookmarks, hyperlinks, coordinate-driven batch_operations |
docx_pipeline | Composition: locate+mutate in one step, automatic bidirectional linking |
docx_validator | Post-edit validation |
comment | Canonical comment text (build_mapping_comment) |
These ship pre-importable inside Agent
execute_code—do not hand-author raw XML strings.
Cross-document hyperlinks (common in automotive/patent workflows)
ASPICE “requirements ↔ tests” traceability and patent “spec ↔ figure list” jumps rely on cross-doc links. The skill wraps a four-step primitive:
Pipeline helper:
Cross-document troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Opens home page instead of anchor | Used w:anchor (internal-only) | Cross-doc must use r:id + relationship |
| Lands in TOC, not body | _Toc bookmark noise | Place bookmarks on body paragraphs; neutralize _Toc if needed |
| Word navigation fails silently | Bookmark name > 40 chars (CJK sanitization) | Keep names ≤ 40 chars, bm_ prefix |
| Field hyperlinks not clickable | Control fldChar runs carry rPr | Keep control runs style-free; formatting only on visible text runs |
See references/hyperlinks.md inside the skill for the full checklist.
Bulk + bidirectional workflows
Real programs need hundreds of coordinated bookmarks/links. docx_link_engine supports batch flows:
Bulk bookmarks (single unzip)
Bulk cross-document hyperlinks
Split one keyword into many targets
Coordinate-driven batches (recommended)
For large specs, run keyword_locator.batch_locate() once, feed coordinates into batch_operations:
N-to-N bidirectional example
Runtime footguns
Footgun 1: docx ≠ out overwriting progress
Footgun 2: Mixing doc.save() with dle.insert_*() in one loop
python-docx writes the in-memory graph; dle.insert_*() reads disk XML. Alternating them fights for the file.
Keyword disambiguation
Operations like “replace XX with YY in §3.2.1” blow up if you str.find() everywhere—TOC duplicates and cross-chapter collisions happen constantly. keyword_locator narrows with para ranges + context words:
Usually pairs with document-editing: ES gives para_range, locator fine-tunes coordinates, docx_link_engine performs the mutation.
Scenario guide
| Scenario | Approach |
|---|---|
| Contract/report/memo from template | docx-js greenfield with TOC/headers |
| Bulk template fields | docx_utils.safe_replace_text |
| Patent specification revisions | keyword_locator + docx_utils.insert_paragraphs_after |
| Requirements ↔ tests trace links | docx_pipeline.bidirectional_link |
| OA responses as track changes | unpack → insert <w:ins> / <w:del> |
| Review annotations | comment.build_mapping_comment + XML comments |
| Cross-doc references | pipeline.locate_and_apply(doc, specs) |
Invocation
Natural-language triggers:
- “Create a Word doc”
- “Rewrite chapter 3 with Q2 metrics”
- “Add bidirectional hyperlinks between these specs”
- “Batch-insert review comments”
- “Accept every tracked change”
How this skill relates to others
| Skill | Role |
|---|---|
| docx (this page) | Low-level DOCX file APIs |
| document-editing | Cross-format search → edit → snapshot flows (calls docx internally) |
| xlsx | Spreadsheet analog |
| html-report | Interactive HTML dashboards |
| patent-doc-formatter | Industry-specific formatter atop docx |
Hard rules (breaking them corrupts packages)
| # | Rule |
|---|---|
| R1 | Inside execute_code, must import ragbase_skills.docx; never stitch raw OOXML strings by hand |
| R2 | Disambiguate with para_range + keywords—no global str.find() (TOC collisions) |
| R3 | Insert mid-document via docx_utils.insert_paragraphs_after() (doc.add_paragraph() appends eof only) |
| R4 | Temp dirs via tempfile.mkdtemp(prefix="docx_") |
| R5 | Run docx_validator.validate_docx(path) before shipping |
| R6 | Cross-doc links cannot rely on w:anchor; use r:id relationships |
| R7 | Bookmark names ≤ 40 chars, bm_ prefix, anchored on body paragraphs |
| R8 | Leading/trailing spaces inside <w:t> need xml:space="preserve" |