Skip to main content
ClaudeWave
Skill47 repo starsupdated yesterday

docx-advanced-patterns

Advanced python-docx patterns for nested tables, complex cells, and content extraction beyond .text property. Techniques for forms, checklists, and complex layouts.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/belumume/claude-skills /tmp/docx-advanced-patterns && cp -r /tmp/docx-advanced-patterns/web-desktop-exports/docx-advanced-patterns ~/.claude/skills/docx-advanced-patterns
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# DOCX Advanced Patterns Skill

Specialized patterns for python-docx that handle complex document structures not covered by basic `.text` extraction.

## When to Use This Skill

Invoke this skill when working with DOCX files that have:
- Nested tables within table cells
- Forms with checkbox options
- Complex multi-row cell layouts
- Checklists with embedded options
- Cell content that doesn't appear with `.text` property

**Use alongside** the official `docx` skill for comprehensive document handling.

## Core Pattern: Nested Table Extraction

### Problem

python-docx's `cell.text` property only extracts direct paragraph text - it **does not** traverse nested tables within cells.

**Symptom:**
```python
cell.text  # Returns: '' or '\n'
# But cell visually contains content!
```

### Detection

Check if a cell contains nested tables:

```python
if cell.tables:
    print(f"Found {len(cell.tables)} nested table(s)")
    # Cell has nested content - need special extraction
```

### Solution (Simple)

```python
def extract_cell_content_with_nested_tables(cell):
    """
    Extract all text from a cell, including text from nested tables.

    Args:
        cell: python-docx _Cell object

    Returns:
        str: Combined text from cell paragraphs and nested tables
    """
    text_parts = []

    # Get direct paragraph text (not inside nested tables)
    for para in cell.paragraphs:
        para_text = para.text.strip()
        if para_text:
            text_parts.append(para_text)

    # Get content from nested tables
    if cell.tables:
        for nested_table in cell.tables:
            for nested_row in nested_table.rows:
                # For checkbox lists: Column 0 = label, Column 1 = checkbox
                # Extract text from first column only
                if nested_row.cells:
                    first_col_text = nested_row.cells[0].text.strip()
                    # Filter out checkbox characters
                    if first_col_text and first_col_text not in ['', '☐', '☑', '☒']:
                        text_parts.append(first_col_text)

    return '\n'.join(text_parts) if text_parts else ''
```

### Solution (Recursive for Deep Nesting)

For documents with multiple levels of table nesting:

```python
def extract_cell_content_recursively(cell):
    """
    Recursively extract text from cell including deeply nested tables.

    Handles arbitrary nesting depth.
    """
    text_parts = []

    def _extract_recursive(cell_obj):
        # Get direct paragraphs
        for para in cell_obj.paragraphs:
            para_text = para.text.strip()
            if para_text and para_text not in ['', '☐', '☑', '☒']:
                text_parts.append(para_text)

        # Recursively get nested tables
        for nested_table in cell_obj.tables:
            for nested_row in nested_table.rows:
                for nested_cell in nested_row.cells:
                    _extract_recursive(nested_cell)

    _extract_recursive(cell)
    return '\n'.join(text_parts) if text_parts else ''
```

## Usage Examples

### Example 1: Extracting Form Checkbox Options

**Document Structure:**
```
Table Cell contains:
  Nested Table:
    Row 1: "High potential" | ☐
    Row 2: "Moderate potential" | ☐
    Row 3: "Low potential" | ☐
```

**Extraction:**
```python
from docx import Document

doc = Document('form.docx')
table = doc.tables[0]
cell = table.rows[1].cells[0]

# Wrong way - returns empty
basic_text = cell.text
print(basic_text)  # Output: '' or '\n'

# Right way - extracts nested content
full_text = extract_cell_content_with_nested_tables(cell)
print(full_text)
# Output:
# High potential
# Moderate potential
# Low potential
```

### Example 2: Processing All Cells in a Table

```python
def process_table_with_nested_content(table):
    """Process all cells, handling nested tables"""
    for row in table.rows:
        for cell in row.cells:
            # Extract with nested table support
            content = extract_cell_content_with_nested_tables(cell)

            if content:
                # Process content (translate, analyze, etc.)
                processed = do_something_with(content)
                print(f"Cell content: {processed}")
```

### Example 3: Detecting Nested Tables

```python
def analyze_document_structure(doc):
    """Find all cells with nested tables"""
    nested_cells = []

    for t_idx, table in enumerate(doc.tables):
        for r_idx, row in enumerate(table.rows):
            for c_idx, cell in enumerate(row.cells):
                if cell.tables:
                    nested_cells.append({
                        'table': t_idx,
                        'row': r_idx,
                        'col': c_idx,
                        'nested_count': len(cell.tables)
                    })

    return nested_cells

# Usage
doc = Document('complex_form.docx')
nested = analyze_document_structure(doc)

for item in nested:
    print(f"Table {item['table']}, Row {item['row']}, Col {item['col']}: "
          f"{item['nested_count']} nested table(s)")
```

## Common Use Cases

### 1. Government Forms

Forms often use nested tables for checkbox grids:

```python
def extract_form_responses(doc):
    """Extract all form checkbox options"""
    responses = {}

    for table in doc.tables:
        for row in table.rows:
            # First cell = question
            question = row.cells[0].text.strip()

            # Second cell = checkbox options (nested table)
            if row.cells[1].tables:
                options = extract_cell_content_with_nested_tables(row.cells[1])
                responses[question] = options.split('\n')

    return responses
```

### 2. Evaluation Forms

Extract rating scales and options:

```python
def extract_evaluation_items(doc):
    """Extract evaluation criteria and options"""
    evaluations = []

    for table in doc.tables:
        for row_idx, row in enumerate(table.rows[1:], 1):
            # Get criterion
            criterion = row.cells[0].text.strip
deep-brainstormingSkill

Use when brainstorming a product or feature where multiple valid technology choices exist and the wrong one is costly, when the user asks for 'objectively best' or 'highest quality', or when the domain has tools/frameworks where marketing or popularity biases could mislead research agents. Also use when starting architecture decisions, evaluating tech stacks, or when the user mentions bias, vendor lock-in, hallucinated benchmarks, or wants research-backed decisions rather than default recommendations.

document-quality-standardsSkill

Use when creating or editing documents (DOCX, PDF, XLSX, PPTX) that need professional output. Adds visual verification, typography hygiene, and formula patterns.

docx-template-fillingSkill

Fill DOCX template forms preserving 100% original structure - logos, footers, styles, metadata. Zero-artifact insertion. Output indistinguishable from manual entry.

obsidian-vault-builderSkill

Use when adding/editing/querying content in an existing Obsidian vault, configuring plugins, integrating Claude Code with Obsidian via Local REST API or CLI, automating ongoing capture/organization/retrieval, designing a personal knowledge management workflow, OR building academic study vaults (course prep, exam-ready, mock-exam content — the durable academic-study patterns from a deprecated companion skill have been folded into this one).

pdf-handlingSkill

Extract PDFs to text and images before reading

project-retrospectiveSkill

>-

ralph-loopSkill

Activate autonomous Ralph Wiggum loop mode for iterative task completion. Use when you have a well-defined task with clear completion criteria that benefits from persistent, autonomous execution.

rlm-orchestratorSkill

>-