フォーマット非依存の IR
DocumentIR は Office Oxide のフォーマット間構造的ブリッジです。.docx、.xlsx、レガシーな .ppt を開くと、同じ形が返ります — セクションのリストで、各セクションにはタイプ付きの要素(見出し、段落、テーブル、リスト、画像)の列があります。
IR は to_html、save_as、レガシー → OOXML 変換を支えます。下流のパイプライン — 検索インデックス、RAG チャンカー、カスタムレンダラ — にとっても適切なサーフェスです。1 つのスキーマ を処理すればよく、6 つの形式固有のスキーマを扱う必要がありません。
IR を読む
Rust
use office_oxide::Document;
let doc = Document::open("report.docx")?;
let ir = doc.to_ir();
for section in &ir.sections {
println!("{:?}", section.title);
for el in §ion.elements {
// el は Element 列挙型 — Heading、Paragraph、Table、List、Image など
}
}
Python
from office_oxide import Document
with Document.open("report.docx") as doc:
ir = doc.to_ir()
for section in ir["sections"]:
print(section.get("title"))
for el in section["elements"]:
kind = el["kind"] # "Heading" | "Paragraph" | "Table" | "List" | "Image"
JavaScript
using doc = Document.open('report.docx');
const ir = doc.toIr();
for (const section of ir.sections) {
for (const el of section.elements) {
// el.kind: "Heading" | "Paragraph" | "Table" | "List" | "Image"
}
}
Go
import "encoding/json"
irJSON, _ := doc.ToIRJSON()
var ir struct {
Sections []struct {
Title *string `json:"title"`
Elements []json.RawMessage `json:"elements"`
} `json:"sections"`
}
_ = json.Unmarshal([]byte(irJSON), &ir)
C#
using System.Text.Json;
using var doc = Document.Open("report.docx");
using var ir = JsonDocument.Parse(doc.ToIrJson());
foreach (var section in ir.RootElement.GetProperty("sections").EnumerateArray())
{
// ...
}
スキーマ
形は意図的に小さく安定しています。
{
"sections": [
{
"title": "オプションのセクションタイトル", // string | null
"elements": [
{ "kind": "Heading", "level": 1, "text": "..." },
{ "kind": "Paragraph", "runs": [
{ "text": "Hello ", "bold": false, "italic": false },
{ "text": "world", "bold": true, "italic": false }
] },
{ "kind": "List", "ordered": true, "items": ["one", "two"] },
{ "kind": "Table", "rows": [
["A1", "B1"],
["A2", "B2"]
] },
{ "kind": "Image", "filename": "image1.png", "data": "<base64>" }
]
}
]
}
フォーマットごとのマッピング:
| フォーマット | セクション境界 | 注 |
|---|---|---|
| DOCX | <w:sectPr> ごとに 1 セクション(なければ body 全体) |
見出しは w:pStyle で識別 |
| XLSX | ワークシートごとに 1 セクション | title = シート名; 使用範囲ごとに 1 つの Table 要素 |
| PPTX | スライドごとに 1 セクション | title = スライドタイトルプレースホルダ; ノートは最後の段落として付加 |
| DOC / XLS / PPT | OOXML 同等品と同じ形 | レガシー CFB パイプライン経由でパース |
なぜ IR を使うのか
- 1 度ビルドして何度もレンダー。DOCX、XLSX、PPTX を同じ形に変換し、単一の検索/チャンク化パイプラインを実行。
- フォーマット変更を生き延びる LLM コンテキスト。ソースが
.docから.docxに移行してもスキーマはドリフトしません。 save_asでラウンドトリップ。IR を編集してから、サポートされている任意のフォーマットで新しいドキュメントを書き出す。
use office_oxide::create::create_from_ir;
use office_oxide::DocumentFormat;
create_from_ir(&ir, DocumentFormat::Docx, "out.docx")?;
シリアライズ
Rust の DocumentIR は Serialize / Deserialize(serde 経由)を派生。Python の to_ir() はプレーンな dict を返します(既に JSON シリアライズ可能)。Node、Go、C#、C バインディングは to_ir_json() / ToIRJSON() / ToIrJson() で JSON 文字列を公開します。
関連項目
- Markdown 抽出 — LLM フレンドリーなテキスト用
- HTML 抽出 — スタイル付き出力が欲しいとき
- 変換: レガシー → OOXML — 内部で IR を使用