Here you go. (Two caveats: I'm not good in AppleScript - Claude helped..., and the output is OK but not perfect). Here's the AppleScript:
-- Keynote to Markdown Exporter
-- Version: Text + Deduplizierung + einfache Markdown-Bullets + LLM-bewusste visuelle Hinweise
tell application "Keynote Creator Studio"
if not (exists front document) then
display dialog "Bitte zuerst eine Keynote-Präsentation öffnen." buttons {"OK"}
return
end if
set theDocument to front document
set docName to name of theDocument
set slideCount to count of slides of theDocument
set md to "# " & docName & linefeed & linefeed
repeat with i from 1 to slideCount
set theSlide to slide i of theDocument
set md to md & "---" & linefeed & linefeed
set md to md & "## Folie " & i & linefeed & linefeed
try
set textItems to text items of theSlide
set seenTexts to {}
repeat with t in textItems
try
set rawText to object text of t as text
set cleanText to my trimText(rawText)
if cleanText is not "" then
if seenTexts does not contain cleanText then
set end of seenTexts to cleanText
set md to md & my formatTextBlockAsMarkdown(cleanText) & linefeed & linefeed
end if
end if
end try
end repeat
on error errMsg
set md to md & "_Text konnte nicht gelesen werden: " & errMsg & "_" & linefeed & linefeed
end try
set visualSummary to my getVisualSummary(theSlide)
if visualSummary is not "" then
set md to md & "### Visuelle Elemente" & linefeed & linefeed
set md to md & visualSummary & linefeed
end if
try
set notesText to presenter notes of theSlide as text
set notesText to my trimText(notesText)
if notesText is not "" then
set md to md & "### Presenter Notes" & linefeed & linefeed
set md to md & notesText & linefeed & linefeed
end if
end try
end repeat
end tell
set fileName to my cleanFileName(docName) & ".md"
set outPath to ((path to desktop folder as text) & fileName)
set fileRef to open for access file outPath with write permission
set eof of fileRef to 0
write md to fileRef as «class utf8»
close access fileRef
display dialog "Markdown exportiert nach:" & linefeed & outPath buttons {"OK"}
on getVisualSummary(theSlide)
set summaryText to ""
set imageCount to my safeCount("images", theSlide)
set shapeCount to my safeCount("shapes", theSlide)
set tableCount to my safeCount("tables", theSlide)
set chartCount to my safeCount("charts", theSlide)
set groupCount to my safeCount("groups", theSlide)
set movieCount to my safeCount("movies", theSlide)
if imageCount is not "0" then
set summaryText to summaryText & "- " & imageCount & " Bild/Grafik(en) vorhanden; visueller Inhalt nicht im Markdown enthalten." & linefeed
end if
if tableCount is not "0" then
set summaryText to summaryText & "- " & tableCount & " Tabelle(n) vorhanden; Tabelleninhalt nicht exportiert." & linefeed
end if
if chartCount is not "0" then
set summaryText to summaryText & "- " & chartCount & " Diagramm(e) vorhanden; visuelle Daten nicht exportiert." & linefeed
end if
if movieCount is not "0" then
set summaryText to summaryText & "- " & movieCount & " Video(s) vorhanden; Medieninhalt nicht exportiert." & linefeed
end if
if shapeCount is not "0" then
set summaryText to summaryText & "- " & shapeCount & " Form(en) vorhanden; visueller Inhalt möglicherweise nicht vollständig im Markdown enthalten." & linefeed
end if
if groupCount is not "0" then
set summaryText to summaryText & "- " & groupCount & " gruppierte Objekt(e) vorhanden; visueller Inhalt möglicherweise nicht vollständig im Markdown enthalten." & linefeed
end if
return summaryText
end getVisualSummary
on safeCount(objectType, theSlide)
try
tell application "Keynote Creator Studio"
if objectType is "images" then
return (count of images of theSlide) as text
else if objectType is "shapes" then
return (count of shapes of theSlide) as text
else if objectType is "tables" then
return (count of tables of theSlide) as text
else if objectType is "charts" then
return (count of charts of theSlide) as text
else if objectType is "groups" then
return (count of groups of theSlide) as text
else if objectType is "movies" then
return (count of movies of theSlide) as text
else
return "0"
end if
end tell
on error
return "0"
end try
end safeCount
on formatTextBlockAsMarkdown(theText)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to linefeed
set theLines to text items of theText
set AppleScript's text item delimiters to oldDelims
set formattedText to ""
set lineCount to count of theLines
repeat with i from 1 to lineCount
set thisLine to item i of theLines
set thisLine to my trimSpaces(thisLine)
if thisLine is "" then
set formattedText to formattedText & linefeed
else if i is 1 then
set formattedText to formattedText & thisLine & linefeed
else
set formattedText to formattedText & "- " & thisLine & linefeed
end if
end repeat
return my trimText(formattedText)
end formatTextBlockAsMarkdown
on cleanFileName(theName)
set badChars to {":", "/", "\", "*", "?", """, "<", ">", "|"}
set cleanName to theName
repeat with c in badChars
set AppleScript's text item delimiters to c
set parts to text items of cleanName
set AppleScript's text item delimiters to "-"
set cleanName to parts as text
end repeat
set AppleScript's text item delimiters to ""
return cleanName
end cleanFileName
on trimText(theText)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to {return}
set parts to text items of theText
set AppleScript's text item delimiters to linefeed
set cleaned to parts as text
set AppleScript's text item delimiters to oldDelims
repeat while cleaned starts with linefeed
set cleaned to text 2 thru -1 of cleaned
end repeat
repeat while cleaned ends with linefeed
set cleaned to text 1 thru -2 of cleaned
end repeat
return cleaned
end trimText
on trimSpaces(theText)
set cleaned to theText
repeat while cleaned starts with " "
set cleaned to text 2 thru -1 of cleaned
end repeat
repeat while cleaned ends with " "
set cleaned to text 1 thru -2 of cleaned
end repeat
return cleaned
end trimSpaces
I'd be curious to see your AppleScript. I've never dug into the Keynote file format, just assumed it was like Pages and too proprietary to be worthwhile.
I have considered adding presentation capabilities to Marked, something along the lines of Deckset, but I've not pursued it yet.