Skip to content

About

Lossless, undoable editing of OOXML packages (docx, pptx, xlsx) over lxml

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ooxml-edit

CI

The format-neutral half of an Office Open XML editor: the OPC package read and written back losslessly, parts added, copied, removed and reaped, schema-ordered insertion, undo and redo with batches, and durable ids stamped into an extension list. What a .pptx, a .docx and an .xlsx editor all need, and nothing any one of them needs alone.

Depends on lxml and ooxml-common (standard library only: the reading of number format codes, the measured date names and the locale that every library shares). Python 3.10+.

A part that was never parsed is written back as the exact bytes that were read.

Install

Not on PyPI yet, nor is ooxml-common: install it from GitHub first, then this package from GitHub or a checkout:

pip install "ooxml-common @ git+https://github.com/uvrt/ooxml-common@main"
pip install "ooxml-edit @ git+https://github.com/uvrt/ooxml-edit@main"
pip install -e '.[dev]'     # from a checkout, with pytest

Example

from ooxml_edit.history import History
from ooxml_edit.opc import OpcPackage
from ooxml_edit.xml import make, append_in_order, register_child_order, register_namespaces

register_namespaces({"my": "urn:example:my-format"})
register_child_order({"my:props": ("my:name", ("my:item", "my:note"), "my:extLst")})

package = OpcPackage.open("in.zip")
history = History(package)

part = package.main_document_part()
history.checkpoint()                      # before every mutation
append_in_order(package.tree(part), make("my:item", val="1"))
package.mark_dirty(part)

history.undo()                            # the original bytes again
package.save("out.zip")

What it covers

  • Core (ooxml_edit.opc, .xml, .history, .stamp, .provenance, .dates, .markdown, .errors): lossless OPC packages, parts and relationships, safe removal (release/reap), embedded packages, schema-ordered insertion, undo/redo with batches and versions, durable ids, the record of where placed values came from, date patterns in measured month names, and a small Markdown subset (emphasis, strikethrough, code spans, escapes, lines and lists) read into marked runs and written back. See docs/CORE.md.
  • ooxml_edit.charts (optional): charts with their embedded workbooks, new charts from data, and SmartArt diagrams, edited the same way in a deck or a Word document. See docs/CHARTS.md.
  • ooxml_edit.pictures (optional): an SVG picture as Office stores one (the blip's SVG extension) and the SVG recoloured as PowerPoint's Graphics Fill and Outline rewrite one, a theme colour kept by its class -- the same in a deck and a Word document, which draws it alike.
  • ooxml_edit.sheets (optional): a workbook's cells written losslessly -- text, rich text (runs with the cell's font, bold, italic, struck through), numbers, booleans, dates in the workbook's date system, formulas, blanks -- with shared strings, cell formats, rows with or without r, tables, the calculation chain and calcPr kept in step, a shared formula group's master released with its members' formulas kept, and the edit's footprint (outside_footprint) written down and checked. What charts writes a chart's embedded workbook with, and xlsx-agent's edits.
  • ooxml_edit.tools (optional): the plumbing of an agent tool layer -- tool definitions for the Anthropic and OpenAI APIs, sessions, refs and batches. See docs/TOOLS.md and docs/TOOLS-ROADMAP.md.

Not in it: any one format's vocabulary in the core (no PresentationML, WordprocessingML or SpreadsheetML outside the optional subpackages -- tests/test_neutrality.py checks this), rendering (that is ooxml-common's), and any one format's tools. Why, and how it relates to ooxml-common: docs/DESIGN.md.

Status

Version 0.11.0, used by pptx-agent and docx-agent. Not on PyPI. Changes: CHANGELOG.md.

Tests

python -m pytest -q
python -m pytest -m provider     # online checks; need ANTHROPIC_API_KEY (and
                                 # ANTHROPIC_WORKSPACE_ID for a key without a workspace)

The tests build the small packages they need (tests/synthetic.py, and tests/charts_synthetic.py for charts of every kind, their workbooks and SmartArt, and tests/sheets_synthetic.py, a made-up shop's stock-list template, for sheets); no Office document is committed here. Chart edits are checked against the embedded workbook by an independent reader, tests/xlsx.py. tests/test_public_api.py holds the names the agents import from here (docs/USED-BY.md), so a rename fails here first. See CONTRIBUTING.md.

Family

  • pptx2svg -- renders PowerPoint (.pptx) slides to SVG and PNG.
  • docx2svg -- renders Word (.docx) documents to SVG, page by page.
  • ooxml-common -- the format-neutral reading, DrawingML, fonts and text metrics both renderers share.
  • ooxml-edit (this repo) -- lossless, undoable editing of OOXML packages, shared by both agent layers.
  • pptx-agent -- an AI-editable PowerPoint layer: inspect, edit, re-render.
  • docx-agent -- an AI-editable Word layer: inspect, edit (optionally as tracked changes), re-render.

Licence

MIT; see LICENSE.

About

Lossless, undoable editing of OOXML packages (docx, pptx, xlsx) over lxml

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages