Releases: yfedoseev/office_oxide
v0.1.1 | Richer IR type system, DOCX writer output, improved PPTX/XLSX IR renderers, and writer APIs in all language bindings
IR — extended type system
TextSpangains nine typography fields:font_name,font_size_half_pt,
color,highlight,underline(UnderlineStyleenum),vertical_align
(VerticalAlign: Superscript / Subscript / Baseline),all_caps,
small_caps,char_spacing_half_pt.Paragraphgains twelve layout fields:alignment(ParagraphAlignment:
Left / Center / Right / Justify / Distribute),indent_left_twips,
indent_right_twips,first_line_indent_twips,space_before_twips,
space_after_twips,line_spacing(LineSpacing: Auto / Multiple / Exact /
AtLeast),background_color,border(ParagraphBorder),keep_with_next,
keep_together,page_break_before,outline_level.Tablegainswidth_twips,column_widths_twips,border
(TableBorder),alignment(TableAlignment),indent_left_twips,
cell_padding_twips,caption.TableRowgainsheight_twips,allow_break,repeat_as_header.TableCellgainsbackground_color,border,vertical_align
(CellVerticalAlign),text_align,width_twips,padding(CellPadding),
text_direction(TextDirection).Imagegainsdata,format(ImageFormat),pixel_width,
pixel_height,display_width_emu,display_height_emu,decorative,
positioning(ImagePositioning: Inline or Floating withFloatingImage).Sectiongainspage_setup(PageSetup),columns(ColumnLayout),
break_type(SectionBreakType), and six header/footer slots
(header,footer,first_page_header,first_page_footer,
even_page_header,even_page_footer).Metadatagainsauthor,subject,keywords,created,modified,
description(written todocProps/core.xml).- New
Elementvariants:TextBox,PageBreak,ColumnBreak,
Footnote(Note),Endnote(Note),CodeBlock. Listgainsstart_number,style(ListStyle),level.
ListItem.contentpromoted fromVec<InlineContent>toVec<Element>
to allow block-level content (tables, images) inside list items.InlineContentgainsFootnoteRefandEndnoteRefvariants.- New supporting types:
BorderLine,TableBorder,ParagraphBorder,
CellPadding,FloatingImage,HeaderFooter,TextBox,Note,
FootnoteRef,CodeBlock,PageSetup,ColumnLayout. - New enums:
UnderlineStyle,ParagraphAlignment,LineSpacing,
BorderStyle,CellVerticalAlign,TableAlignment,TextDirection,
ImageFormat,ImagePositioning,SectionBreakType,VerticalAlign,
FloatAnchor,TextWrap,ListStyle. - All new fields are
Option<_>or default tofalse/None— fully
backwards compatible; existing callers require only..Default::default()
on struct literals.
DocxWriter — OOXML emission for all new fields
- Run properties:
<w:rFonts>,<w:sz>/<w:szCs>,<w:color>,
<w:shd>(highlight),<w:u>,<w:vertAlign>,<w:caps>,
<w:smallCaps>,<w:spacing>(character spacing). - Paragraph properties:
<w:jc>,<w:ind>,<w:spacing>(before/after/
line),<w:pBdr>,<w:shd>,<w:keepNext>,<w:keepLines>,
<w:pageBreakBefore>,<w:outlineLvl>. - Table:
<w:tblW>,<w:tblInd>,<w:tblBorders>,<w:jc>(table),
<w:tblCellMar>,<w:tblGrid>/<w:gridCol>. - Table row:
<w:trHeight>,<w:tblHeader>,<w:cantSplit>. - Table cell:
<w:tcW>,<w:gridSpan>,<w:vMerge>,<w:shd>(cell),
<w:tcBorders>,<w:vAlign>,<w:textDirection>,<w:tcMar>(per-edge
padding), cell-leveltext_alignpropagated to contained paragraphs. - Table caption: emitted as a
Caption-styled paragraph before<w:tbl>. - Images: inline
<wp:inline>and floating<wp:anchor>with
<wp:wrapSquare>/<wp:wrapTight>/<wp:wrapThrough>/
<wp:wrapTopAndBottom>/<wp:wrapNone>. - Text boxes:
<wp:anchor>+<wps:txbx>+<w:txbxContent>. - Sections:
<w:sectPr>with<w:pgSz>,<w:pgMar>,<w:cols>(uniform
and per-column widths with separator rule),<w:type>(Continuous / NextPage
/ EvenPage / OddPage). Header/footer parts written to/word/header*.xmland
/word/footer*.xmlwith correct relationship entries. - Footnotes / endnotes:
/word/footnotes.xmland/word/endnotes.xml
parts; inline<w:footnoteReference>/<w:endnoteReference>runs with
FootnoteReference/EndnoteReferencecharacter styles. {PAGE}/{NUMPAGES}sentinels in header/footer text spans emitted as
<w:fldChar>/<w:instrText>field runs.- Page break:
<w:br w:type="page">. Column break:<w:br w:type="column">. - Code blocks:
Code-styled paragraph with preserved whitespace and
line breaks. - Lists:
<w:numFmt>driven byListStyle;<w:startOverride>for
non-1start_number; block-level item content (tables, images) written
alongside the numbered paragraph. - Metadata:
author,subject,keywords,description,created,
modifiedwritten todocProps/core.xmlas Dublin Core properties.
PPTX IR renderer — ir_to_pptx
- Rich text runs: paragraphs and headings now emit styled
<a:r>runs via
add_rich_text()— bold, italic, font size, color, and font name from
TextSpanare all preserved. Previously all formatting was stripped. - Table elements: rendered as tab-separated cell text (rows joined with
\n)
instead of being silently dropped. - Image elements: embedded as native PPTX media via the new
SlideData::add_image()API — writes a<p:pic>shape with<p:blipFill>
and an OPC media part. PNG, JPEG, and GIF are supported. - CodeBlock elements: rendered with Courier New font run instead of being
silently dropped. - Slide dimensions: first
Section.page_setupis now forwarded to
PptxWriter::set_presentation_size()(1 twip = 914 400/1 440 EMU), fixing
clipped output for landscape A4 and other non-16:9 documents. - New
PptxWriter::set_presentation_size(cx, cy)method; emits<p:sldSz>
with the correct EMU values instead of always writing the 16:9 default.
XLSX IR renderer — ir_to_xlsx
- Header row styling: rows with
TableRow.is_header = trueare now written
with bold weight and a grey (D3D3D3) background viaset_cell_styled().
TableCell.background_coloroverrides the default grey when set. - Cell background color: non-header cells with
TableCell.background_color
set now get a solid fill style applied. - Column widths:
Table.column_widths_twipsis now converted to Excel
character-width units (twips × 96 / (1440 × 7), clamped 3–80) and written
viaset_column_width(). - Merged cells:
TableCell.col_spanandrow_span> 1 now emit a
<mergeCells>/<mergeCell ref="…"/>block in the worksheet XML instead of
being ignored. - New
SheetData::merge_cells(row, col, row_span, col_span)method; inserts
<mergeCells>between</sheetData>and</worksheet>. - Row cursor tracks absolute position across all elements in a section, so
paragraphs and headings interleaved with tables land in the correct rows.
Writer APIs — all language bindings
XlsxWriter and PptxWriter (previously Rust-only) are now callable from
every binding layer via a new index-based C FFI surface:
New C FFI symbols (include/office_oxide_c/office_oxide.h):
office_xlsx_writer_new/free,office_xlsx_writer_add_sheet(returns sheet
index),office_xlsx_sheet_set_cell,office_xlsx_sheet_set_cell_styled
(bold + hex background),office_xlsx_sheet_merge_cells,
office_xlsx_sheet_set_column_width,office_xlsx_writer_save,
office_xlsx_writer_to_bytesoffice_pptx_writer_new/free,office_pptx_writer_set_presentation_size,
office_pptx_writer_add_slide(returns slide index),
office_pptx_slide_set_title,office_pptx_slide_add_text,
office_pptx_slide_add_image(PNG/JPEG/GIF bytes + EMU geometry),
office_pptx_writer_save,office_pptx_writer_to_bytes
Go — XlsxWriter and PptxWriter structs with CGo wrappers and
runtime.SetFinalizer for safe GC.
C# / .NET — new OfficeOxide.XlsxWriter and OfficeOxide.PptxWriter
classes (IDisposable); P/Invoke declarations added to NativeMethods.
Node.js — XlsxWriter and PptxWriter ESM + CJS classes; koffi
function prototypes; TypeScript ImageFormat type and class declarations.
Python — XlsxWriter and PyO3PptxWriter PyO3 classes calling Rust
directly (no C FFI round-trip); exported from office_oxide with full type
stubs in _native.pyi.
Bug fixes
TableCell.padding(CellPadding) was defined in the IR but silently
dropped by the writer; now emits<w:tcMar>with per-edge twip values.TableCell.text_alignwas defined in the IR but silently dropped; now
propagated to contained paragraphs (respects pre-existing paragraph
alignment, so explicit paragraph alignment is never overwritten).Table.captionwas defined in the IR but silently dropped; now emitted
as aCaption-styled paragraph immediately before the table.
Install
Rust cargo add office_oxide
Python pip install office-oxide
JavaScript (WASM, universal) npm install office-oxide-wasm
Node.js (native) npm install office-oxide
Go
go get github.com/yfedoseev/office_oxide/go
# fetch the native library matching your platform:
go run github.com/yfedoseev/office_oxide/go/cmd/install@latestC# / .NET dotnet add package OfficeOxide
CLI
cargo binstall office_oxide_cli # pre-built binary
brew install yfedoseev/tap/office-oxide
scoop bucket add yfedoseev https://github.com/yfedoseev/scoop-bucket && scoop install office-oxideRaw C FFI — download the native-<platform>-<arch> asset below and include include/office_oxide_c/office_oxide.h.
Changelog
Full history: [CHANGELOG...
v0.1.0 | Initial public release
Cross-language bindings
- Rust core (
office_oxideon crates.io): unifiedDocumenthandle for
all six formats,EditableDocumentfor DOCX/XLSX/PPTX editing, format-
agnosticDocumentIR. - Python (
office-oxideon PyPI): context-managerDocument/
EditableDocument,os.PathLikesupport, complete type stubs in
_native.pyi(Literalformat names,_Pathalias). - Go (
github.com/yfedoseev/office_oxide/go): CGo wrapper over the C FFI
with idiomaticOpen/Close/ error-return API,go/cmd/installhelper
that fetches the matching native archive and prints the
CGO_CFLAGS/CGO_LDFLAGSto export. - C# / .NET (
OfficeOxideon NuGet):LibraryImportP/Invoke,
IDisposable,async/await,IsAotCompatible=true,IsTrimmable=true.
FourSetCelloverloads +SetCellEmpty. Net 8 and net 10 target
frameworks. - Node.js native (
office-oxideon npm): koffi-based,
no node-gyp, ESM + CJS entry points with anexportsmap, TypeScript
definitions,Symbol.disposesupport, platform prebuilds staged into
prebuilds/<platform>-<arch>/. - WASM (
office-oxide-wasmon npm): three sub-path exports — default
ESM for bundlers,office-oxide-wasm/nodefor CJS,office-oxide-wasm/web
for native-ESM browser imports. TypeScript definitions shipped. - C FFI (
include/office_oxide_c/office_oxide.h): stable
office_document_*/office_editable_*surface with out-param error
codes and explicit memory ownership. Exported from the cdylib + staticlib;
the substrate that Go, C#, and Node-native link against.
Tooling
- CLI (
office-oxidebinary):text,markdown,html,info,ir
subcommands. - MCP server (
office-oxide-mcpbinary):extractandinfotools
over JSON-RPC 2.0 / stdio.
Performance
- Up to 100× faster than
python-docx,openpyxl,python-pptx,xlrd. - Beats
calamineon XLSX and all Rust / Python alternatives on .xls. - 100% pass rate on valid Office files (6,062-file corpus: LibreOffice,
Apache POI, python-pptx, python-docx, Pandoc, etc.). All 97 non-passing
files are invalid inputs — corrupted ZIPs, missing required parts, malformed
XML, or non-Office files with Office extensions.
Documentation & examples
- Per-language getting-started guides in
docs/: Rust, Python,
Go, C#, JavaScript (native), WASM, and C / raw FFI. - Per-binding READMEs in
python/,go/,
csharp/OfficeOxide/,
js/,wasm-pkg/. - Identical
extract/replace/read_xlsxdemos per language under
examples/.
Release CI
- Version parity across
Cargo.toml,pyproject.toml,
wasm-pkg/package.json,js/package.json, and
csharp/OfficeOxide/OfficeOxide.csproj. - 6-target native-lib build matrix producing
.tar.gz/.ziparchives
with the shared library, static archive, and public header. - 3-target WASM build (bundler / nodejs / web) with per-target module-type
hints so Node + bundlers + browsers each load the right code. - NuGet packaging with
runtimes/<rid>/native/prebuilts, Node
prebuilds/<platform>-<arch>/staging, and ago/v*module tag for the
Go module proxy.
Install
Rust cargo add office_oxide
Python pip install office-oxide
JavaScript (WASM, universal) npm install office-oxide-wasm
Node.js (native) npm install office-oxide
Go
go get github.com/yfedoseev/office_oxide/go
# fetch the native library matching your platform:
go run github.com/yfedoseev/office_oxide/go/cmd/install@latestC# / .NET dotnet add package OfficeOxide
CLI
cargo binstall office_oxide_cli # pre-built binary
brew install yfedoseev/tap/office-oxide
scoop bucket add yfedoseev https://github.com/yfedoseev/scoop-bucket && scoop install office-oxideRaw C FFI — download the native-<platform>-<arch> asset below and include include/office_oxide_c/office_oxide.h.
Changelog
Full history: CHANGELOG.md