Skip to main content

docx-document-builder

既存の Word (.docx) テンプレートやサンプルの文書に、文書のスタイル(フォント・章・段落・改行)を保ったまま内容を流し込み、文字と段落をサンプルと同じ粒度に収め、段落・章・文書全体の文体と論理構成もサンプルにそろえるスキル。「このWordのテンプレートに流し込んで」「この文書と同じ形式で報告書を作って」「前回の報告書を雛形にして」「このdocxから内容を取り出して」などで発動する。

Source facts

Repository
ynitto/sandbox
Last source activity
October 11, 2026 at 04:39
Detected SKILL.md language
Japanese
Stars
1
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
19 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
docx-document-builder
description
既存の Word (.docx) テンプレートやサンプルの文書に、文書のスタイル(フォント・章・段落・改行)を保ったまま内容を流し込み、文字と段落をサンプルと同じ粒度に収め、段落・章・文書全体の文体と論理構成もサンプルにそろえるスキル。「このWordのテンプレートに流し込んで」「この文書と同じ形式で報告書を作って」「前回の報告書を雛形にして」「このdocxから内容を取り出して」などで発動する。
metadata
{"version":"1.2.0","tier":"experimental","category":"document","tags":["docx","word","document","template","python-docx","json"]}
# docx-document-builder Word の文書を作るスキル。xlsx-report-builder・pptx-presentation-builder の docx 版で、考え方とサブコマンドは同じ。**基本の使い方は、依頼のフレーズから流れ(フロー)を選んで進める**こと。個々のサブコマンドを直接呼ぶ使い方は、オプション([サブコマンド一覧](#サブコマンド一覧個別に呼ぶ場合))。 - テンプレート(体裁の決まった .docx、前の案件の文書)がある → 文書のスタイルをそのまま使い、内容を流し込む - テンプレートが無い → JSON スペックから新規に生成する docx ならではの約束が 3 つある。 1. **文書のスタイルを保つ**。文字を差し替えるときは、段落(スタイル・字下げ・行間・番号)と文字(フォント・大きさ・色・太字)の書式を、テンプレートの見本の段落から取る。章(見出しのスタイルと番号)はそのまま続き、繰り返した節の中の番号つきリストは節ごとに 1 から振り直す。データの改行(`\n`)は段落の中の改行、空行(`\n\n`)は段落の区切りになる。`件名:` のようなラベルは、太字などの書式ごと残して後ろだけを差し替える 2. **サンプルと同じ粒度に収める**。文字の大きさ・字下げ・余白は変えず、データの量の方を合わせる。サンプルの文字数・段落の数・項目数(`max_chars`・`max_items`)を超えると、`render` はどの欄を何字・何段落減らせばよいかを挙げて止まる。量を調整する(要約する・まとめる)のは LLM の仕事 3. **サンプルと同じ書きぶりにする**。段落ごとの役割、章(部分)ごとの趣旨と論理構成、文書全体の章の流れを定義に書き、データはそれに沿って書く。文末(です・ます/だ・である/体言止め)・1 文の長さ・数字と句読点の表記は `analyze` がサンプルから測り、違う文があると `render` が挙げて止まる パスはこの SKILL.md からの相対パス。コマンド実行前にこのディレクトリに `cd` すること。 ## 起動手順 スキル開始時に必ず実行する: ```bash cd .github/skills/docx-document-builder uv sync ``` ## 使い方: フレーズ → フロー 依頼のフレーズから、次のどれかのフローを選ぶ。判断がつかないときは、まず「テンプレート(元にする文書)はありますか。ある場合、どこで作られたものですか」と聞く。 | # | 依頼のフレーズ(例) | フロー(→ は順に進む。【確認】はユーザーに確認する) | 使うサブコマンド | |---|----------------------|------------------------------------------------------|------------------| | 1 | 「このWordに流し込んで」「この文書と同じ形式で作って」「前回の報告書を雛形にして」「他のプロジェクトの文書を元に作って」 | 出所を聞く【流用なら可否を確認】→ テンプレートの事実を読む → 段落・表ごとに 残す/流し込む/繰り返す/無視する を決める【確認】→ 定義を確定して検査 → データを用意(粒度に合わせて量を調整)→ 再構成 → 見て確かめる | `inspect`・`analyze`・`check`・`render` | | 2 | 「今月分も同じ文書で作って」「同じ形式でもう一度」(定義が確定済み) | データを用意 → 再構成(専用スクリプトがあればそれを実行)→ 確かめる | `render`(または専用スクリプト) | | 3 | 「この文書の内容を差し替えたい」「前の報告書を直して出し直したい」 | 記入済みの文書からデータを取り出す → データを直す → 再構成 | `extract`・`render` | | 4 | 「章を足して」「テンプレートが更新された」「入れる欄を変えたい」 | 既存の定義を取り出す → 定義を直す【確認】→ 検査 → 書き出し直す/再構成。文書の構成が変わったなら #1 に戻る | `export --from-script`・`check`・`render` | | 5 | 「毎回使えるスクリプトにして」「LLM なしで回せるように」 | 定義を確定して検査 → 専用の単体スクリプトを書き出す → 動作を確かめる | `check`・`export` | | 6 | 「報告書を作って」でテンプレートが無く、見出し・本文・箇条書き・表で足りる | データと構成を確認 → JSON スペックを組む → 生成 → 確かめる | `example`・`build` | | 7 | 「このdocxの構造を教えて」「どこが入力欄か調べて」「サンプルの値が残っていないか見て」 | テンプレートの事実を読む → 結果を要約して返す(生成はしない) | `inspect`(`analyze`) | - #1 の「流用」(他プロジェクトの文書)は、同じフローに流用の可否の確認を足す。値・メタデータを持ち越さない決めごと(`strict`・`keep`・`properties.scrub`)は、流用でなくても既定で入る - LLM が関わるのは、判断(段落の役割・定義)と、データの用意(量の調整を含む)まで。`check`・`render`・`extract`・`export` と、書き出した専用スクリプトは、決まった処理だけで動く - #2・#5 は、定義が確定していることが前提。無ければ #1 から ## フローの詳細: テンプレートへの流し込み(#1〜#5) 詳細は [references/template.md](references/template.md)。 ### 段の一覧 | 段 | 何をするか | 誰が | コマンド | |----|-----------|------|----------| | T0 | テンプレートの出所を聞く。他プロジェクトの文書なら、流用してよいか(社外秘・個人情報・権利)を確認する | LLM → ユーザー | — | | T1 | テンプレートの事実(段落・見出し・リスト・表・書式・収まる量・章の構成・同じ形の節・仮値の疑い・来歴)を読む | コマンド → LLM | `inspect` / `analyze` | | T2 | 段落・表ごとに 残す・流し込む・繰り返す・無視する を決め、段落・章・全体の趣旨と論理構成を書き、一覧をユーザーに確認してもらう | LLM + ユーザー | — | | T3 | 定義を確定し、整合と「テンプレートの値の残り」を検査する | コマンド | `check` | | T4 | データを用意する。趣旨・論理構成・文体に沿って書き、粒度(`max_chars`・`max_items`)に合わせて要約する・まとめる | LLM | — | | T5 | 再構成する。収まらない欄があれば、挙がった欄だけ T4 に戻って直す | コマンド(LLM なし) | `render` | | T6 | 同じ文書を繰り返し作るなら、専用の単体スクリプトにする | コマンド | `export` | | T7 | 出力を見て確かめる(画像にして見る) | LLM | — | ### T1: テンプレートの事実を読む ```bash uv run python scripts/docx_builder.py inspect path/to/template.docx # 判断用の事実(--json も可) uv run python scripts/docx_builder.py analyze path/to/template.docx -o def.yaml # 定義の下書き(自動検出) ``` `inspect` は、本文の段落・表を順に番号(ブロック `#1`・`#2` …)を振って出す。定義はこの番号で段落・表を指す。 - 段落の種類(段落・見出しの段・リストの記号か番号と段・表・コンテンツコントロール)、スタイル、フォントと文字の大きさ、配置 - **収まる量**(1 行の字数、文字の大きさ)と、いま使っている行数。段落の中の改行・改ページ・セクションの区切り・図・フィールド - 用紙と余白、本文の幅、行の格子、ページ数の見積もり - **章の構成**(見出しと、その章が持つブロックの範囲)と、**同じ形の節の並び**(繰り返しの候補と、その手がかり) - **仮の値の疑い**(`サンプル`・`〇〇`・`yyyy` など)と**注記の疑い**(`※`) - **来歴・持ち越しの注意**: 文書のプロパティ(作成者・会社名・タイトル)、プレビュー画像、コメント、変更履歴、ヘッダー・フッター、脚注、外部へのリンク、埋め込みのオブジェクト、元にした Word テンプレートの場所、隠し文字、目次のフィールド、マクロ `analyze` の下書きは確定ではない。判断は `inspect` の事実を読んだこちら(LLM)が行う。 ### T2: 段落・表ごとに、役割を決める 定義は、文書を見出しごとの**部分(parts)**に分け、部分ごとに次の役割を書く。 | 役割 | 意味 | 定義での書き方 | 向く段落・表 | |------|------|----------------|----------| | 残す(keep) | テンプレートのまま出す | `keep` | 章の見出し、`目的:` だけの段落、固定の注記 | | 流し込む(fill) | データの文字で置き換える(`null` なら空) | `texts`・`lists`・表の `cells` | 表題・日付・宛名・本文の段落・箇条書き・`件名:〇〇` の後ろ | | 繰り返す(repeat) | 見本を、データの件数だけ複製する | 部分の `repeat`、表の `key`・`columns` | 1 件 1 節(見出し + 本文)、表の行 | | 文書の値(doc) | データではないが、文書ごとに変わる値。文の一部だけでも差し替える | `texts` の `{text: "{文書.年度}年度 第{文書.四半期}四半期 業務報告書"}`、`件名:` の後ろは `文書.件名`、`header_footer`、`properties` | 表題の年度・四半期、日付、宛名の「○○ 御中」、見出しの「(2025年9月)」、フッターの表題、作成日・作成者・版・件名 | | 無視する(ignore) | 出力に残さない | `clear`(文字だけ空に)、部分の `drop`(部分ごと取り除く) | 記入例・使い方の説明・見本の 2 つめ以降の節 | 判断の目安: - **表題・日付・宛名・フッターは、文字の中の可変の部分を見る**。「2025年度 第1四半期 業務報告書」の年度・四半期は次の文書では変わるが、「業務報告書」は変わらない。文全体をデータにせず、変わる部分だけを文書の値(データの `文書:`)にする。`analyze` は表紙・見出し・ヘッダー/フッターの中から年度・四半期・年月・日付・期間・版・宛名を見つけて下書きし、確認の項目に挙げる。毎回同じ文字は `keep` に戻す。作成日・作成者・版・件名などのラベルの後ろの値も `文書.` のキーになり、文書全体で 1 つの値が入る(xlsx-report-builder と同じ) - **同じ形の節が続く**(施策ごとに 1 節など)→ 1 つめを `repeat` の見本にし、残りは `drop`。`analyze` は、見出しに共通の言葉があるか、どの節にも同じラベル・表の見出しがあるときだけそう下書きする。形だけが同じ節(「概要」と「背景」)は繰り返しにせず、確認の項目に挙げる - **見出しの番号**は、スタイルの自動の番号ならそのまま続く。`2.1 施策 A` のように手で打った番号は `format: "2.{n} {}"` で振り直す(`{n}` が 1 始まりの番号、`{}` が値) - **ラベルと値が 1 つの段落にある**(`件名:〇〇`)→ `after: "件名:"` で、ラベルの書式(太字など)ごと残して後ろだけを差し替える - **本文の段落の続き**は 1 つの欄(`#6-#8`)にする。データは空行で段落を分けた文字。段落の数は `max_items` - **表の最後の行(合計・小計)**は残し、値はデータに書く(`合計.件数` のような欄)。合計は計算しないので、足した値を書く - **ラベルに対する値は、残さない**。日付・宛名・作成者・版・顧客名は前の案件の実データ。流し込むか空にする - **データに書くのは、文書ごとに変わる値だけ**。どの行も同じ文字の列は `keep: true`、押印・承認・確認者の列は `clear: true` - **様式の名前・欄の名前は残す**。`備品購入申請書` のような表題と、入力欄・表のすぐ前の `備考` は `keep`。印の欄だけの表もそのまま残す - **表の見た目に頼る値は、データでは意味の分かる形にする**。○× の列は `完了: true` と書き、変換は定義(`map`・`when`・`part`)に任せる - 迷う段落は、決めずにユーザーに聞く。聞くときは、ブロックの番号・文字・候補の役割・理由を 1 行ずつ示す #### 文章の型を書く(趣旨・論理構成・文体) 書式だけでなく、サンプルの書きぶりも写す。`inspect` の文字を読み、段落・章・文書全体の 3 つの単位で定義に書く(書き方は [references/template.md](references/template.md#文章の型趣旨論理構成文体))。 | 単位 | 書くもの | 定義 | |------|----------|------| | 段落(欄) | 文末と 1 文の長さ(`analyze` が測る)、段落ごとの役割(1 段落め: 結論、2 段落め: 理由、など) | 欄の `ending`・`sentence_chars`・`logic` | | 章(部分) | 趣旨(その章で言いたいこと)、論理構成(結論から書くか、背景から積み上げるか、根拠に何を使うか) | 部分の `intent`・`logic` | | 文書全体 | 章の流れ(概要 → 施策 → 進捗、など)、数字と句読点の表記(表記は `analyze` が測る) | `style.logic`・`style.digits`・`style.punctuation` | - 段落の役割は、接続の言葉(まず・一方・したがって)や、数字・例の使い方も見て書く - `analyze` が測った文末は、サンプルが仮の文や書き方の説明なら外す - 判断の一覧と一緒に、趣旨・論理構成もユーザーに見せる #### 前の文書の値・メタデータを持ち越さない `analyze` の下書きは、はじめから次の形になっている。外すのは、ユーザーが望んだときだけ。 1. **`strict: true`**。文字を持つ段落・表が、`texts`・`lists`・`keep`・`clear`・表のどれにも入らないまま残ると、`check` と `render` がブロックの番号と文字を挙げて止まる。挙がったものを、そのまま全部 `keep` に貼らない 2. **`properties.scrub: true`**。作成者・最終更新者・会社名・タイトルなどを空にし、プレビュー画像・カスタムプロパティ・コメントを取り除き、変更履歴を承諾して作成者の名前を消し、元にした Word テンプレートの場所を外す。与えたい値(`title: "第3四半期 報告"`)は同じ `properties` に書く 3. **ヘッダー・フッター・脚注・グラフの値・埋め込みのオブジェクト・外部へのリンク・隠し文字**は、`inspect` が挙げるが、自動では書き換えない(ヘッダー・フッターの年度・表題などの可変の部分だけは、`analyze` が `header_footer` に下書きする)。ユーザーに見せて扱いを決める(テンプレートの側で直す) 決めたら、判断の一覧(ブロック | 文字 | 役割 | 理由)を**ユーザーに見せて確認してもらう**。確認前に定義を確定しない。 ### T3: 定義を検査する ```bash uv run python scripts/docx_builder.py check --def def.yaml # テンプレートは定義の template(定義ファイルからの相対パス)から読む。--template で上書き ``` 整合(ブロックの範囲・段落か表か・`after` のラベル・表の見出し)を確かめ、雛形データで試しに再構成する。最後に、データの書き方と**収まる量**(`施策[].points[]: 最大 5 項目・1 項目 12 字まで`)の一覧が出る。T4 はこの一覧を見て書く。 ### T4〜T5: データを用意して再構成する データは、部分のキー(`表紙`・`概要` …)ごとの欄を持つ JSON か YAML([assets/template.data.example.yaml](assets/template.data.example.yaml))。繰り返す部分は配列。数値・事実を捏造しない。 `check` の一覧に出る趣旨・論理構成・文体に沿って書く。段落は役割の順に、章は文書全体の流れ(`style.logic`)の順に並べる。章の趣旨に合わない内容は、別の章に押し込まずにユーザーに聞く。 ```bash uv run python scripts/docx_builder.py render --def def.yaml --data data.yaml -o out.docx ``` 収まらない欄があると、次のように挙げて止まる(終了コード 1)。**フォントを小さくしたり、余白を狭めたりしない**。挙がった欄の文章を要約する・段落や項目をまとめる、のどちらかでデータを直し、もう一度 `render` する。文体の違いは、その文をサンプルの文末・表記に書き直す。 ``` 収まらない値があります。テンプレートの粒度に合わせて、データの量を減らすか言い換えてください: 表紙.title(#1): 30 字。サンプルの粒度は 18 字まで(12 字減らす) 概要.body(#6-#7): 4 段落。サンプルの粒度は 3 段落まで(1 段落減らすか、まとめる) 施策[0].points(#12-#13): 6 項目。サンプルの粒度は 5 項目まで(1 項目減らすか、まとめる) サンプルの文体と違う文があります。定義の文体(ending・sentence_chars・style)に合わせて書き直してください: 概要.body(#6-#7) 1 段落め: 「夜間バッチの遅延が 2 回ありました。」はです・ます調。サンプルはだ・である調 概要.body(#6-#7) 2 段落め: 1 文が 61 字(「来月から監視の間隔を…」)。サンプルの 1 文は 26 字まで(文を分けるか短くする) ``` - 1 ページに収める様式なら、定義に `max_pages: 1` を書く。ページ数の見積もりが超えると止まる - 粒度の上限そのもの(`max_chars`・`max_items`)を変えるのは、ユーザーが望んだときだけ - `--allow-overflow` は、止めずに警告にする(下書きを見せるときだけ使う) データが大きくなるなら、ファイルを分けてよい。`--data` に複数のファイルかフォルダを渡すと、1 つにまとめて流し込む。繰り返す部分・リスト・表の行はファイルの順(フォルダなら名前順)につなぐ。同じ欄に違う値があると止まる。書き出した専用スクリプトも同じ。分け方は**章のまとまり**ごと。定義の `parts[].group` が同じ部分を 1 ファイルにし、無ければ部分ごとに分ける。`analyze` は、見出し 1 の章の名前を `group` に入れる。`extract --split DIR` は、取り出したデータをこのまとまりごとのファイルに分けて書く。 ```bash uv run python scripts/docx_builder.py render --def def.yaml --data 01-表紙.yaml 02-概要.yaml -o out.docx uv run render_report.py --data data/ -o out.docx # フォルダの中のデータファイルを名前順に ``` 記入済みの文書(前の案件の文書・以前に `render` した文書)からデータを起こすなら、`extract` で取り出してから直す。 ```bash uv run python scripts/docx_builder.py extract filled.docx --def def.yaml -o data.yaml ``` ### T6: この文書専用の単体スクリプトにする(任意) ```bash uv run python scripts/docx_builder.py export --def def.yaml -o render_report.py uv run render_report.py --data data.yaml -o out.docx # PEP 723 で依存(lxml・python-docx・pyyaml)を自動で入れる ``` - テンプレートは既定では別ファイルのまま、スクリプトからの相対パスで読む。1 ファイルにしたいときだけ `--embed` - `--data` には、分けたデータの複数のファイルかフォルダも渡せる - `--example-data` でデータの雛形と収まる量、`--extract-def` で埋め込みの定義を取り出せる - 改修は、スクリプトを手で書き換えず、定義を直して `export --from-script render_report.py --def def.yaml -o render_report.py` で書き出し直す。`--def` を付けなければエンジンだけを最新にする ### T7: 確かめる 1. 出力を画像にして、ページごとに見る(`soffice --headless --convert-to pdf out.docx` → `pdftoppm -png -r 50 out.pdf page`)。フォント・見出しの番号・リストの番号・段落の間隔・改行・表の書式がテンプレートと同じか確かめる 2. サンプルの値(`サンプル`・前の顧客名・前の日付)が残っていないか確かめる。ヘッダー・フッターも見る 3. 流用した場合は、文書のプロパティ・コメント・変更履歴に、元のプロジェクトの情報が残っていないか確かめる 4. 目次があれば、Word で開いてフィールドを更新する(`render` は、開いたときに更新を求める設定にする) テストの実行: `uv run python -m unittest discover -s tests -v` 具体的な文書で依頼から出来上がりまでを通すシナリオは [tests/scenarios/](tests/scenarios/README.md) にある。エージェントに「このシナリオを再生して」と頼んで回す。 ## フローの詳細: 新規生成(#6) 1. 内容と構成を確認する。数値・事実は捏造しない 2. JSON スペックを組む。構造は [references/spec.md](references/spec.md)。雛形は `uv run python scripts/docx_builder.py example` 3. 生成する: `uv run python scripts/docx_builder.py build --spec spec.json` 4. T7 と同じく、画像にして確かめる ブロックの種類は `title`・`heading`(見出し 1〜3。章の番号はスタイルで振る)・`paragraph`(`\n` は改行、空行は段落の区切り)・`bullets`・`numbered`・`table`・`page_break`。作った文書は、そのままテンプレートとして #1 に使える。 ## サブコマンド一覧(個別に呼ぶ場合) すべて `uv run python scripts/docx_builder.py <サブコマンド>`。 | サブコマンド | 役割 | 主な引数 | |--------------|------|----------| | `inspect <template.docx>` | テンプレートの事実(段落・見出し・表・書式・収まる量・章の構成・仮値の疑い・来歴)を出す | `--json` | | `analyze <template.docx>` | 定義の下書きを書く(確定ではない) | `-o def.yaml`(拡張子で JSON / YAML を選ぶ) | | `check --def <def>` | 定義の整合と、テンプレートの値の残り(`strict`)を検査し、収まる量の一覧を出す | `--template` | | `render --def <def> --data <data> -o <out.docx>` | テンプレート + 定義 + データから再構成する | `--template`、`--data -`(標準入力)、`--data a.yaml b.yaml` / `--data DIR`(分けたデータをまとめる)、`--allow-overflow` | | `extract <filled.docx> --def <def>` | 記入済みの文書から、定義に沿ってデータを取り出す(`render` の逆) | `-o data.yaml`(省略時は標準出力に JSON)、`--template`、`--split DIR`(章のまとまりごとのファイルに分ける) | | `export --def <def> -o <render.py>` | 定義を埋め込んだ、単体で動く専用スクリプトを書き出す | `--embed`、`--template`、`--from-script <旧.py>` | | `build --spec <spec.json>` | テンプレート無しで、JSON スペックから新規生成する | stdin も可 | | `example` | `build` のサンプルスペックを出す | — | ## できること / できないこと | 対象 | 可否 | |------|------| | 段落の文字の差し替え(段落・文字の書式、段落の中の改行を保つ)、ラベルの後ろだけの差し替え | ✅ | | 本文の段落の数・リストの項目数と段の増減(同じ位置・同じ段の見本の書式で) | ✅ | | 節(見出し + 本文)の繰り返し・見本の節の削除。見出しの番号は続け、番号つきリストは節ごとに振り直す | ✅ | | 表の行の増減(見出し・合計の行は残す)、○× などの変換、2 列の記入欄 | ✅ | | コンテンツコントロール(ブロックのもの)への記入 | ✅ | | 収まる量の検査(サンプルの粒度・高さの決まったセル・ページ数の見積もり) | ✅ | | 文体の検査(文末・1 文の長さ・数字と句読点の表記)と、段落・章・全体の趣旨と論理構成の書き添え | ✅ 趣旨・論理構成は LLM が書き、データを書くときに使う | | 前の文書のコメント・変更履歴・プロパティの除去 | ✅ | | ヘッダー・フッターの段落の差し替え(年度・表題・宛名などの文書の値) | ✅ `header_footer` | | 脚注・テキストボックスの中の文字の差し替え | ❌ そのまま残す(`inspect` が挙げる) | | 1 つの段落の中の、一部だけの書式(途中の太字) | ❌ 差し替えた値は 1 つの書式になる(ラベルは `after` で残せる) | | 画像・グラフの差し替え | ❌ そのまま残す | ## ガードレール | 制限 | 内容 | |------|------| | データの事実性 | 依頼に無い数値・事実を作らない。量を減らすときは要約・統合し、意味を変えない | | スタイル | フォント・文字の大きさ・字下げ・行間・余白をデータに合わせて変えない。合わせるのはデータの量 | | 章 | 章の見出しのスタイルと番号はテンプレートのまま。番号を文字で打ち直さない(手で打った番号は `format` で振る) | | 書きぶり | サンプルの文末・表記・章の趣旨を、データに合わせて変えない。合わない内容は、ユーザーに聞く | | 機密 | 流用元の実データ・コメント・変更履歴・プロパティを持ち越さない |
View on GitHub