Home Link

Hello, my name is Brett Terpstra, and it’s nice to meet you. Elegant solutions to complex problems. Curious?

eversaverheader

Saving Safari browsing sessions to Evernote

Mar 06, 2010 (148 days ago)

I primarily use Safari for web browsing, mostly because it's smoother and faster than Firefox, and the Web Inspector is just as useful as Firebug. As time passes, I end up with a lot of web pages open, and I like to clear out my browser tabs on a regular basis. Safari doesn't really have a long-term session-saving option, so I save lists of open tabs to various applications. I used to use SafariStand to do this, but it got too buggy and slow for me. I use VoodooPad for it, but I like the sorting and searching option in Evernote, both on my desktop, and synced online and to my iPhone.

As much as I love Evernote, its editor is, well, a hassle. Importing text clippings can strip line breaks and leave you with quite a mess, and cleaning it up is less than pleasant. I've found that using AppleScript, HTML and Evernote together allows me to create pretty well-formatted notes from web and text clippings, aside from using Evernote's PDF features. In most cases—like website clippings—I don't need or want a full PDF, replete with ads and comments (Clippable was designed with that in mind). The trick when creating a note in Evernote via AppleScript is to use a little HTML to get the basic formatting. Evernote's AppleScript library provides a command tailored to this purpose.

To demonstrate, I'll show you how to save your browsing session in Safari as a nicely formatted list in Evernote. For this I set up a new Notebook called "Bookmarks," and am keeping the markup very simple. Evernote strips most styling from imported HTML, but accepts structural items like headlines, lists, tables, etc., applying its own default formatting to the elements.

To begin, open AppleScript Editor (or Script Editor in Leopard) and create a new document. Save it as "EverSurfSaver.scpt" (or your own, better name) in ~/Library/Scripts/Applications/Safari, creating the folders if you need to. This makes the script show up at the top of the list when you're in Safari, and not clutter your script menu in other applications. Speaking of the Script Menu, if yours isn't showing up in your menubar, and you want it to, look in the General tab of AppleScript Editor (Snow Leopard) or open the AppleScript Utility (Leopard). I launch most of my scripts with LaunchBar, but I keep the AS menu around.

In my script, the first thing I did was set up a template for the link formatting, and a search-and-replace function to implement it. It's not terribly advanced, it just gives you %name and %url as placeholders, and you can set up the string however you like. I prefer this method to building long this & that & return & etc. strings in AppleScript (although that still happens pretty often). My template for the links is set up as an unordered list, so it looks like this:


property _template : "<li><a href=\"%url\">%name</a></li>"

This is, fairly obviously, taking a name and a url and creating a hyperlink, wrapped in a list item. Note that any double quotes in the template string need to be escaped with a blackslash. The search-and-replace function is one that I use often, and I can't remember who to attribute for the original code, for which I apologize...


--search and replace function for template
on snr(tofind, toreplace, TheString)
    set atid to text item delimiters
    set text item delimiters to tofind
    set textItems to text items of TheString
    set text item delimiters to toreplace
    if (class of TheString is string) then
        set res to textItems as string
    else -- (assume Unicode)
        set res to textItems as Unicode text
    end if
    set text item delimiters to atid
    return res
end snr

Now we can update our template with shorter calls to the snr function. We'll get around to using the template in a moment.

Next, we want to set up some basic variables to format the title of our note and create our list variable (open an unordered list) so that they're all available outside of other functions and tell statements. I'm using a shell call (do shell script) to create the date strings, just because it's so much faster than formatting a date in AppleScript.


set prettyDate to do shell script "date '+%A, %B %d, %Y at %l:%M %p'"
set theTitle to "Bookmarks " & prettyDate
set urlList to "<ul>"

The command date '+%A, %B %d, %Y at %l:%M %p' will create a date string that looks like Saturday, March 06, 2010 at  9:04 AM. Note the extra space before the "9:04." That's because it's a single-digit hour and gets padded where the zero would be with other formatting. You can remove this with a little *NIX string handling, but I'm just going to live with it for the purposes of this post.

