Word document manipulation with python-docx - handling split placeholders, headers/footers, nested tables

MITAuto-check passedDocuments & Office

Install DOCX

skills CLI
$ npx skills add Raidriar7170/hermes-skilleval --skill docx -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Raidriar7170/hermes-skilleval docx --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Raidriar7170/hermes-skilleval.git skills-src && mkdir -p .claude/skills && cp -r skills-src/artifacts/v0.3/skillsbench-pilot/v0.3-stage2-input-package-candidate-20260701T010000Z/candidate-data/skill-sources/skillsbench__docx .claude/skills/docx && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
docx
GitHub stars
125
Used in
1 other repo
Token cost
~2k tokens
SKILL.md length
140 words
Files
1
Skills in repo
8
Repo updated
First seen
Licence
MIT

At a glance

Word document manipulation with python-docx - handling split placeholders, headers/footers, nested tables

  • Works in 5 steps: Forgetting headers/footers - They're not… → Missing nested tables - Must recurse… → Split placeholders - Always work at… → …
  • Tasks that involve Word documents
  • SKILL.md covers Critical: Split Placeholder…, Headers and Footers, Nested Tables and Conditional Sections, plus 2 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

DOCX is an agent skill from Raidriar7170/hermes-skilleval. Word document manipulation with python-docx - handling split placeholders, headers/footers, nested tables

Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Documents & Office, covering Word documents. It works with Microsoft Word and python-docx. The repository describes itself as: Verification-gated skill routing and self-improvement harness for Hermes-style agent skills. The licence is MIT.

When your agent uses it

  • Tasks that involve Word documents

Example prompts

  • “/docx”

Requirements

  • Python 3

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Forgetting headers/footers - They're not in doc.paragraphs
  2. Missing nested tables - Must recurse into cell.tables
  3. Split placeholders - Always work at paragraph level, not run level
  4. Losing formatting - Keep first run's formatting when rebuilding
  5. Conditional markers left behind - Remove {{IF_...}} markers after processing

What it can do on your machine

Read from SKILL.md and the folder at commit 8f6a21e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are python).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

DOCX loads about 2k tokens when it runs. Until then it costs about 28 tokens; SKILL.md has 140 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~28
When it runs · the whole SKILL.md, loaded when a task matches
~2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Raidriar7170/hermes-skilleval at commit 8f6a21e, republished under its MIT licence (© Raidriar7170). 140 words, ~1,968 tokens.

Download SKILL.mdSave it as .claude/skills/docx/SKILL.md (or your agent's skills folder).
name
docx
description
Word document manipulation with python-docx - handling split placeholders, headers/footers, nested tables

Word Document Manipulation with python-docx

Critical: Split Placeholder Problem

The #1 issue with Word templates: Word often splits placeholder text across multiple XML runs. For example, {{CANDIDATE_NAME}} might be stored as:

  • Run 1: {{CANDI
  • Run 2: DATE_NAME}}

This happens due to spell-check, formatting changes, or Word's internal XML structure.

Naive Approach (FAILS on split placeholders)
python
# DON'T DO THIS - won't find split placeholders
for para in doc.paragraphs:
    for run in para.runs:
        if '{{NAME}}' in run.text:  # Won't match if split!
            run.text = run.text.replace('{{NAME}}', value)
Correct Approach: Paragraph-Level Search and Rebuild
python
import re

def replace_placeholder_robust(paragraph, placeholder, value):
    """Replace placeholder that may be split across runs."""
    full_text = paragraph.text
    if placeholder not in full_text:
        return False

    # Find all runs and their positions
    runs = paragraph.runs
    if not runs:
        return False

    # Build mapping of character positions to runs
    char_to_run = []
    for run in runs:
        for char in run.text:
            char_to_run.append(run)

    # Find placeholder position
    start_idx = full_text.find(placeholder)
    end_idx = start_idx + len(placeholder)

    # Get runs that contain the placeholder
    if start_idx >= len(char_to_run):
        return False

    start_run = char_to_run[start_idx]

    # Clear all runs and rebuild with replacement
    new_text = full_text.replace(placeholder, str(value))

    # Preserve first run's formatting, clear others
    for i, run in enumerate(runs):
        if i == 0:
            run.text = new_text
        else:
            run.text = ''

    return True
Best Practice: Regex-Based Full Replacement
python
import re
from docx import Document

def replace_all_placeholders(doc, data):
    """Replace all {{KEY}} placeholders with values from data dict."""

    def replace_in_paragraph(para):
        """Replace placeholders in a single paragraph."""
        text = para.text
        # Find all placeholders
        pattern = r'\{\{([A-Z_]+)\}\}'
        matches = re.findall(pattern, text)

        if not matches:
            return

        # Build new text with replacements
        new_text = text
        for key in matches:
            placeholder = '{{' + key + '}}'
            if key in data:
                new_text = new_text.replace(placeholder, str(data[key]))

        # If text changed, rebuild paragraph
        if new_text != text:
            # Clear all runs, put new text in first run
            runs = para.runs
            if runs:
                runs[0].text = new_text
                for run in runs[1:]:
                    run.text = ''

    # Process all paragraphs
    for para in doc.paragraphs:
        replace_in_paragraph(para)

    # Process tables (including nested)
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for para in cell.paragraphs:
                    replace_in_paragraph(para)
                # Handle nested tables
                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)

    # Process headers and footers
    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)

