├── masters.key ├── keynote 5.3 scripts ├── key2remark.applescript ├── key2tp.applescript ├── key2md.applescript ├── tp2key.applescript └── key2rmd.applescript ├── master to convert to CSS.md ├── README.md ├── tp2k.applescript ├── k2md.applescript ├── masters.html ├── k2rmd.applescript └── k2remark.applescript /masters.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derickfay/key2txt/HEAD/masters.key -------------------------------------------------------------------------------- /keynote 5.3 scripts/key2remark.applescript: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/derickfay/key2txt/HEAD/keynote 5.3 scripts/key2remark.applescript -------------------------------------------------------------------------------- /master to convert to CSS.md: -------------------------------------------------------------------------------- 1 | # Prioritized list of master slide types to convert to CSS 2 | 3 | ## Title & Subtitle 4 | - DONE 5 | - vertical center 6 | - center 7 | - subtitle as h2 8 | 9 | ## Title - Center 10 | - DONE 11 | - vertical center 12 | - center 13 | 14 | ## Title & Bullets 15 | - DONE 16 | - center title 17 | 18 | ## Bullets 19 | - DONE 20 | - nothing needed 21 | 22 | ## Blank 23 | - DONE 24 | - nothing needed 25 | 26 | ## Photo - Horizontal 27 | - DONE 28 | - flag image 29 | - bottom center title 30 | - image holder 31 | 32 | ## Title - Top 33 | - DONE 34 | - center title (same as Title & Bullets) 35 | 36 | ## Title, Bullets & Photo 37 | - flag image 38 | - center title 39 | - left column 40 | - right column image holder 41 | 42 | ## Title & Bullets - 2 Column 43 | - center title 44 | - left column 45 | - right column 46 | 47 | ## Photo - Vertical 48 | - flag image 49 | - left column: 50 | - center title and subtitle as h2 51 | - vertical center 52 | - right column: 53 | - image holder 54 | -------------------------------------------------------------------------------- /keynote 5.3 scripts/key2tp.applescript: -------------------------------------------------------------------------------- 1 | tell application "TaskPaper" 2 | set theDoc to make new document 3 | set text contents of theDoc to "" 4 | end tell 5 | 6 | tell application "Keynote" 7 | set theShow to slides of slideshow 1 8 | repeat with mySlide in theShow 9 | set theTitle to title of mySlide 10 | set theBody to body of mySlide 11 | set eachBullet to paragraphs of theBody 12 | set theNotes to ("(slide " & slide number of mySlide as string) & ") " & notes of mySlide 13 | set eachNote to paragraphs of theNotes 14 | 15 | tell application "TaskPaper" 16 | tell theDoc 17 | set theProject to make new project 18 | if theTitle is not "Double-click to edit" then 19 | set name of theProject to theTitle 20 | else 21 | set name of theProject to "" 22 | end if 23 | tell theProject 24 | repeat with i in eachBullet 25 | if i as string is not "Double-click to edit" then 26 | set theTask to make new task 27 | set text content of theTask to i 28 | end if 29 | 30 | end repeat 31 | repeat with i in eachNote 32 | set theNote to make new note 33 | set text content of theNote to i 34 | end repeat 35 | end tell 36 | end tell 37 | end tell 38 | end repeat 39 | end tell 40 | -------------------------------------------------------------------------------- /keynote 5.3 scripts/key2md.applescript: -------------------------------------------------------------------------------- 1 | (* Convert Keynote Presentation to Markdown without metadata or presenter notes 2 | 3 | by Derick Fay 4 | 2013-09-20 5 | 6 | usage: 7 | Open a Keynote presentation, then run the script. Markdown will be copied to the clipboard. 8 | 9 | This is a stripped-down version of 'Convert Keynote Presentation to Remark Markdown' designed to produce a Markdown representation of the presentation contents as displayed (i.e. no presenter notes or metadata) 10 | 11 | limitations: 12 | - doesn't do anything with images since they are not readable with Applescript 13 | *) 14 | 15 | tell application "Keynote" 16 | set mdResult to "" 17 | set lfs to " 18 | 19 | " 20 | set x to 0 21 | set theShow to slides of slideshow 1 22 | repeat with mySlide in theShow 23 | -- ignore skipped slides 24 | if skipped of mySlide is false then 25 | -- collect the contents of the slides 26 | set theTitle to title of mySlide 27 | set theBody to body of mySlide 28 | set eachBullet to paragraphs of theBody 29 | 30 | --create the markdown 31 | -- ignore blank text fields 32 | if theTitle is not "Double-click to edit" then 33 | set mdResult to mdResult & "# " & theTitle & lfs 34 | end if 35 | 36 | repeat with i in eachBullet 37 | if i as string is not "Double-click to edit" then 38 | set mdResult to mdResult & "- " & i & lfs 39 | end if 40 | end repeat 41 | 42 | -- add a new slide unless this is the last slide - i.e. avoid having a blank slide at the end 43 | set x to x + 1 44 | if x < (count of theShow) then 45 | set mdResult to mdResult & "---" & lfs 46 | end if 47 | end if 48 | end repeat 49 | end tell 50 | 51 | set the clipboard to mdResult -------------------------------------------------------------------------------- /keynote 5.3 scripts/tp2key.applescript: -------------------------------------------------------------------------------- 1 | tell application "TaskPaper" 2 | set theProjects to projects of document 1 3 | 4 | repeat with theProject in theProjects 5 | set theProjectName to name of theProject 6 | 7 | set theTasks to tasks of theProject 8 | set theBodyText to "" 9 | set n to 0 10 | repeat with theTask in theTasks 11 | set n to n + 1 12 | set theTaskText to (name of theTask as rich text) 13 | set theBodyText to theBodyText & theTaskText 14 | if n is not (count of theTasks) then 15 | set theBodyText to theBodyText & return 16 | end if 17 | 18 | end repeat 19 | 20 | set theNotes to notes of theProject 21 | set theNotesText to "" 22 | repeat with theNote in theNotes 23 | set theNoteText to name of theNote 24 | set theNotesText to theNotesText & return & theNoteText 25 | end repeat 26 | 27 | 28 | tell application "Keynote" 29 | activate 30 | tell slideshow 1 31 | if (text 1 through 2) of theProjectName = "![" then 32 | set theFileName to item 2 of my explode(theProjectName, {"(", ")"}) 33 | make image slides paths {theFileName} 34 | set theProjectName to "" 35 | -- above line works in stand-alone script but not here 36 | else 37 | set newSlide to make new slide 38 | if theProjectName is "" then 39 | set master of current slide to master slide "Bullets" 40 | end if 41 | 42 | 43 | end if 44 | tell current slide 45 | set title to theProjectName 46 | set body to theBodyText 47 | set notes to theNotesText 48 | end tell 49 | end tell 50 | end tell 51 | 52 | end repeat 53 | 54 | end tell 55 | 56 | on explode(the_string, separators) 57 | set old_delims to AppleScript's text item delimiters 58 | set AppleScript's text item delimiters to separators 59 | set r to every text item of the_string 60 | set AppleScript's text item delimiters to old_delims 61 | return r 62 | end explode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Keynote to Text 2 | 3 | A suite of Applescripts aimed at converting Keynote documents to text formats (Markdown, [Remark](http://gnab.github.io/remark/#1) Markdown, and Taskpaper), and back (Taskpaper only so far...). 4 | 5 | The scripts for Markdown have comments and documentation. The Taskpaper scripts don't, but should be pretty self-explanatory. They require TaskPaper 2, as TaskPaper 3 has dropped Applescript support. (But there is a version for TP 3 in [this thread](http://support.hogbaysoftware.com/t/applescript-support-in-taskpaper-3/1309/8?u=derickfay). 6 | 7 | ### Keynote version requirements: 8 | 9 | The scripts with k2 in the filename are preliminary conversions to Keynote 6. 10 | 11 | The scripts with key2 in the filename work with Keynote 5.3 (Keynote '09) but not with Keynote 6. 12 | 13 | Since I am using the trick described here to [keep Keynote 6 and Keynote 5.3 Applescript separate](https://discussions.apple.com/thread/5487564?tstart=0), some of the scripts refer to "Keynote 5.3" instead of "Keynote" in the tell commands. Adjust according to the name of the Keynote 5.3 (i.e. Keynote '09) application file on your machine. 14 | 15 | ### To do: 16 | 17 | I am going to concentrate on improving export to Remark Markdown 18 | 19 | - Finish CSS equivalents for the master slide types in Keynote 20 | - change existing CSS conversion to center titles only, rather than center entire slide then left-justify content 21 | - Create styles to go along with them 22 | 23 | ## Other Useful Tools 24 | 25 | [Taskpaper to Markdown](https://gist.github.com/ttscoff/511174) 26 | 27 | [Markdown to Taskpaper](http://www.leancrew.com/all-this/2011/11/the-return-of-taskpaper/) 28 | 29 | I had envisioned writing a Markdown to Keynote script but I think I will just convert md2tp where needed instead. Taskpaper's Applescript understands the structure of the document which makes for less work than trying to parse the Markdown. 30 | 31 | 32 | -------------------------------------------------------------------------------- /tp2k.applescript: -------------------------------------------------------------------------------- 1 | -- by Derick Fay 2 | -- 2014-04-02: updated for Keynote 6 3 | 4 | -- requires TaskPaper 2 (not TaskPaper 3) 5 | 6 | tell application "TaskPaper" 7 | set theProjects to projects of document 1 8 | 9 | repeat with theProject in theProjects 10 | set theProjectName to name of theProject 11 | 12 | set theTasks to tasks of theProject 13 | set theBodyText to "" 14 | set n to 0 15 | repeat with theTask in theTasks 16 | set n to n + 1 17 | set theTaskText to (name of theTask as rich text) 18 | set theBodyText to theBodyText & theTaskText 19 | if n is not (count of theTasks) then 20 | set theBodyText to theBodyText & return 21 | end if 22 | 23 | end repeat 24 | 25 | set theNotes to notes of theProject 26 | set theNotesText to "" 27 | repeat with theNote in theNotes 28 | set theNoteText to name of theNote 29 | set theNotesText to theNotesText & return & theNoteText 30 | end repeat 31 | 32 | 33 | tell application "Keynote" 34 | activate 35 | tell document 1 36 | if (text 1 through 2) of theProjectName = "![" then 37 | set theFileName to item 2 of my explode(theProjectName, {"(", ")"}) 38 | make image slides paths(theFileName) 39 | set theProjectName to "" 40 | -- above line works in stand-alone script but not here 41 | else 42 | set newSlide to make new slide 43 | if theProjectName is "" then 44 | set the base slide of current slide to master slide "Bullets" 45 | end if 46 | end if 47 | tell newSlide 48 | set object text of default title item to theProjectName 49 | set object text of default body item to theBodyText 50 | set presenter notes to theNotesText 51 | end tell 52 | end tell 53 | end tell 54 | 55 | end repeat 56 | 57 | end tell 58 | 59 | on explode(the_string, separators) 60 | set old_delims to AppleScript's text item delimiters 61 | set AppleScript's text item delimiters to separators 62 | set r to every text item of the_string 63 | set AppleScript's text item delimiters to old_delims 64 | return r 65 | end explode 66 | -------------------------------------------------------------------------------- /k2md.applescript: -------------------------------------------------------------------------------- 1 | (* Convert Keynote Presentation to Markdown without metadata or presenter notes 2 | 3 | by Derick Fay 4 | 5 | 2014-04-02: updated for Keynote 6 6 | 2013-09-20: Keynote '09 version 7 | 8 | usage: 9 | Open a Keynote presentation, then run the script. Markdown will be written to a file with the same name as the original, in a user-selected directory. 10 | 11 | This is a stripped-down version of 'Convert Keynote Presentation to Remark Markdown' designed to produce a Markdown representation of the presentation contents and presenter notes 12 | 13 | limitations: 14 | - doesn't do anything with images since they are not readable with Applescript 15 | *) 16 | 17 | set theFolder to choose folder with prompt "Select output location" 18 | 19 | tell application "Keynote" 20 | set theFileName to name of document 1 21 | set mdResult to "" 22 | set lfs to " 23 | 24 | " 25 | set x to 0 26 | set theShow to slides of document 1 27 | repeat with mySlide in theShow 28 | -- ignore skipped slides 29 | if skipped of mySlide is false then 30 | -- collect the contents of the slides 31 | set theTitle to the object text of the default title item of mySlide 32 | set theBody to the object text of the default body item of mySlide 33 | set eachBullet to paragraphs of theBody 34 | --create the markdown 35 | -- ignore blank text fields 36 | if theTitle is not "Double-click to edit" and theTitle is not "" then 37 | set mdResult to mdResult & "# " & theTitle & lfs 38 | end if 39 | 40 | repeat with i in eachBullet 41 | if i as string is not "Double-click to edit" and (length of i as string > 0) then 42 | set mdResult to mdResult & "* " & i & " 43 | " 44 | end if 45 | end repeat 46 | 47 | if (length of eachBullet > 0) then 48 | set mdResult to mdResult & " 49 | " 50 | end if 51 | 52 | set allNotes to "" 53 | set eachNote to the paragraphs of the presenter notes of mySlide 54 | 55 | repeat with i in eachNote 56 | if (length of i as string > 0) then 57 | set allNotes to allNotes & i & " " 58 | end if 59 | end repeat 60 | 61 | (* comment out the following to hide presenter notes *) 62 | if ((length of allNotes as string) > 0) then 63 | set mdResult to mdResult & "> " & allNotes & lfs 64 | end if 65 | 66 | -- add a new slide unless this is the last slide - i.e. avoid having a blank slide at the end 67 | set x to x + 1 68 | if x < (count of theShow) then 69 | set mdResult to mdResult & "---" & lfs 70 | end if 71 | end if 72 | end repeat 73 | end tell 74 | 75 | set theFile to ((POSIX path of theFolder) as string) & theFileName & ".md" 76 | 77 | do shell script "echo " & quoted form of mdResult & " > " & quoted form of theFile -------------------------------------------------------------------------------- /masters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Title 5 | 6 | 24 | 25 | 26 | 248 | 250 | 253 | 254 | -------------------------------------------------------------------------------- /keynote 5.3 scripts/key2rmd.applescript: -------------------------------------------------------------------------------- 1 | (* Convert Keynote Presentation to Remark Markdown 2 | 3 | by Derick Fay 4 | 2013-10-27 5 | 6 | usage: 7 | Open a Keynote presentation, then run the script. Markdown will be written to a file with the same name as the original, in a user-selected directory. Designed to produce Markdown for use with Remark ( http://gnab.github.io/remark/#1 ) 8 | an alert will display if the presentation has any potentially missing images based on master slides used 9 | 10 | Keynote master slides supported with automatic styling: 11 | Title & Subtitle 12 | Title - Center 13 | Title & Bullets 14 | Bullets 15 | Blank 16 | Photo - Horizontal 17 | Title - Top 18 | Title, Bullets & Photo 19 | Title & Bullets - 2 Column - TODO 20 | Photo - Vertical - TODO 21 | 22 | limitations: 23 | - doesn't do anything with images since they are not readable with Applescript 24 | - ignores transitions 25 | - "Title & Bullets - 2 Column" and "Title, Bullets and Photo" Keynote themes don't style properly 26 | - styles are currently embedded in script and should be moved to external file eventually 27 | - doesn't detect nested lists 28 | - treats every paragraph as a bullet whether it's a bullet in Keynote or not 29 | *) 30 | set theFolder to choose folder with prompt "Select output location" 31 | 32 | tell application "Keynote 5.3" (* Change to "Keynote" if you haven't installed Oct 2013 version of iWork *) 33 | set buildByBullet to true (* uses the trick described here https://github.com/gnab/remark/issues/46 to simulate a build-in by bullet point *) 34 | set lfs to " 35 | 36 | " 37 | set mdResult to "" 38 | set x to 0 39 | set missingImages to 0 -- we will count potentially missing images based on the names of master slides 40 | set theShow to slides of slideshow 1 41 | set theShowTitle to title of slide 1 of slideshow 1 42 | set theFileName to name of slideshow 1 43 | repeat with mySlide in theShow 44 | -- ignore skipped slides 45 | if skipped of mySlide is false then 46 | -- collect the contents of the slides 47 | set theTitle to title of mySlide 48 | set theBody to body of mySlide 49 | set eachBullet to paragraphs of theBody 50 | set theNotes to notes of mySlide 51 | set eachNote to paragraphs of theNotes 52 | set theMaster to master of mySlide 53 | 54 | --create the markdown 55 | --set mdResult to mdResult & "master: " & name of theMaster & lfs 56 | 57 | --add classes for Titles corresponding to Keynote themes 58 | set c to "" 59 | set n to name of theMaster 60 | if (n = "Title & Subtitle") or (n = "Title - Center") then 61 | set c to "class: middle, center" -- based on https://github.com/gnab/remark/wiki/Text-Alignment 62 | else if (n = "Title & Bullets") or (n = "Title - Top") or (n = "Title & Bullets - 2 Column") then 63 | set c to "class: center" 64 | else if n = "Photo - Horizontal" then 65 | set missingImages to missingImages + 1 66 | set c to "class: bottom, center" 67 | else if n = "Title, Bullets & Photo" then 68 | set missingImages to missingImages + 1 69 | set c to "class: center" 70 | else if n = "Photo - Vertical" then 71 | set missingImages to missingImages + 1 72 | set c to "class: center, middle" 73 | end if 74 | 75 | if c is not "" then 76 | set mdResult to mdResult & c & lfs 77 | end if 78 | 79 | -- Photo - Horizontal puts the photo above the Title 80 | if (n = "Photo - Horizontal") then 81 | set mdResult to mdResult & "![Missing image](image.jpg)" & lfs 82 | end if 83 | 84 | -- Photo - Vertical puts title & subtitle in the left column 85 | if (n = "Photo - Vertical") then 86 | set mdResult to mdResult & ".left-column[" & lfs 87 | end if 88 | 89 | -- ignore blank text fields & insert the Title 90 | if theTitle is not "Double-click to edit" then 91 | set mdResult to mdResult & "# " & theTitle & lfs 92 | end if 93 | 94 | if (n = "Title, Bullets & Photo") then 95 | set mdResult to mdResult & ".left-column[" & lfs 96 | end if 97 | 98 | -- add classes for slide bodies corresponding to Keynote themes 99 | set closeSlide to false 100 | if (n = "Title & Bullets - 2 Column") then 101 | set c to ".two-column[" 102 | set mdResult to mdResult & c & lfs 103 | set closeSlide to true 104 | end if 105 | 106 | -- process the body of the slide 107 | set y to 0 108 | set closeIt to false 109 | repeat with i in eachBullet 110 | if i as string is not "Double-click to edit" then 111 | if (n = "Title & Subtitle") or (n = "Photo - Vertical") then 112 | set mdResult to mdResult & "## " & i & lfs 113 | else 114 | -- add classes for bullets corresponding to Keynote themes 115 | set c to "" 116 | set closeIt to false 117 | if (n = "Title & Bullets") or (n = "Title, Bullets & Photo") or (n = "Title & Bullets - 2 Column") then 118 | set c to ".left[" 119 | set closeIt to true 120 | end if 121 | 122 | if c is not "" then 123 | set mdResult to mdResult & c & lfs 124 | end if 125 | 126 | -- add the bullet itself 127 | set mdResult to mdResult & "- " & i & lfs 128 | set y to y + 1 129 | if y < (count of eachBullet) then 130 | if buildByBullet then 131 | if closeIt then 132 | set mdResult to mdResult & "]" & lfs 133 | end if 134 | set closeIt to false 135 | -- include presenter notes on the first slide of a multi-bullet slide so they are there for the full (virtual) slide 136 | if y = 1 then 137 | if eachNote is not {} then 138 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 139 | repeat with i in eachNote 140 | if i is not "" then 141 | set mdResult to mdResult & i & lfs 142 | end if 143 | end repeat 144 | end if 145 | end if 146 | set mdResult to mdResult & "--" & lfs 147 | end if 148 | end if 149 | 150 | 151 | end if 152 | end if 153 | end repeat 154 | 155 | if closeIt then 156 | set mdResult to mdResult & "]" & lfs 157 | end if 158 | if closeSlide then 159 | set mdResult to mdResult & "]" & lfs 160 | end if 161 | if (n = "Photo - Vertical") or (n = "Title, Bullets & Photo") then 162 | set mdResult to mdResult & "]" & lfs & ".right[![Missing image](image.jpg)]" & lfs 163 | end if 164 | 165 | -- include presenter notes if they aren't there already - if no bullets were added, then they weren't added 166 | if y = 0 then 167 | if eachNote is not {} then 168 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 169 | repeat with i in eachNote 170 | if i is not "" then 171 | set mdResult to mdResult & i & lfs 172 | end if 173 | end repeat 174 | end if 175 | end if 176 | 177 | -- add a new slide unless this is the last slide - i.e. avoid having a blank slide at the end 178 | set x to x + 1 179 | if x < (count of theShow) then 180 | set mdResult to mdResult & "---" & lfs 181 | end if 182 | end if 183 | end repeat 184 | end tell 185 | 186 | display alert ((missingImages as string) & " image(s) may be missing") 187 | 188 | set theFile to ((POSIX path of theFolder) as string) & theFileName & ".md" 189 | 190 | do shell script "echo " & quoted form of mdResult & " > " & quoted form of theFile -------------------------------------------------------------------------------- /k2rmd.applescript: -------------------------------------------------------------------------------- 1 | (* Convert Keynote Presentation to Remark Markdown 2 | 3 | by Derick Fay 4 | 5 | 2014-04-02: updated for Keynote 6 - quickly, without comprehensive testing 6 | 2013-09-20: Keynote '09 version 7 | 8 | usage: 9 | Open a Keynote presentation, then run the script. Markdown will be written to a file with the same name as the original, in a user-selected directory. Designed to produce Markdown for use with Remark ( http://gnab.github.io/remark/#1 ) 10 | an alert will display if the presentation has any potentially missing images based on master slides used 11 | 12 | Keynote master slides supported with automatic styling: 13 | Title & Subtitle 14 | Title - Center 15 | Title & Bullets 16 | Bullets 17 | Blank 18 | Photo - Horizontal 19 | Title - Top 20 | Title, Bullets & Photo 21 | Title & Bullets - 2 Column - TODO 22 | Photo - Vertical - TODO 23 | 24 | limitations: 25 | - doesn't do anything with images since they are not readable with Applescript 26 | - ignores transitions 27 | - "Title & Bullets - 2 Column" and "Title, Bullets and Photo" Keynote themes don't style properly 28 | - styles are currently embedded in script and should be moved to external file eventually 29 | - doesn't detect nested lists 30 | - treats every paragraph as a bullet whether it's a bullet in Keynote or not 31 | *) 32 | set theFolder to choose folder with prompt "Select output location" 33 | 34 | tell application "Keynote" (* Change to "Keynote" if you haven't installed Oct 2013 version of iWork *) 35 | set buildByBullet to true (* uses the trick described here https://github.com/gnab/remark/issues/46 to simulate a build-in by bullet point *) 36 | set lfs to " 37 | 38 | " 39 | set mdResult to "" 40 | set x to 0 41 | set missingImages to 0 -- we will count potentially missing images based on the names of master slides 42 | set theShow to slides of document 1 43 | set theShowTitle to object text of the default title item of slide 1 of document 1 44 | set theFileName to name of document 1 45 | repeat with mySlide in theShow 46 | -- ignore skipped slides 47 | if skipped of mySlide is false then 48 | -- collect the contents of the slides 49 | set theTitle to the object text of the default title item of mySlide 50 | set theBody to the object text of the default body item of mySlide 51 | set eachBullet to paragraphs of theBody 52 | set theNotes to the presenter notes of mySlide 53 | set eachNote to paragraphs of theNotes 54 | set theMaster to name of base slide of mySlide 55 | 56 | --create the markdown 57 | --set mdResult to mdResult & "master: " & name of theMaster & lfs 58 | 59 | --add classes for Titles corresponding to Keynote themes 60 | set c to "" 61 | set n to theMaster 62 | if (n = "Title & Subtitle") or (n = "Title - Center") then 63 | set c to "class: middle, center" -- based on https://github.com/gnab/remark/wiki/Text-Alignment 64 | else if (n = "Title & Bullets") or (n = "Title - Top") or (n = "Title & Bullets - 2 Column") then 65 | set c to "class: center" 66 | else if n = "Photo - Horizontal" then 67 | set missingImages to missingImages + 1 68 | set c to "class: bottom, center" 69 | else if n = "Title, Bullets & Photo" then 70 | set missingImages to missingImages + 1 71 | set c to "class: center" 72 | else if n = "Photo - Vertical" then 73 | set missingImages to missingImages + 1 74 | set c to "class: center, middle" 75 | end if 76 | 77 | if c is not "" then 78 | set mdResult to mdResult & c & lfs 79 | end if 80 | 81 | -- Photo - Horizontal puts the photo above the Title 82 | if (n = "Photo - Horizontal") then 83 | set mdResult to mdResult & "![Missing image](image.jpg)" & lfs 84 | end if 85 | 86 | -- Photo - Vertical puts title & subtitle in the left column 87 | if (n = "Photo - Vertical") then 88 | set mdResult to mdResult & ".left-column[" & lfs 89 | end if 90 | 91 | -- ignore blank text fields & insert the Title 92 | if theTitle is not "Double-click to edit" then 93 | set mdResult to mdResult & "# " & theTitle & lfs 94 | end if 95 | 96 | if (n = "Title, Bullets & Photo") then 97 | set mdResult to mdResult & ".left-column[" & lfs 98 | end if 99 | 100 | -- add classes for slide bodies corresponding to Keynote themes 101 | set closeSlide to false 102 | if (n = "Title & Bullets - 2 Column") then 103 | set c to ".two-column[" 104 | set mdResult to mdResult & c & lfs 105 | set closeSlide to true 106 | end if 107 | 108 | -- process the body of the slide 109 | set y to 0 110 | set closeIt to false 111 | repeat with i in eachBullet 112 | if i as string is not "Double-click to edit" then 113 | if (n = "Title & Subtitle") or (n = "Photo - Vertical") then 114 | set mdResult to mdResult & "## " & i & lfs 115 | else 116 | -- add classes for bullets corresponding to Keynote themes 117 | set c to "" 118 | set closeIt to false 119 | if (n = "Title & Bullets") or (n = "Title, Bullets & Photo") or (n = "Title & Bullets - 2 Column") then 120 | set c to ".left[" 121 | set closeIt to true 122 | end if 123 | 124 | if c is not "" then 125 | set mdResult to mdResult & c & lfs 126 | end if 127 | 128 | -- add the bullet itself 129 | set mdResult to mdResult & "- " & i & lfs 130 | set y to y + 1 131 | if y < (count of eachBullet) then 132 | if buildByBullet then 133 | if closeIt then 134 | set mdResult to mdResult & "]" & lfs 135 | end if 136 | set closeIt to false 137 | -- include presenter notes on the first slide of a multi-bullet slide so they are there for the full (virtual) slide 138 | if y = 1 then 139 | if eachNote is not {} then 140 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 141 | repeat with i in eachNote 142 | if i is not "" then 143 | set mdResult to mdResult & i & lfs 144 | end if 145 | end repeat 146 | end if 147 | end if 148 | set mdResult to mdResult & "--" & lfs 149 | end if 150 | end if 151 | 152 | 153 | end if 154 | end if 155 | end repeat 156 | 157 | if closeIt then 158 | set mdResult to mdResult & "]" & lfs 159 | end if 160 | if closeSlide then 161 | set mdResult to mdResult & "]" & lfs 162 | end if 163 | if (n = "Photo - Vertical") or (n = "Title, Bullets & Photo") then 164 | set mdResult to mdResult & "]" & lfs & ".right[![Missing image](image.jpg)]" & lfs 165 | end if 166 | 167 | -- include presenter notes if they aren't there already - if no bullets were added, then they weren't added 168 | if y = 0 then 169 | if eachNote is not {} then 170 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 171 | repeat with i in eachNote 172 | if i is not "" then 173 | set mdResult to mdResult & i & lfs 174 | end if 175 | end repeat 176 | end if 177 | end if 178 | 179 | -- add a new slide unless this is the last slide - i.e. avoid having a blank slide at the end 180 | set x to x + 1 181 | if x < (count of theShow) then 182 | set mdResult to mdResult & "---" & lfs 183 | end if 184 | end if 185 | end repeat 186 | end tell 187 | 188 | display alert ((missingImages as string) & " image(s) may be missing") 189 | 190 | set theFile to ((POSIX path of theFolder) as string) & theFileName & ".md" 191 | 192 | do shell script "echo " & quoted form of mdResult & " > " & quoted form of theFile -------------------------------------------------------------------------------- /k2remark.applescript: -------------------------------------------------------------------------------- 1 | (* Convert Keynote Presentation to Remark HTML 2 | 3 | by Derick Fay 4 | 2014-04-02: updated for Keynote 6 - quickly, without comprehensive testing 5 | 2013-10-27: Keynote '09 version 6 | 7 | usage: 8 | Open a Keynote presentation, then run the script. Remark ( http://gnab.github.io/remark/#1 ) HTML will be written to a file with the same name as the original, in a user-selected directory. 9 | an alert will display if the presentation has any potentially missing images based on master slides used 10 | 11 | Keynote master slides supported with automatic styling: 12 | Title & Subtitle 13 | Title - Center 14 | Title & Bullets 15 | Bullets 16 | Blank 17 | Photo - Horizontal 18 | Title - Top 19 | Title, Bullets & Photo 20 | Title & Bullets - 2 Column - TODO 21 | Photo - Vertical - TODO 22 | 23 | limitations: 24 | - doesn't do anything with images since they are not readable with Applescript 25 | - ignores transitions 26 | - "Title & Bullets - 2 Column" and "Title, Bullets and Photo" Keynote themes don't style properly 27 | - styles are currently embedded in script and should be moved to external file eventually 28 | - doesn't detect nested lists 29 | - treats every paragraph as a bullet whether it's a bullet in Keynote or not 30 | *) 31 | 32 | set theFolder to choose folder with prompt "Select output location" 33 | 34 | tell application "Keynote" (* Change to "Keynote" if you haven't installed Oct 2013 version of iWork *) 35 | set buildByBullet to true (* uses the trick described here https://github.com/gnab/remark/issues/46 to simulate a build-in by bullet point *) 36 | set lfs to " 37 | 38 | " 39 | set mdResult to "" 40 | set x to 0 41 | set missingImages to 0 -- we will count potentially missing images based on the names of master slides 42 | set theShow to slides of document 1 43 | set theShowTitle to object text of the default title item of slide 1 of document 1 44 | set theFileName to name of document 1 45 | repeat with mySlide in theShow 46 | -- ignore skipped slides 47 | if skipped of mySlide is false then 48 | -- collect the contents of the slides 49 | set theTitle to the object text of the default title item of mySlide 50 | set theBody to the object text of the default body item of mySlide 51 | set eachBullet to paragraphs of theBody 52 | set theNotes to the presenter notes of mySlide 53 | set eachNote to paragraphs of theNotes 54 | set theMaster to name of base slide of mySlide 55 | --create the markdown 56 | --set mdResult to mdResult & "master: " & name of theMaster & lfs 57 | 58 | --add classes for Titles corresponding to Keynote themes 59 | set c to "" 60 | set n to theMaster 61 | if (n = "Title & Subtitle") or (n = "Title - Center") then 62 | set c to "class: middle, center" -- based on https://github.com/gnab/remark/wiki/Text-Alignment 63 | else if (n = "Title & Bullets") or (n = "Title - Top") or (n = "Title & Bullets - 2 Column") then 64 | set c to "class: center" 65 | else if n = "Photo - Horizontal" then 66 | set missingImages to missingImages + 1 67 | set c to "class: bottom, center" 68 | else if n = "Title, Bullets & Photo" then 69 | set missingImages to missingImages + 1 70 | set c to "class: center" 71 | else if n = "Photo - Vertical" then 72 | set missingImages to missingImages + 1 73 | set c to "class: center, middle" 74 | end if 75 | 76 | if c is not "" then 77 | set mdResult to mdResult & c & lfs 78 | end if 79 | 80 | -- Photo - Horizontal puts the photo above the Title 81 | if (n = "Photo - Horizontal") then 82 | set mdResult to mdResult & "![Missing image](image.jpg)" & lfs 83 | end if 84 | 85 | -- Photo - Vertical puts title & subtitle in the left column 86 | if (n = "Photo - Vertical") then 87 | set mdResult to mdResult & ".left-column[" & lfs 88 | end if 89 | 90 | -- ignore blank text fields & insert the Title 91 | if theTitle is not "Double-click to edit" then 92 | set mdResult to mdResult & "# " & theTitle & lfs 93 | end if 94 | 95 | if (n = "Title, Bullets & Photo") then 96 | set mdResult to mdResult & ".left-column[" & lfs 97 | end if 98 | 99 | -- add classes for slide bodies corresponding to Keynote themes 100 | set closeSlide to false 101 | if (n = "Title & Bullets - 2 Column") then 102 | set c to ".two-column[" 103 | set mdResult to mdResult & c & lfs 104 | set closeSlide to true 105 | end if 106 | 107 | -- process the body of the slide 108 | set y to 0 109 | set closeIt to false 110 | repeat with i in eachBullet 111 | if i as string is not "Double-click to edit" then 112 | if (n = "Title & Subtitle") or (n = "Photo - Vertical") then 113 | set mdResult to mdResult & "## " & i & lfs 114 | else 115 | -- add classes for bullets corresponding to Keynote themes 116 | set c to "" 117 | set closeIt to false 118 | if (n = "Title & Bullets") or (n = "Title, Bullets & Photo") or (n = "Title & Bullets - 2 Column") then 119 | set c to ".left[" 120 | set closeIt to true 121 | end if 122 | 123 | if c is not "" then 124 | set mdResult to mdResult & c & lfs 125 | end if 126 | 127 | -- add the bullet itself 128 | set mdResult to mdResult & "- " & i & lfs 129 | set y to y + 1 130 | if y < (count of eachBullet) then 131 | if buildByBullet then 132 | if closeIt then 133 | set mdResult to mdResult & "]" & lfs 134 | end if 135 | set closeIt to false 136 | -- include presenter notes on the first slide of a multi-bullet slide so they are there for the full (virtual) slide 137 | if y = 1 then 138 | if eachNote is not {} then 139 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 140 | repeat with i in eachNote 141 | if i is not "" then 142 | set mdResult to mdResult & i & lfs 143 | end if 144 | end repeat 145 | end if 146 | end if 147 | set mdResult to mdResult & "--" & lfs 148 | end if 149 | end if 150 | 151 | 152 | end if 153 | end if 154 | end repeat 155 | 156 | if closeIt then 157 | set mdResult to mdResult & "]" & lfs 158 | end if 159 | if closeSlide then 160 | set mdResult to mdResult & "]" & lfs 161 | end if 162 | if (n = "Photo - Vertical") or (n = "Title, Bullets & Photo") then 163 | set mdResult to mdResult & "]" & lfs & ".right[![Missing image](image.jpg)]" & lfs 164 | end if 165 | 166 | -- include presenter notes if they aren't there already - if no bullets were added, then they weren't added 167 | if y = 0 then 168 | if eachNote is not {} then 169 | set mdResult to mdResult & "???" & lfs --use Remark Markdown format for presenter notes 170 | repeat with i in eachNote 171 | if i is not "" then 172 | set mdResult to mdResult & i & lfs 173 | end if 174 | end repeat 175 | end if 176 | end if 177 | 178 | -- add a new slide unless this is the last slide - i.e. avoid having a blank slide at the end 179 | set x to x + 1 180 | if x < (count of theShow) then 181 | set mdResult to mdResult & "---" & lfs 182 | end if 183 | end if 184 | end repeat 185 | end tell 186 | 187 | 188 | set mdResult to " 189 | 190 | 191 | " & theShowTitle & " 192 | 193 | 211 | 212 | 213 | 215 | 217 | 220 | 221 | " 222 | 223 | display alert ((missingImages as string) & " image(s) may be missing") 224 | 225 | set theFile to ((POSIX path of theFolder) as string) & theFileName & ".html" 226 | 227 | do shell script "echo " & quoted form of mdResult & " > " & quoted form of theFile 228 | 229 | --------------------------------------------------------------------------------