
docx
by 7th-ave-labs
SKILL.md
name: docx description: Read, create, edit, and review Microsoft docx files; handle tracked changes, comments, and OOXML workflows. Use when users mention Word documents, docx editing, or tracked changes.
DOCX Reading, Creation, and Editing
Overview
Use python-docx for simple operations. For tracked changes, comments, or OOXML manipulation, use the Advanced Workflows section.
Reading DOCXs
If _parsed/ folder exists (preferred)
rg "search term" /root/workspace/Document_parsed/
cat /root/workspace/Document_parsed/page_3.md
If no _parsed/ folder
Option 1: Text extraction with python-docx
from docx import Document
doc = Document('file.docx')
for para in doc.paragraphs:
print(para.text)
Option 2: Convert to markdown with pandoc (preserves structure, shows tracked changes)
pandoc --track-changes=all file.docx -o output.md
Creating DOCXs
from docx import Document
from docx.shared import Pt
doc = Document()
doc.add_heading('Document Title', 0)
para = doc.add_paragraph()
run = para.add_run('Bold text')
run.bold = True
table = doc.add_table(rows=2, cols=2)
table.cell(0, 0).text = 'Header 1'
doc.save('/root/workspace/output.docx')
After creating: Save the DOCX under /root/workspace so it syncs automatically.
When to use docx-js (advanced layouts)
- Use when you need pixel-precise layouts, rich styling, or HTML→DOCX conversions that
python-docxcan’t easily express. - Sandbox already installs
docx@latest; seedocx-js.mdfor full examples. - Minimal pattern:
const { Document, Packer, Paragraph, TextRun } = require('docx');
const fs = require('fs');
const doc = new Document({
sections: [{ children: [new Paragraph({ children: [new TextRun({ text: 'Hello', bold: true })] })] }],
});
Packer.toBuffer(doc).then((buffer) => fs.writeFileSync('/root/workspace/output.docx', buffer));
Editing DOCXs
from docx import Document
doc = Document('/root/workspace/file.docx')
for para in doc.paragraphs:
if 'old text' in para.text:
for run in para.runs:
run.text = run.text.replace('old text', 'new text')
doc.save('/root/workspace/file.docx')
# Always verify after saving
verify = Document('/root/workspace/file.docx')
for i, p in enumerate(verify.paragraphs[:10]):
print(f'[{i}] {p.text}')
Advanced Workflows (OOXML)
Use for: tracked changes, comments, direct XML manipulation.
Complete Workflow for Comments/Tracked Changes
Full example (from start to finish):
# 1. Unpack the DOCX
python /root/skills/docx/ooxml/scripts/unpack.py /root/workspace/Protocol.docx /root/workspace/Protocol_unpacked/
# 2. Edit with Python (pass the unpacked directory)
python - << 'EOF'
import sys
sys.path.insert(0, '/root/skills/docx')
from scripts.document import Document
doc = Document('/root/workspace/Protocol_unpacked', author='Reviewer', initials='RV')
# Add a comment on Section 3
main = doc['word/document.xml']
para = main.find_paragraph_containing('3. Study Design')
if para:
doc.add_comment(start=para, end=para, text='Clarify dosing schedule with clinical team.')
doc.save() # Saves to the unpacked directory
print('✓ Comment added')
EOF
# 3. Pack back to DOCX (overwrites original)
python /root/skills/docx/ooxml/scripts/pack.py /root/workspace/Protocol_unpacked/ /root/workspace/Protocol.docx
# 4. Verify
python /root/skills/docx/scripts/list_changes.py /root/workspace/Protocol.docx
Tracked changes: supported API pattern
- There is no
suggest_insertion_after; use the existing helpers:suggest_deletion(elem)to mark old text/paragraph/table-paragraph as deletedDocxXMLEditor.suggest_paragraph(xml)to wrap a new paragraph in<w:ins>insert_after(elem, xml_string)to place the insertion (stays in the same parent/cell)
- Minimal replace-with-redline pattern:
import sys
sys.path.insert(0, '/root/skills/docx')
import html
from scripts.document import Document, DocxXMLEditor as DX
doc = Document('unpacked_dir', author='Reg Team', initials='RT')
main = doc['word/document.xml']
def make_para(text: str) -> str:
raw = ('<w:p xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">'
f'<w:r><w:t xml:space="preserve">{html.escape(text)}</w:t></w:r></w:p>')
return DX.suggest_paragraph(raw)
def redline_para(old_text, new_text):
p = main.get_node(tag='w:p', contains=old_text)
main.suggest_deletion(p)
main.insert_after(p, make_para(new_text)) # tracked insertion
Unpack/Pack
Default: For simple edits (no comments/tracked changes), prefer direct python-docx on the .docx file—no unpack needed.
IMPORTANT (only when user asks for comments/tracked changes): The Document class for tracked changes and comments requires an unpacked directory, not a .docx file. Always unpack first:
# Step 1: Unpack the DOCX to a working directory
python /root/skills/docx/ooxml/scripts/unpack.py /root/workspace/file.docx /root/workspace/file_unpacked/
# Step 2: Edit using Document API (see below)
# Step 3: Pack back to DOCX (overwrites original)
python /root/skills/docx/ooxml/scripts/pack.py /root/workspace/file_unpacked/ /root/workspace/file.docx
Naming convention: Use {basename}_unpacked/ for the working directory to keep things organized.
Document Library
import sys
sys.path.insert(0, '/root/skills/docx')
from scripts.document import Document
# Pass the UNPACKED directory, not the .docx file
doc = Document('/root/workspace/file_unpacked', author="DocAgent", track_revisions=True)
# Find paragraph (handles text split across runs)
main = doc["word/document.xml"]
para = main.find_paragraph_containing("paragraph text")
# Add comment (inline highlighting works in Word/OnlyOffice)
if para:
doc.add_comment(start=para, end=para, text="Comment on this paragraph")
# Save changes to the unpacked directory
doc.save()
# Then pack back to .docx (see Unpack/Pack section above)
Reference: See ooxml.md for detailed OOXML patterns.
Troubleshooting: Text Not Found
If get_node(contains="...") fails (text split across runs), use:
main = doc["word/document.xml"]
# Handles split text and Unicode normalization
para = main.find_paragraph_containing("batch formulas are provided")
if para:
doc.add_comment(start=para, end=para, text="Your comment")
# List paragraphs to find correct search text
for i, text, elem in main.list_paragraphs(limit=20):
print(f"[{i}] {text}")
Review Workflow (Accept/Reject Changes)
List Changes
python /root/skills/docx/scripts/list_changes.py file.docx
Accept All (Clean Document, edits in place)
python /root/skills/docx/scripts/accept_all.py file.docx
Reject All (Restore Original, edits in place)
python /root/skills/docx/scripts/reject_all.py file.docx
Verify Clean
pandoc --track-changes=all file.docx -o verify.md
# Should show no insertions/deletions
Interactive Review (fine-grained accept/reject)
python /root/skills/docx/scripts/review.py file.docx output.docx
# Commands: list | accept <id> | reject <id> | accept-all | reject-all
# resolve <id> | delete <id> | save | quit
Note: Interactive review saves to a separate output file since you may want to discard changes.
Visual Verification
After any meaningful layout or styling changes, render to images and inspect.
Preferred helper:
python /root/skills/docx/scripts/render_docx.py file.docx --output_dir /root/tmp/docx_render
# Then call: view { path: "/root/tmp/docx_render/page-1.png" }
Manual fallback:
soffice -env:UserInstallation=file:///root/tmp/lo_profile_$$ --headless --convert-to pdf --outdir /root/tmp file.docx
pdftoppm -png /root/tmp/file.pdf /root/tmp/preview
# Then call: view { path: "/root/tmp/preview-1.png" }
Inspect every affected page. If anything looks off (clipped text, misaligned tables, broken bullets), fix the DOCX and re-render until clean.
Quality Expectations
- No AI citation tokens: Never include
[145036110387964†L158-L160]or【turn...】 - Unicode hygiene: Use ASCII hyphens (
-), avoid non-breaking/curly dashes unless present - Formatting intact: No clipped text, broken tables, or overlapping elements; preserve existing styles
- Verification: Reload after saving and spot-check edited pages (visual pass when formatting changes)
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です