Headers and Footers

Headers/footers are separate from main document body:

python
from docx import Document

doc = Document('template.docx')

# Access headers/footers through sections
for section in doc.sections:
    # Header
    header = section.header
    for para in header.paragraphs:
        # Process paragraphs
        pass

    # Footer
    footer = section.footer
    for para in footer.paragraphs:
        # Process paragraphs
        pass

Nested Tables

Tables can contain other tables. Must recurse:

python
def process_table(table, data):
    """Process table including nested tables."""
    for row in table.rows:
        for cell in row.cells:
            # Process paragraphs in cell
            for para in cell.paragraphs:
                replace_in_paragraph(para, data)

            # Recurse into nested tables
            for nested_table in cell.tables:
                process_table(nested_table, data)

Conditional Sections

For {{IF_CONDITION}}...{{END_IF_CONDITION}} patterns:

python
def handle_conditional(doc, condition_key, should_include, data):
    """Remove or keep conditional sections."""
    start_marker = '{{IF_' + condition_key + '}}'
    end_marker = '{{END_IF_' + condition_key + '}}'

    for para in doc.paragraphs:
        text = para.text
        if start_marker in text and end_marker in text:
            if should_include:
                # Remove just the markers
                new_text = text.replace(start_marker, '').replace(end_marker, '')
                # Also replace any placeholders inside
                for key, val in data.items():
                    new_text = new_text.replace('{{' + key + '}}', str(val))
            else:
                # Remove entire content between markers
                new_text = ''

            # Apply to first run
            if para.runs:
                para.runs[0].text = new_text
                for run in para.runs[1:]:
                    run.text = ''

Complete Solution Pattern

python
from docx import Document
import json
import re

def fill_template(template_path, data_path, output_path):
    """Fill Word template handling all edge cases."""

    # Load data
    with open(data_path) as f:
        data = json.load(f)

    # Load template
    doc = Document(template_path)

    def replace_in_para(para):
        text = para.text
        pattern = r'\{\{([A-Z_]+)\}\}'
        if not re.search(pattern, text):
            return

        new_text = text
        for match in re.finditer(pattern, text):
            key = match.group(1)
            placeholder = match.group(0)
            if key in data:
                new_text = new_text.replace(placeholder, str(data[key]))

        if new_text != text and para.runs:
            para.runs[0].text = new_text
            for run in para.runs[1:]:
                run.text = ''

    # Main document
    for para in doc.paragraphs:
        replace_in_para(para)

    # Tables (with nesting)
    def process_table(table):
        for row in table.rows:
            for cell in row.cells:
                for para in cell.paragraphs:
                    replace_in_para(para)
                for nested in cell.tables:
                    process_table(nested)

    for table in doc.tables:
        process_table(table)

    # Headers/Footers
    for section in doc.sections:
        for para in section.header.paragraphs:
            replace_in_para(para)
        for para in section.footer.paragraphs:
            replace_in_para(para)

    doc.save(output_path)

# Usage
fill_template('template.docx', 'data.json', 'output.docx')

Common Pitfalls

  1. Forgetting headers/footers - They're not in doc.paragraphs
  2. Missing nested tables - Must recurse into cell.tables
  3. Split placeholders - Always work at paragraph level, not run level
  4. Losing formatting - Keep first run's formatting when rebuilding
  5. Conditional markers left behind - Remove {{IF_...}} markers after processing

© Raidriar7170, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in artifacts/v0.3/skillsbench-pilot/v0.3-stage2-input-package-candidate-20260701T010000Z/candidate-data/skill-sources/skillsbench__docx of Raidriar7170/hermes-skilleval.

Open the folder on GitHubat commit 8f6a21e

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in Raidriar7170/hermes-skilleval, which our catalogue first saw on October 7, 2026.

Compare with similar skills

DOCX next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

DOCX compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
DOCX this skillRaidriar7170/hermes-skilleval1251 repos~2kAutomated safety check: PassMIT
Word Document Reader and WriterHKUDS/DeepTutor41k—~2.5kAutomated safety check: PassApache-2.0
BiSheng DOCX Builderdataelement/bisheng12k—~2.6kAutomated safety check: PassApache-2.0
DOCX ToolkitXiaomiMiMo/MiMo-Code14k—~2.4kAutomated safety check: PassApache-2.0
Word DOCX ToolkitTokenRhythm/opensquilla7.1k—~1.7kAutomated safety check: PassApache-2.0
Markdown to Word Convertercat-xierluo/SuitAgent206—~559Automated safety check: PassMIT

