Skip to main content

A tool for manipulating Apple Keynote presentation files.

Project description

keynote-parser

build:

keynote-parser is a Python module for unpacking and re-packing Apple Keynote .key files. It supports Keynote files generated by Keynote version 10.1 (current as of August 2020).

Keynote uses a proprietary, compressed binary format to store its presentations. This format is comprised of a zip file containing images and videos, as well as Snappy-compressed Protobuf .iwa files containing metadata, text, and all other definitions used in the presentation.

keynote-parser unpacks these component files into .yaml files in a directory, making them editable by text editors and/or scripts, then allows re-packing of these files into a working Keynote archive.

What could you use this for? Well, I use it to allow versioning of Keynote files in Git, which makes diffs more understandable (rather than binary), as well as modifying text in Keynote files in response to external scripts. (e.g.: figures that update from databases before giving a presentation)

Installation

pip3 install keynote-parser

Usage

# Unpack MyPresentation.key into ./MyPresentation/
keynote-parser unpack MyPresentation.key

# Re-pack ./MyPresentation/ into MyPresentation.out.key
keynote-parser pack ./MyPresentation/

# List the files within a Keynote archive
keynote-parser ls MyPresentation.key

# Dump a particular .iwa file into its yaml representation on stdout
keynote-parser cat MyPresentation.key /Index/Slide-00001.iwa

# Replace text within a Keynote file in-place
keynote-parser replace MyPresentation.key --find "hello world" --replace "hello dolly"

Formats

keynote-parser supports reading a list of replacements from a JSON file passed in as --replacements. This file must have the form:

{
  "replacements": [
    {
      "find": "regexp to search for",
      "replace": "string to replace with"
    },
    ...
  ]
}

This argument can be passed to keynote-parser replace to replace text in a Keynote file in-place. It can also be passed to keynote-parser pack to pack a directory into a Keynote file, replacing text along the way.

Replacing Images

The replacements json format can also be used to replace images in a Keynote file. To do so:

  • Use the keynote-parser ls command to determine the name of the image to replace.
  • Set the find pattern to the image's name, with the -\d\d\d suffix removed.
  • Set the replace field to the local path to the replacement image.

keynote-parser will automatically rescale the replacement image to fit all of the sizes of the target image.

Updates

As keynote-parser includes private Protobuf definitions extracted from a copy of Keynote, new versions of Keynote will inevitably create .key files that cannot be read by keynote-parser. As new versions of Keynote are released, the following steps must be undertaken:

  • Run proto-dump on the new copy of Keynote to dump new Proto files.
    • Any . characters in the Protobuf definitions must be changed to _ characters manually, or via the rename_proto_files.py script in the protos directory of this repo.
  • Connect to a running copy of Keynote with lldb (or any other debugger) and manually copy the results of [TSPRegistry sharedRegistry] into mapping.py.
    • Versions of macOS >= 10.11 may protect Keynote from being attached to by a debugger - to attach, temporarily disable System IntegrityProtection to get this data.
    • The parse_proto_mapping.py script in protos may help turn the output from this step into a JSON mapping, usable in mapping.py.

Credits

keynote-parser was built by Peter Sobot but heavily based on prior work by Sean Patrick O'Brien. A copy of O'Brien's format documentation is included in the docs folder for posterity.

License

All code in this repository is licensed under the MIT License.

Copyright 2019-2020 Peter Sobot

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keynote-parser-1.10.1.4.tar.gz (427.1 kB view details)

Uploaded Source

Built Distribution

keynote_parser-1.10.1.4-py3-none-any.whl (441.9 kB view details)

Uploaded Python 3

File details

Details for the file keynote-parser-1.10.1.4.tar.gz.

File metadata

  • Download URL: keynote-parser-1.10.1.4.tar.gz
  • Upload date:
  • Size: 427.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.0 CPython/3.8.5

File hashes

Hashes for keynote-parser-1.10.1.4.tar.gz
Algorithm Hash digest
SHA256 e7e46d281de2699ae69cb907c367ee850264f625141ab05fe23951726eb9cefa
MD5 69ae0c65971cd8db70045c386049bcb0
BLAKE2b-256 8521b06701b2604b2d3e7ca6e1e00e367fe12fcaeb3f94d08981ee0a55548e6e

See more details on using hashes here.

File details

Details for the file keynote_parser-1.10.1.4-py3-none-any.whl.

File metadata

  • Download URL: keynote_parser-1.10.1.4-py3-none-any.whl
  • Upload date:
  • Size: 441.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.50.0 CPython/3.8.5

File hashes

Hashes for keynote_parser-1.10.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 a0e541dcbf88c3adb23d34df70999eb7a584e84d98347e0c999d927251a9374a
MD5 6d77c24dd82ed1726047840be196513f
BLAKE2b-256 b8c3367b8a17b8c79375d004df84ea9dd0b4cc693dc7abaae634d3209465742c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page