<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Brett TerpstraCode - Brett Terpstra</title>
	<atom:link href="http://brettterpstra.com/category/projects/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://brettterpstra.com</link>
	<description>Elegant solutions to complex problems.</description>
	<lastBuildDate>Thu, 09 Feb 2012 15:01:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Introducing Gather, a Cocoa Markdownifier</title>
		<link>http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier/</link>
		<comments>http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 02:43:36 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3619</guid>
		<description><![CDATA[<p>I wrote something a couple of nights ago that I thought I’d share. I’m calling it “Gather,” and it’s basically an “appified” version of my Readability/Markdownify work. A Cocoa version of Marky the Markdownifier, if you will. You can paste in a URL and it will attempt to find the core text of the page, download it and turn it&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier/">Introducing Gather, a Cocoa Markdownifier</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/02/GatherNew250.png?9d7bd4" alt="" title="GatherNew250" width="250" height="250" class="alignright size-full wp-image-3624" />I wrote something a couple of nights ago that I thought I’d share. I’m calling it “Gather,” and it’s basically an “appified” version of my <a href="http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/">Readability/Markdownify</a> work. A Cocoa version of <a href="http://markdownrules.com/">Marky the Markdownifier</a>, if you will. You can paste in a URL and it will attempt to find the core text of the page, download it and turn it into Markdown for clean web clipping. It displays the result in a field you can copy from, and it can optionally auto-copy the result to your clipboard.</p>

<p>It’s a little shaky, especially on sites with bad markup. I’d say that right now it has about a 60% success rate. As I have time to work on it I’ll be improving this and adding a bevy of features that may eventually become an App Store submission. We’ll see. This proof-of-concept version<sup id="fnref:icon"><a href="#fn:icon" rel="footnote">1</a></sup>, however, is free to download. I’ll ask nicely that you please not steal the idea and <a href="http://www.youtube.com/watch?v=PyupJo5SRHI&amp;feature=related">beat me to the punch</a>.</p>

<p>This build is Lion-only; it won’t run at all on Snow Leopard. I’m not really taking any feature suggestions right now, as I already have an extensive roadmap for it that will turn it into something highly useful in many situations (and I’m quite aware of what it lacks in this state). I <em>would</em> enjoy hearing from you with your reactions, though.</p>

<h3>Credit due</h3>

<p>This version uses <a href="https://github.com/curthard89/COCOA-Stuff/tree/master/GGReadabilityParser">GGReadability</a> by Curtis Hard. You should definitely check out his work-in-progress app, <a href="http://www.geekygoodness.com/">Caffeinated</a>. It’s an RSS reader with Google Reader support and some serious potential. I’m also using <a href="http://www.aaronsw.com/2002/html2text/">HTML2Text</a> for “markdownifying.”</p>

<p>Enjoy.</p>

<h3>Download</h3>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/Gather0.1.zip?9d7bd4" title="Download Gather (198)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2012/02/GatherNew250.png?9d7bd4" alt="download image for Gather" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/Gather0.1.zip?9d7bd4" title="Download Gather (198)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/Gather0.1.zip?9d7bd4" title="Download Gather (198)">Gather</a> — Turn web pages into clean Markdown for clipping. <a href="http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier">More Info</a></p></div>

<div class="footnotes">
<hr />
<ol>

<li id="fn:icon">
<p>I know the icon is pretty terrible. I liked my <a href="http://cdn2.brettterpstra.com/wp-content/uploads/2012/02/GatheredOriginal.png?9d7bd4">first version</a> when it was in Photoshop, but it looked horrible in the Dock. It’ll get better. <a href="#fnref:icon" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/introducing-the-marked-bonus-pack/' rel='bookmark' title='Introducing the Marked Bonus Pack'>Introducing the Marked Bonus Pack</a></li>
<li><a href='http://brettterpstra.com/meet-marky-the-markdownifier/' rel='bookmark' title='Meet Marky, the Markdownifier'>Meet Marky, the Markdownifier</a></li>
<li><a href='http://brettterpstra.com/instapaper-beyond-bugs/' rel='bookmark' title='Instapaper Beyond Bugs (fixed)'>Instapaper Beyond Bugs (fixed)</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier/">Introducing Gather, a Cocoa Markdownifier</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/introducing-gather-a-cocoa-markdownifier/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Connecting nvALT and Address Book</title>
		<link>http://brettterpstra.com/connecting-nvalt-and-address-book/</link>
		<comments>http://brettterpstra.com/connecting-nvalt-and-address-book/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 03:11:46 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[nvalt]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3615</guid>
		<description><![CDATA[<p>Here’s a quick, simple AppleScript to help you hook Notational Velocity/nvALT into Address Book. I sometimes want to attach a note or list of links to an entry in my address book, but I don’t like using the notes field. I tend to keep all of my notes1 in nvALT, and I prefer not to scatter them too far. All&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/connecting-nvalt-and-address-book/">Connecting nvALT and Address Book</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/02/Johnny-Appleseed.jpg?9d7bd4" alt="" title="Johnny Appleseed" width="300" height="199" class="alignright size-full wp-image-3616" />Here’s a quick, simple AppleScript to help you hook <a href="http://notational.net/">Notational Velocity</a>/<a href="http://brettterpstra.com/project/nvalt/">nvALT</a> into Address Book. I sometimes want to attach a note or list of links to an entry in my address book, but I don’t like using the notes field. I tend to keep <em>all</em> of my notes<sup id="fnref:diff"><a href="#fn:diff" rel="footnote">1</a></sup> in nvALT, and I prefer not to scatter them too far. All I needed was a way to quickly create and link an nvALT note to each address…</p>

<p>As of recent versions, Notational Velocity and nvALT have a URL handler for nv:// (or nvalt://). Using the <code>/find/</code> parameter allows you to initiate a search in NV from a link, e.g. <code>nv://find/abnote%3AJohnny Appleseed</code>. If you use a unique prefix and full name, you can pinpoint a single note without having to create a file or locate the note’s ID. The first time you click the link, it will open a search in NV, and pressing Return will create the note and begin editing. Once the note is there, it will locate it instantly the next time you click the link.</p>

<p>I’m using the prefix “abnote:” on my notes. This AppleScript will create the URL entry automatically from the selected entries’ first and last names, and you can edit the prefix in the script to be anything you like. Just save it as “Add NV Note.scpt” in <code>~/Library/Scripts/Applications/Address Book</code> and it will show up in your script menu<sup id="fnref:menu"><a href="#fn:menu" rel="footnote">2</a></sup> when you’re in Address Book. You can run it on a bunch of entries (it’s not optimized to run on an entire large address book, though), or one at a time as you need it.</p>

<p>I wrote this on Lion. I honestly have no idea if it works on anything earlier. It might<sup id="fnref:might"><a href="#fn:might" rel="footnote">3</a></sup>.</p>

<h2>The script</h2>


<div class="wp_syntax"><div class="code"><pre class="applescript"><span class="kw3">tell</span> <span class="kw1">application</span> <span class="st0">&quot;Address Book&quot;</span>
	<span class="kw3">set</span> thePeople <span class="kw3">to</span> <span class="kw2">the</span> <span class="kw1">selection</span>
	<span class="kw3">repeat</span> <span class="kw3">with</span> thisPerson <span class="kw3">in</span> thePeople
		<span class="kw3">set</span> theName <span class="kw3">to</span> <span class="kw1">name</span> <span class="kw3">of</span> thisPerson <span class="kw2">as</span> <span class="kw1">string</span>
		<span class="kw1">make</span> <span class="kw1">new</span> url at <span class="kw3">end</span> <span class="kw3">of</span> urls <span class="kw3">of</span> thisPerson <span class="kw3">with</span> <span class="kw1">properties</span> <span class="br0">&#123;</span>label:<span class="st0">&quot;NV Note&quot;</span>, value:<span class="st0">&quot;nv://find/abnote%3A&quot;</span> <span class="sy0">&amp;</span> theName<span class="br0">&#125;</span>
	<span class="kw3">end</span> <span class="kw3">repeat</span>
	<span class="kw1">save</span>
<span class="kw3">end</span> <span class="kw3">tell</span></pre></div></div>


<div class="footnotes">
<hr />
<ol>

<li id="fn:diff">
<p>Notes, for me, are different from <a href="http://brettterpstra.com/logging-with-day-one-geek-style/">log entries</a>. I actually <em>like</em> keeping those separate most of the time. <a href="#fnref:diff" rev="footnote">↩</a></p>
</li>

<li id="fn:menu">
<p>Enabled in AppleScript Editor, Preferences-&gt;General-&gt;Show Script menu in menubar. Or better, use <a href="http://www.red-sweater.com/fastscripts/">FastScripts</a>. <a href="#fnref:menu" rev="footnote">↩</a></p>
</li>

<li id="fn:might">
<p>It might not. <a href="#fnref:might" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/address-book-search-and-skype-from-the-command-line/' rel='bookmark' title='Address Book search and Skype from the command line'>Address Book search and Skype from the command line</a></li>
<li><a href='http://brettterpstra.com/nvalt-2-1-in-the-wild/' rel='bookmark' title='nvALT 2.1 in the wild'>nvALT 2.1 in the wild</a></li>
<li><a href='http://brettterpstra.com/ios-app-review-reading-list/' rel='bookmark' title='iOS App Review: Reading List'>iOS App Review: Reading List</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/connecting-nvalt-and-address-book/">Connecting nvALT and Address Book</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/connecting-nvalt-and-address-book/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>ScrivWatcher, one more time</title>
		<link>http://brettterpstra.com/scrivwatcher-one-more-time/</link>
		<comments>http://brettterpstra.com/scrivwatcher-one-more-time/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 14:00:36 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3607</guid>
		<description><![CDATA[<p>I’ve updated ScrivWatcher (a utility for previewing compiled Scrivener documents live in Marked) to 1.5. This version has better error handling and a progress bar showing compile progress. It’s still a droplet, you just drop onto the progress bar window instead of a drop pad, or drop a ‘.scriv’ file directly onto the icon. For the command line savvy, the&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scrivwatcher-one-more-time/">ScrivWatcher, one more time</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/01/ScrivWatcher-250.png?9d7bd4" alt="" title="ScrivWatcher-250" width="250" height="250" class="alignright size-full wp-image-3608" />I’ve updated ScrivWatcher (a utility for previewing compiled Scrivener documents live in Marked) to 1.5. This version has better error handling and a progress bar showing compile progress. It’s still a droplet, you just drop onto the progress bar window instead of a drop pad, or drop a ‘.scriv’ file directly onto the icon.</p>

<p>For the command line savvy, the <a href="https://gist.github.com/1676667">gist</a> has been updated as well. Run it with “-h” to see all of the options. There’s even a progress bar in the terminal (default setting).</p>

<p>The big news, though, is that I have this working within <a href="http://markedapp.com">Marked</a>. The next version will be able to accept dropped Scrivener projects and provide a compiled preview that updates with changes from Scrivener. No external application needed! That release should be ready relatively soon, I’m putting out a beta for testing this week.</p>

<p>For now, here’s the latest (and probably last) version of ScrivWatcher:</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2012/01/ScrivWatcher-250.png?9d7bd4" alt="download image for ScrivWatcher" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)">ScrivWatcher</a> — Watch a Scrivener project and preview it in Marked by dragging the .scriv file to this droplet. <a href="http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/">More Info</a></p></div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/' rel='bookmark' title='ScrivWatcher droplet, an easier live Scrivener preview'>ScrivWatcher droplet, an easier live Scrivener preview</a></li>
<li><a href='http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/' rel='bookmark' title='Preview a full Scrivener document in Marked, live'>Preview a full Scrivener document in Marked, live</a></li>
<li><a href='http://brettterpstra.com/the-second-marked-giveaway/' rel='bookmark' title='The second Marked giveaway!'>The second Marked giveaway!</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scrivwatcher-one-more-time/">ScrivWatcher, one more time</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/scrivwatcher-one-more-time/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ScrivWatcher droplet, an easier live Scrivener preview</title>
		<link>http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/</link>
		<comments>http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 13:56:15 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3594</guid>
		<description><![CDATA[<p>I got the droplet for ScrivWatcher working, so you don’t need to run the script from the command line if you don’t want to. I made some further updates to the script1, and the version on GitHub will stay in sync with this application as it develops, so you can choose to go either way. Just unzip the download below&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/">ScrivWatcher droplet, an easier live Scrivener preview</a></p>]]></description>
			<content:encoded><![CDATA[<p>I got the droplet for <a href="http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/">ScrivWatcher</a> working, so you don’t need to run the script from the command line if you don’t want to. I made some further updates to the script<sup id="fnref:changes"><a href="#fn:changes" rel="footnote">1</a></sup>, and the <a href="https://gist.github.com/1676667/">version on GitHub</a> will stay in sync with this application as it develops, so you can choose to go either way.</p>

<p>Just unzip the download below and put the app in your Applications folder (or wherever). Then drop a <a href="http://www.literatureandlatte.com/scrivener.php">Scrivener</a> project on it and it will open the compiled file as a <a href="http://markedapp.com">Marked</a> preview and start watching. You can also launch the application and you’ll get a droppable window that you can drag Scrivener projects to, or put it in your Dock for easy access.</p>

<p>Let me know how it works. If everything’s groovy, I’ll be adding this and some other updates to the Bonus Pack as soon as possible. I’ll probably try to get droplets for the MarsEdit, nvALT, etc. watchers working as well. I present at Macworld | iWorld at 10am today, so that’s going to have to wait while I rehearse!</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2012/01/ScrivWatcher-250.png?9d7bd4" alt="download image for ScrivWatcher" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/ScrivWatcher1.5.zip?9d7bd4" title="Download ScrivWatcher (204)">ScrivWatcher</a> — Watch a Scrivener project and preview it in Marked by dragging the .scriv file to this droplet. <a href="http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/">More Info</a></p></div>

<h3>Changelog</h3>

<h4>1.3</h4>

<ul>
<li>Script detects whether it’s running on the command line or in the droplet. If it’s on the command line, adds progress bar support for caching and concatenating.</li>
</ul>

<h4>1.2</h4>

<ul>
<li>Error catcher for some XML parsing issues on more complex document structures</li>
<li>Rewrote the whole system to cache <code>textutil</code> conversions and only update when the rtf version is newer than the text version. It can now handle files with many sections much, much faster.</li>
<li>Turned off headline generation from page titles by default. If you want it back, you can edit the script inside the app bundle and set titles_as_headers to true. I’ll try to build a more external configuration for it soon.</li>
</ul>

<h4>1.1</h4>

<ul>
<li>Watches project XML file so changes to sorting and order update the preview as well</li>
<li>Names preview files based on project name to avoid overwriting other open previews</li>
<li>Opens dragged document in Scrivener if it’s not already open</li>
</ul>

<div class="footnotes">
<hr />
<ol>

<li id="fn:changes">
<p>mostly just in error handling, but it also quits when Marked quits now. That’s handy if you’re running in the background. <a href="#fnref:changes" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/' rel='bookmark' title='Preview a full Scrivener document in Marked, live'>Preview a full Scrivener document in Marked, live</a></li>
<li><a href='http://brettterpstra.com/scrivwatcher-one-more-time/' rel='bookmark' title='ScrivWatcher, one more time'>ScrivWatcher, one more time</a></li>
<li><a href='http://brettterpstra.com/marked-scripts-nvalt-evernote-marsedit-scrivener/' rel='bookmark' title='Marked scripts: nvALT, Evernote, MarsEdit, Scrivener'>Marked scripts: nvALT, Evernote, MarsEdit, Scrivener</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/">ScrivWatcher droplet, an easier live Scrivener preview</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Preview a full Scrivener document in Marked, live</title>
		<link>http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/</link>
		<comments>http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 19:25:59 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3589</guid>
		<description><![CDATA[<p>BooneJS tweeted me a script yesterday that takes my original “scrivwatch” script and makes it handle full Scrivener documents. It scrapes the XML file to get the order of RTF files in the document, then used the original method to convert and concatenate all of it into a plain text file. If you write in Scrivener using Markdown, you get&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/">Preview a full Scrivener document in Marked, live</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="https://twitter.com/#!/BooneJS">BooneJS</a> tweeted me a script yesterday that takes my original <a href="http://brettterpstra.com/marked-scripts-nvalt-evernote-marsedit-scrivener/">“scrivwatch”</a> script and makes it handle full Scrivener documents. It scrapes the XML file to get the order of RTF files in the document, then used the original method to convert and concatenate all of it into a plain text file. If you write in Scrivener using Markdown, you get a file that <a href="http://markedapp.com">Marked</a> can preview as a rendered document with any theme. It uses the original datestamp polling to watch for any change in any of the files in the project and update Marked within a second or two.</p>

<p>I took the script and ran with it this morning, switching it over to REXML parsing and adding in titles for sections and pages. The original script broke on a couple of my projects, but the recursive XML handler I set up fixes the issue.</p>

<p>To run it, you just need to save the script on your drive and make it executable (<code>chmod a+x /path/to/scrivwatcher.rb</code>). Then you can run <code>/path/to/scrivwatcher.rb /path/to/YourProject.scriv</code>. Marked will open automatically and changes will be reflected every time you save. To stop the script, you need to type Control-c in the terminal window you ran it from.</p>

<p>I’m going to try to wrap this into a droplet that you can just drop a Scrivener project on and launch both Scrivener and Marked with scrivwatcher syncing the two. Once I’ve determined whether that’s win or fail, I’ll update the <a href="http://support.markedapp.com/kb/how-to-tips-and-tricks/marked-bonus-pack-scripts-commands-and-bundles">Marked Bonus Pack</a> with it. Yes, I will eventually find time to build this functionality into Marked, along with the rest of the Bonus Pack scripts.</p>

<p>The script is currently a <a href="https://gist.github.com/1676667">gist on GitHub</a> if you want to play with it. I’ll be updating the gist as I have time to clean it up and make a few things (much) more elegant. If you want to fork and help me out, it’s always appreciated!</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/scrivwatcher-droplet-an-easier-live-scrivener-preview/' rel='bookmark' title='ScrivWatcher droplet, an easier live Scrivener preview'>ScrivWatcher droplet, an easier live Scrivener preview</a></li>
<li><a href='http://brettterpstra.com/scrivwatcher-one-more-time/' rel='bookmark' title='ScrivWatcher, one more time'>ScrivWatcher, one more time</a></li>
<li><a href='http://brettterpstra.com/marked-scripts-nvalt-evernote-marsedit-scrivener/' rel='bookmark' title='Marked scripts: nvALT, Evernote, MarsEdit, Scrivener'>Marked scripts: nvALT, Evernote, MarsEdit, Scrivener</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/">Preview a full Scrivener document in Marked, live</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/preview-a-full-scrivener-document-in-marked-live/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Service for writing MultiMarkdown footnotes inline</title>
		<link>http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline/</link>
		<comments>http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 16:52:39 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[multimarkdown]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3576</guid>
		<description><![CDATA[<p>This post should have been titled “What happens to my mornings.” I get a lot of one-off requests for scripts and tips on how to handle tasks specific to people’s workflow or writing style. I generally keep myself pretty busy, so I usually reply with a quick idea or thought and leave it up to them to run with it.&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline/">A Service for writing MultiMarkdown footnotes inline</a></p>]]></description>
			<content:encoded><![CDATA[<p>This post should have been titled “What happens to my mornings.”</p>

<p>I get a lot of one-off requests for scripts and tips on how to handle tasks specific to people’s workflow or writing style. I generally keep myself pretty busy, so I usually reply with a quick idea or thought and leave it up to them to run with it. <a href="http://havecamerawilltravel.com/">David Coleman</a> emailed me this morning, though, with a request that struck me as an interesting enough idea to whip up a script before work.</p>

<p>What David wanted to do was take the idea behind my “Inline Links to References” command in the <a href="http://brettterpstra.com/project/markdown-service-tools/">Markdown Service Tools</a> and do something similar for footnotes, allowing him to write footnotes inline in a paragraph and have them converted before processing with MultiMarkdown. It’s not such a chore to skip a few lines and drop in the footnote syntax that this should be part of the spec, but it <em>is</em> something I would find handy in several situations. So…</p>

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

<p>The format I picked uses a syntax like this to denote a footnote:</p>

<pre><code>This is the regular text(*This is the footnote*), and you can drop the footnote in at any point.
</code></pre>

<p>The Service can handle footnotes inside of lines, at the end of lines, spanning multiple lines with breaks (creates paragraphs) and does fine with Markdown <em>within</em> the footnote. One nice thing about this syntax is that–if you’re previewing as you write–it italicizes the output to differentiate it until you’ve used the service to move it out of the main text.</p>

<p>Multi-line footnotes need to begin at the end of a line of text, and just use double-newlines to separate paragraphs within the footnote, e.g.:</p>

<pre><code>...the end of the paragraph. (*This is a footnote

which is going to span

more than one line*)
</code></pre>

<p>Here’s the script, also available as a Service download at the end of the post.</p>

<p><strong>Update:</strong> I just added a fix (in code below and the Service download) for making sure that footnote reference titles aren’t duplicated if you have existing MultiMarkdown-formatted footnotes in the document.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="co1">#!/usr/bin/env ruby</span>
&nbsp;
<span class="kw1">def</span> e_sh<span class="br0">&#40;</span>str<span class="br0">&#41;</span>
	str.<span class="me1">to_s</span>.<span class="kw3">gsub</span><span class="br0">&#40;</span><span class="sy0">/</span><span class="br0">&#40;</span>?=<span class="br0">&#91;</span>^a<span class="sy0">-</span>zA<span class="sy0">-</span>Z0<span class="sy0">-</span><span class="nu0">9</span>_.\<span class="sy0">/</span>\<span class="sy0">-</span>\x7F<span class="sy0">-</span>\xFF\n<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">/</span>n, <span class="st0">'<span class="es0">\\</span>'</span><span class="br0">&#41;</span>
<span class="kw1">end</span>
&nbsp;
input = STDIN.<span class="me1">read</span>
&nbsp;
footnotes = input.<span class="me1">scan</span><span class="br0">&#40;</span><span class="sy0">/</span>\<span class="br0">&#40;</span>\<span class="sy0">*</span><span class="br0">&#40;</span>.<span class="sy0">*</span>?<span class="br0">&#41;</span>\<span class="sy0">*</span>\<span class="br0">&#41;</span><span class="sy0">/</span>m<span class="br0">&#41;</span>
existing = input.<span class="me1">scan</span><span class="br0">&#40;</span><span class="sy0">/</span>^\<span class="br0">&#91;</span>\^fn<span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span>\<span class="br0">&#93;</span>: <span class="sy0">/</span>i<span class="br0">&#41;</span>
counter = existing.<span class="me1">empty</span>? ? <span class="nu0">1</span> : existing.<span class="me1">uniq</span>.<span class="me1">sort</span><span class="br0">&#91;</span><span class="sy0">-</span><span class="nu0">1</span><span class="br0">&#93;</span>.<span class="me1">join</span>.<span class="me1">to_i</span> <span class="sy0">+</span> <span class="nu0">1</span>
&nbsp;
output = <span class="br0">&#91;</span><span class="br0">&#93;</span>
footnotes.<span class="me1">each</span> <span class="br0">&#123;</span><span class="sy0">|</span>note<span class="sy0">|</span> 
	output <span class="sy0">&lt;&lt;</span> <span class="br0">&#123;</span><span class="st0">'orig'</span> <span class="sy0">=&gt;</span> note<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>, <span class="st0">'title'</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;fn#{counter}&quot;</span>, <span class="st0">'footnote'</span> <span class="sy0">=&gt;</span> note<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="br0">&#125;</span>
	counter <span class="sy0">+</span>= <span class="nu0">1</span>
<span class="br0">&#125;</span>
&nbsp;
o = <span class="br0">&#91;</span><span class="br0">&#93;</span>
output.<span class="me1">each_with_index</span> <span class="br0">&#123;</span> <span class="sy0">|</span>x,i<span class="sy0">|</span> 
	o.<span class="me1">push</span><span class="br0">&#40;</span><span class="st0">&quot;[^#{x['title']}]: #{x['footnote'].gsub(/<span class="es0">\n</span><span class="es0">\n</span>(<span class="es0">\s</span>*.)/,&quot;</span>\n\n\t\\<span class="nu0">1</span><span class="st0">&quot;)}&quot;</span><span class="br0">&#41;</span>
	input.<span class="kw3">gsub!</span><span class="br0">&#40;</span><span class="sy0">/</span>\<span class="br0">&#40;</span>\<span class="sy0">*</span><span class="co1">#{e_sh x['orig']}\*\)/m,&quot;[^#{x['title']}]&quot;)</span>
<span class="br0">&#125;</span>
<span class="kw3">puts</span> input.<span class="me1">strip</span> <span class="sy0">+</span> <span class="st0">&quot;<span class="es0">\n</span><span class="es0">\n</span>#{o.join(&quot;</span>\n\n<span class="st0">&quot;)}<span class="es0">\n</span>&quot;</span></pre></div></div>


<p>I’m in San Francisco for an AOL Tech code jam right now, so I don’t have a lot of time to thoroughly test this. Please let me know about any bugs that need fixing.</p>

<p>If you’re in San Francisco and like coffee or beer, hit me up <a href="http://twitter.com/ttscoff">on Twitter</a>. If you’re here for Macworld, then you’d better be at my <a href="http://www.macworldiworld.com/techtalks/thursday-overview/thursday-agenda/#903">“40 Tips in 40 Minutes”</a> talk with David Sparks and Merlin Mann on Thursday!</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/ConvertInlineFootnotesService1.21.zip?9d7bd4" title="Download Convert Inline Footnotes Service (68)"><img src="http://brettterpstra.com/wp-content/plugins/download-monitor/page-addon/thumbnail.gif?9d7bd4" alt="download image for Convert Inline Footnotes Service" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/ConvertInlineFootnotesService1.21.zip?9d7bd4" title="Download Convert Inline Footnotes Service (68)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/ConvertInlineFootnotesService1.21.zip?9d7bd4" title="Download Convert Inline Footnotes Service (68)">Convert Inline Footnotes Service</a> — Convert inline footnotes in ‘(*Footnote to be created*)‘ format to MultiMarkdown footnotes. <a href="http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline">More Info</a></p></div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/a-better-os-x-system-service-for-evernote-notes-with-multimarkdown/' rel='bookmark' title='A better System Service for Evernote clipping — with MultiMarkdown'>A better System Service for Evernote clipping — with MultiMarkdown</a></li>
<li><a href='http://brettterpstra.com/auto-convert-your-inline-markdown-links-to-references/' rel='bookmark' title='Auto-convert your inline Markdown links to references'>Auto-convert your inline Markdown links to references</a></li>
<li><a href='http://brettterpstra.com/a-system-service-for-to-url-shortening/' rel='bookmark' title='A System Service for to. url shortening'>A System Service for to. url shortening</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline/">A Service for writing MultiMarkdown footnotes inline</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/a-service-for-writing-multimarkdown-footnotes-inline/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>iOS-inspired popup box CSS</title>
		<link>http://brettterpstra.com/ios-inspired-popup-box-css/</link>
		<comments>http://brettterpstra.com/ios-inspired-popup-box-css/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 21:00:19 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[webdesign]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3564</guid>
		<description><![CDATA[<p>I tweeted the other day that I had made some CSS buttons in a sleep-deprived haze that I really dug. The only reason I even remembered they were there was a command-line-generated entry in Day One that linked to the file. This is why I log. Anyway, I polished them up a little and threw up a GitHub page for&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/ios-inspired-popup-box-css/">iOS-inspired popup box CSS</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/01/popupcssscreenshot.jpg?9d7bd4" alt="Popup CSS Screenshot" title="Popup CSS" width="300" height="323" class="alignright size-full wp-image-3565" />I tweeted the other day that I had made some CSS buttons in a sleep-deprived haze that I really dug. The only reason I even remembered they were there was a <a href="http://brettterpstra.com/logging-with-day-one-geek-style/">command-line-generated entry in Day One</a> that linked to the file. This is why <a href="http://brettterpstra.com/a-solution-for-scatterbrains/">I log</a>.</p>

<p>Anyway, I polished them up a little and threw up a GitHub page for them. If you’re a web designer and you’re looking for an iOS-like popup style, they might be of use to you. You can see the demo, the markup and classes and download the CSS (and minified version) at <a href="http://ttscoff.github.com/popupsCSS/">http://ttscoff.github.com/popupsCSS/</a>.</p>

<p><strong>Late “I-forgot-to-mention” addendum:</strong> These styles were developed primarily with <a href="http://markedapp.com">Marked</a> in mind, meaning there are <del datetime="2012-01-20T21:38:59+00:00">no non-webkit vendor prefixes</del> <ins datetime="2012-01-20T21:38:59+00:00">I guess I put in prefixless and moz versions in my sleep again</ins> and they are not at all cross-browser tested. I’ll put up a more complete version when I get a chance. If you take matters into your own hands, please fork on github or send me your updates for inclusion!</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/title-track-something-precious/' rel='bookmark' title='Title track: Something Precious'>Title track: Something Precious</a></li>
<li><a href='http://brettterpstra.com/pinboard-redesign-experiment/' rel='bookmark' title='Pinboard redesign experiment'>Pinboard redesign experiment</a></li>
<li><a href='http://brettterpstra.com/textmate-drag-command-for-base64-encoding-images/' rel='bookmark' title='TextMate drag command for Base64 encoding images'>TextMate drag command for Base64 encoding images</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/ios-inspired-popup-box-css/">iOS-inspired popup box CSS</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/ios-inspired-popup-box-css/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>System Service: Clip to Day One</title>
		<link>http://brettterpstra.com/system-service-clip-to-day-one/</link>
		<comments>http://brettterpstra.com/system-service-clip-to-day-one/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 22:53:25 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3555</guid>
		<description><![CDATA[<p>I’m enjoying logging with Day One right now, and getting geeky with it. To that end, I put this project together during the few breaks I’ve had over the last couple of days leading up to the new Engadget live blog launch today1. The result is a practical proof of concept in the form of a System Service for clipping&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/system-service-clip-to-day-one/">System Service: Clip to Day One</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/01/dayoneautomator.jpg?9d7bd4" alt="" title="dayoneautomator" width="250" height="243" class="alignright size-full wp-image-3556" />I’m enjoying logging with <a href="http://dayoneapp.com/">Day One</a> right now, and <a href="http://brettterpstra.com/logging-with-day-one-geek-style/">getting geeky with it</a>. To that end, I put this project together during the few breaks I’ve had over the last couple of days leading up to the new <a href="http://www.engadget.com/">Engadget</a> live blog launch today<sup id="fnref:lb"><a href="#fn:lb" rel="footnote">1</a></sup>. The result is a practical proof of concept in the form of a System Service for clipping any text to Day One. I figured that this could actually be really handy for more people than just me, so here it is.</p>

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

<p>Dayone uses a very simple XML format in separate files to store your entries. It’s easy to replicate the structure using a script, allowing you to directly generating your own Day One entries from any part of your workflow. I’m bypassing the <code>dayone</code> CLI and dropping the updates in directly for added flexibility. Don’t get me wrong, I absolutely <em>love</em> that Day One comes with a CLI, I just wanted to experiment around it.</p>

<p>I’m using the new iCloud support for sync, and this Service is built to work with that folder structure by default. The version below (and in the download) looks in “~/Library/Mobile Documents/” (where iCloud stores documents) for a folder containing the word “dayoneapp.” I don’t know offhand what the bizarre names of the folders indicate, but they differ between accounts, so we have to grep out the matching folder. Assuming your Journal is called Journal_dayone (default) and you’re using iCloud, you shouldn’t have to edit anything. If it doesn’t work, run this in Terminal and copy the resulting path into the “dayonepath” variable:</p>

<pre><code>find ~/Library/Mobile\ Documents/ -name "Journal_dayone"
</code></pre>

<p>If you’re using Dropbox, you’ll just need to make a minor alteration to the “dayonepath” variable. Delete the line starting with “dayonedir” and hardcode the Unix (POSIX) path to the “entries” folder, located directly inside of the Journal.dayone bundle in your Dropbox root folder. It will most likely be <code>/Users/[yourusername]/Dropbox/Journal.dayone/entries/</code> if you haven’t changed any defaults in Dropbox or Day One.</p>

<p>The service itself is available for download at the end of the post, or you can take the script below and home-roll your own in Automator. It should work out of the box, no need for ruby gems or symlinked CLIs.</p>

<p>The only configuration you <em>may</em> want to edit is the “starred” variable. This defaults to off because Services aren’t interactive and you probably don’t want to star <em>every</em> entry you clip. If you <em>do</em>, though, just change “starred = false” to “starred = true” and it will make your calendar look like a planetarium.</p>

<p>The Service will use <code>/usr/bin/textutil</code> to strip out any rich text artifacts. I’m not certain this is necessary, but I found that when clipping rich text I would lose all of my line breaks and indents. This seems to solve it. The script also looks for text with hard breaks and handles them Github-style, preserving breaks using Markdown line break syntax.</p>

<p>If you have <a href="http://growl.info">Growl</a> running, you’ll get a notification. To be polite, it checks for Growl before attempting any notifications. The check can be slow sometimes, though, so you may want to either remove the check if you always have Growl running, or remove the whole Growl section at the end if you don’t.</p>

<h3>The script:</h3>

<p>Here’s the script. The same script can be found in the Service download at the end by opening the .workflow file in Automator. You can easily customize/edit from there, so this is posted just for reference.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby">require 'time'
require 'erb'
&nbsp;
def e_sh(str)
	str.to_s.gsub(/(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/n, '\\').gsub(/\n/, &quot;'\n'&quot;).sub(/^$/, &quot;''&quot;)
end
&nbsp;
input = STDIN.read
entrytext = %x{echo #{e_sh input}|textutil -stdin -convert txt -stdout}
entrytext.gsub!(/\n([^\n])/,&quot;    \n\\1&quot;)
uuid = %x{uuidgen}.gsub(/-/,'').strip
datestamp = Time.now.utc.iso8601
starred = false
&nbsp;
dayonedir = %x{ls ~/Library/Mobile\\ Documents/|grep dayoneapp}.strip
dayonepath = &quot;~/Library/Mobile\ Documents/#{dayonedir}/Documents/Journal_dayone/entries/&quot;
&nbsp;
template = ERB.new &lt;&lt;-XMLTEMPLATE
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
	&lt;key&gt;Creation Date&lt;/key&gt;
	&lt;date&gt;<span class="sy0">&lt;%</span>= datestamp <span class="sy0">%&gt;</span>&lt;/date&gt;
	&lt;key&gt;Entry Text&lt;/key&gt;
	&lt;string&gt;&lt;![CDATA[<span class="sy0">&lt;%</span>= entrytext <span class="sy0">%&gt;</span>]]&gt;&lt;/string&gt;
	&lt;key&gt;Starred&lt;/key&gt;
	&lt;<span class="sy0">&lt;%</span>= starred <span class="sy0">%&gt;</span>/&gt;
	&lt;key&gt;UUID&lt;/key&gt;
	&lt;string&gt;<span class="sy0">&lt;%</span>= uuid <span class="sy0">%&gt;</span>&lt;/string&gt;
&lt;/dict&gt;
&lt;/plist&gt;
XMLTEMPLATE
&nbsp;
fh = File.new(File.expand_path(dayonepath+uuid+&quot;.doentry&quot;),'w+')
fh.puts template.result(binding)
fh.close
&nbsp;
growl_running = %x{osascript -e 'tell application &quot;system events&quot; to return (count of (every process whose bundle identifier is &quot;com.Growl.GrowlHelperApp&quot;)) &gt; 0'}
&nbsp;
if growl_running
  %x{osascript -e 'tell application id &quot;com.Growl.GrowlHelperApp&quot; to register as application &quot;Clip to Day One&quot; all notifications {&quot;Clip Complete&quot;} default notifications {&quot;Clip Complete&quot;} icon of application &quot;Day One&quot;'}
  %x{osascript -e 'tell application id &quot;com.Growl.GrowlHelperApp&quot; to notify with name &quot;Clip Complete&quot; title &quot;Log to Day One&quot; description &quot;Clipped to Day One&quot; application name &quot;Clip to Day One&quot;'}
end</pre></div></div>


<p><strong>Side note:</strong> I mentioned to <a href="https://twitter.com/#!/brianstucki">@brianstucki</a> that this Service might contain the necessary ingredients for an Evernote-to-Day-One solution, but I’ve realized it’s really only the last part of the equation. What you’d probably want to do with most RTF/text notes is export HTML, extract the “created on” meta and parse it into the correct date format, then pipe the rest of the contents through markdownify_cli.php, passing the result to <code>dayone new</code>. Then you’ll have nice, Markdown versions of your notes from Evernote, preserving much of the formatting. I tested this, and it works pretty flawlessly for text notes.</p>

<h3>Download</h3>

<p>For complete instructions on installing the service (and adding a keyboard shortcut for it), see the how-to <a href="http://brettterpstra.com/howtos/install-an-os-x-system-service/">posted here</a>.</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/ClipToDayOne.service.zip?9d7bd4" title="Download Clip to Day One Service (138)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2012/01/dayoneautomator.jpg?9d7bd4" alt="download image for Clip to Day One Service" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/ClipToDayOne.service.zip?9d7bd4" title="Download Clip to Day One Service (138)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/ClipToDayOne.service.zip?9d7bd4" title="Download Clip to Day One Service (138)">Clip to Day One Service</a> — A System Service to clip any text to a Day One journal entry. <a href="http://brettterpstra.com/system-service-clip-to-day-one/">More Info</a></p></div>

<div class="footnotes">
<hr />
<ol>

<li id="fn:lb">
<p>If you missed it, you missed out, but it’s going to get even better. You’ll have a ton of opportunities in the next couple of months  to check out what is almost certainly–and it’s not just me saying this–the best tool available for live blogging events. <em>I’m so excited, I just can’t hide it…</em> <a href="#fnref:lb" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/quick-tip-quickly-clear-stuck-growl-notifications/' rel='bookmark' title='Quick Tip: Quickly clear stuck Growl notifications'>Quick Tip: Quickly clear stuck Growl notifications</a></li>
<li><a href='http://brettterpstra.com/a-system-service-for-to-url-shortening/' rel='bookmark' title='A System Service for to. url shortening'>A System Service for to. url shortening</a></li>
<li><a href='http://brettterpstra.com/updated-songza-lucky-link-service/' rel='bookmark' title='Updated: Songza Lucky Link Service'>Updated: Songza Lucky Link Service</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/system-service-clip-to-day-one/">System Service: Clip to Day One</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/system-service-clip-to-day-one/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Logging with Day One, geek style</title>
		<link>http://brettterpstra.com/logging-with-day-one-geek-style/</link>
		<comments>http://brettterpstra.com/logging-with-day-one-geek-style/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 01:17:45 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3543</guid>
		<description><![CDATA[<p>I have long kept a journal–more precisely, a log–using VoodooPad with the Scratchpad scripts by Ian Beck. It’s been a great system, but after years of usage it’s started to become a bit cumbersome. VoodooPad can handle the load, but running the custom scripts is inconvenient on a document with thousands of pages. In the interest of trying new things&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/logging-with-day-one-geek-style/">Logging with Day One, geek style</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/01/Day-One_icon.jpg?9d7bd4" alt="" title="Day One_icon" width="250" height="250" class="alignright size-full wp-image-3545" />I have long kept a journal–more precisely, a log–using VoodooPad with the <a href="http://tagamac.com/2009/09/scratchpad_part2/">Scratchpad scripts</a> by Ian Beck. It’s been a great system, but after years of usage it’s started to become a bit cumbersome. VoodooPad can handle the load, but running the custom scripts is inconvenient on a document with thousands of pages. In the interest of trying new things (and fiddling away some time this evening), I decided to try switching the system over to Day One.</p>

<p><a href="http://dayoneapp.com/">Day One</a> is a gorgeous app for keeping a personal journal. I discovered it, if I recall correctly, <a href="http://www.macsparky.com/blog/2011/12/21/journaling-with-day-one.html">via David Sparks</a>. It has iOS companion apps and iCloud syncing. It also has excellent search capabilities, likes MultiMarkdown and can export my entries to plain text at any time. I like it because it’s good-looking and concise; just what I need, with no feature bloat. Plus, it’s specifically designed to do exactly what I want: keep a timestamped journal of what I’m working on, have accomplished or have just discovered in my digital travels.</p>

<p>Day One already has a quick entry palette in the menubar. It also has a command line interface (<code>/usr/local/bin/dayone</code>)<sup id="fnref:cli"><a href="#fn:cli" rel="footnote">1</a></sup> which provides some geeky options (try <code>dayone</code> in Terminal) and the flexibility needed to replace my current logging system. You can create entries quickly with either method, but I wanted just a little bit more out of it. I built a quick script which allows a basic syntax for starring entries and defining dates (using natural language) inline in the entry itself. It can be used from the command line, from LaunchBar (or similar) and can be incorporated into just about any scriptable workflow.</p>

<p>The natural language portion of the script is built on the “Chronic” Ruby gem, so running this script as is requires that you have that installed. If you don’t have it available, just run <code>gem install chronic</code> to add the gem. If you run into errors doing that, try <code>sudo gem install chronic</code> and provide your system password. Here’s the script, complete with some explanation in the comments.</p>


<div class="wp_syntax"><div class="code"><pre class="ruby"><span class="co1">#!/usr/bin/ruby</span>
&nbsp;
<span class="co1"># logtodayone.rb</span>
<span class="co1"># Brett Terpstra (http://brettterpstra.com)</span>
<span class="co1"># Use and modify freely, attribution appreciated</span>
<span class="co1"># </span>
<span class="co1"># This script works with the Day One[1] command line utility</span>
<span class="co1"># It parses an input string for an exclamation point prefix to mark starred</span>
<span class="co1"># and/or a [date string] at the beginning to parse natural language dates</span>
<span class="co1"># </span>
<span class="co1"># Requirements:</span>
<span class="co1"># Chronic ruby gem</span>
<span class="co1">#</span>
<span class="co1"># Example usage:</span>
<span class="co1"># logtodayone.rb &quot;! This is a starred entry.&quot;</span>
<span class="co1"># logtodayone.rb &quot;[yesterday 3pm] Something I did yesterday at 3:00PM&quot;</span>
<span class="co1"># logtodayone.rb &quot;! [-2 1:30am] A starred entry about something I did two days ago&quot;</span>
&nbsp;
<span class="kw3">require</span> <span class="st0">'rubygems'</span>
<span class="kw3">require</span> <span class="st0">'chronic'</span> <span class="co1"># (`gem install chronic`)</span>
&nbsp;
<span class="kw1">if</span> ARGV.<span class="me1">length</span> <span class="sy0">&gt;</span> <span class="nu0">0</span>
  input = ARGV.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">&quot; &quot;</span><span class="br0">&#41;</span>.<span class="me1">strip</span>
<span class="kw1">else</span>
  <span class="kw3">print</span> <span class="st0">&quot;Log entry: &quot;</span>
  input = <span class="kw3">gets</span>.<span class="me1">strip</span>
<span class="kw1">end</span>
&nbsp;
<span class="co1"># If the input starts with an exclamation point, make it starred</span>
starred = input =~ <span class="sy0">/</span>^!<span class="sy0">/</span> ? <span class="st0">&quot;true&quot;</span> : <span class="st0">&quot;false&quot;</span>
<span class="co1"># remove the bang from the input string</span>
input = input.<span class="kw3">gsub</span><span class="br0">&#40;</span><span class="sy0">/</span>^!\s<span class="sy0">*/</span>,<span class="st0">''</span><span class="br0">&#41;</span>
&nbsp;
<span class="co1"># if there's a [date] specified, parse it</span>
<span class="kw1">if</span> input =~ <span class="sy0">/</span>^\<span class="br0">&#91;</span><span class="br0">&#40;</span>.<span class="sy0">*</span>?<span class="br0">&#41;</span>\<span class="br0">&#93;</span><span class="sy0">/</span>
  datestring = $1
  <span class="co1"># if the date starts with -X, assume it means X days ago</span>
  <span class="kw1">if</span> datestring =~ <span class="sy0">/</span>^\<span class="sy0">-</span><span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>
    datestring.<span class="kw3">sub!</span><span class="br0">&#40;</span><span class="sy0">/</span>\<span class="sy0">-</span><span class="br0">&#40;</span>\d<span class="sy0">+</span><span class="br0">&#41;</span><span class="sy0">/</span>,<span class="st0">&quot;<span class="es0">\\</span>1 days ago &quot;</span><span class="br0">&#41;</span>
  <span class="kw1">end</span>
  <span class="co1"># Replace a single 'y' within the date brackets with &quot;Yesterday&quot; for parsing</span>
  datestring.<span class="kw3">sub!</span><span class="br0">&#40;</span><span class="sy0">/</span>\by\b<span class="sy0">/</span>,<span class="st0">'yesterday'</span><span class="br0">&#41;</span>
  <span class="co1"># Parse the resulting date string with Chronic</span>
  d = Chronic.<span class="me1">parse</span><span class="br0">&#40;</span>datestring, <span class="br0">&#123;</span>:context <span class="sy0">=&gt;</span> <span class="re3">:past</span>, <span class="re3">:ambiguous_time_range</span> <span class="sy0">=&gt;</span> <span class="nu0">8</span><span class="br0">&#125;</span><span class="br0">&#41;</span>
  d = <span class="kw4">DateTime</span>.<span class="me1">now</span> <span class="kw1">if</span> d.<span class="kw2">nil</span>?
<span class="kw1">else</span>
  <span class="co1"># if no [date] specified, make it right now</span>
  d = <span class="kw4">DateTime</span>.<span class="me1">now</span>
<span class="kw1">end</span>
date = d.<span class="me1">strftime</span><span class="br0">&#40;</span><span class="st0">&quot;%m/%d/%Y %l:%M%p&quot;</span><span class="br0">&#41;</span> <span class="co1"># dayone formatted</span>
input = input.<span class="kw3">gsub</span><span class="br0">&#40;</span><span class="sy0">/</span>^\<span class="br0">&#91;</span>.<span class="sy0">*</span>?\<span class="br0">&#93;</span>\s<span class="sy0">*/</span>,<span class="st0">''</span><span class="br0">&#41;</span> <span class="co1"># remove [date] from input</span>
&nbsp;
<span class="sy0">%</span>x<span class="br0">&#123;</span>echo <span class="st0">&quot;#{input}&quot;</span><span class="sy0">|/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>bin<span class="sy0">/</span>dayone <span class="sy0">-</span>d=<span class="st0">&quot;#{date}&quot;</span> <span class="sy0">-</span>s=<span class="co1">#{starred} new}</span></pre></div></div>


<h3>Some usage tips</h3>

<p>You can star an entry by beginning it with an exclamation point. I’m not sure how I’ll use stars yet, but I figured the option was there, so I’d add a syntax for it.</p>

<p>I often end up logging things after the fact but before I <a href="http://brettterpstra.com/a-solution-for-scatterbrains/">forget what I was doing</a>, so it’s important for me to be able to enter an approximate date and time for the sake of organization. Date strings are entered in square brackets at the beginning (or after an exclamation point) of the entry. The natural language accepts basic strings such as “yesterday 3pm” or “noon” and converts them to Day One-compatible dates. It also accepts “-X” operators to specify a number of days ago (I’m assuming I won’t be logging entries in the future). “y” by itself will be converted to “yesterday.” A typical entry for me would look like “[y 11:45pm] working on silly scripts for logging to Day One.” An entry with no exclamation point and no date brackets is just read as a normal entry at the current time.</p>

<p>I’m using generic @tags–a habit carried over from my VoodooPad scratchpad–to make my entries easily searchable by topic or project. Beyond that, I’m just relying on Day One’s built-in chronological organization and full-text search.</p>

<p>The script is all fine and good, but it’s not much use if it’s not convenient to access. Here are a few of the ways I’m making it universally accessible in my workflow.</p>

<h4>Bash alias</h4>

<p>First things first, lets make it really easy to log entries from the command line. A simple alias in your <code>~/.bash_profile</code> shortens things up:</p>

<pre><code>alias log="~/scripts/logtodayone.rb"
</code></pre>

<p>Now you can make an entry with <code>log "the thing I was just doing"</code>.</p>

<h4>LaunchBar Action</h4>

<p>Given that few of us are <em>always</em> on the command line, it would be nice to access the script easily from other utility apps. I personally use LaunchBar, but you can create similar scripts for Alfred, Quicksilver, etc. If you use LaunchBar, you can just save the three-line script below as <code>Log to Day One.scpt</code> in <code>~/Library/Application Support/LaunchBar/Actions</code>:</p>

<pre><code>on handle_string(message)
  do shell script "/Users/ttscoff/scripts/logtodayone.rb \"" &amp; message &amp; "\""
end handle_string
</code></pre>

<p>Now, just pop up LaunchBar and type <code>ldo</code> or similar to select the action, then type space to get a text field where you can type your log entry. The script syntax applies in full, so start with an exclamation point to star the entry, and use natural language date syntax between square brackets to specify a date, if needed.</p>

<h4>Git commit wrapper</h4>

<p>I do something similar to this with an nvALT note, so I thought I’d try it with Day One for a while. It’s a basic bash function to copy a note from a git commit into my daily log. It just wraps <code>git -am</code> (commit all, message), so more complex commit commands won’t work. It covers 90% of the commits I’d actually want in my journal, though.</p>

<pre><code>function cdo(){
  msg=$*
  path=$(pwd)
  ~/scripts/logtodayone.rb "@${path##*/} $msg"
  git commit -am "$msg"
}
</code></pre>

<p><strong>Update:</strong> I made the git wrapper significantly smarter, thanks to a little assist from <a href="http://nnutter.com/2012/01/git-todo/">@nnutter</a>. It basically parses up your git tree for the actual repo name instead of using the directory name you’re currently in.</p>

<pre><code># experimental wrapper for git to log commits to Day One
# lots of credit to http://nnutter.com/2012/01/git-todo/
function cdo(){
  msg=$*
  GIT_DIR=$(git rev-parse --git-dir)
  if ! (( $? )); then
      GIT_DIR=$(echo "$GIT_DIR" | awk -F/ '{nlast = NF -1;print $nlast}')
      if [ -z "$GIT_DIR" ]; then
                path=$(pwd)
                GIT_DIR=${path##*/}
      fi
            ~/scripts/logtodayone.rb "@$GIT_DIR $msg"
  fi

  git commit -am "$msg"
}
</code></pre>

<p>So that’s my fiddling for the evening. Back to doing something more useful (like preparing for my <a href="http://www.macworldiworld.com/techtalks/thursday-overview/thursday-agenda/#903">Macworld | iWorld talk with Merlin Mann and David Sparks</a>).</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:cli">
<p>I forgot this originally, but you need to symlink the dayone CLI from the app bundle to your /usr/local/bin directory. As <a href="http://brettterpstra.com/logging-with-day-one-geek-style/#comment-31321">mentioned in the comments</a>, more information can be found in the <a href="http://dayoneapp.com/faq/">faq</a>.<span id="more-3543"></span>### The script <a href="#fnref:cli" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/system-service-clip-to-day-one/' rel='bookmark' title='System Service: Clip to Day One'>System Service: Clip to Day One</a></li>
<li><a href='http://brettterpstra.com/voodoopad-log-navigation-plugins/' rel='bookmark' title='VoodooPad log navigation plugins'>VoodooPad log navigation plugins</a></li>
<li><a href='http://brettterpstra.com/scatterbrains-2-the-geekening/' rel='bookmark' title='Scatterbrains 2: The geekening'>Scatterbrains 2: The geekening</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/logging-with-day-one-geek-style/">Logging with Day One, geek style</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/logging-with-day-one-geek-style/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Scripting Readability and Markdownify for clipping web pages</title>
		<link>http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/</link>
		<comments>http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 15:07:28 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3524</guid>
		<description><![CDATA[<p>I wanted to share a handy tool that I realized I use daily but rarely talk about. I call it Read2Text, but it’s really just a Frankenstein script which combines Python Readability (license) with html2text (license). The combination allows you to grab web pages, process them with a port of Arc90’s Readability and convert the HTML to Markdown, ready for&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/">Scripting Readability and Markdownify for clipping web pages</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' display: block; margin-right: auto; margin-left: auto;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2012/01/read2textheader.jpg?9d7bd4" alt="read2text header image" title="read2text header" width="650" height="165" class="aligncenter size-full wp-image-3526" /></p>

<p>I wanted to share a handy tool that I realized I use daily but rarely talk about. I call it Read2Text, but it’s really just a Frankenstein script which combines <a href="https://github.com/gfxmonk/python-readability/blob/master/README">Python Readability</a> (<a href="http://www.apache.org/licenses/LICENSE-2.0">license</a>) with <a href="http://www.aaronsw.com/2002/html2text/">html2text</a> (<a href="https://github.com/aaronsw/html2text/blob/master/COPYING">license</a>). The combination allows you to grab web pages, process them with a port of <a href="http://lab.arc90.com/2009/03/02/readability/">Arc90’s Readability</a> and convert the HTML to Markdown, ready for pasting or piping to a text file.</p>

<p><a href="http://brettterpstra.com/project/nvalt/">nvALT</a> has this built in, but it’s been a little crashy lately. I find it more reliable to just do this from the command line. If you install it in your path (both the <code>read2text</code> script and the “readability” folder), you can run <code>read2text http://brettterpstra.com/keybinding-madness/ | pbcopy</code>.</p>

<p>You’ll get a Markdown-ified version of the page, with links, image links, headers, code blocks and text intact, but no comments, sidebars, ads, etc. It’s not perfect, but it does a solid job and cleanup only takes me a minute, even on huge sites. I use this most of the time instead of clipping to Evernote these days.</p>

<p>I alias it in my .bash_profile to <code>rtt</code>, and often redirect the output straight to a text file in my nvALT folder: <code>rtt http://grml.org/zsh/zsh-lovers.html &gt; ~/Dropbox/Notes/nvALT2.1/zsh\ lovers.md</code></p>

<p>Now I have a new note that automatically shows up in nvALT with the text of the zsh-lovers page (yeah, I tried switching to zsh this morning. I’ll have to come back to that). Anyway, I thought others might find this hack of use, so I’m making the download available below.</p>

<div class="download_desc"><p class="download-icon"><a href="http://brettterpstra.com/downloads/Read2Text1.zip?9d7bd4" title="Download Read2Text (289)"><img src="http://cdn2.brettterpstra.com/wp-content/uploads/downloads/thumbnails/2012/01/read2texticon.png?9d7bd4" alt="download image for Read2Text" width="64" /></a><br /><a href="http://brettterpstra.com/downloads/Read2Text1.zip?9d7bd4" title="Download Read2Text (289)" class="download-button">Download</a></p><p class="desc"><a href="http://brettterpstra.com/downloads/Read2Text1.zip?9d7bd4" title="Download Read2Text (289)">Read2Text</a> — A Frankenstinian combination of html2text and Python Readability. This command line tool makes clipping web pages into Markdown text without ads and comments simple. <a href="http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages">More Info</a></p></div>

<p>By the way, I also have <a href="http://markdownrules.com/">a web service</a> for this. You can get <a href="http://fuckyeahmarkdown.com/go/?u=http%3A%2F%2Fbrettterpstra.com%2Fscripting-readability-markdownify-for-clipping-web-pages%2F&amp;read=1">raw markdown</a> or a <a href="http://fuckyeahmarkdown.com/go/?read=1&amp;showframe=1&amp;u=http%3A%2F%2Fbrettterpstra.com%2Fscripting-readability-markdownify-for-clipping-web-pages%2F">nice interface</a> for previewing and copying. There’s also an API and bookmarklets for integration into your favorite browser. Have fun!</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/meet-marky-the-markdownifier/' rel='bookmark' title='Meet Marky, the Markdownifier'>Meet Marky, the Markdownifier</a></li>
<li><a href='http://brettterpstra.com/nvalt-1-0-8-progress/' rel='bookmark' title='nvALT 1.0.8 progress'>nvALT 1.0.8 progress</a></li>
<li><a href='http://brettterpstra.com/clippable/' rel='bookmark' title='Clippable'>Clippable</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/">Scripting Readability and Markdownify for clipping web pages</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/scripting-readability-markdownify-for-clipping-web-pages/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Desktop Quotes Geeklet</title>
		<link>http://brettterpstra.com/desktop-quotes-geeklet/</link>
		<comments>http://brettterpstra.com/desktop-quotes-geeklet/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 14:30:43 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[geeklet]]></category>
		<category><![CDATA[geektool]]></category>
		<category><![CDATA[nerdtool]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3494</guid>
		<description><![CDATA[<p>Well, here it is: my last Geeklet post of 2011. I think it’s the simplest Geeklet I have, but it’s kind of fun. It uses the I ♥ Quotes API to put a random quote on your desktop. There’s a variety of quote categories to choose from, ranging from geeky to humorous, religious to sci-fi. See the API page for&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/desktop-quotes-geeklet/">Desktop Quotes Geeklet</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/marktwainquote.jpg?9d7bd4" alt="mark twain quote header image" title="mark twain quote" width="650" height="116" class="alignright size-full wp-image-3501" /></p>

<p>Well, here it is: my last Geeklet post of 2011. I think it’s the simplest Geeklet I have, but it’s kind of fun. It uses the <a href="http://iheartquotes.com/api">I ♥ Quotes</a> API to put a random quote on your desktop.</p>

<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/simpsonschalkboard.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/simpsonschalkboard-150x150.jpg?9d7bd4" alt="Simpsons Chalkboard" title="Simpsons Chalkboard" width="150" height="150" class="alignright shadow size-thumbnail wp-image-3499" /></a>There’s a variety of quote categories to choose from, ranging from geeky to humorous, religious to sci-fi. See the <a href="http://iheartquotes.com/api">API page</a> for a list and replace “literature” in the url with whatever you like. You can pull from multiple categories by separating them with a “+” in the url. There’s even a <code>simpsons_chalkboard</code> category to play with.</p>

<p>Here’s the one-line command that you can stick right into the Geeklet/Nerdlet without worrying about a shell script <ins datetime="2012-01-01T15:55:15+00:00">(<strong>Updated:</strong> <em>I added some more <code>awk</code> fun to the end to rewrap the output while preserving the break before a “– Author” attribution</em>)</ins>:</p>

<pre><code>curl -s 'http://www.iheartquotes.com/api/v1/random?max_lines=5&amp;source=literature+macintosh'| \
grep -v "http://iheartquotes"| \
sed -e 's/\&amp;amp;/\&amp;/g'|sed -e 's/&amp;quot;//g'| \
awk '{printf "%s ",$0} END {print ""}'|awk -F"--" -v OFS="\n\n—" ' $1=$1'
</code></pre>

<p>You should remove the “\” and newline at the end of each line (putting it all on one single line).</p>

<p>The first part (before the first pipe) just uses <code>curl</code> to grab a random quote from the “literature” section of the Quotes site (the <code>-s</code> makes it operate “silently” with no additional feedback). The url query parameters limit the quotes to a maximum of <del datetime="2012-01-01T16:08:46+00:00">two</del> five<sup id="fnref:five"><a href="#fn:five" rel="footnote">1</a></sup> lines, just to maintain a somewhat consistent length and make it easier to set up fonts and styles. The result of the API call is sent to <code>grep -v</code> to remove the credit line at the end of the response, and then on to <code>sed</code> for a little typographic cleanup (replace quote entities and convert double hyphens to an em dash). The two <code>awk</code> statements at the end will first remove any line breaks, and then, if there’s a double-hyphen (which <em>almost</em> always means an attribution line in these API responses), it adds a double newline and converts that to an em dash<sup id="fnref:emdash"><a href="#fn:emdash" rel="footnote">2</a></sup>.</p>

<p>Have fun with it, and have a Happy New Year!</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:five">
<p>I upped this from two to five because, with the new rewrapping I’m doing, I could fit a lot more text into a wider geeklet. <a href="#fnref:five" rev="footnote">↩</a></p>
</li>

<li id="fn:emdash">
<p>The only time this causes problems is when there’s a double-hyphen actually <em>used</em> as an em dash in the quote, which I’ve only had happen once so far. <a href="#fnref:emdash" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/geeklet-1-minute-average-cpu-load/' rel='bookmark' title='Geeklet: 1-minute average CPU load'>Geeklet: 1-minute average CPU load</a></li>
<li><a href='http://brettterpstra.com/geeklet-top-ram-processes/' rel='bookmark' title='Geeklet: Top RAM Processes'>Geeklet: Top RAM Processes</a></li>
<li><a href='http://brettterpstra.com/geeklet-top-cpu-processes/' rel='bookmark' title='Geeklet: Top CPU processes'>Geeklet: Top CPU processes</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/desktop-quotes-geeklet/">Desktop Quotes Geeklet</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/desktop-quotes-geeklet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A simple but handy Bash function: console</title>
		<link>http://brettterpstra.com/a-simple-but-handy-bash-function-console/</link>
		<comments>http://brettterpstra.com/a-simple-but-handy-bash-function-console/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 09:30:39 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3487</guid>
		<description><![CDATA[<p>Here’s a quick riff on an older bash alias I use which will allow you to easily scan system messages from Terminal. I’ve long had an alias in my ~/.bash_profile called console. It simply tailed the system log with ‘alias console=‘tail –f /var/log/system.log’. Bam I decided to amp it up a little for added convenience. The function below allows me&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-simple-but-handy-bash-function-console/">A simple but handy Bash function: console</a></p>]]></description>
			<content:encoded><![CDATA[<p>Here’s a quick riff on an older bash alias I use which will allow you to easily scan system messages from Terminal.</p>

<p>I’ve long had an alias in my <code>~/.bash_profile</code> called <code>console</code>. It simply tailed the system log with ‘alias console=‘tail –f /var/log/system.log’.</p>

<h3>Bam</h3>

<p>I decided to amp it up a little for added convenience. The function below allows me to add additional arguments which are translated into a regular expression for filtering the log output. Arguments, separated by spaces on the command line, are joined into a regular expression as OR matches. You can specify as many as you like to track each as a keyword. It’s case insensitive and you can use basic regular expression syntax in each parameter. Examples:</p>

<pre><code>$ console byword

$ console usbmuxd servermgrd

$ console mark(ed|y) multimarkdown composer
</code></pre>

<p><code>console</code> with no arguments will still just tail the log with no filter.</p>

<h3>The function</h3>

<p>Just stick this in your <code>~/.bash_profile</code> file, run <code>. ~/.bash_profile</code> and try it out.</p>

<pre><code>function console () {
  if [[ $# &gt; 0 ]]; then
    query=$(echo "$*"|tr -s ' ' '|')
    tail -f /var/log/system.log|grep -i --color=auto -E "$query"
  else
    tail -f /var/log/system.log
  fi
}
</code></pre>

<p>If you want to track more than just the <code>system.log</code> file, you can just add additional filenames, separated by a space, after system.log for each <code>tail</code> command in the function.</p>

<p>There, that was handy.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/fk-a-useful-bash-function/' rel='bookmark' title='fk: a useful bash function'>fk: a useful bash function</a></li>
<li><a href='http://brettterpstra.com/oft-bash-function-for-opening-a-specific-filetype/' rel='bookmark' title='oft: Bash function for opening a specific filetype'>oft: Bash function for opening a specific filetype</a></li>
<li><a href='http://brettterpstra.com/a-bash-function-for-markdown-bloggers/' rel='bookmark' title='A Bash function for Markdown bloggers'>A Bash function for Markdown bloggers</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/a-simple-but-handy-bash-function-console/">A simple but handy Bash function: console</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/a-simple-but-handy-bash-function-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Markdown QuickTags 0.8 for Christmas</title>
		<link>http://brettterpstra.com/markdown-quicktags-0-8-for-christmas/</link>
		<comments>http://brettterpstra.com/markdown-quicktags-0-8-for-christmas/#comments</comments>
		<pubDate>Sun, 25 Dec 2011 21:38:28 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[mdqt]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3450</guid>
		<description><![CDATA[<p>We’re having a low-key holiday this year. I mean really low-key. Aditi’s napping on the couch, the dogs are all sleeping, the cats and the bird are lazily preening themselves and I just fixed Markdown QuickTags. Markdown QuickTags, my WordPress plugin which adds a massive number of Markdown-editing features to the built-in post/page editor had broken with the release of&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/markdown-quicktags-0-8-for-christmas/">Markdown QuickTags 0.8 for Christmas</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/mdqt0.8screenshot-full.jpg?9d7bd4"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-3452 shadow" title="Markdown QuickTags 0.8" src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/mdqt0.8screenshot.jpg?9d7bd4" alt="Markdown QuickTags 0.8 Screenshot" width="300" height="227" /></a>We’re having a low-key holiday this year. I mean <em>really</em> low-key. Aditi’s napping on the couch, the dogs are all sleeping, the cats and the bird are lazily preening themselves and I just fixed Markdown QuickTags.</p>

<p><a href="http://wordpress.org/extend/plugins/markdown-quicktags/">Markdown QuickTags</a>, my WordPress plugin which adds a massive number of Markdown-editing features to the built-in post/page editor had broken with the release of WordPress 3.3. Basically, the <code>quicktags.js</code> file which generates the buttons in the HTML editor changed completely. For the better, of course, but that’s what Markdown QuickTags (hackishly) overrides to work its magic, and the change pulled the rug out from under the plugin. I had to rewrite a good portion of the JavaScript, and it took me a while just to figure out what was going on, but it’s back in action. I’m writing this post with it right now.</p>

<p>I added some new font options (served via Google Fonts), more size choices and a live editor preview from the settings page. I’m working on adding a few “themes” to the editor and making it a little more customizable, but it’s lower on my list than things like, <em>um,</em> working.</p>

<p>Eventually I’ll make a video of it in action, I think I’ve probably snuck in a few features that I’ve done a poor job of documenting, anyway. I revamped the look this time, too (much more <a href="http://bywordapp.com/">Byword</a>–esque) so a screenshot refresh is in order as well. But that’s for <em>after</em> Christmas.</p>

<p>Happy Holidays, hope you’re all having great times.</p>

<p>If you write in Markdown and use WordPress, you’d be insane not to try this out. Version 0.8 just became available <a href="http://wordpress.org/extend/plugins/markdown-quicktags/">in the WordPress Plugin Repository</a>.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/markdown-quicktags-wordpress-plugin/' rel='bookmark' title='Markdown QuickTags: WordPress plugin for Markdown lovers'>Markdown QuickTags: WordPress plugin for Markdown lovers</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-0-7/' rel='bookmark' title='Markdown QuickTags 0.7'>Markdown QuickTags 0.7</a></li>
<li><a href='http://brettterpstra.com/markdown-quicktags-makes-1000-people-happier-and-more-attractive/' rel='bookmark' title='Markdown QuickTags makes 1000 people happier and more attractive'>Markdown QuickTags makes 1000 people happier and more attractive</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/markdown-quicktags-0-8-for-christmas/">Markdown QuickTags 0.8 for Christmas</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/markdown-quicktags-0-8-for-christmas/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running a website with VoodooPad</title>
		<link>http://brettterpstra.com/running-a-website-with-voodoopad-pro/</link>
		<comments>http://brettterpstra.com/running-a-website-with-voodoopad-pro/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 18:25:01 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[voodoopad]]></category>
		<category><![CDATA[webdesign]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3430</guid>
		<description><![CDATA[<p>VoodooPad is a powerful note-collecting, wikifying, productivity machine. With the right scripts, you can make just about anything happen, at least within the realm of text, images and web pages. VoodooPad has a built in web server, and can export your notebook as a full website, with links intact. I like the web export the best, because it gives me&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/running-a-website-with-voodoopad-pro/">Running a website with VoodooPad</a></p>]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/VoodooPad_icon.jpg?9d7bd4" alt="VoodooPad icon" title="VoodooPad_icon" width="300" height="300" class="alignright size-full wp-image-3433" /><a href="http://flyingmeat.com/voodoopad/">VoodooPad</a> is a powerful note-collecting, wikifying, productivity machine. With the right scripts, you can make just about anything happen, at least within the realm of text, images and web pages. VoodooPad has a built in web server, and can export your notebook as a full website, with links intact. I like the web export the best, because it gives me a crazy amount of control over the output. To that end, I built a website using nothing but VoodooPad, hopped up on some custom scripts. I can update it just by editing in the awesome auto-linking editor, and click one button to update my live site. That’s what this post is going to be about.</p>

<p>It’s showing its age (I’ve come to loathe the design), but the site I’m talking about is the <a href="http://bundle.weblogzinc.com/">Blogsmith Bundle Documentation</a> site. Peek around, you’ll see how easily everything gets cross-linked and how quickly you can navigate a fair amount of information. Keep in mind that you can make a VoodooPad site look any way you please, don’t judge the possibilities based on my aging design.</p>

<p><strong>Why would you want to do this?</strong> Once you get the pieces in place (it’s no more complicated than any other ground-up website build-out), it’s a great way to statically generate up-to-date content. It’s easy to make changes to existing content and update the live site with the click of a button, plus VoodooPad is flexible enough to allow for separate testing and production output. Page links are always current and automatically update as you change things around, and the Wiki-linking features of VoodooPad make it great for reference content. Which leads to the second question…</p>

<p><strong>What kind of website is right for this?</strong> Well, if it makes a good VoodooPad document, and doesn’t need to do anything terribly dynamic, it’s probably a good candidate. Remember that the output from VoodooPad is going to be flat (all in one directory), so if for some reason your proposed website requires a directory structure, you’d be better off building it another way. With that said, the flat structure has never been an issue for me; I do all of my organizing and editing in VoodooPad for this site, visual modifications are made in the template, I have automated scripts for pushing content live; I never actually touch the myriad files in that directory.</p>

<p>Read on for some nitty gritty…</p>

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

<h2>Getting started</h2>

<p>First, I built the whole notebook in plain text, using Markdown. VoodooPad does a pretty decent job converting Rich Text to HTML, but if you’re as picky about markup as I am, using <a href="http://en.wikipedia.org/wiki/Markdown">Markdown</a> on plain text is the way to go. There’s a Markdown plugin available in VoodooPad, but I really wanted to use <a href="http://fletcherpenney.net/multimarkdown/users_guide/multimarkdown_syntax_guide/">MultiMarkdown</a> to get tables, footnotes and more. Unfortunately, I didn’t find a way to make MultiMarkdown blend within the VoodooPad workflow, but I did find <a href="http://www.freewisdom.org/projects/python-markdown/">Python Markdown Extra</a>, which turned out to be perfectly workable for this task. We’ll get to that in a second.</p>

<h3>Notebook tips</h3>

<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://cdn2.brettterpstra.com/wp-content/uploads/2011/12/plain_text_pages.jpg?9d7bd4" alt="VoodooPad Document Settings" class="alignright shadow"></p>

<ol>
<li>Use plain text. Open your Document Info palette and have VoodooPad start each page as plain text. Wiki-links and everything will still work fine, and VoodooPad will render those to HTML when you export. No sweat. But we’re working in Markdown here, so avoid any of the Rich Text formatting capabilities of VoodooPad.

<ul>
<li>I’d also recommend you turn off Smart Quotes; our scripts will smarten your straight quotes into web-friendly entities on the way.</li>
<li>For Markdown, setting Tab to insert four spaces is a good idea in the Editing preferences as well.</li>
</ul></li>
<li>Don’t use titles in the page. If possible, cover that in your template; it will help you consistently use titles as <code>&lt;h1&gt;</code> or <code>&lt;h2&gt;</code> headers in the same location on every page.</li>
<li>Use a default page template. Create a page called “NewPageTemplate” and put in any elements you’d like on every page. This will be called every time you add or link a new page. Mine’s blank, and all of my repeated elements are handled in my template. It’s just handy to not be erasing unnecessary clutter when you’re ready to write a new page.</li>
</ol>

<h3>Python Markdown</h3>

<p>Installing and setting up <a href="http://www.freewisdom.org/projects/python-markdown/">Python Markdown</a> gives you the ability to add classes, ids and other markup elements that will make actually designing a template a lot more fun. Python has an <code>easy_install</code> command, and you can run it to add Markdown Extra to your local library:</p>

<pre><code>easy_install markdown
</code></pre>

<p>To make sure your Python path is set to include your site packages, ensure that there’s a <code>PYTHONPATH</code> line is in your .bash_profile:</p>

<pre><code>PYTHONPATH=/Library/Python/2.7/site-packages...
</code></pre>

<p>Yours may be longer, but it needs to have that path (or a path for a different version) in it. On Snow Leopard I ended up having to symlink my 2.6/site-packages to the 2.5/site-packages directory due to some weirdness with my Python install and the way that VoodooPad looks for packages. On Lion and Python 2.7, though, it seems to run fine without any persuasion.</p>

<p>Now you’ve got the power of Markdown Extra for your web export. It’s very similar to <a href="http://fletcherpenney.net/multimarkdown/">MultiMarkdown</a>/<a href="http://michelf.com/projects/php-markdown/extra/">PHP Markdown Extra</a>, and has support for tables, fenced code blocks, code highlighting, footnotes and more. See the <a href="http://www.freewisdom.org/projects/python-markdown/">Python Markdown Extra homepage</a> for syntax documentation, and be sure to browse the extra <a href="http://www.freewisdom.org/projects/python-markdown/Available_Extensions">extensions</a> available.</p>

<h2>Special Pages</h2>

<h3>The Index</h3>

<p>If you create a page called “index,” it will become “index.html” or “index.php” (depending on your settings in the export). Either way, this will become your home page. You can manually edit it, which is preferable in the case of a static website, or you can create scripts to generate lists of the latest content, etc. I’m using it to manage a static site, so I don’t have any dynamic content generators ready for you. You can take what I do have for some of the other scripted pages and modify… if you’re adventurous enough to be trying this out, you’re probably adventurous enough to brave some Python.</p>

<h3>Creating a sitemap with excludes</h3>

<p>I have a Sitemap script that runs whenever I load up a page tagged “sitemap” (there’s only one page with that tag, but you can see the possibilities).</p>

<p>Create a new page called “ScriptSiteMap” and add this code:</p>


<div class="wp_syntax"><div class="code"><pre class="python">page = eventDictionary<span class="br0">&#91;</span><span class="st0">'item'</span><span class="br0">&#93;</span>
document = windowController.<span class="me1">document</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">if</span> <span class="st0">&quot;sitemap&quot;</span> <span class="kw1">in</span> page.<span class="me1">tagNames</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:
  thelist = <span class="st0">&quot;&quot;</span>
  textView = windowController.<span class="me1">textView</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="kw1">for</span> key <span class="kw1">in</span> document.<span class="me1">keys</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:
    a_page = document.<span class="me1">pageForKey_</span><span class="br0">&#40;</span>key<span class="br0">&#41;</span>
    <span class="kw1">if</span> <span class="st0">&quot;excluded&quot;</span> <span class="kw1">not</span> <span class="kw1">in</span> a_page.<span class="me1">tagNames</span><span class="br0">&#40;</span><span class="br0">&#41;</span>:
      thelist = thelist + <span class="st0">&quot;* &quot;</span> + a_page.<span class="me1">displayName</span><span class="br0">&#40;</span><span class="br0">&#41;</span> + <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>
    page.<span class="me1">setDataAsString_</span><span class="br0">&#40;</span>thelist<span class="br0">&#41;</span></pre></div></div>


<p>In your Event Scripts palette, add a new script under “Page opened.” Point it to “ScriptSiteMap.” Now create a blank page named Sitemap and tag it with “sitemap”. Whenever you load open that page now, it will generate a sitemap for the entire site. It can be slow once your site gets large, but you’ll want to open it after adding new pages and before exporting.</p>

<p>You’ll note that I have a line in scripts like this that looks like:</p>

<pre><code>if "excluded" not in a_page.tagNames():
</code></pre>

<p>This way, I can exclude pages from being included in dynamically-generated content just by adding an “excluded” tag to the page. All of my scripts, notes, todo lists for the site, etc. are tagged “excluded” and don’t show up in any menus on the site.</p>

<h3>Include a curated sidebar</h3>

<p>You can include any page’s content in your template using the “#include” tag. This is handy for, say, a sidebar that you want to manually curate (or generate with a script). Just put the display name of the page into a tag like this in your template:</p>

<!--#include page="Sidebar" -->

<p>That’s it!</p>

<h3>Adding Media</h3>

<p>If you add the appropriate javascript (etc.) to your template, you can easily include video and audio in your site. Just put the straight markup needed into the page in VoodooPad and Markdown Extra will pass it through to your site. I actually embed movies directly in my VoodooPad document so they just output into the main folder, then I can include markup like this in a page:</p>


<div class="wp_syntax"><div class="code"><pre class="html">&lt;video id=&quot;movie&quot; width=&quot;700&quot; height=&quot;394&quot; preload controls&gt;
  &lt;source src=&quot;optshift4.mp4&quot; type='video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;' /&gt;
  &lt;source src=&quot;optshift4.ogv&quot; type='video/ogg; codecs=&quot;theora, vorbis&quot;' /&gt;
  &lt;object width=&quot;700&quot; height=&quot;394&quot; type=&quot;application/x-shockwave-flash&quot;
    data=&quot;flowplayer-3.2.2.swf&quot;&gt;
    &lt;param name=&quot;movie&quot; value=&quot;flowplayer-3.2.2.swf&quot; /&gt;
    &lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;
    &lt;param name=&quot;flashvars&quot; value='config={&quot;clip&quot;: {&quot;url&quot;: &quot;optshift4.flv&quot;, &quot;autoPlay&quot;:false, &quot;autoBuffering&quot;:true}}' /&gt;
    Download video as &lt;a href=&quot;optshift4.mp4&quot;&gt;MP4&lt;/a&gt;.
  &lt;/object&gt;
&lt;/video&gt;</pre></div></div>


<p>That creates a page <a href="http://bundle.weblogzinc.com/docs/$us.php">like this</a>.</p>

<h2>Creating a custom template</h2>

<p>The next thing you’ll want to tackle is a custom template. Find your “Web Export Plugins” folder at <code>~/Library/Application Support/VoodooPad/Web Export PlugIns</code> and duplicate one that feels like a good start. You can always start from scratch once you understand the basics; working from a copy will ensure that you have all the building blocks to begin with. Right click on your copied template and “Show Package Contents” to open a new window and see what’s inside (or just head there in Terminal and open the whole folder as a project in your favorite editor).</p>

<p>For the most part, it’s just HTML, CSS and JavaScript (if you want), so have at ‘em. Just pay attention to the existing variables that will insert the rendered content. <code>$page$</code> is the main one to be concerned with, but there are other variables available.</p>

<p>My output was originally all HTML, but I recently modified it to output PHP extensions and made my template use PHP to include a header and footer. This makes it really easy to make changes to the layout portions of the markup, as well as the linked scripts and styles, without having to re-export every time. I won’t go into detail, but if you know a little PHP, it should be easy to figure out.</p>

<p>I added some jQuery, and used animation, <a href="http://colorpowered.com/colorbox/">ColorBox</a> and footnote hover bubbles<sup id="fnref:bubbles"><a href="#fn:bubbles" rel="footnote">1</a></sup>. If you keep your scripts, css and images in subdirectories, copying them into your final export is a lot easier. You’ll find a <code>postflight.sh</code> script in your theme’s folder, and if you open it you’ll see where you need to specify what files to copy out with the export. Mine looks something like this:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0">#!/bin/bash</span>
&nbsp;
<span class="re2">SRC_DIR</span>=<span class="sy0">`</span><span class="kw3">cd</span> <span class="st0">&quot;<span class="es3">${0%/*}</span>&quot;</span>; <span class="kw3">pwd</span><span class="sy0">`</span>
<span class="kw2">cp</span> <span class="re5">-r</span> <span class="st0">&quot;<span class="es2">$SRC_DIR</span>/images&quot;</span> <span class="st0">&quot;<span class="es2">$VPWebExportOutputDirectory</span>/.&quot;</span>
<span class="kw2">cp</span> <span class="re5">-r</span> <span class="st0">&quot;<span class="es2">$SRC_DIR</span>/scripts&quot;</span> <span class="st0">&quot;<span class="es2">$VPWebExportOutputDirectory</span>/.&quot;</span>
<span class="kw2">cp</span> <span class="re5">-r</span> <span class="st0">&quot;<span class="es2">$SRC_DIR</span>/css&quot;</span> <span class="st0">&quot;<span class="es2">$VPWebExportOutputDirectory</span>/.&quot;</span>
<span class="kw2">cp</span> <span class="st0">&quot;<span class="es2">$SRC_DIR</span>/favicon.ico&quot;</span> <span class="st0">&quot;<span class="es2">$VPWebExportOutputDirectory</span>/.&quot;</span></pre></div></div>


<h2>Web Export Script</h2>

<p>Once you’ve got a template ready, it’s time to add some scripts to the document. I should warn you ahead of time that I’m still learning my way around Python. While these work, there may be more elegant ways to do this.</p>

<p>Create a page in my site document called “ScriptWebExport” that contains the following:</p>


<div class="wp_syntax"><div class="code"><pre class="python"><span class="kw1">global</span> <span class="kw3">re</span>
<span class="kw1">import</span> <span class="kw3">re</span>
&nbsp;
<span class="kw1">import</span> markdown
<span class="kw1">import</span> smartypants
&nbsp;
<span class="co1"># Grab the page from the current event (Web Export will markup page)</span>
page = eventDictionary<span class="br0">&#91;</span><span class="st0">'item'</span><span class="br0">&#93;</span>
&nbsp;
<span class="co1"># Get the text of the page as a string</span>
content = page.<span class="me1">dataAsAttributedString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="kw3">string</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp;
<span class="co1"># Remove some content before processing, in this case my todo items</span>
output = <span class="kw3">re</span>.<span class="me1">sub</span><span class="br0">&#40;</span>r<span class="st0">'<span class="es0">\[</span>TODO<span class="es0">\]</span> .+'</span>, <span class="st0">''</span>, content<span class="br0">&#41;</span>
&nbsp;
<span class="co1"># run the markdown module on the content, including or excluding any extensions desired</span>
<span class="co1"># you can just include 'extras' to get them all, instead of loading each individual extension</span>
html = markdown.<span class="me1">markdown</span><span class="br0">&#40;</span>output, <span class="br0">&#91;</span><span class="st0">'footnotes(PLACE_MARKER=+++footnotes+++)'</span>,<span class="st0">'headerid(level=2)'</span>,<span class="st0">'def_list'</span>,<span class="st0">'abbr'</span>,<span class="st0">'tables'</span>,<span class="st0">'fenced_code'</span>,<span class="st0">'codehilite'</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp;
<span class="co1"># return the Markdown Extra-processed page to be passed on for additional VoodooPad markup and linking</span>
eventDictionary<span class="br0">&#91;</span><span class="st0">'itemMutableAttributedString'</span><span class="br0">&#93;</span>.<span class="me1">mutableString</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">setString_</span><span class="br0">&#40;</span>smartypants.<span class="me1">smartyPants</span><span class="br0">&#40;</span>html<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div>


<p>Now you just need to open up <strong>Window-&gt;Palettes-&gt;Event Scripts</strong> and add a new script under the “Web export will mark up page” trigger. Set it to the “ScriptWebExport” page and choose the Python interpreter. With a template ready and your Markdown Extra rendering, you’re ready to go.</p>

<h2>Web Export</h2>

<p>Now you’re ready to export. You can go ahead and test it out (File-&gt;Export Document-&gt;Web Export). Choose your template and pick a folder for the files. If you’re outputting <code>php</code> extensions, make sure you’re putting them somewhere you have php-enabled access to. Files with an <code>html</code> extension will load up in your browser no matter where you put them. VoodooPad exports your entire site “flat,” meaning it’s all in one directory. It’s easier this way, and since you’re doing all of the content management in the VoodooPad environment, you don’t really have to worry about it. Your theme can store includes, css, images and scripts in subdirectories.</p>

<p>This part is entirely optional, but I run a postflight script (set in the Web Export panel) that updates a git repository and pushes it to the live server after an update. I have two presets, one that pushes and one that doesn’t; deployment and development.</p>

<p>Here’s the script I use:</p>


<div class="wp_syntax"><div class="code"><pre class="bash"><span class="co0">#!/bin/bash</span>
&nbsp;
<span class="kw3">cd</span> <span class="st0">&quot;/path/to/my/export folder&quot;</span>
<span class="kw2">git</span> ls-files <span class="re5">-o</span> <span class="sy0">|</span> <span class="kw2">git</span> update-index <span class="re5">--add</span> <span class="re5">--stdin</span>
<span class="kw2">git</span> commit <span class="re5">-am</span> <span class="st0">&quot;Updating the VoodooPad website on <span class="es5">`date`</span>&quot;</span>
<span class="kw2">git</span> push origin master</pre></div></div>


<p>This does an automatic update and commits any files that have changed, were added or have been deleted. It’s a nice backup, too, just in case you exported something you weren’t ready for. Then I have a post-receive hook on the origin server that pushes out a copy of the latest changes to the web directory automatically.</p>

<p>You could accomplish much the same thing with Docksend in Transmit or just by outputting your documents to a mounted server folder. Have a preset for saving to a local folder for testing, and one for pushing to your remote folder in whatever way you prefer.</p>

<h2>In Closing</h2>

<p>Well, that’s my best shot at sharing what I’ve learned managing a website with VoodooPad. It’s not right for every situation, but it’s great for handling documentation and informational websites that change regularly and are well-suited for the kind of inter-page linking that VoodooPad makes so easy. I’ll be curious to hear if this sparks anyone’s imagination… can’t wait to see your site!</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:bubbles">
<p>Just in case I wanted to go nuts with footnotes at some point. <a href="#fnref:bubbles" rev="footnote">↩</a></p>
</li>

</ol>
</div>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/a-quick-voodoopad-script-plugin-go-to-today/' rel='bookmark' title='A Quick VoodooPad Script Plugin — Go To Today'>A Quick VoodooPad Script Plugin — Go To Today</a></li>
<li><a href='http://brettterpstra.com/voodoopad-log-navigation-plugins/' rel='bookmark' title='VoodooPad log navigation plugins'>VoodooPad log navigation plugins</a></li>
<li><a href='http://brettterpstra.com/how-to-be-popular-at-parties/' rel='bookmark' title='How to be popular at parties'>How to be popular at parties</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/running-a-website-with-voodoopad-pro/">Running a website with VoodooPad</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/running-a-website-with-voodoopad-pro/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>na: per-project todos in Terminal</title>
		<link>http://brettterpstra.com/na-per-project-todos-in-terminal/</link>
		<comments>http://brettterpstra.com/na-per-project-todos-in-terminal/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 14:00:06 +0000</pubDate>
		<dc:creator>Brett</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[TaskPaper]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://brettterpstra.com/?p=3421</guid>
		<description><![CDATA[<p>As I’ve mentioned before, I keep todo.taskpaper files in my web and code project folders. These allow me to keep track of bugs, ideas, notes, etc., and the archive it creates helps me remember what I did, when I did it and how it worked. I like having them separated per project; it’s the way my one-track mind works. I&#8230;</p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/na-per-project-todos-in-terminal/">na: per-project todos in Terminal</a></p>]]></description>
			<content:encoded><![CDATA[<p>As I’ve mentioned before, I keep todo.taskpaper files in my web and code project folders. These allow me to keep track of bugs, ideas, notes, etc., and the archive it creates helps me remember what I did, when I did it and how it worked. I like having them separated per project; it’s the way my one-track mind works. I like the plain-text format because I can use any variety of methods (including <a href="http://www.hogbaysoftware.com/products/taskpaper">TaskPaper</a> itself) to manipulate and quickly update the files. This gave me the idea to have Terminal just notify me of current todos whenever I switched to a project. Thus, <code>na</code> was born. Whether or not it’s useful to anyone else remains to be seen, but I figured I’d share it anyway.</p>

<p>Yesterday at 5:30pm, this little project was working fine with about eight lines of code. Then I had an idea or two, and by morning it was 160 lines of code. It definitely got out of hand, but I rather like the final product. The bulk of the script is straight bash and UN*X commands, but I shelled a lot of the more complex string handling out to Ruby. I’m too lazy to deal with <code>awk</code> and <code>sed</code> past a certain point.</p>

<p>Feel free to skip to <a href="https://github.com/ttscoff/na">the <code>na</code> GitHub repo</a>, peek at the readme.md file and start playing. I welcome any revisions/iterations of this, so feel free to fork and let me know what you do with it!</p>

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

<h3>Meet “na”</h3>

<p><code>na</code> is a bash function designed to make it easy to see what your next actions are for any project, right from the command line. It works with TaskPaper-format files (but any plain text format will do), looking for @na tags (or whatever you specify) in todo files in your current folder. It can also auto-display next actions when you enter a project directory, automatically locating any todo files and listing their next actions when you <code>cd</code> to the project (optionally recursive).</p>

<h3>Features</h3>

<p>You can list next actions in files in the current directory by typing <code>na</code>. By default, <code>na</code> looks for “.taskpaper” files and extracts items tagged “@na” and not “@done”. All of these can be changed in the configuration.</p>

<h4>Easy matching</h4>

<p><code>na</code> features intelligent project matching. Every time it locates a todo file, it adds the project to the database. Once a project is recorded, you can list its actions by using any portion of the parent directories names. If your project is in “~/Sites/dev/markedapp,” you could quickly list its next actions by typing <code>na dev mark</code>. It will always look for the shortest match.</p>

<h4>Recursion</h4>

<p><code>na</code> can also recurse subdirectories to find all todo files in child folders as well. Use the <code>-r</code> switch to do a recursive search on the current directory. <code>na -r</code> with no arguments will recurse from your current location, looking for todo files in all subdirectories. Maximum depth for recursion can be controlled in the config (default is 4). <code>na -r</code> can take a path or project title fragments as arguments as well, and will recurse from the matched directory. A configuration option allows you to have the auto-display recurse by default.</p>

<h4>Adding todos</h4>

<p>You can also quickly add todo items from the command line with the <code>-a</code> switch. The script will look for a file in the current directory called todo.taskpaper (or whatever extension you’ve set). If found, it will try to locate an “Inbox:” project, or create one if it doesn’t exist. Any arguments after <code>-a</code> will be combined to create a new task in TaskPaper format. They will automatically be assigned as next actions (tagged “@na”) and will show up when <code>na</code> lists the tasks for the project.</p>

<p>More details and usage examples (as well as the download) <a href="https://github.com/ttscoff/na">on the GitHub page</a>.</p>
<p>Related posts:<ol>
<li><a href='http://brettterpstra.com/totally-taskpaper/' rel='bookmark' title='Totally TaskPaper'>Totally TaskPaper</a></li>
<li><a href='http://brettterpstra.com/quick-tip-throttling-parallel-batch-processes-in-terminal/' rel='bookmark' title='Quick Tip: throttling parallel batch processes in Terminal'>Quick Tip: throttling parallel batch processes in Terminal</a></li>
<li><a href='http://brettterpstra.com/quick-link-terminal-navigation-utilities/' rel='bookmark' title='Quick Link: Terminal navigation utilities'>Quick Link: Terminal navigation utilities</a></li>
</ol></p><p>Originally posted on <a href="http://brettterpstra.com" title="BrettTerpstra.com">BrettTerpstra.com</a> at <a href="http://brettterpstra.com/na-per-project-todos-in-terminal/">na: per-project todos in Terminal</a></p>]]></content:encoded>
			<wfw:commentRss>http://brettterpstra.com/na-per-project-todos-in-terminal/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic (Feed is rejected)
Page Caching using disk: enhanced
Database Caching 35/187 queries in 0.695 seconds using xcache
Object Caching 4422/4611 objects using xcache
Content Delivery Network via cdn2.brettterpstra.com

Served from: brettterpstra.com @ 2012-02-09 18:41:57 -->
