<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A0ANSHY_eip7ImA9WhRbFEs.&quot;"><id>tag:blogger.com,1999:blog-14372968</id><updated>2012-02-05T13:23:19.842-06:00</updated><category term="book stores" /><category term="nytimes" /><category term="news" /><category term="web" /><category term="books" /><category term="dtd" /><category term="fonts" /><category term="everythingismiscellaneous" /><category term="Alex Ross" /><category term="art" /><category term="projects" /><category term="westlaw" /><category term="virginia woolf" /><category term="Mercurial" /><category term="firefox" /><category term="helvetica" /><category term="travel" /><category term="Git" /><category term="saramago" /><category term="Fake Steve Jobs" /><category term="geekery" /><category term="space shuttle" /><category term="blueBook" /><category term="sitemaintenance" /><category term="Mark Mail" /><category term="Carl Malamud" /><category term="thisamericanlife" /><category term="reporting" /><category term="business" /><category term="mechanical turk" /><category term="XSLT" /><category term="tech notes" /><category term="standing" /><category term="xproc" /><category term="Tim O'Reilly" /><category term="endeavour" /><category term="XML" /><category term="Stephen King" /><category term="houston" /><category term="links" /><category term="iPhone" /><category term="calabash" /><category term="exist-db" /><category term="tech support" /><category term="book review" /><category term="highways" /><category term="design" /><category term="radiohead" /><category term="college sports" /><category term="testing" /><category term="blogging" /><category term="manolis kelaidis" /><category term="conferences" /><category term="journalism" /><category term="cooking" /><category term="space" /><category term="XSpec" /><category term="iraglass" /><category term="kiran desai" /><category term="the wire" /><category term="Alan Kay" /><category term="PTC/User" /><category term="Clockster" /><category term="nicole krauss" /><category term="google books" /><category term="creativity" /><category term="visualizations" /><category term="grammar" /><category term="xquery" /><category term="bicycle" /><category term="sushi" /><category term="google notebook" /><category term="internet" /><category term="short stories" /><category term="windows" /><category term="Switcheroo" /><category term="excerpt" /><category term="emacs" /><category term="classical music" /><category term="ebooks" /><category term="austin" /><category term="bridges" /><category term="law" /><category term="vacation" /><category term="photography" /><category term="The Rest is Noise" /><category term="maker faire" /><category term="programming" /><category term="politics" /><category term="clearview" /><category term="Wordcycler" /><category term="Michael Chabon" /><category term="music" /><category term="chili" /><category term="case law" /><category term="publishing" /><category term="regex" /><category term="wikipedia" /><category term="newspapers" /><category term="recipe" /><category term="web2.0" /><category term="hacks" /><category term="food" /><category term="webrunner" /><category term="google reader" /><category term="inequality" /><category term="maps" /><category term="writing" /><category term="fiction" /><category term="readings" /><category term="utilities" /><title>Words in Boxes</title><subtitle type="html">Nouns, verbs, and occasionally adjectives.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.wordsinboxes.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.wordsinboxes.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>175</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/IndigoFlats" /><feedburner:info uri="indigoflats" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0ANSHY9eCp7ImA9WhRbFEs.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-7662103622373562382</id><published>2012-02-05T13:23:00.000-06:00</published><updated>2012-02-05T13:23:19.860-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-05T13:23:19.860-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Git" /><category scheme="http://www.blogger.com/atom/ns#" term="Mercurial" /><title>Migrating repositories from Bitbucket to Github</title><content type="html">&lt;p&gt;A few years ago, I decided to use Mercurial &amp;amp; Bitbucket instead of Git &amp;amp; Github for my public repositories, because Mercurial seemed simpler and worked better on Windows.  But times have changed.  I use OS X now, and Github has become both overwhelmingly better and more popular.  So it’s time to pick up and &lt;a href="https://github.com/jsulak"&gt;move&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a guide on how to do just that.  It assumes that your repos have a small number of committers, and that you’re comfortable with the command line.&lt;/p&gt;

&lt;h2 id="cleanupyourmercurialrepository"&gt;1. Clean up your Mercurial repository&lt;/h2&gt;

&lt;p&gt;Chances are your Bitbucket and Github usernames are not the same.  Or if you’re like me, you didn’t keep your ~/.hgrc settings the same across machines, so your commit usernames aren’t consistent even if they’re all actually yours.  The migration is a chance to tidy up.  &lt;/p&gt;

&lt;p&gt;To do this, we can use Mercurial’s &lt;a href="http://mercurial.selenic.com/wiki/ConvertExtension"&gt;convert extension&lt;/a&gt;, which can create a new, ‘filtered’ repository from an existing repository.  In our case, we’ll alter the usernames to match what we want to appear on Github.  &lt;/p&gt;

&lt;p&gt;The convert extension is enabled by adding these lines to our ~/.hgrc:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[extensions]
hgext.convert=&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next, we’ll create a text file that maps old usernames to our new usernames.  This is easy with some bash magic.  Go to your repository directory and on the command line type:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;hg log | grep user: | sort | uniq | sed ’s/user: *//‘ &amp;gt; users.txt&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;users.txt contains a sorted and filtered list of all the usernames attached to commits, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;username
username@localhost
username &amp;lt;username@gmail.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit this file so it maps old usernames to new usernames.  If you have any existing Github repositories, I recommend running &lt;code&gt;git log&lt;/code&gt;to get the exact username / email pair Github expects.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;username=Username Fullname &amp;lt;username@gmail.com&amp;gt;
username@localhost=Username Fullname &amp;lt;username@gmail.com&amp;gt;
username &amp;lt;username@gmail.com&amp;gt;=Username Fullname &amp;lt;username@gmail.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’re ready to convert (replace SOURCE_HG_REPO and CLEAN_HG_REPO with real directory names, of course):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ..
hg convert --authors SOURCE_HG_REPO/users.txt SOURCE_HG_REPO CLEAN_HG_REPO&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And bam, you have a new, tidied mercurial repository in CLEAN_HG_REPO.&lt;/p&gt;

&lt;h2 id="converttherepositorytogit"&gt;2. Convert the repository to Git&lt;/h2&gt;

&lt;p&gt;Converting a repository from Mercurial to Git is simple.  We’ll use a script called &lt;a href="http://repo.or.cz/w/fast-export.git"&gt;fast-export&lt;/a&gt;.  The following instructions are adapted from &lt;a href="http://hivelogic.com/articles/converting-from-mercurial-to-git/"&gt;Dan Benjamin’s&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The easiest way to get fast-export is to clone it from its Git repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/tmp
git clone git://repo.or.cz/fast-export.git &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we’ll create a new, empty Git repository, and use fast-export to populate it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git init DEST_GIT_REPO
cd DEST_GIT_REPO
~/tmp/fast-export/hg-fast-export.sh -r CLEAN_HG_REPO
git checkout HEAD&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And bam, you have a new Git repository, complete with your entire commit history.  Don’t forget: you’ll need to convert your .hgignore into .gitignore.&lt;/p&gt;

&lt;h2 id="pushthenewrepositorytogithub"&gt;3. Push the new repository to Github&lt;/h2&gt;

&lt;p&gt;Now it’s time take your shiny new Git repository and slap it up on Github.  Go to your Github profile page, and click “New Repository.”  Fill out the form, and follow the instructions to import an existing Git repo, which goes something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd DEST_GIT_REPO
git remote add origin git@github.com:username/REPO_NAME.git
git push -u origin master&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="dontforgettomigrateotherdata"&gt;4. Don’t forget to migrate other data&lt;/h2&gt;

&lt;p&gt;I haven’t found a way to automatically migrate them, but don’t forget about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issues&lt;/li&gt;
&lt;li&gt;Wiki. I tended to use a one-page Wiki as a landing page.  The Github convention is to use a readme.md markdown document.  You’ll have to convert the Wiki markup to Markdown.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="deletingyourbitbucketrepository"&gt;5. Deleting your Bitbucket repository&lt;/h2&gt;

&lt;p&gt;On the “Admin” tab of your Bitbucket repository page, you can choose to delete the repository.  Make sure to enter the url of your new Github repository in the “Redirect to” field!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-7662103622373562382?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/Ot5t3C0EjqI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7662103622373562382?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7662103622373562382?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/Ot5t3C0EjqI/migrating-repositories-from-bitbucket.html" title="Migrating repositories from Bitbucket to Github" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2012/02/migrating-repositories-from-bitbucket.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHQ3c-fCp7ImA9WhRXFEo.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-6373017897697560956</id><published>2011-12-21T08:39:00.002-06:00</published><updated>2011-12-21T08:45:32.954-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-21T08:45:32.954-06:00</app:edited><title>Wordcycler 2.0 Released</title><content type="html">&lt;p&gt;It’s been a long time coming, but I’ve released a new version of &lt;a href="http://www.wordcycler.com"&gt;Wordcycler&lt;/a&gt;, the program for two-way Instapaper sync for Windows and your e-book reader.  There is only one major change — now, instead of scraping the site, Wordcycler uses the offical &lt;a href="http://www.instapaper.com/api/full"&gt;Instapaper full API&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This means two things for current users:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Wordcycler will be more reliable and future-proof.  Since Wordcycler was nothing but a glorified site scraper, it has always been one minor Instapaper site upgrade away from being completely broken.  We’ve been lucky so far, but it’s a bomb waiting to go off.  The official API is guarranteed to keep working.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To use Wordcycler, &lt;strong&gt;you must be an &lt;a href="http://www.instapaper.com/subscription"&gt;Instapaper subscriber&lt;/a&gt;&lt;/strong&gt;.  Only subscriber accounts have access the full API.  It’s only $1 a month and helps keep Instapaper running, so I recommend &lt;a href="http://www.instapaper.com/subscription"&gt;you subscribe&lt;/a&gt; if you haven’t already.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;I realize this is a trade-off, so if this is a deal-breaker you should not upgrade. But I will not be updating the 1.x versions of Wordcycler, so if Marco Arment changes the HTML and breaks Wordcycler, you will be on your own.  Using the full API is the right thing to do, if only just to be a good Instapaper citizen.&lt;/p&gt;&lt;h2&gt;The Future of Wordcycler&lt;/h2&gt;&lt;p&gt;The fact is, I don’t use Wordcycler myself much anymore.  I own a Mac now, and I do most of my Instapaper reading on my iPhone.  Wordcycler is not a money-making project, so my time and attention has been spent on my day job, my personal life, and other projects &amp;ndash; the usual reasons.  Wordcycler 2.0 has been sitting on my drive half-finished for about six months, but I wanted to finish it up to leave things in a good spot.&lt;/p&gt;&lt;p&gt;So that’s a long way of saying that this could be the last release of Wordcycler.  It’s been a fun ride, and it’s been very gratifying to see so many people get use out of it.  But it’s time to stop kidding myself that I have the time to maintain it, especially now that I’m no longer an active user myself.  I’m exploring the possibility of open-sourcing Wordcycler, but no promises yet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-6373017897697560956?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/YOUtvq_jw7w" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6373017897697560956?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6373017897697560956?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/YOUtvq_jw7w/wordcycler-20-released.html" title="Wordcycler 2.0 Released" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2011/12/wordcycler-20-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAMQH0zfip7ImA9WhRTF0w.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-2701981522512627811</id><published>2011-11-07T20:03:00.000-06:00</published><updated>2011-11-07T20:03:01.386-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-07T20:03:01.386-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="books" /><title>What I’ve Been Reading (History)</title><content type="html">&lt;ol&gt;
&lt;li&gt;David Crane, &lt;a href="http://www.amazon.com/gp/product/B001NJUOYY/?tag=woinbo-20"&gt;Scott of the Antarctic&lt;/a&gt;.  My recent fascination with Scott’s two polar expeditions and the “heroic age” of Antarctic exploration probably merits its own post.  &lt;a href="http://en.wikipedia.org/wiki/Apsley_Cherry-Garrard"&gt;Apsley Cherry-Garrard&lt;/a&gt;’s first-hand account, the aptly-named &lt;a href="http://www.gutenberg.org/ebooks/14363"&gt;The Worst Journey in the World&lt;/a&gt; is also a great read.&lt;/li&gt;
&lt;li&gt;Alfred Lansing, &lt;a href="http://www.amazon.com/gp/product/B001Q3KDMA/?tag=woinbo-20"&gt;Endurance: Shackleton’s Incredible Voyage&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Charles Mann, &lt;a href="http://www.amazon.com/gp/product/B000JMKVE4/?tag=woinbo-20"&gt;1491: New Revelations of the Americas Before Columbus&lt;/a&gt;.  This is maybe &lt;em&gt;the&lt;/em&gt; best history book I’ve ever read.  Interesting facts on almost every page. &lt;/li&gt;
&lt;li&gt;Charles Mann, &lt;a href="http://www.amazon.com/gp/product/B004G606EY/?tag=woinbo-20"&gt;1493: Uncovering the New World Columbus Created&lt;/a&gt;.  Also endlessly fascinating, if not quite as strong as its predecessor.  &lt;/li&gt;
&lt;li&gt;Max Hastings, &lt;a href="http://www.amazon.com/Winstons-War-ebook/dp/B00338QEKQ/?tag=woinbo-20"&gt;Winston’s War: Churchill, 1940-1945&lt;/a&gt;.  I was surprised by how desperate the British plight in WWII was, how impotent they actually were through most of it, and how much it bankrupted the empire.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That will probalby be the last of the non-fiction for a while; I’m just starting &lt;a href="http://www.amazon.com/1Q84-ebook/dp/B004LROUW2/?tag=woinbo-20"&gt;1Q84&lt;/a&gt;, which clocks in at over 900 pages.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-2701981522512627811?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/94Xnj9ova1E" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/2701981522512627811?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/2701981522512627811?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/94Xnj9ova1E/what-ive-been-reading-history.html" title="What I’ve Been Reading (History)" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2011/11/what-ive-been-reading-history.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4ARnc-eip7ImA9WhdTE0U.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-5891978769611294645</id><published>2011-07-10T09:07:00.004-05:00</published><updated>2011-07-11T06:15:47.952-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-11T06:15:47.952-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="standing" /><title>On Switching to a Standing Desk</title><content type="html">&lt;p&gt;About a month ago I decided to try working at a standing desk. Four trashcans, two shelves, and several books later, I created this:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-9QlUnmWkH9U/Thmydn6P4GI/AAAAAAAABEc/2jpjUAjAqo8/s1600/standing%2Bdesk.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/-9QlUnmWkH9U/Thmydn6P4GI/AAAAAAAABEc/2jpjUAjAqo8/s320/standing%2Bdesk.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5627725431375388770" /&gt;&lt;/a&gt;
&lt;p&gt;Despite its humble appearance, it functioned beautifully.  It's since been replaced by an honest, actual adjustable-height desk, and I'm still standing and liking it a lot.&lt;/p&gt;