Similar skills

  • Reads, creates and edits Word .docx files with python-docx, and drops to raw OOXML for tracked changes, comments and byte-exact edits.

    41k GitHub stars~2.5k tokensUpdated today
    Documents & OfficeAuto-check passed
  • BiSheng DOCX Builder

    dataelement/bisheng

    Builds or edits Word .docx documents inside BiSheng's code executor with python-docx, handling Chinese fonts, tables of contents, page numbers and official-document layout.

    12k GitHub stars~2.6k tokensUpdated today
    Documents & OfficeAuto-check passed
  • DOCX Toolkit

    XiaomiMiMo/MiMo-Code

    Produces, edits and reads Microsoft Word files through python-docx and lxml, with a decision table for picking the lightest workflow for a given task.

    14k GitHub stars~2.4k tokensUpdated 5 days ago
    Documents & OfficeAuto-check passed
  • Word DOCX Toolkit

    TokenRhythm/opensquilla

    Inspects, edits in place or creates Word .docx files with bundled Python scripts, keeping existing styles intact when content changes.

    7.1k GitHub stars~1.7k tokensUpdated 4 days ago
    Documents & OfficeAuto-check passed
  • Markdown to Word Converter

    cat-xierluo/SuitAgent

    Converts Markdown files into Word documents formatted to Chinese typesetting conventions, with presets for academic, legal, report and book layouts.

    206 GitHub stars~559 tokensUpdated 1 mo ago
    Documents & OfficeAuto-check passed
  • DOCX

    einverne/dotfiles

    Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction.

    121 GitHub starsUsed in 35 repos~2.5k tokens
    Documents & OfficeAuto-check: notes

More from Raidriar7170/hermes-skilleval

All 8 skills in this repo
  • Senior Data Scientist

    Raidriar7170/hermes-skilleval

    World-class data science skill for statistical modeling, experimentation, causal inference, and advanced analytics.

    125 GitHub starsUsed in 6 repos~1.4k tokens
    Auto-check passed
  • Dialogue Graph

    Raidriar7170/hermes-skilleval

    A library for building, validating, visualizing, and serializing dialogue graphs.

    125 GitHub starsUsed in 1 repo~597 tokens
    Auto-check passed
  • Geospatial Routing Data

    Raidriar7170/hermes-skilleval

    Geospatial routing data handling for depot and station coordinates, route node IDs, internal index mappings, great-circle distance matrices, and route-distance reconstruction.

    125 GitHub starsUsed in 1 repo~1.5k tokens
    Auto-check passed
  • Logistics Rules To Optimization

    Raidriar7170/hermes-skilleval

    Translate logistics and operations rules into optimization variables and constraints.

    125 GitHub starsUsed in 1 repo~2.8k tokens
    Auto-check passed
  • Routing Subtour Elimination

    Raidriar7170/hermes-skilleval

    Subtour-elimination methods for TSP, VRP, pickup/dropoff routing, and routing MIPs with binary arc variables.

    125 GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed
  • Scip Opt

    Raidriar7170/hermes-skilleval

    SCIP optimization with PySCIPOpt. An agent skill from Raidriar7170/hermes-skilleval.

    125 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check passed

Questions about DOCX

What does DOCX do?

Word document manipulation with python-docx - handling split placeholders, headers/footers, nested tables. DOCX is an agent skill from Raidriar7170/hermes-skilleval.

When should I use DOCX?

DOCX fits situations like: tasks that involve Word documents.

How do I install DOCX in Claude Code?

Run `npx skills add Raidriar7170/hermes-skilleval --skill docx -a claude-code`. Or copy the skill folder (artifacts/v0.3/skillsbench-pilot/v0.3-stage2-input-package-candidate-20260701T010000Z/candidate-data/skill-sources/skillsbench__docx in Raidriar7170/hermes-skilleval) into .claude/skills/docx in your project. Claude Code loads it when a task matches its description.

How do I install DOCX in Codex?

Run `npx skills add Raidriar7170/hermes-skilleval --skill docx -a codex`. Or copy the skill folder (artifacts/v0.3/skillsbench-pilot/v0.3-stage2-input-package-candidate-20260701T010000Z/candidate-data/skill-sources/skillsbench__docx in Raidriar7170/hermes-skilleval) into .agents/skills/docx in your project. Codex loads it when a task matches its description.

Can I use DOCX in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Raidriar7170/hermes-skilleval --skill docx -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/docx, .gemini/skills/docx, .github/skills/docx and .opencode/skills/docx in your project.

What does DOCX need to run?

SKILL.md names no scripts, command-line tools or credentials: DOCX is instructions for the agent only. Our summary lists: Python 3.

Does DOCX access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is DOCX safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does DOCX use?

DOCX is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does DOCX use?

About 2k tokens (SKILL.md is roughly 7.9k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to DOCX?

Skills that share tags, products or a category with DOCX: Word Document Reader and Writer (HKUDS/DeepTutor, 41k stars), BiSheng DOCX Builder (dataelement/bisheng, 12k stars), DOCX Toolkit (XiaomiMiMo/MiMo-Code, 14k stars) and Word DOCX Toolkit (TokenRhythm/opensquilla, 7.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains DOCX?

Raidriar7170 (a GitHub user) maintains it in Raidriar7170/hermes-skilleval, which has 125 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 26, 2026.

Source: Raidriar7170/hermes-skilleval on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.