The slides of a Keynote presentation, their master slides, presenter notes,
animations (builds) and transitions are held in KN (Keynote) messages,
defined in KNArchives.proto. Apple has not published them; the
definitions below are those iWorkFileFormat recovered from Keynote 6.0 (2013), read as
explained on document
messages. The slide editing commands of KNCommandArchives.proto
(types 100 to 148) are not listed.
Slide nodes
The show’s slide tree starts at a root slide node. Every node points to one slide
and to its child nodes, so the order of the slides is a depth-first walk of the tree.
The node also keeps the slide’s thumbnails (as files in Data/) and flags
the program uses for the navigator.
message SlideNodeArchive { // KN, type 4
repeated TSP.Reference children = 1;
optional TSP.Reference slide = 2; // KN.SlideArchive
optional TSP.Reference database_thumbnail = 3;
required bool isHidden = 4; // skipped slide
required bool isCollapsed = 5 [deprecated = true];
required bool hasBuilds = 6;
required bool hasTransition = 7;
optional bool hasNote = 8;
repeated TSP.Reference database_thumbnails = 9;
repeated TSP.Size thumbnailSizes = 10;
optional string uniqueIdentifier = 11;
optional string copyFromSlideIdentifier = 12;
optional uint32 slideSpecificHyperlinkCount = 13;
optional bool thumbnailsAreDirty = 14;
optional uint32 eventCount = 15;
repeated TSP.DataReference thumbnails = 16;
optional bool isCollapsedInOutlineView = 17;
optional bool isSlideNumberVisible = 18 [default = false];
optional bool hasBodyInOutlineView = 19;
}
The depth-first slide order is the site’s reading of a tree with
children; the dump does not state it.
Slides and master slides
Types 5 and 6 are both KN.SlideArchive; the registry does not say
what distinguishes them. A slide refers to its master (master), its slide
style, its drawables in back-to-front order, its builds and transition, and its title,
body, object and slide-number placeholders. A master slide is a slide too: the theme
lists the masters.
message SlideArchive { // KN, types 5 and 6
message SageTagMapEntry {
required string tag = 1;
required TSP.Reference info = 2;
}
required TSP.Reference style = 1; // KN.SlideStyleArchive
repeated TSP.Reference builds = 2; // KN.BuildArchive
repeated KN.BuildChunkArchive buildChunks = 3;
required KN.TransitionArchive transition = 4;
optional TSP.Reference titlePlaceholder = 5;
optional TSP.Reference bodyPlaceholder = 6;
repeated TSP.Reference drawables = 7;
optional string name = 10;
optional TSD.GeometryArchive titlePlaceholderGeometry = 11;
optional uint32 titlePlaceholderShapeStyleIndex = 12;
optional uint32 titlePlaceholderTextStyleIndex = 13;
optional TSD.GeometryArchive bodyPlaceholderGeometry = 14;
optional uint32 bodyPlaceholderShapeStyleIndex = 15;
optional uint32 bodyPlaceholderTextStyleIndex = 16;
optional TSP.Reference master = 17;
repeated TSD.GuideArchive staticGuides = 18;
required bool inDocument = 19;
optional TSP.Reference slideNumberPlaceholder = 20;
optional TSD.GeometryArchive slideNumberPlaceholderGeometry = 21;
optional uint32 slideNumberPlaceholderShapeStyleIndex = 22;
optional uint32 slideNumberPlaceholderTextStyleIndex = 23;
optional TSWP.ShapeStylePropertiesArchive titleLayoutProperties = 24;
optional TSWP.ShapeStylePropertiesArchive bodyLayoutProperties = 25;
optional TSWP.ShapeStylePropertiesArchive slideNumberLayoutProperties = 26;
optional TSP.Reference note = 27; // KN.NoteArchive
repeated KN.SlideArchive.SageTagMapEntry sage_tag_to_info_map = 28;
optional TSP.Reference classicStylesheetRecord = 29;
optional TSP.Reference objectPlaceholder = 30;
repeated TSP.Reference bodyParagraphStyles = 31;
optional bool deprecated_objectPlaceholderVisibleForExport = 34;
repeated TSP.Reference bodyListStyles = 35;
optional TSP.Reference userDefinedGuideStorage = 36;
optional string thumbnailTextForTitlePlaceholder = 37;
optional string thumbnailTextForBodyPlaceholder = 38;
optional TSP.Reference info_using_object_placeholder_geometry = 39;
optional bool info_using_object_placeholder_geometry_matches_object_placeholder_geometry = 40;
}
message SlideStylePropertiesArchive {
optional TSD.FillArchive fill = 1; // slide background
optional KN.TransitionAttributesArchive transition = 2;
optional bool transition_null = 3;
optional bool titlePlaceholderVisibility = 4;
optional bool bodyPlaceholderVisibility = 5;
optional bool slideNumberPlaceholderVisibility = 6;
optional bool objectPlaceholderVisibility = 7;
}
message SlideStyleArchive { // KN, type 9
required TSS.StyleArchive super = 1;
optional uint32 override_count = 10 [default = 0];
optional KN.SlideStylePropertiesArchive slide_properties = 11;
}
message PlaceholderArchive { // KN, types 7 and 12
enum Kind {
kKindPlaceholder = 0;
kKindSlideNumberPlaceholder = 1;
kKindTitlePlaceholder = 2;
kKindBodyPlaceholder = 3;
kKindObjectPlaceholder = 4;
}
required TSWP.ShapeInfoArchive super = 1; // a text shape
optional KN.PlaceholderArchive.Kind kind = 2 [default = kKindPlaceholder];
}
message NoteArchive { // KN, type 15: presenter notes
required TSP.Reference containedStorage = 1; // TSWP.StorageArchive, kind NOTE
}
message SlideNumberAttachmentArchive { // KN, type 22
required TSWP.TextualAttachmentArchive super = 1;
}
The meaning of the “sage” tag map is not explained by the dump. The text of a
title or body placeholder is in the TSWP.StorageArchive its
TSWP.ShapeInfoArchive contains (see
text and styles).
Transitions
A slide’s transition plays when the show moves to the next slide. The effect is a
string naming one of Keynote’s effects, not a number; the dump does not list the
names. The database_… fields are the older form of the same
attributes.
message AnimationAttributesArchive {
optional string animationType = 1;
optional string effect = 2;
optional double duration = 3;
optional uint32 direction = 4;
optional double delay = 5;
optional bool isAutomatic = 6;
optional TSP.Color color = 7;
}
message TransitionAttributesArchive {
enum TransitionCustomAttributesTimingCurveType {
TransitionCustomAttributesTimingCurveTypeLinear = 1;
TransitionCustomAttributesTimingCurveTypeEaseIn = 2;
TransitionCustomAttributesTimingCurveTypeEaseOut = 3;
TransitionCustomAttributesTimingCurveTypeEaseInEaseOut = 4;
}
enum TransitionCustomAttributesTextDeliveryType {
TransitionCustomAttributesTextDeliveryTypeByObject = 1;
TransitionCustomAttributesTextDeliveryTypeByWord = 2;
TransitionCustomAttributesTextDeliveryTypeByCharacter = 3;
TransitionCustomAttributesTextDeliveryTypeByLine = 4;
}
optional string database_animationType = 1;
optional string database_effect = 2;
optional double database_duration = 3;
optional uint32 database_direction = 4;
optional float database_delay = 5;
optional bool isAutomatic = 6;
optional TSP.Color database_color = 7;
optional KN.AnimationAttributesArchive animationAttributes = 8;
optional float custom_twist = 9;
optional uint32 custom_mosaic_size = 10;
optional uint32 custom_mosaic_type = 11;
optional bool custom_bounce = 12;
optional bool custom_magic_move_fade_unmatched_objects = 13;
optional KN.TransitionAttributesArchive.TransitionCustomAttributesTimingCurveType custom_timing_curve = 15;
optional KN.TransitionAttributesArchive.TransitionCustomAttributesTextDeliveryType custom_text_delivery_type = 16;
}
message TransitionArchive {
required KN.TransitionAttributesArchive attributes = 2;
}
The codes of direction, custom_mosaic_size and
custom_mosaic_type are not named in the dump.
Builds
A build animates one drawable on a slide (the action_… fields belong to
action builds, going by their names). A build is split into chunks, and the
slide’s buildChunks list gives the order
in which all chunks of all builds play, each with its own delay, duration and
whether it starts automatically.
message BuildChunkArchive {
required TSP.Reference build = 1; // KN.BuildArchive
required uint32 index = 2; // which chunk of that build
optional double delay = 3;
optional double duration = 4;
optional bool automatic = 5;
optional bool referent = 6;
}
message BuildAttributesArchive {
enum BuildAttributesAcceleration { kNone = 0; kEaseIn = 1; kEaseOut = 2; kEaseBoth = 3; }
enum BuildAttributesRotationDirection { kClockwise = 31; kCounterclockwise = 32; }
enum BuildAttributesCurveStyle { kStraight = 0; kCurved = 1; }
enum BuildAttributesTextDelivery {
kTextDeliveryUndefined = 0;
kTextDeliveryByObject = 1;
kTextDeliveryByWord = 2;
kTextDeliveryByCharacter = 3;
kTextDeliveryByLine = 4;
}
enum BuildAttributesDeliveryOption {
kDeliveryOptionUndefined = 0;
kDeliveryOptionForward = 1;
kDeliveryOptionBackward = 2;
kDeliveryOptionFromCenter = 3;
kDeliveryOptionFromEdges = 4;
kDeliveryOptionRandom = 5;
}
enum ActionBuildAttributesJiggleIntensity {
kJiggleIntensitySmall = 0;
kJiggleIntensityMedium = 1;
kJiggleIntensityLarge = 2;
}
optional string database_animationType = 1;
optional string database_effect = 2;
optional uint32 database_direction = 3;
optional uint32 eventTrigger = 4;
optional double database_delay = 5;
optional double delayAutomaticAfter = 6;
optional double delayAutomaticWith = 7;
optional double database_duration = 8;
optional double action_rotationAngle = 9;
optional KN.BuildAttributesArchive.BuildAttributesRotationDirection action_rotationDirection = 10;
optional double action_scaleSize = 11;
optional double action_colorAlpha = 12;
optional KN.BuildAttributesArchive.BuildAttributesAcceleration action_acceleration = 13;
optional KN.BuildAttributesArchive.BuildAttributesCurveStyle curveStyle = 14;
optional string motionPathString = 15 [deprecated = true];
optional TSP.Color database_color = 16;
optional double ChartRotation3D = 17;
optional KN.AnimationAttributesArchive animationAttributes = 18;
optional bool custom_bounce = 19;
optional KN.BuildAttributesArchive.BuildAttributesTextDelivery custom_textDelivery = 20;
optional KN.BuildAttributesArchive.BuildAttributesDeliveryOption custom_deliveryOption = 21;
optional TSD.PathSourceArchive action_motionPathSource = 22;
optional bool custom_action_decay = 23;
optional uint32 custom_action_repeatCount = 24;
optional double custom_action_scale = 25;
optional KN.BuildAttributesArchive.ActionBuildAttributesJiggleIntensity custom_action_jiggleIntensity = 26;
optional uint32 startOffset = 27;
optional uint32 endOffset = 28;
}
message BuildArchive { // KN, type 8
required TSP.Reference drawable = 1; // the animated drawable
required string delivery = 2;
required double duration = 3;
required KN.BuildAttributesArchive attributes = 4;
}
The rotation directions really are 31 and 32 in the dump. The strings that
delivery, animationType and effect take, and
the codes of eventTrigger and direction, are not listed in
any public source found.
Recordings and soundtrack
A recorded narration keeps a timeline of events (slide changes, laser pointer
positions, pauses, movie control) and the recorded movie in segments. The soundtrack
plays audio files from Data/ during the show.
message RecordingArchive { // KN, type 16
enum RecordingSyncState {
kRecordingSyncStateInSyncWithShow = 0;
kRecordingSyncStateOutOfSyncWithShow = 1;
}
repeated TSP.Reference event_tracks = 1; // KN.RecordingEventTrackArchive
optional TSP.Reference movie_track = 2; // KN.RecordingMovieTrackArchive
optional double duration = 3;
optional KN.RecordingArchive.RecordingSyncState sync_state = 4 [default = kRecordingSyncStateInSyncWithShow];
optional TSP.Date modification_date = 5;
}
message RecordingEventTrackArchive { // KN, type 17
optional string type = 1;
repeated KN.RecordingEventArchive events = 2;
}
message RecordingEventArchive {
optional double start_time = 1 [default = -1];
optional KN.RecordingNavigationEventArchive navigation_event_archive = 1000;
optional KN.RecordingLaserEventArchive laser_event_archive = 1001;
optional KN.RecordingPauseEventArchive pause_event_archive = 1002;
optional KN.RecordingMovieEventArchive movie_event_archive = 1003;
}
message RecordingNavigationEventArchive {
enum RecordingNavigationEventAnimationPhase {
kRecordingNavigationEventAnimationNone = 0;
kRecordingNavigationEventAnimationStart = 1;
kRecordingNavigationEventAnimationEnd = 2;
}
optional TSP.Reference target_slide_node_reference = 1;
optional uint32 target_event_index = 2;
optional KN.RecordingNavigationEventArchive.RecordingNavigationEventAnimationPhase animation_phase = 3 [default = kRecordingNavigationEventAnimationNone];
}
message RecordingLaserEventArchive {
optional TSP.Point unscaled_location = 1;
}
message RecordingPauseEventArchive {
enum RecordingPauseEventType {
kRecordingPauseEventTypeResume = 0;
kRecordingPauseEventTypePause = 1;
kRecordingPauseEventTypeConcealWithBlack = 2;
kRecordingPauseEventTypeConcealWithWhite = 3;
}
optional KN.RecordingPauseEventArchive.RecordingPauseEventType pause_event_type = 1 [default = kRecordingPauseEventTypeResume];
}
message RecordingMovieEventArchive {
enum RecordingMovieEventType {
kRecordingMovieEventNone = 0;
kRecordingMovieEventSeek = 1;
kRecordingMovieEventSetRate = 2;
kRecordingMovieEventStartPlayback = 3;
kRecordingMovieEventStopPlayback = 4;
kRecordingMovieEventBeginScrubbing = 5;
kRecordingMovieEventEndScrubbing = 6;
}
optional TSP.Reference movie_info_reference = 1;
optional KN.RecordingMovieEventArchive.RecordingMovieEventType movie_event_type = 2 [default = kRecordingMovieEventSeek];
optional double movie_event_value = 3;
}
message RecordingMovieTrackArchive { // KN, type 18
repeated KN.MovieSegmentArchive movie_segments = 1;
}
message MovieSegmentArchive {
optional TSP.Reference database_movie_data = 1;
optional double start_time = 2 [default = -1];
optional TSP.DataReference movie_data = 3;
}
message Soundtrack { // KN, type 21
enum SoundtrackMode {
kKNSoundtrackModePlayOnce = 0;
kKNSoundtrackModeLoop = 1;
kKNSoundtrackModeDoNotPlay = 2;
}
optional double volume = 1;
optional KN.Soundtrack.SoundtrackMode mode = 2 [default = kKNSoundtrackModePlayOnce];
repeated TSP.DataReference movie_media = 3;
}
An event carries one of the four event messages, in field 1000 to 1003; the dump
does not list the strings of RecordingEventTrackArchive.type.