&lt;p&gt;So why did I do this?  This whole idea of standing while working has gotten a lot of talk recently, most prominently in the New York Times article &lt;a href="http://www.flickr.com/photos/marcoarment/3234209861/"&gt;Stand Up While You Read This&lt;/a&gt;.   This &lt;a href="http://jessenoller.com/2011/04/25/switching-to-a-standing-desk-thoughts/"&gt;blog post&lt;/a&gt; by Jesse Noller and &lt;a href="http://5by5.tv/buildanalyze/21"&gt;Episode 21 of Build and Analyze&lt;/a&gt; finally convinced me to give it a shot.&lt;/p&gt;

&lt;p&gt;Here what I was hoping to get out of it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Better posture.&lt;/strong&gt;  Like many people, I tend to slouch in my chair.  I find it easier to keep better posture while standing.  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More active.&lt;/strong&gt;  The thing about standing at a desk is that I'm not just standing -- I'm fidgeting, stepping back and forth, and generally moving around.  This makes me...  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More alert.&lt;/strong&gt;  I tend to get sleepy after lunch.  Having to keep myself upright without the aid of a chair counteracts that.  It keeps me on task.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respect(?)&lt;/strong&gt; When people first come across you using your standing desk, they give you an expression that could either be respect or what's-up-with-that-dude wariness (I can never tell). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My initial goal was to stand nonstop all day.  During my two weeks with the nonadjustable desk, that's all I could do.  It was a good way to get over the initial habit-building hump, but let's just say that by the end of the day, my feet were ... tired.  &lt;/p&gt;

&lt;p&gt;Since I've gotten the adjustable desk, I've settled into a 2/3 standing, 1/3 sitting routine.  Much of what I read recommended just powering through the pain until it gets better, but I find that simply breaking up the standing with an couple of hours of sitting in the middle of the day helps enormously.  &lt;/p&gt;

&lt;p&gt;So, if you want to get started, here's what I recommend:&lt;/p&gt;

&lt;p&gt;Rig something on top of your existing desk.  It's cheap and easy (and fun!).  I used parts scavenged from around the office.  Some have used &lt;a href="http://www.flickr.com/photos/marcoarment/3234209861/"&gt;soft drink cans&lt;/a&gt;.  Adjustable desks are expensive so you want to make sure that you'll actually use it before shelling out.&lt;/p&gt;

&lt;p&gt;As for actually making it a habit, there are two philosophical camps out there. The first camp says that humans are evolved to walk around barefoot and that any pain you experience is just your lazy body getting readjusted to its true evolutionary mode of being.  The other camp recommends getting good insoles and a stress mat, and generally working your way into the whole standing routine.&lt;/p&gt;

&lt;p&gt;I probably fall more in the second camp, but I haven't bought anything special.  I simply wear my normal shoes and sit down when it starts to hurt.  Seems to work for me.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-5891978769611294645?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/Fpg76RkTAa4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/5891978769611294645?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/5891978769611294645?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/Fpg76RkTAa4/on-switching-to-standing-desk.html" title="On Switching to a Standing Desk" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-9QlUnmWkH9U/Thmydn6P4GI/AAAAAAAABEc/2jpjUAjAqo8/s72-c/standing%2Bdesk.jpg" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2011/07/on-switching-to-standing-desk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIEQX0zeCp7ImA9WhZaGEs.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-9081442062808952877</id><published>2011-07-05T06:15:00.002-05:00</published><updated>2011-07-05T06:15:00.380-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-05T06:15:00.380-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Clockster" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Clockster: A Simple Online Countdown Timer</title><content type="html">&lt;p&gt;I've created a small, HTML5 online countdown timer called &lt;a href="http://clockster.net/"&gt;Clockster&lt;/a&gt;.  There's not much to it - you enter a time, the browser starts counting down in big numbers, and then beeps and flashes when time expires.  It has a few interesting features:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It's completely HTML based.  Most of the timers out there are Flash based, because until recently that was really the only way to play audio in the browser (for the beeping).  But now all the major browsers support HTML5 audio, rendering it unnecessary.&lt;/li&gt;
&lt;li&gt;If you resize the window, the numbers resize as well.  So you can either see it from across the room, or make a small clock in the corner of your screen.&lt;/li&gt;
&lt;li&gt;There are controls (pause, restart) on the countdown screen.&lt;/li&gt;
&lt;li&gt;The time is specified in the url.  For example, &lt;a href="http://clockster.net/25minutes/"&gt;http://clockster.net/25minutes/&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The front page or any specific timer can be pinned to the Windows taskbar using Chrome or Internet Explorer.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;On the server, Clockster is written in ASP.NET MVC, and hosted on &lt;a href="http://appharbor.com/"&gt;AppHarbor&lt;/a&gt;.  While the server-side aspect of Clockster is very light weight, I've been nothing but happy with AppHarbor.  Deploying is as simple as pushing your Git or Mercurial repository to AppHarbor, which handles building and deploying the site automatically, usually within a few seconds.  (It's like &lt;a href="http://www.heroku.com"&gt;Heroku&lt;/a&gt;, if you're familiar with it.) For a small app like Clockster, it's completely free.&lt;/p&gt;&lt;p&gt;On the client, &lt;a href="http://clockster.net/"&gt;Clockster&lt;/a&gt; uses &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and &lt;a href="http://www.datejs.com/"&gt;date.js&lt;/a&gt;.  The audio is handled by HTML5 audio, which why you need a modern browser to use it.  (That's the fun of doing a completely non-commercial personal site).&lt;/p&gt;&lt;p&gt;Clockster was also a great opportunity to check out &lt;a href="http://nuget.codeplex.com/"&gt;Nuget&lt;/a&gt;, the .NET package manager.  I'm really impressed. It's obviously heavily inspired by Ruby gems, and it makes installing all sorts of project dependencies (like jQuery and Elmah) really easy.&lt;/p&gt;&lt;p&gt;&lt;a href="http://clockster.net/"&gt;Clockster&lt;/a&gt; was a fun project and I hope you check it out.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-9081442062808952877?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/hNPhKu1DlGI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/9081442062808952877?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/9081442062808952877?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/hNPhKu1DlGI/clockster-simple-online-countdown-timer.html" title="Clockster: A Simple Online Countdown Timer" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2011/07/clockster-simple-online-countdown-timer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcGRn07cCp7ImA9Wx9SGE4.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-299070843448431901</id><published>2010-12-08T12:47:00.001-06:00</published><updated>2010-12-08T12:47:07.308-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-08T12:47:07.308-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Wordcycler" /><title>NReadability</title><content type="html">&lt;p&gt;I just released &lt;a href="http://www.wordcycler.com/"&gt;Wordcycler 1.4&lt;/a&gt;. The only change is that Wordcycler will now fetch every page of multi-page articles, which has been a long-time user request.&lt;/p&gt;  &lt;p&gt;If you're a frequent Instapaper user, you might ask why it has taken so long when &lt;a href="http://www.instapaper.com"&gt;Instapaper&lt;/a&gt; itself has been doing this for a while. The answer is that Wordcycler, since version 1.2, doesn't pull the article text from Instapaper.com; instead it pulls each articles from its original site and cleans it locally. I do that to avoid slamming Instapaper with hundreds of requests at once (you'd be surprised how many people maintain 400-item reading lists). &lt;/p&gt;  &lt;p&gt;The technology behind Wordcycler's page cleaning is &lt;a href="http://code.google.com/p/nreadability/"&gt;NReadability&lt;/a&gt;, an open-source C# port of the Javascript &lt;a href="http://lab.arc90.com/experiments/readability/"&gt;Readability bookmarklet&lt;/a&gt;. It strips away all the non-article content of a web page, and cleans up the formatting - just like Instapaper's text view.&amp;#160; &lt;/p&gt;  &lt;p&gt;NReadability is maintained by Marek Stój, and powers his &lt;a href="http://instafetch.immortal.pl/"&gt;Instafetch&lt;/a&gt; app for Android and Windows Phone 7. I was extremely lucky to find NReadability - he posted it a mere days before Instapaper stepped up its rate limiting, which broke any Wordcycler version prior to 1.2. I plugged it in to my code was able to release a repaired version 1.2 almost immediately. &lt;/p&gt;  &lt;p&gt;The one thing NReadability didn't do was fetch multipage articles, so porting that from readability.js was my side project for a few weeks in November. About a week ago, Marek accepted my patch and released version 1.3.1.0. I’m happy I was able to contribute back to this great project.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-299070843448431901?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/sGgYROqwyEQ" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/299070843448431901?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/299070843448431901?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/sGgYROqwyEQ/nreadability.html" title="NReadability" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2010/12/nreadability.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4NQHw9eyp7ImA9Wx5WEUw.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-2247560514507020490</id><published>2010-09-21T20:29:00.001-05:00</published><updated>2010-09-21T20:29:51.263-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-21T20:29:51.263-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tech notes" /><category scheme="http://www.blogger.com/atom/ns#" term="emacs" /><title>Making Emacs Server Play Nice With Windows</title><content type="html">&lt;p&gt;Some people like to use Emacs for everything, even &lt;a href="http://julien.danjou.info/google-maps-el.html"&gt;Google Maps&lt;/a&gt;. That's way too much for me, but I do like to have Emacs available with a minimum of fuss. Here are two tricks that I use to make that happen: (1) creating a right-click &amp;quot;Edit in Emacs&amp;quot; menu item in Windows Explorer, and (2) open the current file in Visual Studio in Emacs. I originally attempted this a while ago, hit a wall, and gave up. I just got it working, so I wanted to write up what I did. &lt;/p&gt;  &lt;p&gt;If Emacs were a normal Windows program, this would be easy, but it predates Windows by over a decade so I guess it gets to play by it's own rules. In order to open a file in an already running instance of Emacs, you have to use the Emacs client executable, and not the regular Emacs executable. The client connects to a server running in Emacs, which you have to explicitly start. &lt;/p&gt;  &lt;p&gt;(The following instructions are all a distillation of the instructions available from the &lt;a href="http://www.emacswiki.org/emacs/EmacsClient#toc11"&gt;Emacs Wiki&lt;/a&gt;.) &lt;/p&gt;  &lt;p&gt;First, add this to your .emacs: &lt;/p&gt;  &lt;pre&gt;(require 'server) 
(server-start)&lt;/pre&gt;

