Change Log:
- 1.00 (MAY 12, 2009) INITIAL RELEASE OF SCRIPT
Okay AppleScripters — here’s the code… Dive in, check it out, and please tell me what you think in the comment thread below!
(*
http://veritrope.com
Evernote HTML Exporter
Version 1.0
May 12, 2009
Project Status, Latest Updates, and Comments Collected at:
http://veritrope.com/tips/evernote-HTML-export
EXTRA SPECIAL THANKS TO PAUL AT ENTROPYTHEBLOG.COM
FOR HIS HELP IN TROUBLESHOOTING THE WEBARCHIVER!
Installation: Just double-click on the script!
FastScripts Installation (Optional, but recommended):
--Download and Install FastScripts from http://www.red-sweater.com/fastscripts/index.html
--Copy script or an Alias to ~/Library/Scripts/Applications/Evernote
--Set up your keyboard shortcut
CHANGELOG:
1.00 INITIAL RELEASE
*)
property CleanTitle : ""
property theNum : "0"
(* CHECK FOR GROWL *)
tell application "System Events"
set processnames to name of every process
end tell
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp"
set the allNotificationsList to {"Success Notification", "Failure Notification"}
set the enabledNotificationsList to {"Success Notification", "Failure Notification"}
register as application ¬
"Evernote to HTML" all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application "Evernote"
end tell
end if
(*MAIN PROGRAM *)
set myPath to (path to home folder)
set EVPath to ("" & myPath & "Library:Application Support:Evernote:data:40145:content:p") as string
tell application "Evernote"
activate
try
(* EVERNOTE NOTEBOOK SELECTION SUBROUTINE *)
set listOfNotebooks to {}
set EVNotebooks to every notebook --GET THE NOTEBOOK LIST
repeat with currentNotebook in EVNotebooks
set currentNotebookName to (the name of currentNotebook)
copy currentNotebookName to the end of listOfNotebooks
end repeat
(*SORT THE FOLDER LIST *)
set Folders_sorted to my simple_sort(listOfNotebooks)
(*USER SELECTION FROM NOTEBOOK LIST *)
set SelNotebook to choose from list of Folders_sorted with title "Select Evernote Notebook" with prompt ¬
"Current Evernote Notebooks" OK button name "OK"
set EVnotebook to item 1 of SelNotebook
set listofNotes to {} (*PREPARE TO GET EVERNOTE'S LIST OF NOTES *)
set allNotes to every note in notebook EVnotebook
repeat with currentNote in allNotes
set currentNoteName to (the title of currentNote)
copy currentNoteName to the end of listofNotes
end repeat
(*SORT THE NOTEBOOK LIST *)
set Notes_sorted to my simple_sort(listofNotes)
(*PICK THE NOTES FROM THE LIST *)
set SelNotes to ¬
choose from list of Notes_sorted with title ¬
"List of Notes" OK button name "Export Notes" cancel button name "Close Window" with multiple selections allowed
-- NOTE: ALL UNTITLED NOTES SHOW UP AS SINGLE "UNTITLED" ENTRY
if (SelNotes is not false) then
(*PICK EXPORT DESTINATION*)
set SaveLoc to choose folder with prompt "Choose The Destination Folder or Volume:" default location (path to desktop folder)
(*DO THE CONVERSION*)
my ENEXExport(EVnotebook, SelNotes, SaveLoc, EVPath)
if "GrowlHelperApp" is in processnames then -- GROWL SUCCESS
tell application "GrowlHelperApp"
notify with name ¬
"Success Notification" title ¬
"Successful Export to HTML!" description ¬
"Number of Notes Exported: " & theNum application name "Evernote to HTML"
end tell
end if
else
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp" -- GROWL FAILURE FOR NO SELECTION
notify with name ¬
"Failure Notification" title ¬
"Export Failure" description ¬
"No notes selected!" application name "Evernote to HTML"
end tell
else if "GrowlHelperApp" is not in processnames then -- NON-GROWL ERROR MSG. FOR NO SELECTION
display dialog "No headline or tab selected!" with icon 0
end if
end if
(* ERROR HANDLING *)
on error errText number errNum
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp" -- GROWL FAILURE FOR ERROR
notify with name ¬
"Failure Notification" title ¬
"Import Failure" description "Export Failed due to the following error: " & errText & return & return & "Note Name: " & CleanTitle ¬
application name "Evernote to HTML"
end tell
else if "GrowlHelperApp" is not in processnames then -- NON-GROWL ERROR MSG. FOR ERROR
display dialog "Item Failed to Import: " & errNum & return & errText with icon 0
end if
end try
end tell
(* SUBROUTINES *)
on ENEXExport(EVnotebook, SelNotes, SaveLoc, EVPath)
(*FIND FOLDER FOR NOTE*)
tell application "Evernote"
set theNum to 0
repeat with SelNote in SelNotes
set noteToExport to (find notes "notebook:"" & EVnotebook & "" intitle:"" & SelNote & """)
set NoteID to (local id of item 1 of noteToExport)
set FolderLoc to my extractBetween(NoteID, "/p", """)
(*PREPARE HTML FOLDER *)
tell application "Finder"
activate
set GetFolder to (EVPath & FolderLoc & ":") as alias
set SingQuote to "-e s/'//g"
set CleanTitle to do shell script ("echo " & quoted form of SelNote & " | sed -e 's/:/ /g' -e 's/"//g' -e 's/—/ /g' " & (quoted form of SingQuote)) --CLEAN OUT COLONS FOR FILE PATH (SOUNDS GROSSER THAN IT IS)
set ExportFolder to ¬
(make new folder at SaveLoc with properties {name:CleanTitle})
set notreco to (every item in GetFolder whose ¬
kind is not "Document")
(*COPY CONTENTS TO HTML EXPORT FOLDER *)
duplicate notreco to ExportFolder
set WebArchive to POSIX path of ((path to me as Unicode text) & "Contents:Resources:webarchiver")
set ArchiveInput to POSIX path of ((ExportFolder as Unicode text) & "content.html")
set ArchiveOutput to POSIX path of ((SaveLoc as Unicode text) & CleanTitle & ".webarchive")
set Exec to "'" & WebArchive & "' -url '" & ArchiveInput & "' -output '" & ArchiveOutput & "'"
do shell script Exec
end tell
set theNum to theNum + 1
end repeat
end tell
end ENEXExport
--REPLACE SUBROUTINE
on replaceString(theString, theOriginalString, theNewString)
set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, theOriginalString}
set theStringParts to text items of theString
if (count of theStringParts) is greater than 1 then
set theString to text item 1 of theStringParts as string
repeat with eachPart in items 2 thru -1 of theStringParts
set theString to theString & theNewString & eachPart as string
end repeat
end if
set AppleScript's text item delimiters to od
return theString
end replaceString
--SORT SUBROUTINE
on simple_sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end simple_sort
--EXTRACT SUBROUTINE
on extractBetween(SearchText, startText, endText)
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to startText
set endItems to text of text item -1 of SearchText
set AppleScript's text item delimiters to endText
set beginningToEnd to text of text item 1 of endItems
set AppleScript's text item delimiters to tid
return beginningToEnd
end extractBetween
http://veritrope.com
Evernote HTML Exporter
Version 1.0
May 12, 2009
Project Status, Latest Updates, and Comments Collected at:
http://veritrope.com/tips/evernote-HTML-export
EXTRA SPECIAL THANKS TO PAUL AT ENTROPYTHEBLOG.COM
FOR HIS HELP IN TROUBLESHOOTING THE WEBARCHIVER!
Installation: Just double-click on the script!
FastScripts Installation (Optional, but recommended):
--Download and Install FastScripts from http://www.red-sweater.com/fastscripts/index.html
--Copy script or an Alias to ~/Library/Scripts/Applications/Evernote
--Set up your keyboard shortcut
CHANGELOG:
1.00 INITIAL RELEASE
*)
property CleanTitle : ""
property theNum : "0"
(* CHECK FOR GROWL *)
tell application "System Events"
set processnames to name of every process
end tell
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp"
set the allNotificationsList to {"Success Notification", "Failure Notification"}
set the enabledNotificationsList to {"Success Notification", "Failure Notification"}
register as application ¬
"Evernote to HTML" all notifications allNotificationsList ¬
default notifications enabledNotificationsList ¬
icon of application "Evernote"
end tell
end if
(*MAIN PROGRAM *)
set myPath to (path to home folder)
set EVPath to ("" & myPath & "Library:Application Support:Evernote:data:40145:content:p") as string
tell application "Evernote"
activate
try
(* EVERNOTE NOTEBOOK SELECTION SUBROUTINE *)
set listOfNotebooks to {}
set EVNotebooks to every notebook --GET THE NOTEBOOK LIST
repeat with currentNotebook in EVNotebooks
set currentNotebookName to (the name of currentNotebook)
copy currentNotebookName to the end of listOfNotebooks
end repeat
(*SORT THE FOLDER LIST *)
set Folders_sorted to my simple_sort(listOfNotebooks)
(*USER SELECTION FROM NOTEBOOK LIST *)
set SelNotebook to choose from list of Folders_sorted with title "Select Evernote Notebook" with prompt ¬
"Current Evernote Notebooks" OK button name "OK"
set EVnotebook to item 1 of SelNotebook
set listofNotes to {} (*PREPARE TO GET EVERNOTE'S LIST OF NOTES *)
set allNotes to every note in notebook EVnotebook
repeat with currentNote in allNotes
set currentNoteName to (the title of currentNote)
copy currentNoteName to the end of listofNotes
end repeat
(*SORT THE NOTEBOOK LIST *)
set Notes_sorted to my simple_sort(listofNotes)
(*PICK THE NOTES FROM THE LIST *)
set SelNotes to ¬
choose from list of Notes_sorted with title ¬
"List of Notes" OK button name "Export Notes" cancel button name "Close Window" with multiple selections allowed
-- NOTE: ALL UNTITLED NOTES SHOW UP AS SINGLE "UNTITLED" ENTRY
if (SelNotes is not false) then
(*PICK EXPORT DESTINATION*)
set SaveLoc to choose folder with prompt "Choose The Destination Folder or Volume:" default location (path to desktop folder)
(*DO THE CONVERSION*)
my ENEXExport(EVnotebook, SelNotes, SaveLoc, EVPath)
if "GrowlHelperApp" is in processnames then -- GROWL SUCCESS
tell application "GrowlHelperApp"
notify with name ¬
"Success Notification" title ¬
"Successful Export to HTML!" description ¬
"Number of Notes Exported: " & theNum application name "Evernote to HTML"
end tell
end if
else
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp" -- GROWL FAILURE FOR NO SELECTION
notify with name ¬
"Failure Notification" title ¬
"Export Failure" description ¬
"No notes selected!" application name "Evernote to HTML"
end tell
else if "GrowlHelperApp" is not in processnames then -- NON-GROWL ERROR MSG. FOR NO SELECTION
display dialog "No headline or tab selected!" with icon 0
end if
end if
(* ERROR HANDLING *)
on error errText number errNum
if "GrowlHelperApp" is in processnames then
tell application "GrowlHelperApp" -- GROWL FAILURE FOR ERROR
notify with name ¬
"Failure Notification" title ¬
"Import Failure" description "Export Failed due to the following error: " & errText & return & return & "Note Name: " & CleanTitle ¬
application name "Evernote to HTML"
end tell
else if "GrowlHelperApp" is not in processnames then -- NON-GROWL ERROR MSG. FOR ERROR
display dialog "Item Failed to Import: " & errNum & return & errText with icon 0
end if
end try
end tell
(* SUBROUTINES *)
on ENEXExport(EVnotebook, SelNotes, SaveLoc, EVPath)
(*FIND FOLDER FOR NOTE*)
tell application "Evernote"
set theNum to 0
repeat with SelNote in SelNotes
set noteToExport to (find notes "notebook:"" & EVnotebook & "" intitle:"" & SelNote & """)
set NoteID to (local id of item 1 of noteToExport)
set FolderLoc to my extractBetween(NoteID, "/p", """)
(*PREPARE HTML FOLDER *)
tell application "Finder"
activate
set GetFolder to (EVPath & FolderLoc & ":") as alias
set SingQuote to "-e s/'//g"
set CleanTitle to do shell script ("echo " & quoted form of SelNote & " | sed -e 's/:/ /g' -e 's/"//g' -e 's/—/ /g' " & (quoted form of SingQuote)) --CLEAN OUT COLONS FOR FILE PATH (SOUNDS GROSSER THAN IT IS)
set ExportFolder to ¬
(make new folder at SaveLoc with properties {name:CleanTitle})
set notreco to (every item in GetFolder whose ¬
kind is not "Document")
(*COPY CONTENTS TO HTML EXPORT FOLDER *)
duplicate notreco to ExportFolder
set WebArchive to POSIX path of ((path to me as Unicode text) & "Contents:Resources:webarchiver")
set ArchiveInput to POSIX path of ((ExportFolder as Unicode text) & "content.html")
set ArchiveOutput to POSIX path of ((SaveLoc as Unicode text) & CleanTitle & ".webarchive")
set Exec to "'" & WebArchive & "' -url '" & ArchiveInput & "' -output '" & ArchiveOutput & "'"
do shell script Exec
end tell
set theNum to theNum + 1
end repeat
end tell
end ENEXExport
--REPLACE SUBROUTINE
on replaceString(theString, theOriginalString, theNewString)
set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, theOriginalString}
set theStringParts to text items of theString
if (count of theStringParts) is greater than 1 then
set theString to text item 1 of theStringParts as string
repeat with eachPart in items 2 thru -1 of theStringParts
set theString to theString & theNewString & eachPart as string
end repeat
end if
set AppleScript's text item delimiters to od
return theString
end replaceString
--SORT SUBROUTINE
on simple_sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end simple_sort
--EXTRACT SUBROUTINE
on extractBetween(SearchText, startText, endText)
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to startText
set endItems to text of text item -1 of SearchText
set AppleScript's text item delimiters to endText
set beginningToEnd to text of text item 1 of endItems
set AppleScript's text item delimiters to tid
return beginningToEnd
end extractBetween
Hello there,
Following your suggestion, I leave a comment requesting your help. Do you think your script could be modified so that what I requested in the user forum could be performed?
http://discussion.evernote.com/topic/22349-extracting-attachments-from-my-notes/page__fromsearch__1
I was pointed to this resource, and even though it is very cool, it is not exactly what I was looking for (It is close though)
Thanks
Marc,
Evernote recently added the ability to save multiple attachments without the need for an AppleScript!
Highlight the items you want the attachments for and you should see an option to save those attachments directly:
Euuum, I don’t see that option… I’m using the App Store version of Evernote, can this be the reason?
Even if I ever manage to get that feature working, that won’t solve completely my problem because it needs some manual interaction…
Let me explain. This is what I’m looking for: I want to find a way to periodically export all my notes and attachments and store every note with its attachments in a different folder named after the name of the note. This is pretty much what the Evernote App does, but it uses some sort of random name convention for privacy reasons I imagine…
If anything is unclear, just let me know. Not being a native speaker represents quite of a challenge when trying to get to the point.
Hi Marc,
First off — my apologies! You’re correct in saying that the “Save Attachments” feature isn’t in the App Store version of Evernote yet. (I usually try to double-check my advice against both versions, but I was answering you from the road and have the Beta version on my MacBook!)
Now that I’m back in NYC, I’m in front of the App Store version… so let’s dig in!:
To write a script which archives every single item in Evernote into different folders becomes more complicated: Evernote has to export everything into a main export folder first and then the script would have to sort files into individual folders. You’d also have to decide how to handle notes with the same name (i.e., “Untitled”) and, depending on if you wanted to mirror the structure inside your Evernote collection, whether or not to further sub-divide the folders into notebook folders.
If enough people ask for it, I may try to write something like this. (Of course, you can also commission it for the community if you don’t feel like waiting!)
One more thing — I want everyone to feel welcome here and to share and to benefit from our community, and so I am working on making Veritrope.com friendlier to readers who aren’t native English speakers. If you (or anyone else reading this) wouldn’t mind sharing some thoughts on this project, could you please let me know via the Contact Form or by sending me a message on Twitter?
Hi there,
I’m afraid that not being a native speaker isn’t helping me much for I don’t think I made myself clear.
Just do this. Browse: /Users/[user]/Library/Application Support/Evernote/data and you will see the randomly named file structure that I’m referring to.
I just wish I could find a script that I could periodically run in order to generate a organized folder structure with my order and not theirs. I want the folders to use note names. Why? because I’m paranoid about not being able to access my notes unless I don’t use the Evernote client…
Lets say that even since I migrated to Mac -folder watch is not available for the Mac world to my bitter surprise- I have broken my workflow, which previously relied on scanning files locally and have the Evernote client import them. That allowed me to keep my order in my scanned files.
Now, since watched folders isn’t an option, I upload the files to Evernote directly (when they don’t contain important information) and therefore I’m pretty dependent on their will.
I hope this time I managed to describe my problem.
Thanks,
I think I understand now, Marc — and I appreciate you making the effort to communicate in English. (T’ho agraeixo molt!):
You are looking at Evernote’s own local directory, which is not really intended for direct access by users. (This is why you are seeing a file structure which is not friendly to us humans!)
I can think of two suggestions…
Please let me know if this works for you — and if you’re interested in helping to translate some of these tools and instructions for your fellow Mac users!
Hello again,
My jaw almost reached the floor when I saw those words in Catalan language!! (M’has deixat bocabadat!!)
Today something I read some weeks ago dawned on me. I read about this app called Hazel (http://www.noodlesoft.com/hazel.php) which is intended to monitor your hard drive for a certain pattern, and once something matches one of your rules, it automagically performs a custom action.
I could have it monitor my Evernote folder and then grab only my pdf files and drop them into a particular folder… eeeuuummm, I have to think about this.
Regarding your script for overcoming Evernote Mac lack of Watched Folders, I actually stumbled upon this article looking up information about Evernote Watched Folders in the Evernote forum 🙂 The script is pretty cool, but I struggle a lot when trying to bend my own workflow to match what your script enables… If I recall it correctly, your script uploads all what it comes across to Evernote (local notebooks can’t be accessed, can they?).
Regarding translating the tools, why not? I imagine you can access my email address… drop me a line or two! 🙂
Thanks a lot for your prompt answers