docx-advanced-patterns について
docx-advanced-patterns は、python-docx で複雑な DOCX 構造を扱うスキルです。基本的なテキスト抽出では得られない入れ子のテーブルやセルの内容を抽出し、公式 docx スキルを補完します。
主な機能
- 01入れ子テーブルのテキスト抽出
- 02深い入れ子構造の再帰処理
- 03入れ子テーブルを含むセルの検出
- 04チェックボックスとフォームの処理
- 05改行と構造の保持
活用シーン
- 01政府フォームの選択肢の抽出
- 02評価フォームの尺度と選択肢の読み取り
- 03複雑なテーブルセルのデータ処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ belumume/ claude-skills --skill docx-advanced-patternsインストール後、Claude Code で/docx-advanced-patternsを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
DOCX の高度なパターンスキル
基本的な .text 抽出では対応できない複雑なドキュメント構造を処理する、python-docx 向けの特化パターンです。
このスキルを使用するタイミング
次のような DOCX ファイルを扱う場合に、このスキルを呼び出してください。
- 表のセル内に入れ子になった表がある
- チェックボックスの選択肢を含むフォームがある
- 複数行にわたる複雑なセルレイアウトがある
- 選択肢が埋め込まれたチェックリストがある
.textプロパティに表示されないセルコンテンツがある
包括的なドキュメント処理を行う場合は、公式の docx スキルと併用してください。
基本パターン:入れ子になった表の抽出
問題
python-docx の cell.text プロパティで抽出できるのは、直接含まれる段落テキストのみです。セル内にある入れ子の表をたどることはできません。
症状:
cell.text # Returns: '' or '\n'
# But cell visually contains content!
検出
セルに入れ子の表が含まれているか確認します。
if cell.tables:
print(f"Found {len(cell.tables)} nested table(s)")
# Cell has nested content - need special extraction
解決策(簡易版)
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 ''
解決策(深い入れ子に対応する再帰版)
複数階層の表の入れ子があるドキュメントの場合:
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 ''
使用例
例 1:フォームのチェックボックス選択肢の抽出
ドキュメント構造:
Table Cell contains:
Nested Table:
Row 1: "High potential" | ☐
Row 2: "Moderate potential" | ☐
Row 3: "Low potential" | ☐
抽出:
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
例 2:表のすべてのセルの処理
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}")
例 3:入れ子になった表の検出
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)")
よくある使用例
1. 政府機関のフォーム
フォームでは、チェックボックスのグリッドに入れ子の表を使用することがよくあります。
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. 評価フォーム
評価尺度と選択肢を抽出します。
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()
# Get rating options (often nested)
rating_cell = row.cells[1]
rating_options = extract_cell_content_with_nested_tables(rating_cell)
evaluations.append({
'criterion': criterion,
'options': rating_options.split('\n')
})
return evaluations
3. 複雑なデータテーブル
入れ子のレイアウトがあるセルから、構造化データを抽出します。
def extract_complex_cell_data(cell):
"""Extract data from cells with complex nested structures"""
data = {
'main_content': '',
'nested_items': []
}
# Direct paragraphs
for para in cell.paragraphs:
if para.text.strip():
data['main_content'] = para.text.strip()
break
# Nested table data
if cell.tables:
for nested_table in cell.tables:
for nested_row in nested_table.rows:
row_data = [c.text.strip() for c in nested_row.cells]
data['nested_items'].append(row_data)
return data
公式の docx スキルとの統合
このスキルは、公式の docx スキルを補完します。
公式の docx スキルでできること:
- ドキュメントの作成(docx-js)
- 基本的なテキスト抽出(pandoc)
- 変更履歴のワークフロー
- コメントの処理
- 複雑なケースでの XML アクセス
このスキルでできること:
- 入れ子になった表の抽出
- 複雑なセルコンテンツの処理
- フォームとチェックリストの処理
- 高度なコンテンツ抽出パターン
併用方法:
# For basic operations: use official skill
from docx import Document
# For nested table handling: use this skill
from docx_advanced import extract_cell_content_with_nested_tables
# Combine both
doc = Document('complex_form.docx') # Official
for table in doc.tables: # Official
for row in table.rows: # Official
for cell in row.cells: # Official
# Advanced extraction:
content = extract_cell_content_with_nested_tables(cell)
パフォーマンスに関する考慮事項
大規模なドキュメントの場合:
入れ子の表のチェック結果をキャッシュします。
def build_nested_table_cache(doc):
"""Pre-compute which cells have nested tables"""
cache = {}
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:
cache[(t_idx, r_idx, c_idx)] = len(cell.tables)
return cache
# Usage
cache = build_nested_table_cache(doc)
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 (t_idx, r_idx, c_idx) in cache:
# This cell has nested tables
content = extract_cell_content_with_nested_tables(cell)
else:
# Regular extraction
content = cell.text
トラブルシューティング
問題:コンテンツが表示されているのに、抽出結果が空になる
診断:
cell = table.rows[1].cells[0]
print(f"cell.text: '{cell.text}'")
print(f"cell.tables: {len(cell.tables)}")
if not cell.text.strip() and cell.tables:
print("Content is in nested tables!")
修正方法: extract_cell_content_with_nested_tables(cell) を使用します。
問題:チェックボックス文字(、☐)が出力に表示される
修正方法: 取り除きます。
text = cell.text.strip()
# Remove checkbox unicode characters
clean_text = text.replace('', '').replace('☐', '').replace('☑', '').replace('☒', '')
問題:複数行のコンテンツが保持されない
修正方法: 改行で結合します。
'\n'.join(text_parts) # Preserves line structure
ベストプラクティス
-
必ず最初に入れ子の表があるか確認してください。
if cell.tables: content = extract_cell_content_with_nested_tables(cell) else: content = cell.text -
チェックボックス文字を処理してください。
CHECKBOX_CHARS = ['', '☐', '☑', '☒'] if text not in CHECKBOX_CHARS: # Process text -
構造を保持してください。
# Use newlines to maintain line breaks '\n'.join(lines) -
サンプルドキュメントでテストしてください。
def test_extraction(): doc = Document('sample_form.docx') cell = doc.tables[0].rows[1].cells[0] extracted = extract_cell_content_with_nested_tables(cell) assert 'High potential' in extracted assert 'Moderate potential' in extracted
リファレンス実装
上記のパターンは単体で使用できます。このスキルには個別の REFERENCE.md は含まれていません(以前の参照先は現在使われていません)。実用例、統合パターン、再帰的な抽出、パフォーマンスに関する補足は、上記の各セクションに記載されています。
Anthropic Skills への貢献
このパターンは現在、公式の docx スキルには含まれていません。役立つと感じた場合は、以下の手順で貢献をご検討ください。
- https://github.com/anthropics/skills をフォークします
document-skills/docx/SKILL.mdに追加します- 次の内容を含むプルリクエストを送信します。
- パターンの説明
- コード例
- 使用例
成功基準
次の条件を満たせば、パターンは正常に機能しています。
- 入れ子の表があるセルから、完全なコンテンツが返される
- チェックボックスの選択肢が正しく抽出される
- フォームのフィールドが読み取れる
- 抽出時にコンテンツが失われない
- 構造が保持される(改行が維持される)