&lt;p&gt;This will start the server when Emacs starts. To make things even more fun, this sometimes fails on Windows 7. See &lt;a href="http://stackoverflow.com/questions/885793/emacs-error-when-calling-server-start/1313577#1313577"&gt;here&lt;/a&gt; for a solution. &lt;/p&gt;

&lt;h2&gt;Windows Explorer&lt;/h2&gt;

&lt;p&gt;We're going to add a right-click menu to Windows Explorer labeled &amp;quot;Open with Emacs,&amp;quot; which does exactly what it says it does. &lt;/p&gt;

&lt;p&gt;The next step is to edit the registry. Here's how: &lt;/p&gt;

&lt;p&gt;1. Open up the Registry Editor (Windows-R, type &amp;quot;regedit&amp;quot;). 
  &lt;br /&gt;2. Create a new key [HKEY_CLASSES_ROOT\*\Shell\Edit in Emacs\Command]. 

  &lt;br /&gt;3. Set the value of the command to &amp;quot;C:\Program Files\emacs-23.2\bin\emacsclientw.exe&amp;quot; -na &amp;quot;C:\Program Files\emacs-23.2\bin\runemacs.exe&amp;quot; &amp;quot;%1&amp;quot; (adjusting the paths as necessary).&lt;/p&gt;
&lt;center&gt;&lt;a href="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcAjeH7RI/AAAAAAAAA-U/TsH6imP3-w4/s1600-h/registry%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="registry" border="0" alt="registry" src="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcBJV9MHI/AAAAAAAAA-Y/iZIhKQc4dP4/registry_thumb%5B2%5D.png?imgmax=800" width="513" height="201" /&gt;&lt;/a&gt;&lt;/center&gt;

&lt;p&gt;And that's it. This first attempts to open the file with a running Emacs server, but if there isn't one (i.e. Emacs isn't running), then it opens a completely new instance (that's what the &amp;quot;-na&amp;quot; option is for). If you normally launch Emacs with a batch file (which is common), the –na argument can point to that instead.&lt;/p&gt;

&lt;h2&gt;Visual Studio&lt;/h2&gt;

&lt;p&gt;Sometimes when editing a file in Visual Studio, I want to punt the file to Emacs for a bit and work on it there. Fortunately, it's really easy to call the Emacs client from what's called an External Tool in Visual Studio. You can even assign it a keyboard shortcut, such as C-k,C-e, and bam, the file is opened in Emacs. &lt;/p&gt;

