Releases: paper-instruments/paper-docx
Release list
paper-docx 0.2.0
This release tightens what paper-docx will do without proof. Operations that used to guess now refuse and say what to pass instead. You can anchor footnotes, endnotes, hyperlinks, and captions to a span from docx.search, so they compose with the search you already ran.
pip install paper-docx==0.2.0
Breaking changes
Document.scrub and Document.finalize are gone. Each bundled several jobs behind one verb. Accept or reject through Document.revisions, and set author metadata through core_properties.
Text matching is exact by default. find_text() and find_one() take match="exact" unless you ask for match="normalized". If you relied on implicit normalization, pass it.
find_one() no longer accepts near. Contextual ranking stays on find_text(), where it orders the complete candidate set for inspection. find_one() keeps its zero/one/many resolution.
Exact replacement mode and the character-capacity allocator are gone. Span.replace() runs one path. It considers every maximal exact prefix/suffix alignment, preserves unchanged affixes, and edits one proved structural region when those alignments agree on the changed interval. Nonempty replacement text takes the direct w:rPr of the run holding the first consumed character. Ambiguous repeated affixes refuse and tell you to re-find the intended substring.
Portable block locators are gone. A live Block identifies one attached element. Serialized Anchor values carry location evidence and no mutation authority, so reacquire a live target after a reload.
A text-changing Span.replace() consumes its span. Re-find before the next operation. No-ops and rolled-back operations leave the span reusable.
Operations that require one paragraph refuse cross-paragraph targets instead of editing part of the range.
Zip size caps are gone, so large valid packages open. Broken zips still raise a typed refusal.
New
docx.notes.add_footnoteanddocx.notes.add_endnoteattach real notes to a matched span.docx.links.add_hyperlinkand aHyperlink.addresssetter.docx.fields.add_captionwrites SEQ fields.docx.commentops.delete_commentremoves one comment by identity and keeps the modern comment identity parts consistent.docx.protection.set_protectionwrites Restrict Editing, and the setting stays in the document.Drawing.replace_pictureswaps the image behind a drawing and leaves its size, position, and identity alone.docx.controlswrites the custom XML store, so data-bound content controls hold their values.docx.composition.append_documentcopies the source letterhead.docx.compositioncallers control range endpoints.Span.replace(preserve_revision=True)keeps an existing insertion revision instead of flattening it.
Fixes
- Read and write paths apply the same rules and refuse packages Word cannot open.
- Replacement preserves the formatting regions it does not touch.
- Table lookup matches within physical cells and rejects empty search targets.
- Comparison pairs only what it can prove and stopped inferring table row correspondence.
- A failed bookmark operation restores the live span.
- One protection gate covers paragraph mutation, so refusal wording and operation class cannot drift between the single-anchor and range paths.
Compatibility
The import name stays docx. Install paper-docx in a clean environment: paper-docx and python-docx both own that import package, and paper-docx-doctor fails when it finds both.
CI runs the suite on Python 3.9 through 3.13, plus a LibreOffice job that opens saved output with an independent parser.
paper-docx 0.1.0
What's Changed
- paper-docx v0: the complete safe-editing surface (Phases 0–9) by @daanishkhazi in #3
- v0.1: honesty recall, everyday shapes, four new verbs by @daanishkhazi in #5
- v0.11: revision completion, scrub/finalize, compare, composition, fields, format resolver by @daanishkhazi in #6
- Open-source release prep (clean docs on top of the fork) by @daanishkhazi in #7
- Prepare paper-docx 0.1.0 PyPI release by @daanishkhazi in #8
Full Changelog: https://github.com/The-LLM-Data-Company/paper-docx/commits/v0.1.0