Next, we gather all of the tabs open in the front window of Safari. It's entirely possible to cycle through all open windows and get all tabs, but I always surf in "one window" mode, so I'll leave it up to you to look that one up if you need it. We'll be appending the information from each tab to the urlList variable we set up at the beginning.


tell application "Safari"
    set tabList to every tab of front window
    repeat with aTab in tabList
        set aLink to _template
        set aLink to my snr("%name", name of aTab, aLink)
        set aLink to my snr("%url", URL of aTab, aLink)
        set urlList to urlList & aLink & return
    end repeat
end tell
set urlList to urlList & "</ul>"

The block ends by appending the closing tag to our urlList. So we have a simple HTML fragment containing an unordered list of all of our links, the titles hyperlinked to their associated url. All that's left to do now is create our Evernote note from this fragment:


tell application "Evernote"
    set theNote to create note with html urlList title theTitle notebook "Bookmarks"
end tell

That's it. Now there's a note in Evernote, in a notebook called "Bookmarks," titled something like "Bookmarks Saturday, March 06, 2010 at 9:04 AM." Here's the code in its entirety:


property _template : "<li><a href=\"%url\">%name</a></li>"

--search and replace function for template
on snr(tofind, toreplace, TheString)
    set ditd to text item delimiters
    set text item delimiters to tofind
    set textItems to text items of TheString
    set text item delimiters to toreplace
    if (class of TheString is string) then
        set res to textItems as string
    else -- if (class of TheString is Unicode text) then
        set res to textItems as Unicode text
    end if
    set text item delimiters to ditd
    return res
end snr

set prettyDate to do shell script "date '+%A, %B %d, %Y at %l:%M %p'"
set theTitle to "Bookmarks " & prettyDate
set urlList to "<ul>"

tell application "Safari"
    set tabList to every tab of front window
    repeat with aTab in tabList
        set aLink to _template
        set aLink to my snr("%name", name of aTab, aLink)
        set aLink to my snr("%url", URL of aTab, aLink)
        set urlList to urlList & aLink & return
    end repeat
end tell
set urlList to urlList & "</ul>"

tell application "Evernote"
    set theNote to create note with html urlList title theTitle notebook "Bookmarks"
end tell

Click here to open this script in your default script editor.

Addendum

One of the great things about using Evernote for this purpose is that you can add todo checkboxes next to important or "read later" links for reference. If there's a theme to the batch of links (I just saved the results of a long search for decent WordPress e-commerce plugins), you can also add meaningful tags to the note itself. Further, you can add any notes and keywords you want next to or below the link in an indented list item (you never have to deal with markup again after the import, at that point it's just a rich text list).

Because this script only deals with the frontmost window, you can also drag off a specific group of tabs to a new window, and only bookmark those in the Evernote note. With a little "show dialog" or CocoaDialog action, you could easily have the script request tags or notes in the process and append them to the note. If I ever implement that, I'll post it, but I like the simplicity and immediacy it has right now.