&lt;p&gt;The theory is the same as before, but the details are a bit different. Go to Tools &amp;gt; External Tools, and Add a new tool with the following configuration: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Title: Edit In Emacs 
    &lt;br /&gt;Command: C:\Program Files\emacs-23.2\bin\emacsclientw.exe 

    &lt;br /&gt;Arguments: –na &amp;quot;C:\Program Files emacs-23.2\bin\runemacs.exe&amp;quot; &amp;quot;$(ItemPath)&amp;quot; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcBg0_r5I/AAAAAAAAA-c/5GM7Rvu_xA4/s1600-h/visual_studio_external_tools%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="visual_studio_external_tools" border="0" alt="visual_studio_external_tools" src="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcB_xutcI/AAAAAAAAA-g/Hp3pic8qJJY/visual_studio_external_tools_thumb%5B2%5D.png?imgmax=800" width="475" height="464" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now, when you go to Tools &amp;gt; Edit in Emacs, the current file should appear in Emacs. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_RxnSdqnpnDs/TJlcCJDUPnI/AAAAAAAAA-k/rpU25qnM7aw/s1600-h/visual_studio_menu%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="visual_studio_menu" border="0" alt="visual_studio_menu" src="http://lh6.ggpht.com/_RxnSdqnpnDs/TJlcCXvnUMI/AAAAAAAAA-o/lBIaiAz1trI/visual_studio_menu_thumb%5B2%5D.png?imgmax=800" width="339" height="187" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To assign this to a keyboard shortcut, go to Tools &amp;gt; Options, then Environment &amp;gt; Keyboard. In the &amp;quot;Show commands containing&amp;quot; text box, type in &amp;quot;externalcommand.&amp;quot; You'll see a bunch of options that look like this: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_RxnSdqnpnDs/TJlcC0JgkXI/AAAAAAAAA-s/35ImWhGSZj8/s1600-h/visual_studio_keyboard%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="visual_studio_keyboard" border="0" alt="visual_studio_keyboard" src="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcDp-75KI/AAAAAAAAA-w/CpxAZOGdpH0/visual_studio_keyboard_thumb%5B2%5D.png?imgmax=800" width="492" height="444" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As you can tell, this is more complicated than it needs to be. Each &amp;quot;Tools.ExternalCommandX&amp;quot; entry corresponds to an external tool. The number matches the position on the external tools list. In other words, if I made &amp;quot;Edit in Emacs&amp;quot; the first external tool, then I would use &amp;quot;Tools.ExternalCommand1.&amp;quot; Choose that, put your cursor in &amp;quot;Press shortcut keys,&amp;quot; type your keyboard shortcut (C-k, C-e), and press &amp;quot;Assign.&amp;quot; That's it.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-2247560514507020490?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/imh0DH6RYQk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/2247560514507020490?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/2247560514507020490?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/imh0DH6RYQk/making-emacs-server-play-nice-with.html" title="Making Emacs Server Play Nice With Windows" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_RxnSdqnpnDs/TJlcBJV9MHI/AAAAAAAAA-Y/iZIhKQc4dP4/s72-c/registry_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2010/09/making-emacs-server-play-nice-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UEQXo6cSp7ImA9WxFUGE0.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-6890450952448246102</id><published>2010-06-29T06:00:00.000-05:00</published><updated>2010-06-29T06:00:00.419-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-29T06:00:00.419-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Wordcycler" /><title>Announcing Wordcycler</title><content type="html">&lt;p&gt;Earlier this year, &lt;a href="http://blog.zottmann.org/"&gt;Carlo Zottmann&lt;/a&gt; released a little program called &lt;a href="http://goephemera.com/"&gt;Ephemera&lt;/a&gt;, which gave Mac users the ability to synchronize articles between &lt;a href="http://www.instapaper.com/"&gt;Instapaper.com&lt;/a&gt; and their USB e-book reader. I heard nothing but great things about Ephemera, and I really wanted to use it myself. But I'm a PC, not a Mac, so I was out of luck.&lt;/p&gt;  &lt;p&gt;But that’s nothing a bit of code couldn’t fix. So a few months of weekend hacking later, I'm happy to announce &lt;a href="http://www.wordcycler.com/"&gt;Wordcycler&lt;/a&gt;, which brings two-way Instapaper syncing goodness to Windows. &lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="wordcycler" border="0" alt="wordcycler" src="http://lh5.ggpht.com/_RxnSdqnpnDs/TClLahG9IrI/AAAAAAAAA9M/bpyPzh8sZq0/wordcycler7.png?imgmax=800" width="341" height="68" /&gt;So what is &lt;a href="http://www.wordcycler.com/"&gt;Wordcycler&lt;/a&gt;? &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Wordcycler lives in your tray. When you connect your reader via USB, Wordcycler fetches your unread Instapaper items, saves them on the device as single articles, and (if you want) ejects it. All automatically and in seconds.&lt;/p&gt;    &lt;p&gt;When you finish reading an article, delete it from your reader, and it will be archived on Instapaper.com the next time you sync. And any articles that you read and archived on Instapaper.com in the meantime will be deleted from the reader as well.&lt;/p&gt;    &lt;p&gt;Wordcycler can also download the pre-made all-in-one bundles available from Instapaper. Either way you choose to consume, Wordcycler is the fast, easy, Whispernet-charge-free way of experiencing Instapaper on your reading device.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;If this kind of thing interests you, please check it out. I'd love to hear your feedback, bug reports, etc. I plan to keep adding features in the coming weeks (support for Instapaper's folders being the big no-brainer.)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-6890450952448246102?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/HXc2gfP2WlU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6890450952448246102?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6890450952448246102?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/HXc2gfP2WlU/announcing-wordcycler.html" title="Announcing Wordcycler" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_RxnSdqnpnDs/TClLahG9IrI/AAAAAAAAA9M/bpyPzh8sZq0/s72-c/wordcycler7.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2010/06/announcing-wordcycler.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQBQnw_eSp7ImA9WxBaE0k.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-167464511594177489</id><published>2010-03-23T06:39:00.001-05:00</published><updated>2010-03-23T06:39:13.241-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-23T06:39:13.241-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="xquery" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="XSLT" /><title>XSpec 0.2 Released</title><content type="html">&lt;p&gt;Last week, a new version of &lt;a href="http://code.google.com/p/xspec/"&gt;XSpec&lt;/a&gt;, an open-source unit-testing framework for XSLT (and now XQuery) was released.&amp;#160; XSpec allows you to write test suites (called scenarios) to test XSLT functions and templates and XQuery functions.&amp;#160; &lt;/p&gt;  &lt;p&gt;It’s good stuff.&amp;#160; If you do any work with these technologies, I recommend checking out the &lt;a href="http://code.google.com/p/xspec/wiki/GettingStarted"&gt;Getting Started&lt;/a&gt; guide and the &lt;a href="http://code.google.com/p/xspec/wiki/UserGuide"&gt;User Guide&lt;/a&gt; for an introduction.&amp;#160; &lt;/p&gt;  &lt;p&gt;I’m particularly excited about this release because I’m involved in the project – well, in a bit part anyway, mainly providing testing and documentation.&amp;#160; The overwhelming bulk of the credit for the new release is due to &lt;a href="http://www.fgeorges.org/"&gt;Florent Georges&lt;/a&gt;, who has really kicked the project back into gear and has rewritten the core functionality to support XQuery in addition to XSLT.&amp;#160; After a year of dormancy, both development and the &lt;a href="http://groups.google.com/group/xspec-users"&gt;mailing list&lt;/a&gt; are active, which means that XSpec will continue to improve.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-167464511594177489?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/Z-unkkYy5Dk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/167464511594177489?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/167464511594177489?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/Z-unkkYy5Dk/xspec-02-released.html" title="XSpec 0.2 Released" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2010/03/xspec-02-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENRXk9cSp7ImA9WxBUE0o.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-1596252168366768209</id><published>2010-02-28T10:48:00.001-06:00</published><updated>2010-02-28T10:48:14.769-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-28T10:48:14.769-06:00</app:edited><title>George Orwell on Writing and Thinking</title><content type="html">&lt;p&gt;From &lt;a href="http://www.orwell.ru/library/essays/politics/english/e_polit"&gt;&lt;em&gt;Politics and the English Language&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A scrupulous writer, in every sentence that he writes, will ask himself at least four questions, thus: 1. What am I trying to say? 2. What words will express it? 3. What image or idiom will make it clearer? 4. Is this image fresh enough to have an effect? And he will probably ask himself two more: 1. Could I put it more shortly? 2. Have I said anything that is avoidably ugly? But you are not obliged to go to all this trouble. You can shirk it by simply throwing your mind open and letting the ready-made phrases come crowding in. They will construct your sentences for you – even think your thoughts for you, to a certain extent – and at need they will perform the important service of partially concealing your meaning even from yourself. &lt;/p&gt;    &lt;p&gt;… &lt;/p&gt;    &lt;p&gt;What is above all needed is to let the meaning choose the word, and not the other way around. In prose, the worst thing one can do with words is surrender to them. When you think of a concrete object, you think wordlessly, and then, if you want to describe the thing you have been visualizing you probably hunt about until you find the exact words that seem to fit it. When you think of something abstract you are more inclined to use words from the start, and unless you make a conscious effort to prevent it, the existing dialect will come rushing in and do the job for you, at the expense of blurring or even changing your meaning. Probably it is better to put off using words as long as possible and get one's meaning as clear as one can through pictures and sensations. Afterward one can choose -- not simply accept -- the phrases that will best cover the meaning, and then switch round and decide what impressions one's words are likely to make on another person. This last effort of the mind cuts out all stale or mixed images, all prefabricated phrases, needless repetitions, and humbug and vagueness generally. But one can often be in doubt about the effect of a word or a phrase, and one needs rules that one can rely on when instinct fails. I think the following rules will cover most cases: &lt;/p&gt;    &lt;p&gt;(i) Never use a metaphor, simile, or other figure of speech which you are used to seeing in print. &lt;/p&gt;    &lt;p&gt;(ii) Never us a long word where a short one will do. &lt;/p&gt;    &lt;p&gt;(iii) If it is possible to cut a word out, always cut it out. &lt;/p&gt;    &lt;p&gt;(iv) Never use the passive where you can use the active. &lt;/p&gt;    &lt;p&gt;(v) Never use a foreign phrase, a scientific word, or a jargon word if you can think of an everyday English equivalent. &lt;/p&gt;    &lt;p&gt;(vi) Break any of these rules sooner than say anything outright barbarous. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Worth rereading every once and a while.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-1596252168366768209?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/V21eac_UKk4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1596252168366768209?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1596252168366768209?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/V21eac_UKk4/george-orwell-on-writing-and-thinking.html" title="George Orwell on Writing and Thinking" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2010/02/george-orwell-on-writing-and-thinking.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcASX0yeSp7ImA9WxBWFUo.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-3679382033899017814</id><published>2010-02-07T13:14:00.001-06:00</published><updated>2010-02-07T13:14:08.391-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-07T13:14:08.391-06:00</app:edited><title>Switcheroo version 0.4</title><content type="html">&lt;p&gt;I’ve released a &lt;a href="http://bitbucket.org/jasulak/switcheroo/wiki/Home"&gt;new version of Switcheroo&lt;/a&gt;, the humble incremental-search task switcher for Windows.&amp;#160; Changes in this version include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The list that prevents certain windows from appearing in the main window is now editable from the options dialog.&amp;#160; (For example, “Program Manager.”) &lt;/li&gt;    &lt;li&gt;The main window now resizes to the full width and height of the list. &lt;/li&gt;    &lt;li&gt;Fixed a few minor bugs and tested on 32-bit Windows 7. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_RxnSdqnpnDs/S28Q_I-YaOI/AAAAAAAAA3Q/POcAW-HUXvU/s1600-h/screenshot%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="screenshot" border="0" alt="screenshot" src="http://lh6.ggpht.com/_RxnSdqnpnDs/S28Q_xmbDsI/AAAAAAAAA3U/C7BqB_XqXpc/screenshot_thumb%5B2%5D.png?imgmax=800" width="392" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-3679382033899017814?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/wvqaz64f0xk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3679382033899017814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3679382033899017814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/wvqaz64f0xk/switcheroo-version-04.html" title="Switcheroo version 0.4" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_RxnSdqnpnDs/S28Q_xmbDsI/AAAAAAAAA3U/C7BqB_XqXpc/s72-c/screenshot_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2010/02/switcheroo-version-04.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUERHYzfyp7ImA9WxBXFU0.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-7159263194079331209</id><published>2010-01-26T06:00:00.000-06:00</published><updated>2010-01-26T06:00:05.887-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-26T06:00:05.887-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="utilities" /><title>Essential Windows Tools</title><content type="html">&lt;p&gt;When working, I like everything on my computer “just so.”&amp;#160; I want to do things quickly and with minimal mental overhead.&amp;#160; Here’s a list of (developer-centric) tools that make that possible:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;&lt;a href="http://virtuawin.sourceforge.net/"&gt;VirtuaWin&lt;/a&gt;&lt;/strong&gt;. This is hands-down the best &lt;a href="http://en.wikipedia.org/wiki/Virtual_desktop"&gt;virtual desktop&lt;/a&gt; manager for windows.&amp;#160; With a bit of tweaking, you can switch between desktops instantaneously by bumping your mouse pointer at the edge of the screen while holding down the control key.&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.zabkat.com/"&gt;&lt;strong&gt;xplorer2&lt;/strong&gt;&lt;/a&gt;. I use the free “&lt;a href="http://www.zabkat.com/x2lite.htm"&gt;lite&lt;/a&gt;” version.&amp;#160; Great features:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Tabbed views (just like your browser).&amp;#160; Keeps the taskbar clean.&lt;/li&gt;      &lt;li&gt;Filter a directory listing quickly using ctrl-h.&amp;#160; &lt;/li&gt;      &lt;li&gt;When in a folder, pressing F10 and enter starts a command prompt in that folder.&amp;#160; (With a bit more tweaking, get a cygwin bash prompt.)&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://www.cygwin.com/"&gt;&lt;strong&gt;Cygwin + minTTY&lt;/strong&gt;&lt;/a&gt;.&amp;#160; If you spend time on the command prompt, it’s worth it to learn your way around bash.&amp;#160; And MinTTY’s native-windows interface – with fully resizable windows and transparency – is worth the price of admission alone.&amp;#160; I don’t use the built-in command prompt any more, and neither should you. Great features:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Color coded directory listings and grep results.&amp;#160; &lt;/li&gt;      &lt;li&gt;Press control-r and search backwards through your command history. &lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;&lt;a href="http://bitbucket.org/jasulak/switcheroo/wiki/Home"&gt;&lt;strong&gt;Switcheroo&lt;/strong&gt;&lt;/a&gt;. Yes, I wrote it, but what of it?&amp;#160; Switching between (and closing) running applications using incremental search keeps me from reaching for the mouse and breaking my concentration. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.bayden.com/SlickRun/"&gt;&lt;strong&gt;Slickrun&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&amp;#160; A floating, auto-completing prompt that lets you quickly open programs, folders, and websites.&amp;#160; With some batch-script ingenuity, the possibilities are endless.&amp;#160; For example, I can type “vup” or “vdown” to quickly adjust the volume.&amp;#160; Or “newmail” to write a new e-mail in Outlook.&amp;#160; For most commands, I only have to type the first few letters. Set up tip: change the colors, make the font larger, and set it to autohide and chase your mouse cursor.&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.gnu.org/software/emacs/"&gt;&lt;strong&gt;Emacs&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt; The One True Editor.&amp;#160; Learning it is a commitment, but worth it.&amp;#160; If you take the plunge, grab &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897578.aspx"&gt;Ctrl2Cap&lt;/a&gt; and remap your caps lock key as another control key.&amp;#160; With a bit of setup, plays very well with Cygwin.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.winsplit-revolution.com/"&gt;&lt;strong&gt;Winsplit Revolution&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&amp;#160; Not as essential with Windows 7’s built-in window positioning, but the fusion mode is still great.&amp;#160; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://passwordsafe.sourceforge.net/"&gt;&lt;strong&gt;Password Safe&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&amp;#160; Securely encrypt a list of all your passwords.&amp;#160; Now you only have to remember one, which lets you online banking passwords more complex and harder to brute-force.&amp;#160; And you’ll stop using the same one everywhere.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-7159263194079331209?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/mPbYn0h8Idg" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7159263194079331209?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7159263194079331209?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/mPbYn0h8Idg/essential-windows-tools.html" title="Essential Windows Tools" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2010/01/essential-windows-tools.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YEQ308eCp7ImA9WxBXEUs.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-3140334346609202719</id><published>2010-01-22T08:05:00.001-06:00</published><updated>2010-01-22T08:05:02.370-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-22T08:05:02.370-06:00</app:edited><title>Knowledge and productivity are like compound interest</title><content type="html">&lt;blockquote&gt;   &lt;p&gt;What Bode was saying was this: ``Knowledge and productivity are like compound interest.'' Given two people of approximately the same ability and one person who works ten percent more than the other, the latter will more than twice outproduce the former. The more you know, the more you learn; the more you learn, the more you can do; the more you can do, the more the opportunity - it is very much like compound interest. I don't want to give you a rate, but it is a very high rate. Given two people with exactly the same ability, the one person who manages day in and day out to get in one more hour of thinking will be tremendously more productive over a lifetime.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#8211; Richard Hammin, in &lt;em&gt;&lt;a href="http://www.cs.virginia.edu/~robins/YouAndYourResearch.html"&gt;You and Your Research&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-3140334346609202719?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/t0iS3JCUhAs" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3140334346609202719?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3140334346609202719?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/t0iS3JCUhAs/knowledge-and-productivity-are-like.html" title="Knowledge and productivity are like compound interest" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2010/01/knowledge-and-productivity-are-like.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8EQ3oyfip7ImA9WxNUEU8.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-3644458274866662298</id><published>2009-11-01T20:26:00.001-06:00</published><updated>2009-11-01T20:26:42.496-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-01T20:26:42.496-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="projects" /><category scheme="http://www.blogger.com/atom/ns#" term="exist-db" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="xproc" /><category scheme="http://www.blogger.com/atom/ns#" term="Switcheroo" /><title>Recent Projects</title><content type="html">&lt;p&gt;It's been a while since I've written here.&amp;nbsp; In the interim, I've completed a few different small projects.&amp;nbsp; Here they are in no particular order:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;&lt;a href="http://bitbucket.org/jasulak/switcheroo"&gt;Switcheroo&lt;/a&gt;.&amp;nbsp; The humble incremental-search task switcher for Windows.&lt;/p&gt; &lt;p&gt;I wrote this partly to learn a bit of WPF, and partly to scratch my own itch. I got tired of alt-tabbing through a (long) list of open windows, and really wanted something like Emacs's IDO mode buffer switching.&amp;nbsp; This little program allows me to quickly switch to any window by typing in just a few characters of its title. &lt;/p&gt; &lt;li&gt; &lt;p&gt;&lt;a href="http://bitbucket.org/jasulak/exist-xproc-library/"&gt;eXist XProc Extension Library&lt;/a&gt;.&amp;nbsp; A set of XProc extension steps for interacting with an eXist XML database from a client. Using these steps, you can conduct common eXist management tasks from XProc - loading resources, extracting resources, querying data, etc. They fill much the same role as the eXist Ant tasks.&lt;/p&gt; &lt;p&gt;I wrote it as an experiment in creating a non-trivial reusable library in pure XProc.&amp;nbsp; I think it came out fairly well.&amp;nbsp; &lt;/p&gt; &lt;li&gt; &lt;p&gt;&lt;a href="http://bitbucket.org/jasulak/ruby-blue-visual-studio-theme"&gt;Ruby Blue Visual Studio theme&lt;/a&gt;.&amp;nbsp; I really liked the various ruby blue themes available for other editors and wanted one for Visual Studio.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-3644458274866662298?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/bsox15xHUJ0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3644458274866662298?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3644458274866662298?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/bsox15xHUJ0/recent-projects.html" title="Recent Projects" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/11/recent-projects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEGRnc5fyp7ImA9WxJQE0U.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-7138620877934548552</id><published>2009-05-26T20:43:00.001-05:00</published><updated>2009-05-26T20:43:47.927-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-26T20:43:47.927-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="xproc" /><title>XProc Roundup</title><content type="html">&lt;a href="http://www.flickr.com/photos/st3f4n/1419405808/"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="1419405808_7dff1fea23_m" src="http://lh3.ggpht.com/_RxnSdqnpnDs/Shya037r_8I/AAAAAAAAAxs/Q944uulLNZI/1419405808_7dff1fea23_m%5B5%5D.jpg?imgmax=800" width="184" align="right" border="0"&gt;&lt;/a&gt;  &lt;p&gt;Interest in XProc has really picked up recently, which is exciting to see.&amp;nbsp; Here's a roundup of some of the recent activity: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="https://community.emc.com/docs/DOC-3337"&gt;XProc: Step by Step&lt;/a&gt;. Vojtech Toman (who's working on EMC's Calumet implementation) wrote a great introduction to XProc.&amp;nbsp; Calumet itself is scheduled to be released under a developer's license on &lt;a href="https://community.emc.com/docs/DOC-3139"&gt;June 15&lt;/a&gt;.&amp;nbsp; I don't use any of EMC's products, but it's encouraging that such a big player in the market is embracing XProc.  &lt;li&gt;&lt;a href="http://www.xfront.com/xproc/"&gt;XProc Tutorial&lt;/a&gt;.&amp;nbsp; Roger Costello updated his excellent tutorial.&amp;nbsp; It's a bit of a shame that it's in PowerPoint, but it's well organized and comes with several sample scripts.  &lt;li&gt;&lt;a href="http://efasoft.blogspot.com/2009/05/why-xproc-rocks.html"&gt;Why XProc Rocks&lt;/a&gt;.&amp;nbsp; Joel Amoussou talks about XProc and news publishing.  &lt;li&gt;&lt;a href="http://plindenbaum.blogspot.com/2009/05/xml-pipelines-xproc-for-bioinformatics.html"&gt;XML Pipelines / XProc for bioinformatics&lt;/a&gt;. Pierre Lindenbaum describes an interesting use of XProc.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The XProc spec is tantalizingly close to making the transition to proposed recommendation, and all the recent (and positive) attention makes me optimistic that XProc will be a standard that's actually &lt;em&gt;used&lt;/em&gt; in the real world.&amp;nbsp; &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-7138620877934548552?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/naHzXayEUm8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7138620877934548552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7138620877934548552?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/naHzXayEUm8/xproc-roundup.html" title="XProc Roundup" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_RxnSdqnpnDs/Shya037r_8I/AAAAAAAAAxs/Q944uulLNZI/s72-c/1419405808_7dff1fea23_m%5B5%5D.jpg?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2009/05/xproc-roundup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcDQngzeip7ImA9WxVUEks.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-8227232940694569293</id><published>2009-03-16T22:21:00.001-05:00</published><updated>2009-03-16T22:21:13.682-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-16T22:21:13.682-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="xproc" /><category scheme="http://www.blogger.com/atom/ns#" term="XSLT" /><title>Debugging XProc Pipelines</title><content type="html">&lt;p&gt;As I've worked more with XProc, I've written a couple of utility steps to help debug pipelines.&amp;nbsp; Although they started as quick hacks, they've continued helping out long enough to be worth sharing.&amp;nbsp; You can download the library &lt;a href="http://dl.getdropbox.com/u/410195/debug.xpl"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The more interesting of those is a step (wxp:assert) which asserts that the result of a given XPath expression evaluated against one document must be equal that that of a second XPath evaluated against a second document.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Practically speaking, I can assert that the output from a step must match certain expectations.&amp;nbsp; If this assertion is met, the wxp:assert step functions just like a p:identity step, passing XML through its primary input to its primary output without modification.&amp;nbsp; If the assertion fails, the step sends an error message to the console, and optionally throws an XProc error and terminates pipeline execution.&amp;nbsp; &lt;/p&gt; &lt;p&gt;For example, here's an excerpt from an upconversion pipeline:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;group-sections&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;stylesheet&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:document &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;group-sections.xslt&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;wxp:debug-output &lt;/span&gt;&lt;span style="color: red"&gt;step-name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;6-sections-grouped&lt;/span&gt;" &lt;span style="color: red"&gt;debug&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;true&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;

