Evernote Export to HTML AppleScript

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

DOWNLOAD THE SCRIPT FILE

Did this script help you out? Feel free to make a donation!


Interested in what other scripts are available for Evernote?

Click here to see the latest list!

8 Responses to “Evernote Export to HTML AppleScript”

  1. Marc April 21, 2012 at 7:08 am #

    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

    • Justin Lancy April 21, 2012 at 8:17 am #

      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:
      Save Attachments

      • Marc April 22, 2012 at 6:09 pm #

        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.

        • Justin Lancy April 23, 2012 at 1:52 pm #

          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!:

          1. I’m not seeing the “random naming” here — Evernote asks me to choose an export folder. Once I do, it exports all the items as HTML files named after the title of the note. If that note has attachments, it also creates a “resources folder” which is also named after the note’s title.
          2. The export process also creates a file called “index.html”, which is a page with links to each item.

          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?

          • Marc May 1, 2012 at 3:10 pm #

            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,

          • Justin Lancy May 1, 2012 at 3:53 pm #

            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…

            1. Even though the Mac version of Evernote doesn’t have “Watched Folders”, I made my own workflow using Mac’s “Folder Actions” to try and duplicate this function. You can scan your files into your own folder structure and then copy the folder into this Watched Folder to import to Evernote;
            2. You can use Evernote’s export function to periodically archive your items as I described in my earlier response.

            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!

          • Marc May 2, 2012 at 3:47 pm #

            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