IR independente de formato
DocumentIR é a ponte estrutural do Office Oxide entre formatos. Abra um .docx, um .xlsx ou um .ppt legado — você sempre recebe a mesma forma: uma lista de seções, cada uma com uma sequência de elementos tipados (títulos, parágrafos, tabelas, listas, imagens).
O IR sustenta to_html, save_as e a conversão legado → OOXML. Também é a superfície certa para pipelines downstream — índices de busca, chunkers de RAG, renderizadores próprios — porque você processa um único schema em vez de seis específicos por formato.
Ler o 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 é um enum 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())
{
// ...
}
Schema
A forma é deliberadamente pequena e estável.
{
"sections": [
{
"title": "Título de seção opcional", // 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>" }
]
}
]
}
Mapeamento por formato:
| Formato | Limite de seção | Notas |
|---|---|---|
| DOCX | Uma seção por <w:sectPr> (ou o body inteiro se não houver) |
Títulos chaveados por w:pStyle |
| XLSX | Uma seção por planilha | title = nome da planilha; um Table por intervalo usado |
| PPTX | Uma seção por slide | title = placeholder do título do slide; notas anexadas como último parágrafo |
| DOC / XLS / PPT | Mesma forma dos correspondentes OOXML | Parseados pelo pipeline legado de CFB |
Por que usar o IR
- Construa uma vez, renderize de várias formas. Converta DOCX, XLSX e PPTX para a mesma forma e rode um único pipeline de busca/chunking.
- Contexto LLM que sobrevive a mudanças de formato. O schema não muda quando os documentos migram de
.docpara.docx. - Round-trip com
save_as. Edite o IR e escreva um novo documento em qualquer formato suportado.
use office_oxide::create::create_from_ir;
use office_oxide::DocumentFormat;
create_from_ir(&ir, DocumentFormat::Docx, "out.docx")?;
Serialização
O DocumentIR em Rust deriva Serialize / Deserialize (via serde). O to_ir() em Python devolve um dict puro (já serializável em JSON). Os bindings Node, Go, C# e C expõem strings JSON via to_ir_json() / ToIRJSON() / ToIrJson().
Veja também
- Extração Markdown — texto amigável a LLMs
- Extração HTML — quando você quer saída estilizada
- Conversão: legado → OOXML — usa o IR por baixo