&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;wxp:assert &lt;/span&gt;&lt;span style="color: red"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;No sections were deleted during grouping&lt;/span&gt;" 
            &lt;span style="color: red"&gt;xpath-source&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;count(.//subsection)&lt;/span&gt;"
            &lt;span style="color: red"&gt;xpath-alternate&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;count(.//*[self::sect-1 | self::sect-2 | 
                             self::sect-3 | self::sect-4])&lt;/span&gt;" 
            &lt;span style="color: red"&gt;fail-on-error&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;false&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;alternate&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipe &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;result&lt;/span&gt;" 
            &lt;span style="color: red"&gt;step&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;parse-initial-subsections&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;wxp:assert&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;

&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;(This also shows the wxp:debug-output step, which has probably been rendered obsolete by the latest version of Calabash.&amp;nbsp; It simply functions as a p:identity step that also writes the XML it receives to disk for later review.)&lt;/p&gt;
&lt;p&gt;This instance of wxp:assert asserts that the number of subsection elements in the primary &lt;em&gt;source &lt;/em&gt;input port matches the number of sect-1 and sect-2 elements on the &lt;em&gt;alternate&lt;/em&gt; input port.&amp;nbsp; The &lt;em&gt;source&lt;/em&gt; document is produced by the preceding step, and the &lt;em&gt;alternate&lt;/em&gt; document is piped in from a step earlier in the pipeline.&amp;nbsp; This is a quick way to ensure I don't do anything too lame-brained in the "group sections" step.&lt;/p&gt;
&lt;p&gt;Here's another instance from the same upconversion pipeline.&amp;nbsp; This tests the output from a XSLT step that uses regular expressions to parse out section numbers from title elements. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;wxp:assert &lt;/span&gt;&lt;span style="color: red"&gt;label&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;No empty enums after parsing sections&lt;/span&gt;"
    &lt;span style="color: red"&gt;xpath-source&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;count(.//enum[not(.//text()[string-length(normalize-space(.)) gt 0])])&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xpath-alternate&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;0&lt;/span&gt;"
    &lt;span style="color: red"&gt;fail-on-error&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;true&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;In this case, the &lt;em&gt;alternate&lt;/em&gt; XPath expression is a constant (0), so I don't need to provide a document on the &lt;em&gt;alternate&lt;/em&gt; port.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Using wxp:assert steps does slow down a pipline, so I usually remove them once I finish debugging the pipeline.&amp;nbsp; The major exception to this rule is that I leave them active in upconversion pipelines where manual intervention is acceptable and accuracy is more important than speed.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;There are a few interesting in the step's &lt;a href="http://dl.getdropbox.com/u/410195/debug.xpl"&gt;source&lt;/a&gt; worth checking out.&amp;nbsp; Here's a summary of how wxp:assert works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It combines the two source documents into a single document using p:pack. &lt;/li&gt;
&lt;li&gt;That is passed to an XSL stylesheet, which uses the saxon:evaluate extension function to evalutate the two XPaths against their respective nodesets.&amp;nbsp; &lt;/li&gt;
&lt;li&gt;Depending on the value of the fail-on-error option, throw an XProc error and terminate the pipeline.&lt;/li&gt;
&lt;li&gt;Use a final p:identity step to pipe the initial input from the step's &lt;em&gt;source&lt;/em&gt; port to its &lt;em&gt;result&lt;/em&gt; port.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Or course, using a Saxon extension function does tie the pipeline to Calabash (or at least, a Saxon-based processor). I'm interested in hearing ideas about alternate approaches. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-8227232940694569293?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/PMSBVabIqes" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/8227232940694569293?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/8227232940694569293?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/PMSBVabIqes/debugging-xproc-pipelines.html" title="Debugging XProc Pipelines" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/03/debugging-xproc-pipelines.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEAQ3ozfSp7ImA9WxVXE0Q.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-1715262195865978774</id><published>2009-02-11T18:25:00.003-06:00</published><updated>2009-02-11T18:30:42.485-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-11T18:30:42.485-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XSpec" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="XSLT" /><title>Code Review:  Commenting XSLT Regular Expressions</title><content type="html">&lt;p&gt;You learn a lot from reading other people's code.&amp;#160; For example, the other day I ran into a &lt;a href="http://code.google.com/p/xspec/source/browse/trunk/coverage-report.xsl?spec=svn35&amp;amp;r=35"&gt;clever trick&lt;/a&gt; in Jeni Tennison's &lt;a href="http://code.google.com/p/xspec/"&gt;XSpec&lt;/a&gt; code for commenting regular expressions in XSLT: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style=" color: #a31515"&gt;xsl:variable &lt;/span&gt;&lt;span style=" color: red"&gt;name&lt;/span&gt;&lt;span style=" color: blue"&gt;=&lt;/span&gt;&lt;span &gt;&amp;quot;&lt;/span&gt;&lt;span style=" color: blue"&gt;attribute-regex&lt;/span&gt;&lt;span &gt;&amp;quot; &lt;/span&gt;&lt;span style=" color: red"&gt;as&lt;/span&gt;&lt;span style=" color: blue"&gt;=&lt;/span&gt;&lt;span &gt;&amp;quot;&lt;/span&gt;&lt;span style=" color: blue"&gt;xs:string&lt;/span&gt;&lt;span &gt;&amp;quot;&lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style=" color: #a31515"&gt;xsl:value-of&lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;gt;
    &lt;/span&gt;&lt;span &gt;\s+
    (\S+)        &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;1: the name of the attribute &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
    &lt;/span&gt;&lt;span &gt;\s*
    =
    \s*
    (       &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;2: the value of the attribute (with quotes) &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
      &lt;/span&gt;&lt;span &gt;&amp;quot;([^&amp;quot;]*)&amp;quot;  &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;3: the value without quotes &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
      &lt;/span&gt;&lt;span &gt;|
      '([^']*)'  &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;4: also the value without quotes &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
    &lt;/span&gt;&lt;span &gt;)
  &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style=" color: #a31515"&gt;xsl:value-of&lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style=" color: #a31515"&gt;xsl:variable&lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The trick is the &amp;lt;xsl:value-of /&amp;gt; instruction, which casts its contents as a string.&amp;#160; An especially nice thing about this method is that you can refer to other variables within the declaration:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span &gt;   (\S+)    &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;12: the name of the element being opened &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
   &lt;/span&gt;&lt;span &gt;(        &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;13: the attributes of the element &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
     &lt;/span&gt;&lt;span &gt;(      &lt;/span&gt;&lt;span style=" color: blue"&gt;&amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;14: wrapper for the attribute regex &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
       &amp;lt;&lt;/span&gt;&lt;span style=" color: #a31515"&gt;xsl:value-of &lt;/span&gt;&lt;span style=" color: red"&gt;select&lt;/span&gt;&lt;span style=" color: blue"&gt;=&lt;/span&gt;&lt;span &gt;&amp;quot;&lt;/span&gt;&lt;span style=" color: blue"&gt;$attribute-regex&lt;/span&gt;&lt;span &gt;&amp;quot; &lt;/span&gt;&lt;span style=" color: blue"&gt;/&amp;gt;  &amp;lt;!-- &lt;/span&gt;&lt;span style=" color: green"&gt;15-18 attribute stuff &lt;/span&gt;&lt;span style=" color: blue"&gt;--&amp;gt;
     &lt;/span&gt;&lt;span &gt;)*
   )&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Of course, to ignore all the extra white space in a regex constructed this way, you'll need to set the &amp;quot;x&amp;quot; &lt;a href="http://www.w3.org/TR/xpath-functions/#regex-syntax"&gt;flag&lt;/a&gt; in any &amp;lt;xsl:analyze-string /&amp;gt;, replace(), or matches() that refers to it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-1715262195865978774?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/0gWAY38cPxk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1715262195865978774?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1715262195865978774?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/0gWAY38cPxk/code-review-commenting-xslt-regular.html" title="Code Review:  Commenting XSLT Regular Expressions" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/02/code-review-commenting-xslt-regular.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAARn4yeSp7ImA9WxVQF0Q.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-7464698624766258441</id><published>2009-02-04T19:35:00.001-06:00</published><updated>2009-02-04T19:35:47.091-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-04T19:35:47.091-06:00</app:edited><title>“Broken gets fixed. Shoddy lasts forever”</title><content type="html">&lt;p&gt;&lt;a href="http://designaday.tumblr.com/post/75496791/truism"&gt;Jack Moffett&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;One of the developers I work with said this after I complained about a lingering issue in one of our products. It rings true. When deadlines are tight, and there is more work to get done than there are developers or hours in the schedule, it’s not the squeaky wheel, but the jammed one that gets the grease. The lesson, then, is to make sure it gets done right the first time. You never know when you’ll have the opportunity to revisit it.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;(via &lt;a href="http://daringfireball.net/linked/2009/02/04/broken-shoddy"&gt;Daring Fireball&lt;/a&gt;)&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-7464698624766258441?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/aFeKTAD31Rw" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7464698624766258441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/7464698624766258441?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/aFeKTAD31Rw/broken-gets-fixed-shoddy-lasts-forever.html" title="“Broken gets fixed. Shoddy lasts forever”" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/02/broken-gets-fixed-shoddy-lasts-forever.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUBRnw7cSp7ImA9WxVRFU0.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-4250177642802158677</id><published>2009-01-20T21:07:00.001-06:00</published><updated>2009-01-20T21:07:37.209-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-20T21:07:37.209-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Alan Kay" /><title>Stark and Adjustable Meanings</title><content type="html">&lt;p&gt;An interview of &lt;a href="http://queue.acm.org/detail.cfm?id=1039523"&gt;Alan Kay&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;But at PARC our idea was, since you never step in the same river twice, the number-one thing you want to make the user interface be is a learning environment—something that’s explorable in various ways, something that is going to change over the lifetime of the user using this environment. New things are going to come on, and what does it mean for those new things to happen? &lt;p&gt;... Even if the user is an absolute expert, able to remember almost everything, I’m always interested in the difference between what you might call stark meaning and adjustable meaning. &lt;p&gt;I did quite a bit of study on that over the years to understand the influence of having something that you can read. It’s known that our basic language mechanism for both reading and hearing has a fast and a slow process. The fast process has basically a surface phrasal-size nature, and then there’s a slower one. This is why jokes require pauses; the joke is actually a jump from one context to another, and the slower guy, who is dealing with the real meanings, has to catch up to it. &lt;p&gt;There have been many, many studies of this. This argues that the surface form of a language, whatever it is, has to be adjustable in some form.&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-4250177642802158677?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/ld_c3GMIhSk" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4250177642802158677?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4250177642802158677?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/ld_c3GMIhSk/stark-and-adjustable-meanings.html" title="Stark and Adjustable Meanings" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/01/stark-and-adjustable-meanings.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBRn85fCp7ImA9WxVSFkQ.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-4522880298398231011</id><published>2009-01-11T10:09:00.001-06:00</published><updated>2009-01-11T10:09:17.124-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-11T10:09:17.124-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tim O'Reilly" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title>Money Is Gas in the Car</title><content type="html">&lt;p&gt;&lt;a href="http://radar.oreilly.com/2009/01/work-on-stuff-that-matters-fir.html"&gt;Tim O'Reilly talks about the importance of working on things that are important&lt;/a&gt;, not just things that simply make money:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;First off, though, I want to make clear that "work on stuff that matters" &lt;em&gt;does not mean focusing on non-profit work, "causes, or any other form of "do-goodism."&lt;/em&gt; Non-profit projects often do matter a great deal, and &lt;a href="http://www.computerworld.com/action/article.do?command=viewArticleBasic&amp;amp;taxonomyName=Careers&amp;amp;articleId=330574&amp;amp;taxonomyId=10&amp;amp;intsrc=kc_li_story"&gt;people with tech skills can make important contributions&lt;/a&gt;, but it's essential to get beyond that narrow box. I'm a strong believer in the social value of business done right. We need to build an economy in which the important things are paid for in self-sustaining ways rather than as charities to be funded out of the goodness of our hearts. &lt;p&gt;...&lt;/p&gt;&lt;/blockquote&gt; &lt;blockquote&gt; &lt;p&gt;Some of you may end up working at highflying companies. Some of you may succeed, and some of you may fail. I want to remind you that financial success is not the only goal or the only measure of success. It's easy to get caught up in the heady buzz of making money. You should regard money as fuel for what you really want to do, not as a goal in and of itself. &lt;strong&gt;Money is like gas in the car — you need to pay attention or you'll end up on the side of the road —&lt;/strong&gt; &lt;strong&gt;but a well-lived life is not a tour of gas stations!&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-4522880298398231011?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/y5GQV3Q-RnI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4522880298398231011?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4522880298398231011?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/y5GQV3Q-RnI/money-is-gas-in-car.html" title="Money Is Gas in the Car" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/01/money-is-gas-in-car.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AHQH45fSp7ImA9WxVSFEg.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-1521808862087822659</id><published>2009-01-08T18:08:00.001-06:00</published><updated>2009-01-08T18:08:51.025-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-08T18:08:51.025-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dtd" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><title>What's Your Semantic Exit Strategy?</title><content type="html">&lt;p&gt;Quoting &lt;a href="http://www.cafeconleche.org/quotes2009.html#quote2009January7"&gt;Cafe Con Leche&lt;/a&gt; quoting &lt;a href="http://www.alistapart.com/articles/semanticsinhtml5"&gt;A List Apart&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;We&amp;#8217;ll start by posing the question: &amp;#8220;why are we inventing these new elements?&amp;#8221; A reasonable answer would be: &amp;#8220;because HTML lacks semantic richness, and by adding these elements, we increase the semantic richness of HTML&amp;#8212;that can&amp;#8217;t be bad, can it?&amp;#8221; &lt;/p&gt;    &lt;p&gt;By adding these elements, we are addressing the need for greater semantic capability in HTML, but only within a narrow scope. No matter how many elements we bolt on, we will always think of more semantic goodness to add to HTML. And so, having added as many new elements as we like, we still won&amp;#8217;t have solved the problem. We don&amp;#8217;t need to add &lt;strong&gt;specific terms&lt;/strong&gt; to the vocabulary of HTML, we need to add a &lt;strong&gt;mechanism&lt;/strong&gt; that allows semantic richness to be added to a document as required. In technical terms, we need to make HTML &lt;strong&gt;extensible&lt;/strong&gt;. HTML 5 proposes no mechanism for extensibility. &lt;/p&gt;    &lt;p&gt;HTML 5, therefore, implements a feature that breaks a sizable percentage of current browsers, and doesn&amp;#8217;t really allow us to add richer semantics to the language &lt;strong&gt;at all&lt;/strong&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is an important warning for anyone creating or maintaining a custom XML document schema. Creating a tight, semantically correct element for every type of information in your existing documents is easy (and dangerously seductive); creating a mechanism by which the schema's users themselves can gracefully expand the semantic tagging as documents grow is much harder, and ultimately much more important.&amp;#160; Be as general as you can get away with, and as specific as you dare.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-1521808862087822659?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/ib002knUzh4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1521808862087822659?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/1521808862087822659?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/ib002knUzh4/what-your-semantic-exit-strategy.html" title="What&amp;#39;s Your Semantic Exit Strategy?" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2009/01/what-your-semantic-exit-strategy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04EQX08cSp7ImA9WxVSEkk.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-6016016461145529374</id><published>2009-01-06T06:45:00.000-06:00</published><updated>2009-01-06T06:45:00.379-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-06T06:45:00.379-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="utilities" /><title>Lessons from a Windows Reinstall</title><content type="html">&lt;p&gt;The Windows install on my fiancee's laptop, a 3-year-old Gateway, had become unstable and slow (as Windows does if left alone for three years) so it was time to wipe the hard drive and start again.&amp;nbsp; I methodically prepared, backing up all the data to two different locations — Dropbox and an external hard drive.&amp;nbsp; Also, at my father's urging, I created a drive image using the free trial of &lt;a href="http://www.acronis.com/homecomputing/products/trueimage/"&gt;Acronis True Image&lt;/a&gt;, which I stored on an external hard drive.&amp;nbsp; I didn't think I'd need it, because the current install was so horrible that anything was preferable to it. &lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://flickr.com/photos/fatboyke/2668411239/"&gt;&lt;img src="http://farm4.static.flickr.com/3051/2668411239_9c8d7b2342_m.jpg"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;So, I rebooted, I popped in the Gateway system restore disk, and told it to format the drive and reinstall the operating system.&amp;nbsp; &lt;/p&gt; &lt;p&gt;When it was done, the computer booted into Windows.&amp;nbsp; Happy surprise, the restore CD didn't reinstall all of the stupid cruft software that all consumer laptops come loaded with.&amp;nbsp; However, a not-so-happy-surprise — the CD also didn't reinstall any of the Gateway-specific drivers the laptop needed to function, so it couldn't use its wireless card or suspend.&amp;nbsp; &lt;/p&gt; &lt;p&gt;No problem, I thought, I'll get them from the system restore partition on the primary hard drive.&amp;nbsp; Hmm, the restore process repartitioned the drive and killed it.&amp;nbsp; (Really?)&amp;nbsp; Okay, no problem, I'll go to Gateway's website and download the drivers.&amp;nbsp; Hmm, those don't work. (Seriously?) I'll go to the chipset manufacturer's website.&amp;nbsp; Hmm, not there.&amp;nbsp; (Oh, no.)&lt;/p&gt; &lt;p&gt;This problem was entirely my fault.&amp;nbsp; I should have made absolutely sure I had the drivers I needed before wiping the disk, so I'll spare you the whole rant of WHY DOESN'T GATEWAY'S &lt;strong&gt;CUSTOM&lt;/strong&gt; SYSTEM RESTORE DISK CONTAIN THE DRIVERS TO ACTUALLY, YOU KNOW, RESTORE THE SYSTEM?&amp;nbsp; Because, that would be petty.&lt;/p&gt; &lt;p&gt;After some Internet searching, I discovered a free utility called &lt;a href="http://www.boozet.org/dd.htm"&gt;Double Driver&lt;/a&gt;, which allows you to backup and restore all the drivers installed on your system.&amp;nbsp; Which was great, except I'd already killed the Windows installation with the drivers I needed.&amp;nbsp; &lt;/p&gt; &lt;p&gt;To make a long story short, here's what I did:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Created a new drive image of my partially finished reinstall with Acronis True Image.  &lt;li&gt;Restored the original, pre-wipe drive image.  &lt;li&gt;Booted into Windows and ran Double Driver to create an archive of all the installed drivers on my USB drive.  &lt;li&gt;Restored the in-progress drive image.  &lt;li&gt;Used Double Driver to restore all the previously installed drivers.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Success!&amp;nbsp; (Well, Double driver actually missed one file, which I had to retrieve from the backup image.&amp;nbsp; But close enough.)&lt;/p&gt; &lt;p&gt;Also, although Acronis True Image saved the day, I can't recommend it as a product, since its background service slowed to a crawl the two computers I installed it on.&amp;nbsp; Which is too bad.&lt;/p&gt; &lt;p&gt;So, recapping today's lessons, if you're reinstalling Windows, you should first:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Backup all your data.&amp;nbsp; Twice.  &lt;li&gt;Create a drive image of your current install.&amp;nbsp; It will save your bacon.&amp;nbsp; &lt;li&gt;Create an archive of all your drivers using &lt;a href="http://www.boozet.org/dd.htm"&gt;DoubleDriver&lt;/a&gt;.&amp;nbsp; This too will save your bacon. &lt;/li&gt;&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-6016016461145529374?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/0O3RLWwnNP0" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6016016461145529374?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/6016016461145529374?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/0O3RLWwnNP0/lessons-from-windows-reinstall.html" title="Lessons from a Windows Reinstall" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm4.static.flickr.com/3051/2668411239_9c8d7b2342_t.jpg" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2009/01/lessons-from-windows-reinstall.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEAHQXs_fCp7ImA9WxVTFUw.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-4910554757518919946</id><published>2008-12-22T12:11:00.002-06:00</published><updated>2008-12-28T19:05:30.544-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-28T19:05:30.544-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="xproc" /><category scheme="http://www.blogger.com/atom/ns#" term="calabash" /><title>XProc, Part III — Turtles All The Way Down (Steps, Reuse, and Encapsulation)</title><content type="html">&lt;p&gt;This is my third post on &lt;a href="http://xproc.org/"&gt;XProc&lt;/a&gt;. (To see the first two, go &lt;a href="http://www.wordsinboxes.com/2008/11/getting-started-with-xproc-and-calabash.html"&gt;here&lt;/a&gt; and &lt;a href="http://www.wordsinboxes.com/2008/12/getting-started-with-xproc-part-ii.html"&gt;here&lt;/a&gt;.)&amp;nbsp; In this post, I'll talk about the different categories of steps, how to create your own steps and reuse them across pipelines, and how this all relates to the fundamental metaphor of XProc.&amp;nbsp; &lt;/p&gt; &lt;p&gt;One task I do frequently is removing &lt;a href="http://www.arbortext.com/namespace/atict/change-tracking-markup-spec.html"&gt;Arbortext Editor change-tracking markup&lt;/a&gt; from documents. Here's a simple pipeline that does just that:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;u:accept-changes&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;stylesheet&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:document &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;accept_changes.xslt&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The fundamental unit of work in XProc is the "step," which you can think of in the same way you do subroutines in other programming languages. In general, a step takes XML as input, performs an operation on it, and outputs XML. There are &lt;a href="http://www.w3.org/TR/xproc/#step-concept"&gt;three types of steps&lt;/a&gt; in XProc: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://flickr.com/photos/austin80s/2303501094/sizes/l/"&gt;&lt;img height="155" alt="atomic" src="http://lh6.ggpht.com/_RxnSdqnpnDs/SU_YKA4KZ_I/AAAAAAAAAno/ukbRoH5d2_s/image_thumb%5B8%5D.png?imgmax=800" width="256" align="right" border="0"&gt;&lt;/a&gt;Atomic steps.&lt;/strong&gt; These are the most basic building blocks of XProc pipelines, and each carries out a single fundamental XML operation.&amp;nbsp; There are a number of &lt;a href="http://www.w3.org/TR/xproc/#std-components"&gt;built-in atomic steps&lt;/a&gt;, such as &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.pipeline"&gt;p:xslt&lt;/a&gt; (as shown above).&amp;nbsp; These built-in atomic steps will be the foundation for almost everything you do in XProc, so learn them.&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://flickr.com/photos/brapke/186542214/"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="182" alt="image" src="http://lh5.ggpht.com/_RxnSdqnpnDs/SU_YMb6geiI/AAAAAAAAAns/HjrfFG39mIc/image_thumb%5B10%5D.png?imgmax=800" width="244" align="right" border="0"&gt;&lt;/a&gt; &lt;strong&gt;Compound steps.&amp;nbsp; &lt;/strong&gt;These are assembled from other XProc steps.&amp;nbsp; Sometimes they are just a series of implicitly connected atomic steps, and sometimes they use built-in logical control structures, such as &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.for-each"&gt;p:for-each&lt;/a&gt;, to control their execution. &lt;/p&gt;
