agentsclimarketplace

Run2 docx recursive text replacement

Skill cxcscmu/SkillLearnBench/skills/b3-teacher-feedback-gemini-3-flash-preview/offer-letter-generator/run2_docx_recursive_text_replacement

Replaces placeholders in a Word document across all sections, including headers, footers, body paragraphs, and deeply nested tables. It uses paragraph-level replacement to ensure placeholders split across multiple runs are correctly identified.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill run2_docx_recursive_text_replacement

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

1.8 KB, 326 tokens by cl100k_base, as published. Nobody here has run it

To ensure all placeholders (e.g., {{PLACEHOLDER}}) are replaced regardless of their location or document structure, follow this approach using python-docx:

  1. Iterate all Sections: Loop through doc.sections to access header and footer.
  2. Recursive Table Processing: Create a function that iterates through a table's rows and cells. For every cell, it must check cell.paragraphs and recursively call itself for any tables found in cell.tables.
  3. Paragraph-Level Replacement: Instead of iterating through paragraph.runs, perform the replacement on paragraph.text. This avoids issues where Word splits a single placeholder into multiple XML "runs".
  4. Complete Coverage: Apply the replacement logic to:
    • doc.paragraphs
    • doc.tables (using the recursive function)
    • section.header.paragraphs and section.header.tables
    • section.footer.paragraphs and section.footer.tables

Example logic:

def replace_in_paragraph(paragraph, data):
    for key, value in data.items():
        placeholder = f"{{{{{key}}}}}"
        if placeholder in paragraph.text:
            paragraph.text = paragraph.text.replace(placeholder, str(value))

def process_table(table, data):
    for row in table.rows:
        for cell in row.cells:
            for paragraph in cell.paragraphs:
                replace_in_paragraph(paragraph, data)
            for nested_table in cell.tables:
                process_table(nested_table, data)

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.