Skip to content

Instantly share code, notes, and snippets.

@kzaremski
Last active August 8, 2023 08:56
Show Gist options
  • Save kzaremski/830f2bbe5a6a97829b49901833af2f51 to your computer and use it in GitHub Desktop.
Save kzaremski/830f2bbe5a6a97829b49901833af2f51 to your computer and use it in GitHub Desktop.
Apple Notes Exporter Script (AppleScript)
--
-- ** AppleNotesExporter **
-- -- Easily export Apple notes to standard encoding HTML preserving directory structure
--
-- Copyright 2022 Konstantin Zaremski
--
-- 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.
--
-- Replace text
on replaceText(this_text, search_string, replacement_string)
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
return this_text
end replaceText
tell application "Notes"
activate
-- Build list of account human readable names
set theAccountNames to {}
repeat with theAccount in accounts
copy name of theAccount as string to end of theAccountNames
end repeat
-- Select the desired account from the list of human readable names
set chosenAccountName to choose from list theAccountNames with prompt "Select the Apple Notes account to export from:"
-- Quit if cancel
if chosenAccountName is false then
return
end if
-- Set the desired account object to the account that has that human readable name
repeat with theAccount in accounts
-- display dialog ("\"" & name of theAccount as string) & "\" \"" & chosenAccountName & "\""
-- Dont even ask me why the above line was here >:(
if name of theAccount as string = chosenAccountName as string then
set chosenAccount to theAccount
end if
end repeat
-- Get output folder
set outputFolder to (choose folder with prompt "Choose an output location. Note: Note folder organization structure will be preserved. It is best to use an empty directory." as string)
-- Quit if cancel
if outputFolder is false then
return
end if
-- For every note in the account
repeat with theNote in notes of chosenAccount
set noteLocked to password protected of theNote as boolean
set modDate to modification date of theNote as date
set creDate to creation date of theNote as date
set noteID to id of theNote as string
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to "/"
set theArray to every text item of noteID
set AppleScript's text item delimiters to oldDelimiters
if length of theArray > 4 then
set noteID to item 5 of theArray
else
set noteID to ""
end if
if not noteLocked then
set theText to body of theNote as string
set currentContainer to container of theNote
set internalPath to name of currentContainer
-- Path
repeat until name of currentContainer as string = name of default account as string
set currentContainer to container of currentContainer
if name of currentContainer as string ≠ name of default account then
set internalPath to (name of currentContainer & "/" & internalPath)
end if
end repeat
-- Create dir
do shell script "mkdir -p '" & (POSIX path of outputFolder as string) & internalPath & "'"
-- Filename
set fileName to ("[" & my replaceText(noteID as string, "p", "") & "] " & (name of theNote as string)) as string
if length of fileName > 250 then
set fileName to text 1 thru 250 of fileName
end if
global outputFolder
-- Sanitize filename
set fileNameClean to my replaceText(fileName, ":", "-")
set fileNameClean to my replaceText(fileNameClean, "/", "-")
set fileNameClean to my replaceText(fileNameClean, "$", "")
set fileNameClean to my replaceText(fileNameClean, "\"", "-")
set fileNameClean to my replaceText(fileNameClean, "\\", "-")
set filepath to ((POSIX path of outputFolder as string) & internalPath as string) & "/" & fileNameClean & ".html"
set theFile to open for access filepath with write permission
set eof of the theFile to 0
write theText to theFile starting at eof as «class utf8»
close access theFile
-- Convert to UTF-8 proper
-- do shell script "sync; iconv --from-code UTF-8 --to-code=UTF-8 \"" & filepath & "\" > \"" & filepath & "UTF8\"; sync; mv \"" & filepath & "UTF8\" \"" & filepath & "\""
end if
end repeat
-- Display within the Notes application so we are not jumping around
display dialog "Done!
Thanks for using AppleNotesExporter.
https://www.github.com/kzaremski" buttons {"Nice 🔥"} default button "Nice 🔥"
end tell
-- I really don't like AppleScript :(
@kzaremski
Copy link
Author

August 7, 2022: Added the ability to select the note account instead of using the default

@a-toms
Copy link

a-toms commented Mar 18, 2023

Works well for me. Thanks @kzaremski !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment