Skip to content

Add multi-version compatibility - #86

Merged
psobot merged 1 commit into
masterfrom
psobot/historical-versions
Aug 9, 2026
Merged

psobot merged 1 commit into
masterfrom
psobot/historical-versions

Conversation

@psobot

@psobot psobot commented Aug 8, 2026 •

Copy link
Copy Markdown
Owner

Allows unpacking or repacking for specific Keynote versions, going back as far as this library has been around.

@psobot psobot changed the title Bundle every previous Keynote version, and let one be selected Add multi-version compatibility Aug 9, 2026
Apple renamed message types between Keynote releases, so a .yaml file written
by an older keynote-parser names types the current schemas no longer contain -
the caveat the README's Compatibility section has described for years without
offering a way around it. With per-version descriptor pools in place, several
versions can now coexist, so the way around it is to bundle them.

The schemas for versions Apple has long since replaced can't be extracted from
an installed Keynote, but they are already in this repository: every release
tag from v1.10.2.1 carries the .proto files it shipped with and a mapping
module holding that version's TSP registry. dumper/extract_historical_versions.py
recovers them from those tags; it reads only from git and is safe to re-run.

Bundles 10.2, 11.2, 12.0, 12.1, 12.2.1 and 13.1 alongside 14.4 and 14.5. All
eight load together with distinct pools. 10.2 and 11.2 leave a few registry
entries unresolved (3 and 1), which is faithful - those releases did not ship
protos for them either.

Renames turn out to occur at exactly two boundaries: 10.2 -> 11.2 renamed 24
types (Master -> Template) and 13.1 -> 14.4 renamed 36 (TSK -> TSCK). The
versions in between are identical in naming.

--keynote-version is now accepted by unpack, pack, cat and replace, and
argparse restricts it to the bundled set. Threading it through required
IWAFile and IWACompressedChunk to accept a version at all, and fixed a latent
bug: IWAArchiveSegment.from_dict took a version argument but passed it to
neither dict_to_header nor dict_to_message, so packing under a non-default
version silently used the newest schemas anyway.

Two existing tests hardcoded type 6383, which postdates 10.2 and 11.2; they now
derive an id common to every bundled version so adding an older one can't break
them again.

Cost: the wheel grows from 0.40 MB to 1.45 MB, and protos/ from 1.2 MB to
4.4 MB. 188 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179M4xvAKPGrgKpy4AeCsM7
@psobot
psobot force-pushed the psobot/historical-versions branch from be464f3 to 85e8a57 Compare August 9, 2026 03:06
@psobot
psobot merged commit 37f0b26 into master Aug 9, 2026
4 checks passed
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.

1 participant