&lt;p&gt;It turns out that the above accept-changes pipeline — and in fact any pipeline you create — &lt;a href="http://markmail.org/message/dgb6acpf4yulnfh5"&gt;is also a compound step&lt;/a&gt;.&amp;nbsp; (The fact that &lt;a href="http://www.wordsinboxes.com/2008/12/getting-started-with-xproc-part-ii.html"&gt;p:pipeline is a shortcut for p:declare-step&lt;/a&gt; is a dead giveaway.)&amp;nbsp; This is an important idea, and we'll discuss it more below.&amp;nbsp; But for now, remember this:&amp;nbsp; &lt;em&gt;a pipeline and a step are the same thing&lt;/em&gt;.&amp;nbsp; &lt;/p&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Multi-container steps.&lt;/strong&gt;&amp;nbsp; There are only two multi-container steps: &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.choose"&gt;p:choose&lt;/a&gt; and &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.try"&gt;p:try&lt;/a&gt;.&amp;nbsp; These contain two or more alternate pipelines.&amp;nbsp; You cannot define your own custom multi-container step.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;No doubt, in your day-to-day work, you'll never feel the need to stop and consider whether a certain step fits one category or the other.&amp;nbsp; But the difference does have consequences, so it's worth spending a bit of time on it.&lt;/p&gt;
&lt;p&gt;Let's say that you want to use the above accept-changes step as a step within a larger pipeline — for example, a pipeline that removes all of the notes from 2nd-level sections in a document.&amp;nbsp; Here's how you would do that:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;delete-notes&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xmlns:p&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.w3.org/ns/xproc&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xmlns:atict&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;&lt;a href="http://www.arbortext.com/namespace/atict&amp;quot;"&gt;http://www.arbortext.com/namespace/atict&lt;/span&gt;"
&lt;/a&gt;    &lt;span style="color: red"&gt;xmlns:u&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.wordsinboxes.com/xproc&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:serialization &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;result&lt;/span&gt;" &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;" &lt;span style="color: red"&gt;method&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;xml&lt;/span&gt;"  
    &lt;span style="color: red"&gt;omit-xml-declaration&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;false&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;

  &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;Declare accept-changes step &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;u:accept-changes&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;stylesheet&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:document &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;accept_changes.xslt&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  
  &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;Pipeline flow starts here &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;  

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;u:accept-changes &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;remove-tracking-markup&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
  
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:delete &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;delete-level-2-notes&lt;/span&gt;" 
    &lt;span style="color: red"&gt;match&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;/chapter/section/section/note&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
     
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;What's happening is that we are declaring a new step &lt;em&gt;type&lt;/em&gt; called "u:accept-changes," and then invoking an &lt;em&gt;instance&lt;/em&gt; of it as the first step in the pipeline.&amp;nbsp; A few notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The u:accept-changes step declaration itself is not executed directly; only it's instance on line 21 is.&amp;nbsp; More formally, a pipeline element that is the child of another pipeline element (unlike what we've seen before) is used to define a step that can be invoked later.
As an analogy to other programming languages, you are defining a object type and then creating an instance of it.&amp;nbsp; As a result, there is no need in this pipeline for explicit piping; the default implicit connections suffice. 
&lt;li&gt;A step's &lt;em&gt;type&lt;/em&gt; attribute is different than its &lt;em&gt;name&lt;/em&gt; attribute.&amp;nbsp; The value you place in &lt;em&gt;type&lt;/em&gt; becomes the name of the element you use to invoke it (lines 11 and 21).&amp;nbsp; That instance can itself be given a name, which can then be used when controlling the flow of XML using pipes.&amp;nbsp; So, a &lt;em&gt;type&lt;/em&gt; refers to the object, and a &lt;em&gt;name&lt;/em&gt; refers to the instance. 
&lt;li&gt;A step's type must be in a non-XProc namespace, which you must remember to declare.&amp;nbsp; &lt;li&gt;The &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.serialization"&gt;p:serialization&lt;/a&gt; element defines how a specified pipeline output port serializes XML when outputting from the pipeline.&amp;nbsp; It is the equivalent of the xsl:output instruction in XSLT, and takes many of the same options.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Of course, if you're going to just reference your new step type once within the same pipeline that you've declared it in, there's not really much of a point.&lt;/p&gt;
&lt;p&gt;The real power of declaring your own step type comes from the ability to place it in an external library and create instances of it within any number of pipelines.&amp;nbsp; Here's how you do that, using &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.import"&gt;p:import&lt;/a&gt;.&amp;nbsp; First, the library document:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:library 
    &lt;/span&gt;&lt;span style="color: red"&gt;xmlns:p&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.w3.org/ns/xproc&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xmlns:atict&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.arbortext.com/namespace/atict&lt;/span&gt;"
    &lt;span style="color: red"&gt;xmlns:u&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.wordsinboxes.com/xproc&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;u:accept-changes&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;    
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;stylesheet&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:document &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;accept_changes.xslt&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;
      &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:input&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:xslt&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
       
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:library&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Note the root element &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.library"&gt;p:library&lt;/a&gt;, which is used as a container for a collection of custom steps.&amp;nbsp; If I wanted, I could have made the p:pipeline element the root element, and imported that single step, but using p:library leaves more room for future growth.&lt;/p&gt;
&lt;p&gt;Here's the final pipeline, which imports the above library:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;delete-notes&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xmlns:p&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.w3.org/ns/xproc&lt;/span&gt;" 
    &lt;span style="color: red"&gt;xmlns:atict&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.arbortext.com/namespace/atict&lt;/span&gt;"
    &lt;span style="color: red"&gt;xmlns:u&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;http://www.wordsinboxes.com/xproc&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:serialization &lt;/span&gt;&lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;result&lt;/span&gt;" &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;utf-8&lt;/span&gt;" &lt;span style="color: red"&gt;method&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;xml&lt;/span&gt;"  
    &lt;span style="color: red"&gt;omit-xml-declaration&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;false&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;

  &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;Import accept-changes step &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:import &lt;/span&gt;&lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;lib.xpl&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
  
  &amp;lt;!-- &lt;/span&gt;&lt;span style="color: green"&gt;Pipeline flow starts here &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;  

  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;u:accept-changes &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;remove-tracking-markup&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
 
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:delete &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;delete-level-2-notes&lt;/span&gt;" 
    &lt;span style="color: red"&gt;match&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;/chapter/section/section/note&lt;/span&gt;" &lt;span style="color: blue"&gt;/&amp;gt;
     
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;p:pipeline&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;There.&amp;nbsp; A nice and simple pipeline.&amp;nbsp; I (and anyone else) can reference this u:accept-changes step in any number of pipelines, and never worry about how it actually works.&amp;nbsp; (And, if you stored the transform inside the u:accept-changes definition using &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#p.inline"&gt;p:inline&lt;/a&gt;, it would be even more portable.)&amp;nbsp; Later, if I decide that I'm better served by using a Python script to accept changes instead of a transform, I can simply update the step declaration (using &lt;a href="http://www.w3.org/XML/XProc/docs/langspec.html#c.exec"&gt;p:exec&lt;/a&gt;) once in the library.&amp;nbsp; My hope is that &lt;a title="EXProc" href="http://exproc.org/"&gt;XProc will become a common language&lt;/a&gt; for sharing XML manipulation tasks.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;It's also worth noting that if I gave this note-deleting pipeline a type attribute, then it too could be invoked as step in another pipeline.&amp;nbsp; And that pipeline could be invoked as a step, and so on.&amp;nbsp; Turtles all the way down.&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://flickr.com/photos/jef/2810419826/"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="image" src="http://lh5.ggpht.com/_RxnSdqnpnDs/SU_YOi6_JrI/AAAAAAAAAnw/U-wbHC2wuak/image_thumb%5B12%5D.png?imgmax=800" width="244" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Here's where the difference between an atomic step and a compound step comes into play.&amp;nbsp; Although we defined our accept-changes step as a &lt;em&gt;compound step&lt;/em&gt; (because it contains a subpipeline of one step), when we invoke an instance of it, that instance is an &lt;em&gt;atomic step&lt;/em&gt;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If that is confusing (and it sure confused me at first), it helps if you think about the step from two separate perspectives — from within, looking at the implementation details, and without, looking at what actually enters and leaves the step.&amp;nbsp; We've already covered the inside.&amp;nbsp; From the outside, when you call an instance, that instance is a black box which XML enters and XML leaves — &lt;a href="http://markmail.org/message/sofszu2gy4iapgvp"&gt;&lt;em&gt;exactly like a built-in atomic step&lt;/em&gt;&lt;/a&gt;.&amp;nbsp; The fact that it's actually implemented by assembling XProc steps is irrelevant to the calling pipeline.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;There's one more important XProc fact I've talked around but never explicitly stated.&amp;nbsp; &lt;em&gt;The only information that can flow between steps through pipes is XML. &lt;/em&gt;At first, I thought this a stifling restriction, but as I work more with XProc, I think that this prohibition is the key to its power.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Because, when you combine all these ideas, you end up with a very high level of enforced encapsulation that provides a very simple yet powerful abstraction for working with XML.&amp;nbsp; It allows you to worry about &lt;em&gt;what&lt;/em&gt; needs to be done instead of &lt;em&gt;how&lt;/em&gt;.&amp;nbsp; When any pipeline can be used as an atomic step, you can &lt;a href="http://bitworking.org/news/388/broke"&gt;work fractally&lt;/a&gt;, making parts out of the same raw material as the whole, creating higher and higher levels of abstraction.&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://flickr.com/photos/jdvolcan/2396815306/"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="164" alt="image" src="http://lh6.ggpht.com/_RxnSdqnpnDs/SU_YRH_6t6I/AAAAAAAAAn0/4fcvovMcdJw/image_thumb%5B11%5D.png?imgmax=800" width="244" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, to summarize:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A pipeline is a step. 
&lt;li&gt;Although the &lt;em&gt;declaration&lt;strong&gt; &lt;/strong&gt;&lt;/em&gt;of a step may be a compound step, its &lt;em&gt;invocation&lt;/em&gt; is not.&amp;nbsp; &lt;li&gt;XML is the only information that can flow between steps through pipes.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;That's it for now.&amp;nbsp; If you're looking for more XProc information, Dave Pawson has been working on &lt;a href="http://www.dpawson.co.uk/xproc/"&gt;his introduction to XProc&lt;/a&gt;, which is shaping up to be a great resource.&lt;/p&gt;
&lt;p&gt;I may start posting my XProc-related material in a more suitable space, away from my blog.&amp;nbsp; I'm considering using Docbook Website system.&amp;nbsp; Any thoughts?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-4910554757518919946?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/DJWqyVK9ANA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4910554757518919946?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4910554757518919946?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/DJWqyVK9ANA/xproc-part-iii-turtles-all-way-down.html" title="XProc, Part III — Turtles All The Way Down (Steps, Reuse, and Encapsulation)" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_RxnSdqnpnDs/SU_YKA4KZ_I/AAAAAAAAAno/ukbRoH5d2_s/s72-c/image_thumb%5B8%5D.png?imgmax=800" height="72" width="72" /><feedburner:origLink>http://www.wordsinboxes.com/2008/12/xproc-part-iii-turtles-all-way-down.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUEQ3w4cCp7ImA9WxRaFE4.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-4099127641176269102</id><published>2008-12-16T07:30:00.000-06:00</published><updated>2008-12-16T07:30:02.238-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-16T07:30:02.238-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="links" /><title>Recently In Markup</title><content type="html">&lt;ul&gt; &lt;li&gt;&lt;b&gt;&lt;a href="http://www.cafeconleche.org/#December_8_2008_22075"&gt;Cafe con Leche&lt;/a&gt;&lt;/b&gt;&lt;br&gt;"The W3C Core Working group has broken faith with the XML community by publishing an XML 1.0, fifth edition spec that is incompatible with all previous versions."  &lt;li&gt;&lt;b&gt;&lt;a href="http://bitworking.org/news/388/broke"&gt;Joe Gregorio | BitWorking | CS Broke&lt;/a&gt;&lt;/b&gt;&lt;br&gt;"What part of the computer in front of you is fractal?"  &lt;li&gt;&lt;b&gt;&lt;a href="http://www.robvanderwoude.com/batchfiles.html"&gt;Batch files&lt;/a&gt;&lt;/b&gt;&lt;br&gt;More than you ever wanted to know about how to write Windows batch files.  &lt;li&gt;&lt;b&gt;&lt;a href="http://www.fgeorges.org/exslt2-wiki/Main_Page"&gt;Main Page - Exslt2&lt;/a&gt;&lt;/b&gt;&lt;br&gt;The beginning of the discussion for EXSLT 2.0.  &lt;li&gt;&lt;b&gt;&lt;a href="http://www.dpawson.co.uk/nodesets/entries/081201.html"&gt;Marklogic review&lt;/a&gt;&lt;/b&gt;&lt;br&gt;Dave Pawson reviews MarkLogic ... and gives up.  &lt;li&gt;&lt;b&gt;&lt;a href="http://www.jenitennison.com/blog/node/95"&gt;Overlap, Containment and Dominance | Jeni's Musings&lt;/a&gt;&lt;/b&gt;  &lt;li&gt;&lt;b&gt;&lt;a href="http://www.b-list.org/weblog/2008/dec/05/python-3000/"&gt;Let's talk about Python 3.0&lt;/a&gt;&lt;/b&gt;&lt;br&gt;"You build a nice big room-sized cage, and in one end of it you put five monkeys. In the other end you put the banana." &lt;/li&gt;&lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-4099127641176269102?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/OxcMEvfc6sA" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4099127641176269102?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/4099127641176269102?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/OxcMEvfc6sA/recently-in-markup.html" title="Recently In Markup" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2008/12/recently-in-markup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8EQXczeSp7ImA9WxRaEUo.&quot;"><id>tag:blogger.com,1999:blog-14372968.post-3283901783946886486</id><published>2008-12-13T08:00:00.000-06:00</published><updated>2008-12-13T08:00:00.981-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-13T08:00:00.981-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="links" /><title>This Week in Google Reader</title><content type="html">&lt;ul&gt;   &lt;li&gt;&lt;b&gt;&lt;a href="http://apelad.blogspot.com/2008/12/laugh-out-loud-cats-1006.html"&gt;Laugh-Out-Loud Cats #1006&lt;/a&gt;&lt;/b&gt;      &lt;br /&gt;(via &lt;a href="http://apelad.blogspot.com/"&gt;HOBOTOPIA&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;a href="http://feeds.feedburner.com/~r/scienceblogs/uncertainprinciples/~3/480720128/teachers_quarterbacks_and_mark.php"&gt;Teachers, Quarterbacks, and Markets&lt;/a&gt;&lt;/b&gt;      &lt;br /&gt;(via &lt;a href="http://scienceblogs.com/principles/"&gt;Uncertain Principles&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;a href="http://garfieldminusgarfield.net/post/64117945"&gt;Photo&lt;/a&gt;&lt;/b&gt;      &lt;br /&gt;(via &lt;a href="http://garfieldminusgarfield.net/"&gt;garfield minus garfield&lt;/a&gt;)&lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;a href="http://wemadethis.typepad.com/we_made_this/2008/12/wireframe-lamborghini.html"&gt;Wireframe Lamborghini&lt;/a&gt;&lt;/b&gt;      &lt;br /&gt;(via &lt;a href="http://wemadethis.typepad.com/we_made_this/"&gt;We Made This&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14372968-3283901783946886486?l=www.wordsinboxes.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/IndigoFlats/~4/-TgohR5ike8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3283901783946886486?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14372968/posts/default/3283901783946886486?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/IndigoFlats/~3/-TgohR5ike8/this-week-in-google-reader_13.html" title="This Week in Google Reader" /><author><name>jsulak</name><uri>http://www.blogger.com/profile/05736367413367891531</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><feedburner:origLink>http://www.wordsinboxes.com/2008/12/this-week-in-google-reader_13.html</feedburner:origLink></entry></feed>

