<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Brett Terpstra</title>
	
	<link>http://brettterpstra.com</link>
	<description>Elegant solutions to complex problems.</description>
	<lastBuildDate>Tue, 09 Mar 2010 04:54:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BrettTerpstra" /><feedburner:info uri="brettterpstra" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Save Safari tabs to Instapaper</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/gQSADl93_UU/</link>
		<comments>http://brettterpstra.com/2010/03/08/save-safari-tabs-to-instapaper/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 04:34:26 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[instapaper]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=322</guid>
		<description><![CDATA[I posted a way to save your Safari tabs to Evernote, which I've found is generally a great way to save bookmarks. It syncs automatically to your other computers and your iPhone, and it's fast and easy. If you really want to highlight a few tabs to make sure you get back to them, you might consider this script, though.&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/" rel="bookmark">Saving Safari browsing sessions to Evernote</a><!-- (23.644)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (9.49059)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (5.96023)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://brettterpstra.com/wp-content/uploads/2010/03/instapapericon.png" alt="InstaPaper icon" title="instapapericon" width="200" height="200" class="alignright size-full wp-image-323" />I posted a way to <a href="http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/">save your Safari tabs to Evernote</a>, which I’ve found is generally a great way to save bookmarks. It syncs automatically to your other computers and your iPhone, and it’s fast and easy. If you really want to highlight a few tabs to make sure you get back to them, you might consider this script, though. Once you’ve saved your entire Safari browsing session for later, close everything except for those special urls, run the code below as a script, and your open tabs will be saved as entries in your <a href="http://www.instapaper.com/">InstaPaper</a> account.</p>

<p>There are two “property” lines at the top of the script; edit them to set your Instapaper username and password (if you have one, otherwise, set it to <code>""</code>). The next section handles everything, iterating through each tab, grabbing its title and url and building a shell command to do a simple curl call to the <a href="http://blog.instapaper.com/post/73123968/read-later-api">InstaPaper API</a>.</p>

<p>After that, the rest of the script is a routine for <a href="http://en.wikipedia.org/wiki/Percent-encoding">url encoding</a> that I <a href="http://harvey.nu/applescript_url_encode_routine.html">nicked here</a>. It’s called when setting both the <code>_title</code> and <code>_url</code> variables to make the <a href="http://curl.haxx.se/">curl</a> call from the shell work. I haven’t tested this extensively yet, but it’s worked for everything I’ve tried. A title with odd characters in it could potentially cause problems. You can always add a shell-escaping routine…</p>

<div markdown=0>
<pre><code>
property _user : &quot;yourusername&quot;
property _pass : &quot;yourpassword&quot;

tell application &quot;Safari&quot;
    repeat with _tab in tabs of front window
        set _title to my urlencode(name of _tab)
        set _url to my urlencode(URL of _tab)
        set _script to (&not;
            &quot;curl &#x27;https://www.instapaper.com/api/add?username=&quot;&not;
            &amp; _user &amp; &quot;&amp;password=&quot; &amp; _pass &amp; &quot;&amp;url=&quot; &amp; _url &amp; &quot;&amp;title=&quot; &amp; _title &amp; &quot;&#x27;&quot;)
        set output to do shell script _script
    end repeat
end tell

on urlencode(theText)
    set theTextEnc to &quot;&quot;
    repeat with eachChar in characters of theText
        set useChar to eachChar
        set eachCharNum to ASCII number of eachChar
        if eachCharNum = 32 then
            set useChar to &quot;+&quot;
        else if (eachCharNum &ne; 42) and (eachCharNum &ne; 95) and&not;
            (eachCharNum &lt; 45 or eachCharNum &gt; 46) and (eachCharNum &lt; 48 or eachCharNum &gt; 57)&not;
            and (eachCharNum &lt; 65 or eachCharNum &gt; 90) and (eachCharNum &lt; 97 or eachCharNum &gt; 122) then
            set firstDig to round (eachCharNum / 16) rounding down
            set secondDig to eachCharNum mod 16
            if firstDig &gt; 9 then
                set aNum to firstDig + 55
                set firstDig to ASCII character aNum
            end if
            if secondDig &gt; 9 then
                set aNum to secondDig + 55
                set secondDig to ASCII character aNum
            end if
            set numHex to (&quot;%&quot; &amp; (firstDig as string) &amp; (secondDig as string)) as string
            set useChar to numHex
        end if
        set theTextEnc to theTextEnc &amp; useChar as string
    end repeat
    return theTextEnc
end urlencode
</code></pre>
</div>

<p><a href="applescript://com.apple.scripteditor?action=new&amp;script=property%20_user%20:%20%22yourusername%22%0Aproperty%20_pass%20:%20%22yourpassword%22%0A%0Atell%20application%20%22Safari%22%0A%09repeat%20with%20_tab%20in%20tabs%20of%20front%20window%0A%09%09set%20_title%20to%20my%20urlencode(name%20of%20_tab)%0A%09%09set%20_url%20to%20my%20urlencode(URL%20of%20_tab)%0A%09%09set%20_script%20to%20(%C2%AC%0A%09%09%09%22curl%20'https://www.instapaper.com/api/add?username=%22%C2%AC%0A%09%09%09&amp;%20_user%20&amp;%20%22&amp;password=%22%20&amp;%20_pass%20&amp;%20%22&amp;url=%22%20&amp;%20_url%20&amp;%20%22&amp;title=%22%20&amp;%20_title%20&amp;%20%22'%22)%0A%09%09set%20output%20to%20do%20shell%20script%20_script%0A%09end%20repeat%0Aend%20tell%0A%0Aon%20urlencode(theText)%0A%09set%20theTextEnc%20to%20%22%22%0A%09repeat%20with%20eachChar%20in%20characters%20of%20theText%0A%09%09set%20useChar%20to%20eachChar%0A%09%09set%20eachCharNum%20to%20ASCII%20number%20of%20eachChar%0A%09%09if%20eachCharNum%20=%2032%20then%0A%09%09%09set%20useChar%20to%20%22+%22%0A%09%09else%20if%20(eachCharNum%20%E2%89%A0%2042)%20and%20(eachCharNum%20%E2%89%A0%2095)%20and%C2%AC%0A%09%09%09(eachCharNum%20%3C%2045%20or%20eachCharNum%20%3E%2046)%20and%20(eachCharNum%20%3C%2048%20or%20eachCharNum%20%3E%2057)%C2%AC%0A%09%09%09and%20(eachCharNum%20%3C%2065%20or%20eachCharNum%20%3E%2090)%20and%20(eachCharNum%20%3C%2097%20or%20eachCharNum%20%3E%20122)%20then%0A%09%09%09set%20firstDig%20to%20round%20(eachCharNum%20/%2016)%20rounding%20down%0A%09%09%09set%20secondDig%20to%20eachCharNum%20mod%2016%0A%09%09%09if%20firstDig%20%3E%209%20then%0A%09%09%09%09set%20aNum%20to%20firstDig%20+%2055%0A%09%09%09%09set%20firstDig%20to%20ASCII%20character%20aNum%0A%09%09%09end%20if%0A%09%09%09if%20secondDig%20%3E%209%20then%0A%09%09%09%09set%20aNum%20to%20secondDig%20+%2055%0A%09%09%09%09set%20secondDig%20to%20ASCII%20character%20aNum%0A%09%09%09end%20if%0A%09%09%09set%20numHex%20to%20(%22%25%22%20&amp;%20(firstDig%20as%20string)%20&amp;%20(secondDig%20as%20string))%20as%20string%0A%09%09%09set%20useChar%20to%20numHex%0A%09%09end%20if%0A%09%09set%20theTextEnc%20to%20theTextEnc%20&amp;%20useChar%20as%20string%0A%09end%20repeat%0A%09return%20theTextEnc%0Aend%20urlencode%0A">Open this script in your Script Editor.</a></p>


<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/" rel="bookmark">Saving Safari browsing sessions to Evernote</a><!-- (23.644)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (9.49059)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (5.96023)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/gQSADl93_UU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/03/08/save-safari-tabs-to-instapaper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/03/08/save-safari-tabs-to-instapaper/</feedburner:origLink></item>
		<item>
		<title>A better System Service for Evernote clipping — with MultiMarkdown</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/DEJmZTpquSs/</link>
		<comments>http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 00:02:09 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[evernote]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[multimarkdown]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=302</guid>
		<description><![CDATA[Another post, quickly and with less explanation...

The fact that Evernote processes HTML so much better than it does plain or rich text got me thinking and tinkering. I use Markdown (actually, MultiMarkdown) constantly, and it does a great job of turning plain text into valid markup. With (Multi)Markdown, even plain text becomes HTML that--when imported into Evernote--retains most of its&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/" rel="bookmark">Saving Safari browsing sessions to Evernote</a><!-- (18.6)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (18.3934)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (16.0564)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>Another post, quickly and with less explanation…</p>

<p><img src="http://brettterpstra.com/wp-content/uploads/2010/03/EvernoteIcon-300x300.png" alt="Evernote Icon" title="EvernoteIcon" width="300" height="300" class="alignright size-medium wp-image-305" />The fact that Evernote processes HTML so much better than it does plain or rich text got me thinking and tinkering. I use <a href="http://daringfireball.net/projects/markdown/">Markdown</a> (actually, <a href="http://fletcherpenney.net/multimarkdown/">MultiMarkdown</a>) constantly, and it does a great job of turning plain text into valid markup. With (Multi)Markdown, even plain text becomes HTML that–when imported into Evernote–retains most of its formatting. To answer your question, no, I’m not obsessed with Evernote, I’m obsessed with problems I think I could solve. It’s unhealthy.</p>

<p><strong><em>Please note</em></strong>, this requires that you have <a href="http://fletcherpenney.net/">Fletcher Penney’s</a> MultiMarkdown installed in <code>~/Library/Application Support/MultiMarkdown</code>, and that the Perl files (MultiMarkdown.pl and SmartyPants.pl) are located in a ‘bin’ subdirectory (which is the default install). If you don’t have MultiMarkdown, you should get it anyway (all the cool kids have it), so head over to the <a href="http://fletcher.github.com/MultiMarkdown/">download page</a> and grab a copy. Now, on with the show.</p>

<p>I set this up originally as a <a href="http://macromates.com/">TextMate</a> command, intending just to be able to clip code snippets and free-form text to Evernote without thinking too much about it. That worked well, so I modified it to work as a System Service. Specifically, a Snow Leopard service, but I’m providing the Ruby script here and it can be modified for any Mac setup you want.</p>

<p>While it will work just fine on plain text with no markup, it does have a couple of “special” features. If you start a line with a <code>#</code> and a space (e.g.: # This is my header), which is a <a href="http://daringfireball.net/projects/markdown/syntax#header">Markdown convention</a> for a first-level heading, it will use that as the title for the note and strip it out of the text in processing. It only uses the first one it finds, but it will strip out any first-level headers in the selection. I’ll probably modify that later, or just have it leave them in. Also, a line that begins with “tags:” followed by a space and a comma-separated list of words will be split up and used to tag the new note. This is also stripped before processing. It handles spaces in multi-word tags, and odd marks at the beginning or end of a tag, <em>but only one punctuation character, and only at the beginning or end of a tag</em>. The code follows…</p>

<p><span id="more-302"></span></p>

<p>Here’s the Ruby code, messy as it may be:</p>

<div markdown=0>
<pre><code>
    #!/usr/bin/env ruby -rjcode -Ku
    # requires that MultiMarkdown be installed in ~/Library/Application Support/MultiMarkdown
    # That, or edit the script to point to yours :)

    ARGF.each do |f|
    input = f
    contents = &#x27;&#x27;
    tags = &#x27;&#x27;
    title = nil

    def e_as(str)
        str.to_s.gsub(/(?=[&quot;\\])/, &#x27;\\&#x27;)
    end
    input.each_line { |line| 
      if line =~ /^# (.*?)/
        title = line[2..-1]
        break
      end
    }
    title = %x{date &#x27;+Clipped note: %A, %B %d, %Y at %l:%M %p&#x27;|tr -s &quot; &quot;} if title.nil?

    input.each_line { |line| 
      if line =~ /^[Tt]ags: /
        tags = line[5..-1].split(&#x27;,&#x27;).map {|tag| tag = tag.strip.gsub(/^(.)?\b|\b(.)?$/,&quot;\\2\&quot;\\1&quot;) }
        break
      end
    }

    IO.popen(&#x27;&quot;$HOME/Library/Application Support/MultiMarkdown/bin/MultiMarkdown.pl&quot;|&quot;$HOME/Library/Application Support/MultiMarkdown/bin/SmartyPants.pl&quot;&#x27;, &quot;r+&quot;) do |io|
     input.each_line { |line| 
        io &lt;&lt; line unless line =~ /^# |[Tt]ags\: /
     }; io.close_write
     io.each_line do |line|
       contents &lt;&lt; line
     end
    end
    tags = &quot; tags {#{tags.join(&quot;,&quot;)}}&quot; unless tags.empty?
    %x{osascript -e &#x27;tell application &quot;Evernote&quot; to create note with html &quot;#{e_as contents}&quot; title &quot;#{title}&quot; notebook &quot;Unfiled&quot;#{tags}&#x27;}
    end
</code></pre>
</div>

<p>You can create a System Service in Automator with it, set up a command in TextMate, or do whatever else you can think of. If you just want to download the service and try it out, I’ve made it <a href="http://brettterpstra.com/downloads/MarkdownToEvernote.zip">available here</a>. Unzip and copy it to ~/Library/Services (in your home folder). If you set it up as a System Service, assign a shortcut key in the Keyboard pane of System Preferences.</p>

<p>It does choke once in a while, apparently on Markdown-generated code snippets, but I haven’t quite narrowed down why, yet. I’ll update the code if I figure that one out. Overall, though, it makes pretty clippings and allows you to use some Markdown syntax to spice up your text without having to touch the (regrettably abominable) Evernote editor.</p>

<hr />

<p id="downloadlink"><strong>Download</strong></p>
<p class="download_desc"><a href="http://brettterpstra.com/downloads/MarkdownToEvernote.zip" title="Download Markdown To Evernote Service (13)"><img src="http://brettterpstra.com/wp-content/uploads/downloads/thumbnails/2010/03/thumbnail.gif" alt="download image for Markdown To Evernote Service" /></a><a href="http://brettterpstra.com/downloads/MarkdownToEvernote.zip" title="Download Markdown To Evernote Service (13)">Markdown To Evernote Service (87.29 KB)</a> — A Snow Leopard System Service that grabs selected text, processes it with MultiMarkdown and clips the resulting HTML to Evernote, creating a nicely formatted note. Uses the first (and hopefully only) Markdown first-level heading (# My headline) as the title for the note, and will look for a line starting with “tags: ” followed by a comma-separated list of tags as well.

Requires that MultiMarkdown be installed in ~/Library/Application Support/MultiMarkdown. <a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/">More Info</a></p>


<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/" rel="bookmark">Saving Safari browsing sessions to Evernote</a><!-- (18.6)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (18.3934)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (16.0564)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/DEJmZTpquSs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/</feedburner:origLink></item>
		<item>
		<title>fk: redux</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/IsohcqVlpuU/</link>
		<comments>http://brettterpstra.com/2010/03/06/fk-redux/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 17:49:15 +0000</pubDate>
		<dc:creator>btadmin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/2010/03/06/fk-redux/</guid>
		<description><![CDATA[Just a quick change to my post on the bash function fk that I’ve been using. A small modification has greatly improved its usability: make the cancel option always be first in the menu. Just move “Cancel” before the $(fp $1) bit. It’s a little odd that I didn’t do that to begin with…



fp () { #find and list processes&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (69.3447)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (10.5367)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (5.44664)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>Just a quick change to <a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/">my post on the bash function <code>fk</code></a> that I’ve been using. A small modification has greatly improved its usability: make the cancel option always be first in the menu. Just move “Cancel” before the <code>$(fp $1)</code> bit. It’s a little odd that I didn’t do that to begin with…</p>

<div markdown=0>
<pre><code>
fp () { #find and list processes matching a case-insensitive partial-match string
        ps Ao pid,comm|awk &#x27;{match($0,/[^\/]+$/); print substr($0,RSTART,RLENGTH)&quot;: &quot;$1}&#x27;|grep -i $1|grep -v grep
}

fk () { 
    IFS=$&#x27;\n&#x27;
    PS3=&#x27;Kill which process? (1 to cancel): &#x27;
    select OPT in &quot;Cancel&quot; $(fp $1); do
        if [ $OPT != &quot;Cancel&quot; ]; then
            kill $(echo $OPT|awk &#x27;{print $NF}&#x27;)
        fi
        break
    done
    unset IFS
}
</code></pre>
</div>


<ul>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (69.3447)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (10.5367)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (5.44664)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/IsohcqVlpuU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/03/06/fk-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/03/06/fk-redux/</feedburner:origLink></item>
		<item>
		<title>Saving Safari browsing sessions to Evernote</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/Le2k6G5l1Qg/</link>
		<comments>http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 15:45:30 +0000</pubDate>
		<dc:creator>btadmin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[evernote]]></category>
		<category><![CDATA[safari]]></category>
		<category><![CDATA[websurfing]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=290</guid>
		<description><![CDATA[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&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/03/08/save-safari-tabs-to-instapaper/" rel="bookmark">Save Safari tabs to Instapaper</a><!-- (23.5186)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (19.5644)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (12.3559)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://brettterpstra.com/wp-content/uploads/2010/03/EvernoteBookmarksScreenshot-1.jpg" rel="lightbox"><img src="http://brettterpstra.com/wp-content/uploads/2010/03/EvernoteBookmarksScreenshot-1-300x157.jpg" alt="" title="Evernote Bookmarks" width="300" height="157" class="alignright size-medium wp-image-291" /></a>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 <a href="http://hetima.com/safari/stand-e.html">SafariStand</a> to do this, but it got too buggy and slow for me. I use <a href="http://flyingmeat.com/voodoopad/">VoodooPad</a> for it, but I like the sorting and searching option in <a href="http://www.evernote.com/">Evernote</a>, both on my desktop, and synced online and to my iPhone.</p>

<p>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 (<a href="http://brettterpstra.com/tag/clippable/">Clippable</a> 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.</p>

<p>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.</p>

<p><span id="more-290"></span>
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 <code>~/Library/Scripts/Applications/Safari</code>, 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 <a href="http://obdev.at/products/launchbar/index.html">LaunchBar</a>, but I keep the AS menu around.</p>

<p>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 <code>this &amp; that &amp; return &amp; etc.</code> 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:</p>

<div markdown=0>
<pre><code>
property _template : &quot;&lt;li&gt;&lt;a href=\&quot;%url\&quot;&gt;%name&lt;/a&gt;&lt;/li&gt;&quot;
</code></pre>
</div>

<p>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…</p>

<div markdown=0>
<pre><code>
--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
</code></pre>
</div>

<p>Now we can update our template with shorter calls to the <code>snr</code> function. We’ll get around to using the template in a moment.</p>

<p>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 (<code>do shell script</code>) to create the date strings, just because it’s <strong><em>so</em></strong> much faster than formatting a date in AppleScript.</p>

<div markdown=0>
<pre><code>
set prettyDate to do shell script &quot;date &#x27;+%A, %B %d, %Y at %l:%M %p&#x27;&quot;
set theTitle to &quot;Bookmarks &quot; &amp; prettyDate
set urlList to &quot;&lt;ul&gt;&quot;
</code></pre>
</div>

<p>The command <code>date '+%A, %B %d, %Y at %l:%M %p'</code> will create a date string that looks like <strong>Saturday, March 06, 2010 at  9:04 AM</strong>. 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.</p>

<p>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.</p>

<div markdown=0>
<pre><code>
tell application &quot;Safari&quot;
    set tabList to every tab of front window
    repeat with aTab in tabList
        set aLink to _template
        set aLink to my snr(&quot;%name&quot;, name of aTab, aLink)
        set aLink to my snr(&quot;%url&quot;, URL of aTab, aLink)
        set urlList to urlList &amp; aLink &amp; return
    end repeat
end tell
set urlList to urlList &amp; &quot;&lt;/ul&gt;&quot;
</code></pre>
</div>

<p>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:</p>

<div markdown=0>
<pre><code>
tell application "Evernote"
    set theNote to create note with html urlList title theTitle notebook "Bookmarks"
end tell
</code></pre>
</div>

<p>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:</p>

<div markdown=0>
<pre><code>
property _template : &quot;&lt;li&gt;&lt;a href=\&quot;%url\&quot;&gt;%name&lt;/a&gt;&lt;/li&gt;&quot;

--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 &quot;date &#x27;+%A, %B %d, %Y at %l:%M %p&#x27;&quot;
set theTitle to &quot;Bookmarks &quot; &amp; prettyDate
set urlList to &quot;&lt;ul&gt;&quot;

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

tell application &quot;Evernote&quot;
    set theNote to create note with html urlList title theTitle notebook &quot;Bookmarks&quot;
end tell
</code></pre>
</div>

<p><a href="applescript://com.apple.scripteditor?action=new&#038;script=property%20_template%20:%20%22%3Cli%3E%3Ca%20href=%5C%22%25url%5C%22%3E%25name%3C/a%3E%3C/li%3E%22%0A%0A--search%20and%20replace%20function%20for%20template%0Aon%20snr(tofind,%20toreplace,%20TheString)%0A%09set%20ditd%20to%20text%20item%20delimiters%0A%09set%20text%20item%20delimiters%20to%20tofind%0A%09set%20textItems%20to%20text%20items%20of%20TheString%0A%09set%20text%20item%20delimiters%20to%20toreplace%0A%09if%20(class%20of%20TheString%20is%20string)%20then%0A%09%09set%20res%20to%20textItems%20as%20string%0A%09else%20--%20if%20(class%20of%20TheString%20is%20Unicode%20text)%20then%0A%09%09set%20res%20to%20textItems%20as%20Unicode%20text%0A%09end%20if%0A%09set%20text%20item%20delimiters%20to%20ditd%0A%09return%20res%0Aend%20snr%0A%0Aset%20prettyDate%20to%20do%20shell%20script%20%22date%20'+%25A,%20%25B%20%25d,%20%25Y%20at%20%25l:%25M%20%25p'%22%0Aset%20theTitle%20to%20%22Bookmarks%20%22%20&#038;%20prettyDate%0Aset%20urlList%20to%20%22%3Cul%3E%22%0A%0Atell%20application%20%22Safari%22%0A%09set%20tabList%20to%20every%20tab%20of%20front%20window%0A%09repeat%20with%20aTab%20in%20tabList%0A%09%09set%20aLink%20to%20_template%0A%09%09set%20aLink%20to%20my%20snr(%22%25name%22,%20name%20of%20aTab,%20aLink)%0A%09%09set%20aLink%20to%20my%20snr(%22%25url%22,%20URL%20of%20aTab,%20aLink)%0A%09%09set%20urlList%20to%20urlList%20&#038;%20aLink%20&#038;%20return%0A%09end%20repeat%0Aend%20tell%0Aset%20urlList%20to%20urlList%20&#038;%20%22%3C/ul%3E%22%0A%0Atell%20application%20%22Evernote%22%0A%09set%20theNote%20to%20create%20note%20with%20html%20urlList%20title%20theTitle%20notebook%20%22Bookmarks%22%0Aend%20tell">Click here</a> to open this script in your default script editor.</p>

<h3>Addendum</h3>

<p>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).</p>

<p>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.</p>

<p>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 <a href="http://veritrope.com/">Veritrope</a> has a <a href="http://veritrope.com/tips/safari-tabs-to-evernote">similar script</a> (minus the HTML), amongst a large collection of really useful scripts and services. You should check that out, too!</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/03/08/save-safari-tabs-to-instapaper/" rel="bookmark">Save Safari tabs to Instapaper</a><!-- (23.5186)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (19.5644)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (12.3559)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/Le2k6G5l1Qg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/03/06/saving-safari-browsing-sessions-to-evernote/</feedburner:origLink></item>
		<item>
		<title>Clippable updated, goes mobile</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/w2OJZfdQbCY/</link>
		<comments>http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 16:01:12 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[clippable]]></category>
		<category><![CDATA[clippable mobile]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[readability]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=284</guid>
		<description><![CDATA[I've pushed out an update to Clippable, for better or worse. In addition to the previously added line number removal for code blocks, it removes spans used in TextMate formatted code and adds some keyboard shortcuts:


Left arrow: switch to light on dark
Right arrow: switch to black on white
Delete key: return to normal formatting
Escape key: return to original page


These features are&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/" rel="bookmark">Clippable updated to remove source code line numbers</a><!-- (30.4548)--></li>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (20.9366)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable/" rel="bookmark">Clippable</a><!-- (17.8007)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>I’ve pushed out an update to <a href="http://brettterpstra.com/share/readability2.html">Clippable</a>, for better or worse. In addition to the <a href="http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/">previously added</a> line number removal for code blocks, it removes spans used in TextMate formatted code and adds some keyboard shortcuts:</p>

<ul>
<li>Left arrow: switch to light on dark</li>
<li>Right arrow: switch to black on white</li>
<li>Delete key: return to normal formatting</li>
<li>Escape key: return to original page</li>
</ul>

<p>These features are added without modifying the original bookmarklet, so if you’ve got it installed, you’ve got the goodies already. Otherwise, head over to the <a href="http://brettterpstra.com/share/readability2.html">Clippable bookmarklet page</a> and try it out.</p>

<p><a href="http://brettterpstra.com/code/clippable-mobile/"><img src="http://brettterpstra.com/wp-content/uploads/2010/02/clippablemobile-iphoneshot.jpg" alt="Image of Clippable Mobile on the iPhone" title="clippablemobile-iphoneshot" width="300" height="476" class="alignright size-full wp-image-278" /></a>The big news, though, is the introduction of <a href="http://brettterpstra.com/code/clippable-mobile/">Clippable Mobile</a>. It’s a work in progress, but installs on an iPhone and makes use of the special formatting options available in Mobile Safari. It shrinks images, cuts off code blocks, etc., making every attempt to provide a readable page that doesn’t scroll horizontally. There are occasions where it fails on first attempt, but running it again right away fixes everything. I’m still working on figuring out why that happens… a little sleep will probably help. Head over to the <a href="http://brettterpstra.com/code/clippable-mobile/">Clippable Mobile page</a> on your iPhone and follow the instructions to install it. Bug reports are welcome!</p>


<ul>
		<li><a href="http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/" rel="bookmark">Clippable updated to remove source code line numbers</a><!-- (30.4548)--></li>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (20.9366)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable/" rel="bookmark">Clippable</a><!-- (17.8007)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/w2OJZfdQbCY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/</feedburner:origLink></item>
		<item>
		<title>Emma, watching The Westminster Dog Show…</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/7jdfiCCZA6c/</link>
		<comments>http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 02:10:56 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/</guid>
		<description><![CDATA[

Uploaded by www.cellspin.net



		A CellSpin Test
		A (fairly) simple equation evaluation service for Snow Leopard
	


<ul>
		<li><a href="http://brettterpstra.com/2010/02/18/a-cellspin-test/" rel="bookmark">A CellSpin Test</a><!-- (12.3735)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (6.24046)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cellspin.net/user/c765a56250/post/98876/"><img src="http://posts.cellspin.net/posts/52126/2010/02/18/full_607c7d5c2172ad0b14c9abb3b0b88a9e.png" title="Emma, watching The Westminster Dog Show…"/></a></p>

<p>Uploaded by <a href="http://www.cellspin.net">www.cellspin.net</a></p>


<ul>
		<li><a href="http://brettterpstra.com/2010/02/18/a-cellspin-test/" rel="bookmark">A CellSpin Test</a><!-- (12.3735)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (6.24046)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/7jdfiCCZA6c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/</feedburner:origLink></item>
		<item>
		<title>A CellSpin Test</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/wsHUcKdSPiQ/</link>
		<comments>http://brettterpstra.com/2010/02/18/a-cellspin-test/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 21:08:27 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/2010/02/18/a-cellspin-test/</guid>
		<description><![CDATA[This is a quick test of CellSpin, just to see if it does what I think it will.



		Emma, watching The Westminster Dog Show…
		Test post from iphone
	


<ul>
		<li><a href="http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/" rel="bookmark">Emma, watching The Westminster Dog Show…</a><!-- (18.3964)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/test-post-from-iphone/" rel="bookmark">Test post from iphone</a><!-- (9.6885)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>This is a quick test of CellSpin, just to see if it does what I think it will.</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/02/18/emma-watching-the-westminster-dog-show%e2%80%a6/" rel="bookmark">Emma, watching The Westminster Dog Show…</a><!-- (18.3964)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/test-post-from-iphone/" rel="bookmark">Test post from iphone</a><!-- (9.6885)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/wsHUcKdSPiQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/02/18/a-cellspin-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/02/18/a-cellspin-test/</feedburner:origLink></item>
		<item>
		<title>Downtime apology and upcoming projects</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/y63FD1rhoUY/</link>
		<comments>http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:55:59 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Write]]></category>
		<category><![CDATA[clippable]]></category>
		<category><![CDATA[downtime]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[songza]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=221</guid>
		<description><![CDATA[I apologize for the recent downtime, which also affected the Clippable bookmarklet's ability to work. Dreamhost has been pretty awful with downtime lately, and my attempt to switch to a different physical server resulted in a horrible mess for myself and several clients. I have to say that Dreamhost support was extremely helpful in repairing the situation... their support is&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (19.8231)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (11.3452)--></li>
		<li><a href="http://brettterpstra.com/2009/11/02/readability2-leaks-out/" rel="bookmark">Readability2 leaks out</a><!-- (9.70862)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>I apologize for the recent downtime, which also affected the <a href="http://brettterpstra.com/share/readability2.html" title="Clippable bookmarklet page">Clippable</a> bookmarklet’s ability to work. Dreamhost has been pretty awful with downtime lately, and my attempt to switch to a different physical server resulted in a horrible mess for myself and several clients. I have to say that Dreamhost support was extremely helpful in repairing the situation… their support is the main reason I’ve stuck with them through the 4 hours of downtime I’d had up to that point. I’m not sure I’ll be able to swallow much more, but we’ll see if things run as smoothly as they’ve promised from here on out.</p>

<p>In other news, I have a new version of the <a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/">Songza service</a>–one that doesn’t require any additional libraries–which I’ll post soon. A couple of other little projects are in the works, including a service that interprets natural language dates for various purposes. I’m <a href="http://brettterpstra.com/2010/01/29/big-nerd-ranchero/">in Atlanta</a> for a week, then I’ll be in San Francisco covering Macworld for TUAW, so it may be a bit, but I’ll be back!</p>


<ul>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (19.8231)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (11.3452)--></li>
		<li><a href="http://brettterpstra.com/2009/11/02/readability2-leaks-out/" rel="bookmark">Readability2 leaks out</a><!-- (9.70862)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/y63FD1rhoUY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/</feedburner:origLink></item>
		<item>
		<title>Big Nerd Ranchero</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/sM1fwdRKYrE/</link>
		<comments>http://brettterpstra.com/2010/01/29/big-nerd-ranchero/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:42:43 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Write]]></category>
		<category><![CDATA[bignerdranch]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[travel]]></category>
		<category><![CDATA[tuaw]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=219</guid>
		<description><![CDATA[

I'm sitting at the airport in Minneapolis, waiting for a flight to Atlanta. I'm headed for Big Nerd Ranch for a week-long crash course in iPhone programming. I've done a little, but I think it will be a great way to start from the basics and fill in all of the holes in my knowledge. The thing is, I'm a&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (16.0819)--></li>
		<li><a href="http://brettterpstra.com/2009/12/12/where-ive-been-this-week/" rel="bookmark">Where I’ve been this week</a><!-- (6.39386)--></li>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (5.52571)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://brettterpstra.com/wp-content/uploads/2010/01/tuawatbnrheaderimg2.jpg" alt="Headed to Atlanta main post image" height="187" width="650" class="alignleft headerimg" /></p>

<p>I’m sitting at the airport in Minneapolis, waiting for a flight to Atlanta. I’m headed for <a href="http://www.bignerdranch.com">Big Nerd Ranch</a> for a week-long crash course in iPhone programming. I’ve done a little, but I think it will be a great way to start from the basics and fill in all of the holes in my knowledge. The thing is, I’m a little torn about the circumstances; Big Nerd Ranch is paying for this trip and providing a week of classes in order for me to review the facilities for The Unofficial Apple Weblog, where I’m a blogger. There’s nothing innately wrong with the situation, it’s essentially the same as receiving an NFR license for software to review, except for I can’t give away the license at the end, and it’s worth a whole lot more.</p>

<p>I want to maintain my “journalistic integrity,” but I’m not sure how this will turn out in the end. Big Nerd Ranch is pretty legendary, and I feel like it would be a waste to decline the invitation. I also feel like there are plenty of developers and would-be devs who would love to have a look at the offerings. I just don’t want to be pegged as providing reviews in exchange for anything. I’ve always been good about paying for software I’ve reviewed and continued using, returning review hardware (or buying it, in the case of the ViDock). I don’t want this to be a black mark on my integrity.</p>

<p>This is the plan, then: I’ll be letting the ranch speak for itself. I’ll be shooting video and doing interviews with the personalities involved, including <a href="http://www.bignerdranch.com/instructors/hillegass.shtml">Aaron Hillegass</a>, which I’m pretty psyched about. I won’t be adding a lot of commentary or expressing my own opinions about the experience. If something’s great, it should come through as great without much help from me. I’ve noticed that people only question your integrity if you say positive things… but I doubt I’ll have much negative input in this case.</p>

<p>As I said, this is an opportunity I just couldn’t bear to pass up. It’s exciting and very generous of Big Nerd Ranch. What will be, will be, I guess.</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (16.0819)--></li>
		<li><a href="http://brettterpstra.com/2009/12/12/where-ive-been-this-week/" rel="bookmark">Where I’ve been this week</a><!-- (6.39386)--></li>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (5.52571)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/sM1fwdRKYrE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2010/01/29/big-nerd-ranchero/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2010/01/29/big-nerd-ranchero/</feedburner:origLink></item>
		<item>
		<title>A (fairly) simple equation evaluation service for Snow Leopard</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/bduuBDb8oq0/</link>
		<comments>http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 14:33:05 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=215</guid>
		<description><![CDATA[Download the Evaluate Expression Snow Leopard service: EvaluateExpressionService.zip

This is a stripped down version of a command I have in the TextMate bundle we use at TUAW. It allows you to select any basic numeric equation and evaluate it, replacing the selected text with the results. It will ignore your text if it contains anything but numbers and basic mathematical symbols.&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (25.0755)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (20.6296)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (14.944)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://brettterpstra.com/wp-content/uploads/2009/12/equationevalheader.jpg" alt="Expressionevalheader" height="187" width="650" class="alignleft headerimg" />Download the Evaluate Expression Snow Leopard service: <a href="http://brettterpstra.com/share/EvaluateExpressionService.zip">EvaluateExpressionService.zip</a></p>

<p>This is a stripped down version of a command I have in the <a href="http://macromates.com/">TextMate</a> bundle we use at <a href="http://www.tuaw.com/">TUAW</a>. It allows you to select any basic numeric equation and evaluate it, replacing the selected text with the results. It will ignore your text if it contains anything but numbers and basic mathematical symbols. Sure, there are plenty of ways to do calculations in OS X (<a href="http://www.mactropolis.com/how-tos/leopard-tip-spotlight-calculator/">Spotlight</a>, <a href="http://www.obdev.at/products/launchbar/index.html">Launchbar</a>, <a href="http://www.blacktree.com/">Quicksilver</a>), but I’ve had more and more incidents lately where I just wanted to do quick calculations inline, so I whipped this up. A little explanation…</p>

<p><span id="more-215"></span>
The service is built for Snow Leopard only, but I’m including the code here because it could be wrapped up in <a href="http://wafflesoftware.net/thisservice/">ThisService</a> or <a href="http://www.xendai.com/">Bellhop</a> pretty quickly for Leopard. It’s built in Ruby and uses the eval function to process text such as <code>20*(3.5/2)</code> and return the result. It will add commas to numbers longer than 3 digits, but I stripped out the part of the original command that trimmed decimal places; I figured the accuracy might be important and the results are easy to edit manually in this case. I also added a silly feature that I actually find quite useful: it evaluates +/- percentage strings, such as <code>23.99-15%</code>, which I find most useful for calculating savings during sales or quickly handling markup or tax on services and goods. It can’t get too complex, but for most everyday purposes, it does a good job.</p>

<h3>The code:</h3>

<div markdown="0">
<pre><code>
def ts( st )
  # Adds commas to longer numbers
  # Removes .00 left over from % calculations
  mynum = st.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
  dec = mynum.split('.')
  return dec[0] if dec[1].to_i == 0
  mynum
end

ARGF.each do |f|
    # check if the text passed is actually an equation
    if f.match(/^[\%\$\d\*\/\+\-,\. \(\)]+$/)
        # add a preceding 0 to decimals passed for floating point calculation
        num = f.gsub(/(^|[^\d])(\.\d+)/,'\10\2')
        # convert basic percentage equations for eval
        num = num.gsub(/([\d\.]+)(?:\s+?)?([+-])(?:\s+?)?([\d\.]+)%([^\d]|$)/,'\1\2(\1*(\3.to_f * 0.01))\4')
        # process the result to add commas, trim unnecessary decimal places
        print ts(eval(num).to_s)
    # if it's not an equation, return the input (no effect)
    else
        print f
    end
end
</code></pre>
</div>

<p>You can <a href="http://brettterpstra.com/downloads/EvaluateExpressionService.zip">download a ready-to-go Snow Leopard service</a>, or build your own with the code above. Don’t forget to use the Keyboard preference panel to assign a keyboard shortcut to it (I’m using Control-Shift-=). I’d love to hear back if you find it useful!</p>


<ul>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (25.0755)--></li>
		<li><a href="http://brettterpstra.com/2009/11/12/songza-lucky-link-service/" rel="bookmark">Songza Lucky Link Service</a><!-- (20.6296)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/" rel="bookmark">A better System Service for Evernote clipping — with MultiMarkdown</a><!-- (14.944)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/bduuBDb8oq0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/</feedburner:origLink></item>
		<item>
		<title>Clippable updated to remove source code line numbers</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/tm9TxYzEoV8/</link>
		<comments>http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 11:55:31 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[clippable]]></category>
		<category><![CDATA[evernote]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[readability2]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=212</guid>
		<description><![CDATA[I made a couple of minor changes to the Clippable bookmarklet, mostly in the way it handles SyntaxHighlighter code blocks. The SyntaxHighlighter plugin is used (too) often to format and color code source snippets in websites. The result when clipping a page is that the code you get still has line numbers, but no option to view the raw source&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/" rel="bookmark">Clippable updated, goes mobile</a><!-- (41.6698)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable/" rel="bookmark">Clippable</a><!-- (18.8007)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (13.4662)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>I made a couple of minor changes to the <a href="http://brettterpstra.com/share/readability2.html">Clippable bookmarklet</a>, mostly in the way it handles SyntaxHighlighter code blocks. The SyntaxHighlighter plugin is used (too) often to format and color code source snippets in websites. The result when clipping a page is that the code you get still has line numbers, but no option to view the raw source without going back to the web page. Then you end up manually editing out the line numbers if you want to copy and paste the code, which can be a pain in most cases.</p>

<p>Since the point of Clippable was to deal better with things <em>like</em> code blocks (especially for saving snippets to Evernote), it now removes the toolbar and line numbers from SyntaxHighlighter blocks. It also looks for another common technique: converting lines in code to an ordered list inside of a pre block. This is just blotted out with CSS now. Those are the only two highlighting methods it targets at the moment, but I’ll tackle more as I run into them.</p>

<p>If you already have the bookmarklet installed, you’re already benefitting from these changes (the bookmarklet calls the source scripts on my server, so it is, in essence, automatically updated). If not, just cruise over to the <a href="http://brettterpstra.com/share/readability2.html">Clippable page</a> and grab it!</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/" rel="bookmark">Clippable updated, goes mobile</a><!-- (41.6698)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable/" rel="bookmark">Clippable</a><!-- (18.8007)--></li>
		<li><a href="http://brettterpstra.com/2009/11/03/clippable-to-evernote-snow-leopard-service/" rel="bookmark">Clippable to Evernote Snow Leopard Service</a><!-- (13.4662)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/tm9TxYzEoV8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/</feedburner:origLink></item>
		<item>
		<title>Designing Draw</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/K-iOs3FkxGg/</link>
		<comments>http://brettterpstra.com/2009/12/12/designing-draw/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 04:21:21 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[appdesign]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[ericasadun]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=197</guid>
		<description><![CDATA[
Erica Sadun recently released her latest app, Draw (iTunes link), into the wilds of the App Store. I take a special interest in this release because I designed the interface for it from the ground up. Erica, of course, made all of the magic happen; she’d take my photoshop sketches and send them back as amazing working interfaces. In the&#8230;


No related posts.
]]></description>
			<content:encoded><![CDATA[<p><img src="http://brettterpstra.com/wp-content/uploads/2009/12/draw_funner.jpg" alt="Draw Funner" class="headerimg" />
<img src="http://brettterpstra.com/wp-content/uploads/2009/12/draw_front_screen.jpg" alt="Draw Front Screen" class="alignright" /><a href="http://ericasadun.com/">Erica Sadun</a> recently released her latest app, <a href="http://itunes.apple.com/us/app/draw/id325402952?mt=8">Draw</a> (iTunes link), into the wilds of the App Store. I take a special interest in this release because I designed the interface for it from the ground up. Erica, of course, made all of the magic happen; she’d take my photoshop sketches and send them back as amazing working interfaces. In the end, it was a really fun process to go through and Erica was great to work with. Here’s a quick walk-through of the design process.</p>

<p><span id="more-197"></span>
<img src="http://brettterpstra.com/wp-content/uploads/2009/12/draw_design_phases.jpg" alt="Draw Design Phases" class="aligncenter" /></p>

<p>I started with a choice between a chalkboard motif and something more pencil-and-paper based. Erica made that decision pretty easy, and we moved forward with a “sketchbook” look. The pencil picker was an interesting challenge, I needed to make them small and compact and Erica needed to make them, um, work. A little back and forth and she had a working model using my tiny little pencils that even the largest-fingered user would be able to use.</p>

<p>At first, I was mixing hand drawn elements and photorealistic icons, which I ditched in favor of a more congruous hand-drawn aesthetic overall. This included redesigning the more traditional “HUD” slider to be a piece of paper as well. The nub of translucent black originally used to pull the HUD up turned into a paperclip, attached to a slightly discolored piece of paper which slid over the main panel to reveal additional options. Whereas the HUD would have been suited by a typical exponential tween, the paper aesthetic required a little more cartoonish animation, which Erica accomplished adeptly with a nice bounce.</p>

<p>The icons went through quite a few permutations before I gave up on finding the right brush in Illustrator. Eventually, I drew the icon elements (on the same sketchpad I scanned to make the final paper textures) and scanned them in, cleaned them up and turned them into icons. As the sliding elements and icons became less “modern,” the paper textures and hand-drawn elements became less “antique,” and soon they met in the middle in a more harmonic interface.</p>

<p>The color changed over the course of the mockups, eventually ending up on a more neutral blue-grey. It looks dull and dead next to the more “antiqued” previous generations, but it’s much easier to create your own drawings on a neutral page, so I decided to keep things grey. I think it works well for the end user.</p>

<p>The best part of working with Erica is that she could make any of my little visual ideas “work.” In programming my own apps, I often pull some punches because I don’t have the chops to pull them off quickly. It makes a big difference working with someone who knows the iPhone SDK inside and out. I think the finished 1.0 version of <a href="http://itunes.apple.com/us/app/draw/id325402952?mt=8">Draw</a> is a slick, easy-to-use app that will be fun for all ages.

<a href='' title='Draw Main Screen'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/drawfrontscreen-150x150.jpg" class="attachment-thumbnail" alt="Draw Main Screen" title="Draw Main Screen" /></a>
<a href='' title='First Mockup'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup1-150x150.jpg" class="attachment-thumbnail" alt="First Mockup" title="First Mockup" /></a>
<a href='' title='Original HUD'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup1-firsthud-150x150.jpg" class="attachment-thumbnail" alt="Original HUD" title="Original HUD" /></a>
<a href='' title='First Paper HUD'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup1b-paperhud-150x150.jpg" class="attachment-thumbnail" alt="First Paper HUD" title="First Paper HUD" /></a>
<a href='' title='2nd Round'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup2-paperhud-150x150.jpg" class="attachment-thumbnail" alt="2nd Round" title="2nd Round" /></a>
<a href='' title='Mockup 3'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup3-paperhud-150x150.jpg" class="attachment-thumbnail" alt="Mockup 3" title="Mockup 3" /></a>
<a href='' title='Draw Final - Main Screen'><img width="150" height="150" src="http://brettterpstra.com/wp-content/uploads/2009/12/DrawMockup3-finalmain-150x150.jpg" class="attachment-thumbnail" alt="Main Screen-Final" title="Draw Final - Main Screen" /></a>
</p>


<p>No related posts.</p>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/K-iOs3FkxGg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/12/12/designing-draw/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/12/12/designing-draw/</feedburner:origLink></item>
		<item>
		<title>Where I’ve been this week</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/GBYmtnfl9QY/</link>
		<comments>http://brettterpstra.com/2009/12/12/where-ive-been-this-week/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 21:55:20 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Write]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=189</guid>
		<description><![CDATA[

Well, I've been out of touch with a lot of people for the last four days, and I thought I'd save some time and provide a place I could link everyone to for a quick explanation. On Tuesday evening, in the middle of what the weather service is calling our "worst storm in 20 years," I started having stomach cramps.&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (6.74147)--></li>
		<li><a href="http://brettterpstra.com/2010/01/29/big-nerd-ranchero/" rel="bookmark">Big Nerd Ranchero</a><!-- (6.31075)--></li>
		<li><a href="http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/" rel="bookmark">Clippable updated, goes mobile</a><!-- (5.01784)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><img src="http://brettterpstra.com/wp-content/uploads/2009/12/good_times_at_cmh.jpg" alt="Good times at CMH" height="187" width="440" class="headerimg" /></p>

<p>Well, I’ve been out of touch with a lot of people for the last four days, and I thought I’d save some time and provide a place I could link everyone to for a quick explanation. On Tuesday evening, in the middle of what the weather service is calling our “worst storm in 20 years,” I started having stomach cramps. I won’t go into detail about what followed, but I’ll skip forward to the part where Aditi (my loving and amazingly dedicated wife) packed me into her 4-wheel drive Pathfinder and headed out to Community Memorial Hospital. After a brief survey, I was admitted for observation.</p>

<p><span id="more-189"></span>
It looks, at this point, like a bacterial Colitis, which essentially just means an inflammation of the colon with bacterial sources, as opposed to sources that might not be curable. That would be an ideal diagnosis at this point, but I have to schedule a colonoscopy next week which will hopefully shed more definitive light on the situation. I sincerely thank everyone who’s been supporting me and sending warm wishes throughout this, and apologize to those I probably should have contacted by now but have been too overwhelmed to do so.</p>

<p><a href="http://brettterpstra.com/wp-content/uploads/2009/12/getting_ready_for_a_much_needed_shower.jpg" rel="lightbox"><img src="http://brettterpstra.com/wp-content/uploads/2009/12/getting_ready_for_a_shower.jpg" alt="Getting ready for a shower" height="98" width="183" class="alignleft" /></a>The photo (click to enlarge) is of me getting ready for my second shower; the bare patches on my chest are where the previous incarnation of the telemetry patches were located. The wrapping on my arm covers the IV site, which effectively disables that arm and leaves me to shower one-handed. Good times.</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/01/29/downtime-apology-and-upcoming-projects/" rel="bookmark">Downtime apology and upcoming projects</a><!-- (6.74147)--></li>
		<li><a href="http://brettterpstra.com/2010/01/29/big-nerd-ranchero/" rel="bookmark">Big Nerd Ranchero</a><!-- (6.31075)--></li>
		<li><a href="http://brettterpstra.com/2010/02/26/clippable-updated-goes-mobile/" rel="bookmark">Clippable updated, goes mobile</a><!-- (5.01784)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/GBYmtnfl9QY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/12/12/where-ive-been-this-week/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/12/12/where-ive-been-this-week/</feedburner:origLink></item>
		<item>
		<title>My new favorite Bash prompt</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/TpAV0UxqkhU/</link>
		<comments>http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 00:12:33 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[prompt]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/</guid>
		<description><![CDATA[
I do a lot in Terminal. Sometimes, it's easier. Sometimes it's faster. Sometimes I'd just rather type it out. Whatever the reason, I've never been able to stand looking at a boring shell prompt. Bash is my primary shell, mostly because I've never taken the time to learn much else. I'll get there someday. For now, here's my current Bash&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (14.3281)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/fk-redux/" rel="bookmark">fk: redux</a><!-- (11.197)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/" rel="bookmark">Clippable updated to remove source code line numbers</a><!-- (6.60421)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft headerimg" src="http://brettterpstra.com/wp-content/uploads/2009/11/my_new_favorite_bash_prompt.jpg" alt="My new favorite Bash prompt" width="440" height="187" />
I do a lot in Terminal. Sometimes, it’s easier. Sometimes it’s faster. Sometimes I’d just rather type it out. Whatever the reason, I’ve never been able to stand looking at a boring shell prompt. Bash is my primary shell, mostly because I’ve never taken the time to learn much else. I’ll get there someday. For now, here’s my current Bash shell prompt…</p>

<p>I’m using the <code>PROMPT_COMMAND</code> variable to run a few quick functions to generate the prompt. It doesn’t do anything processor-intensive, so I haven’t seen any lag caused by this one (unlike some of my previous experiments). <code>PROMPT_COMMAND</code> is set to call a function called, appropriately, <code>prompt_command()</code>. This, in turn, calls a few external functions defined in my <code>.bash_profile</code>. To use it, just stick all of the code below into your <code>.bash_profile</code>, and modify it as you see fit. Be sure to replace any definitions of <code>PROMPT_COMMAND</code> or <code>PS1</code>.</p>

<p><span id="more-163"></span>
The prompt has a few unique features, and some “hidden” features:</p>

<ul>
<li>The current time is formatted just the way I like it. You can modify the <code>fmt_time</code> function with your own <code>strftime</code> strings as desired.</li>
<li>The current 1m average CPU load is included in the prompt in dark grey, gathered using a quick <code>uptime</code> command.</li>
<li>If the previous command returned an error message, the error code returned will show up at the end of the first line in red.</li>
<li>If you use Git, and your current working directory is a Git repository, the current branch will be shown in green before the actual prompt on the second line. This might cause problems if you don’t have Git installed; if you see Git-related errors, you can remove the section of the code under the Git comment from <code>if</code> to <code>fi</code>. Also remove the <code>${BRANCH}</code> from the last line of the <code>prompt_command</code> function.</li>
<li>Lastly, it sets the title of the tab in Terminal to the last two portions of the current working directory (<code>pwd</code>) string, meaning the current directory and its parent directory.</li>
</ul>

<p><img class="aligncenter size-full wp-image-165" title="TerminalPromptFullMonty" src="http://brettterpstra.com/wp-content/uploads/2009/11/TerminalPromptFullMonty.jpg" alt="TerminalPromptFullMonty" width="536" height="133" /></p>

<p>All of the colors used in the prompt are defined as shell variables. In the final line of the <code>prompt_command</code> function, you can modify the colors just by replacing the color names in the line. That should be pretty self-explanatory.</p>

<div>
<pre><code class="bash">
prompt_command () {
    if [ $? -eq 0 ]; then # set an error string for the prompt, if applicable
        ERRPROMPT=" "
    else
        ERRPROMPT='-&gt;($?) '
    fi
    if [ "\$(type -t __git_ps1)" ]; then # if we're in a Git repo, show current branch
        BRANCH="\$(__git_ps1 '[ %s ] ')"
    fi
    local TIME=`fmt_time` # format time for prompt string
    local LOAD=`uptime|awk '{min=NF-2;print $min}'`
    local GREEN="\[\033[0;32m\]"
    local CYAN="\[\033[0;36m\]"
    local BCYAN="\[\033[1;36m\]"
    local BLUE="\[\033[0;34m\]"
    local GRAY="\[\033[0;37m\]"
    local DKGRAY="\[\033[1;30m\]"
    local WHITE="\[\033[1;37m\]"
    local RED="\[\033[0;31m\]"
    # return color to Terminal setting for text color
    local DEFAULT="\[\033[0;39m\]"
    # set the titlebar to the last 2 fields of pwd
    local TITLEBAR='\[\e]2;`pwdtail`\a'
    export PS1="\[${TITLEBAR}\]${CYAN}[ ${BCYAN}\u${GREEN}@${BCYAN}\
\h${DKGRAY}(${LOAD}) ${WHITE}${TIME} ${CYAN}]${RED}$ERRPROMPT${GRAY}\
\w\n${GREEN}${BRANCH}${DEFAULT}$ "
}
PROMPT_COMMAND=prompt_command

fmt_time () { #format time just the way I likes it
    if [ `date +%p` = "PM" ]; then
        meridiem="pm"
    else
        meridiem="am"
    fi
    date +"%l:%M:%S$meridiem"|sed 's/ //g'
}
pwdtail () { #returns the last 2 fields of the working directory
    pwd|awk -F/ '{nlast = NF -1;print $nlast"/"$NF}'
}
chkload () { #gets the current 1m avg CPU load
    local CURRLOAD=`uptime|awk '{print $8}'`
    if [ "$CURRLOAD" &gt; "1" ]; then
        local OUTP="HIGH"
    elif [ "$CURRLOAD" &lt; "1" ]; then
        local OUTP="NORMAL"
    else
        local OUTP="UNKNOWN"
    fi
    echo $CURRLOAD
}
</code></pre>
</div>


<ul>
		<li><a href="http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/" rel="bookmark">fk: a useful bash function</a><!-- (14.3281)--></li>
		<li><a href="http://brettterpstra.com/2010/03/06/fk-redux/" rel="bookmark">fk: redux</a><!-- (11.197)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/clippable-updated-to-remove-source-code-line-numbers/" rel="bookmark">Clippable updated to remove source code line numbers</a><!-- (6.60421)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/TpAV0UxqkhU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/</feedburner:origLink></item>
		<item>
		<title>fk: a useful bash function</title>
		<link>http://feedproxy.google.com/~r/BrettTerpstra/~3/e5-sPrLtF6E/</link>
		<comments>http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 23:59:53 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[function]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=156</guid>
		<description><![CDATA[This is a function from my OS X .bash_profile. 'fk' is short for Find and Kill, and it lets you do a quick search of your running processes for a case-insensitive partial match of the first parameter passed to it. It's useful for quickly finding a process without worrying about its capitalization or full spelling, and without having to sift&#8230;

<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/fk-redux/" rel="bookmark">fk: redux</a><!-- (66.0192)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (14.7325)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (9.641)--></li>
	</ul>
]]></description>
			<content:encoded><![CDATA[<p>This is a function from my OS X .bash_profile. ‘fk’ is short for Find and Kill, and it lets you do a quick search of your running processes for a case-insensitive partial match of the first parameter passed to it. It’s useful for quickly finding a process without worrying about its capitalization or full spelling, and without having to sift through (or manually grep) a long <code>ps ax</code> list.</p>

<p><span id="more-156"></span></p>

<div markdown="0">
<pre><code class="bash">
fp () { #find and list processes matching a case-insensitive partial-match string
        ps Ao pid,comm|awk '{match($0,/[^\/]+$/); print substr($0,RSTART,RLENGTH)": "$1}'|grep -i $1|grep -v grep
}

fk () { # build menu to kill process
    IFS=$'\n'
    PS3='Kill which process? '
    select OPT in $(fp $1) "Cancel";; do
        if [ $OPT != "Cancel" ]; then
            kill $(echo $OPT|awk '{print $NF}')
        fi
        break
    done
    unset IFS
}
</code></pre>
</div>

<p>On OS X (and similar Linux systems), you should have a file in your home folder (<code>cd ~</code>) called .bash_profile. Just copy and paste this code at the bottom of that file, and then run <code>source ~/.bash_profile</code> in Terminal. Now (and every time you log in) you can run <code>fk process</code>, where <em>process</em> is a partial name of a running application or UNIX process. You’ll get a menu with the matches, and you can kill a specific process by typing its number at the prompt. The last option is always “Cancel,” which will terminate the command without taking any action. I’d love to hear about any improvements you make to this code… I’m far from a Bash pro.</p>


<ul>
		<li><a href="http://brettterpstra.com/2010/03/06/fk-redux/" rel="bookmark">fk: redux</a><!-- (66.0192)--></li>
		<li><a href="http://brettterpstra.com/2009/11/17/my-new-favorite-bash-prompt/" rel="bookmark">My new favorite Bash prompt</a><!-- (14.7325)--></li>
		<li><a href="http://brettterpstra.com/2009/12/31/equation-evaluation-service-for-snow-leopard/" rel="bookmark">A (fairly) simple equation evaluation service for Snow Leopard</a><!-- (9.641)--></li>
	</ul>
<img src="http://feeds.feedburner.com/~r/BrettTerpstra/~4/e5-sPrLtF6E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://brettterpstra.com/2009/11/14/fk-a-useful-bash-function/</feedburner:origLink></item>
	</channel>
</rss>