Also, I forgot to look and see who else was doing something similar (I'm in my own little world a lot). Justin over at Veritrope has a similar script (minus the HTML), amongst a large collection of really useful scripts and services. You should check that out, too!

16 Responses to “Saving Safari browsing sessions to Evernote”

  1. Justin says:

    Both your script and your walk-through are real gifts to your fellow AppleScripters.…. much obliged to you for both (and for the “shout out”)!

    Not to be self-deprecating, but I think your script is an improvement upon my own… and here’s why: As great as Evernote is, one of the seemingly universal complaints about it is how it handles simple text formatting. Based upon some stuff I read on their forum, my guess is that the situation won’t really improve until Evernote finishes revamping the DTD used in creating notes.

    So, the fact that you are using some Script-fu to “pretty up” the data into HTML is actually an important difference — certainly more than a cosmetic one. I think it really opens the door to making more readable notes right now… and also shines a light on a way that people will want to script for Evernote going forward!

    Solutions like yours take the guess-work out of how Evernote will format your data. This is the direction I’ve been moving in with my own scripts (stay tuned for some fun revisions on that front).

    All of which is to say — I am very glad you didn’t see mine first! ;)

    Nice work, Brett!

  2. […] second link is a link to a great detailed post showing you how to save Safari Browsing Sessions to Evernote. This post shows you how with the help of a little AppleScript you can get all your active Safari […]

  3. Mike R says:

    Just for the record, this script runs so quickly and silently that at first I didn’t think it was working — also I forgot that it targets the ‘Bookmarks’ notebook. Nice work Brett!

    If you’re using the WebKit nightlies, you can change the application title in the script to “WebKit” — however it still goes in the Safari scripts folder.

  4. Keizo says:

    It is really nice script. I think it is better has a Growl feature that tell me about get bookmarks to Evernote.

    • Brett says:

      Hey Keizo!

      You can add that pretty easily if you have growlhelper installed. I can’t remember if that’s part of the default install of Growl or not. I’ll post code for that later, if you want to test it out.

      • Keizo says:

        I believe I have install Growlhelper though I don’t know where is it. Anyway I really want to try the code please.

        • Brett says:

          My mistake, the program is growlnotify, and it’s in the main Growl download, just in case you don’t have it. It requires a separate install by running the install​.sh script from Terminal. In an AppleScript, you can call it like this:

          do shell script "/usr/local/bin/growlnotify -m 'Bookmarks saved to Evernote' -t 'EverSave' -i 'Evernote'"

          and insert that line wherever you want to send a notification, editing the Saved to Evernote part to fit the message you want to send. I’ll eventually rework the script to include this, but it’s necessary to check that growlnotify is installed before calling it or it will throw errors. For now, I’ll leave it up to the user to check if they have the utility installed and add the line(s) manually.

        • Brett says:

          You should be able to triple-click the code line in the reply above and select it all, even though it’s not fully visible.

          • Keizo says:

            Thanks Brett.

            It looked like hard for me. Actuary I confused little bit, however I finally did it. The script displayed Growl notification like “Bookmark saved to Evernote”.

  5. I know this is more of a Mac OS X support request, but when I go to save the script into the Library / Scripts / Applications / Safari folder, it says I don’t have permission. Viewing the Safari folder using Get Info shows that “system” has Read & Write access, and “everyone” has Read only. Since I’m not system, it doesn’t appear that I can change this. Any thoughts on how to proceed?

    • Brett says:

      Are you saving to the Library/Scripts… in your user folder, or in the root? You should be in /Users/[yourusername]/Library/Scripts/Applications/Safari. Let me know if that does the trick or not!

      • I’m trying to save in my user folder; that full path doesn’t exist under the drive root’s Library.

        • Brett says:

          But it does exist in your User folder, right? That’s really odd. It should be owned by youruser/staff, and you should be able to trash and replace it if needed. If there’s nothing else in that folder (or if you’ve backed up the contents), go to Terminal, cd to the Scripts/Applications folder and run sudo rm -rf Safari, entering your user password when prompted (assuming your user has admin privileges). Then you should be able to make a new Safari folder with proper permissions … ?

          • Thanks! The problem went all the way up to the Scripts directory, but luckily there was nothing important in there, so I blew them all away and recreated them.

            I’m like the worst commenter ever.… Now I’m having trouble getting the AppleScript menu to show up in the menu bar of Safari. The box is checked to show it in AppleScript Editor’s General tab in Preferences (Show Script menu in menu bar), but it’s just not showing up in Safari.

          • Brett says:

            This threading kind of sucks… I may have to find a better system for comments :).

            Once you check the box in AppleScript Editor, it should always show up, not just in certain applications. The Script menu item over on the right of the menubar should have Application-specific scripts for the current app at the top.

            You could always get FastScripts, too :).

  6. […] 関連の AppleScript を発見した。Saving Safari browsing sessions to Evernote ? Brett Terpstra というのがその AppleScript。Brett さんは MoodBlast の作者で、現在 TUAW […]

Leave a Reply

Comments may use standard Markdown formatting

Entries (RSS) and Comments (RSS).