Skip to content

ODT: read and write tracked changes (text:tracked-changes) - #1517

Merged
echelon merged 2 commits into
storytold:mainfrom
dkhlapov:feat-odt-revisions
Oct 14, 2026
Merged

echelon merged 2 commits into
storytold:mainfrom
dkhlapov:feat-odt-revisions

Conversation

@dkhlapov

@dkhlapov dkhlapov commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Gap 19 in docs/gaps.md (ODT depth): ODT files now keep their tracked changes.

Builds on #1516 (RTF tracked changes). This branch contains #1516's two commits and uses the same revision model. Please merge #1516 first; after that, this PR's own diff is the ODT commits.

What was wrong

ODT import skipped text:tracked-changes. The deleted text stored in each change region was lost, and inserted text became plain text. Export wrote no change tracking.

What changed

crates/formats/src/odt.rs, following ODF 1.3 Part 3 §5.5:

  • Import:
    • Each text:changed-region gives its author and date.
    • Text between text:change-start and text:change-end becomes a tracked insertion.
    • At each text:change point, the region's deleted content is put back as tracked-deleted text. Deleted whole paragraphs keep their deleted paragraph marks, so Accept All and Reject All give the right paragraphs.
    • An insertion nested inside a deletion gives text that is both inserted and deleted.
    • An open body insertion doesn't leak onto deleted paragraph marks.
  • Export: the tracked-changes regions are written with change-start/end for insertions, and a text:change point plus the region for deletions. Text that is both inserted and deleted is written as one deletion region with a nested insertion range.
    • dc:date is always written; the save time is used when a revision has no date.
    • Change marks may sit directly in the body or in table cells, which §5.5.7 allows.
  • Hostile input is bounded: at most 10,000 regions and 64 open insertions; author and date capped at 256 characters; the first of any duplicate ids wins; each deletion is placed once.

Shared model (crates/formats/src/model.rs), on top of #1516's:

Docs: docs/file-format-parity.md ODT row (deleted pictures and tables are dropped from deletions), docs/gaps.md gap 19, and a ROADMAP.md progress-log entry, each with its status line and revision history.

Tests

These failed before the change:

  • import of an insertion by A and a deletion by B, with kinds, authors and dates;
  • deleted whole paragraphs;
  • an export → import round trip;
  • engine Accept All and Reject All;
  • inserted_then_deleted_text_keeps_both_marks, with a single revision kept after a save;
  • exported_changes_always_have_a_date_and_keep_paragraph_separators;
  • odt_inserted_then_deleted_text_round_trips;
  • a_deleted_mark_inside_an_insertion_is_not_inserted;
  • odt_deleted_mark_inside_an_insertion_survives_reject_all.

Coverage: insertions_end_before_a_table_and_inside_a_cell, plus hostile-input tests (20,000 regions, bad ids, nesting).

cargo xtask ci: all 6 steps passed (fmt, clippy, test, assets, layers, wasm). Not checked in LibreOffice.

Review

🤖 Generated with Claude Code

@dkhlapov
dkhlapov marked this pull request as ready for review October 14, 2026 02:22
LabDennis added a commit to LabDennis/wordcraft that referenced this pull request Oct 14, 2026
…FODT

M12: support OTT and FODT Writer documents and preserve paragraph spacing

M12: integrate Writer stories, sections and revisions across ODF formats

Adapt notes/comments from storytold#1057 and section/revision work from storytold#1506, storytold#1516 and storytold#1517. Extend the shared ODT/OTT/FODT paths with master-page stories, section export and combined regression tests. Source contributions and remaining fidelity limits are documented in docs/odf-compatibility.md.


Integrate current upstream while retaining import behavior and embedded-font loading.
dkhlapov and others added 2 commits October 14, 2026 14:30
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	ROADMAP.md
#	crates/engine/src/tests.rs
#	crates/formats/src/model.rs
#	crates/formats/src/odt.rs
#	docs/file-format-parity.md
#	docs/gaps.md
…sertion; one region per deletion

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@echelon

echelon commented Oct 14, 2026

Copy link
Copy Markdown
Member

I rebased this onto main now that #1516 has landed (squash-merged), keeping only the two ODT commits, and merged its ODT import with the per-section page settings from #1506 (parse_tracked now returns the last section too). formats/engine clippy and the ODT tests pass.

@echelon
echelon force-pushed the feat-odt-revisions branch from eba2c33 to 1b7709a Compare October 14, 2026 18:34
LabDennis added a commit to LabDennis/wordcraft that referenced this pull request Oct 14, 2026
…FODT

M12: support OTT and FODT Writer documents and preserve paragraph spacing

M12: integrate Writer stories, sections and revisions across ODF formats

Adapt notes/comments from storytold#1057 and section/revision work from storytold#1506, storytold#1516 and storytold#1517. Extend the shared ODT/OTT/FODT paths with master-page stories, section export and combined regression tests. Source contributions and remaining fidelity limits are documented in docs/odf-compatibility.md.


Integrate current upstream while retaining import behavior and embedded-font loading.
@echelon
echelon merged commit e7e4522 into storytold:main Oct 14, 2026
3 checks passed
@echelon

echelon commented Oct 14, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution, @dkhlapov! This has landed in main. If you haven't already, come join us on Discord: https://discord.gg/artcraft

LabDennis added a commit to LabDennis/wordcraft that referenced this pull request Oct 14, 2026
…FODT

M12: support OTT and FODT Writer documents and preserve paragraph spacing

M12: integrate Writer stories, sections and revisions across ODF formats

Adapt notes/comments from storytold#1057 and section/revision work from storytold#1506, storytold#1516 and storytold#1517. Extend the shared ODT/OTT/FODT paths with master-page stories, section export and combined regression tests. Source contributions and remaining fidelity limits are documented in docs/odf-compatibility.md.

Integrate current upstream while retaining import behavior and embedded-font loading.
LabDennis added a commit to LabDennis/wordcraft that referenced this pull request Oct 15, 2026
…FODT

M12: support OTT and FODT Writer documents and preserve paragraph spacing

M12: integrate Writer stories, sections and revisions across ODF formats

Adapt notes/comments from storytold#1057 and section/revision work from storytold#1506, storytold#1516 and storytold#1517. Extend the shared ODT/OTT/FODT paths with master-page stories, section export and combined regression tests. Source contributions and remaining fidelity limits are documented in docs/odf-compatibility.md.

Integrate current upstream while retaining import behavior and embedded-font loading.
@dkhlapov
dkhlapov deleted the feat-odt-revisions branch October 15, 2026 19:27
vangel76 added a commit to vangel76/wordcraft that referenced this pull request Oct 15, 2026
Notes and comments now work with ODT tracked changes (storytold#1517) and per-section
page settings (storytold#1506); notes and comments read inside a note body never start
a section. Adds a test for the combination.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants