<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[The Joy of Hack]]></title>
  <link href="http://aijazansari.com/atom.xml" rel="self"/>
  <link href="http://aijazansari.com/"/>
  <updated>2012-03-30T00:56:50-05:00</updated>
  <id>http://aijazansari.com/</id>
  <author>
    <name><![CDATA[Aijaz Ansari]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Running Out Of Power At The Grand Canyon]]></title>
    <link href="http://aijazansari.com/2012/03/29/running-out-of-power-at-the-grand-canyon/"/>
    <updated>2012-03-29T17:41:00-05:00</updated>
    <id>http://aijazansari.com/2012/03/29/running-out-of-power-at-the-grand-canyon</id>
    <content type="html"><![CDATA[<p>I&#8217;m currently in the last 48 hours of my first ever visit to the Grand
Canyon in Arizona.  Just hours before setting out to see the Canyon for
the first time, I realized that I couldn&#8217;t recharge my camera&#8217;s battery.
I had 80% of a full charge, and four more days of vacation to go.  Time to
panic?</p>

<!-- more -->


<p>On Monday I drove through Sedona, Arizona with a fully-charged battery,
taking many pictures at each stop.  By early evening we reached our hotel
in Tusayan, a mile from the entrance to the Grand Canyon National Park.
That night I prepared my gadgets for the next day, when we were to visit
the Canyon for the first time.  I charged my phone, charged my laptop, and
tried to charge my camera.</p>

<p>When I placed the camera battery in its charger, the light on the charger
came on and immediately turned off.  &#8220;That&#8217;s odd,&#8221; I thought.  I removed
the battery and placed it in again.  Again, the light went on
momentarily.  I tried a third time, but the light never turned on again.</p>

<p>I could have a bad charger, or a bad battery, or both.  I put the battery
into the camera, and it seemed to work fine.  Breathing a sigh of relief I
realized that it was only my charger that was broken.</p>

<p>If I rationed my photography, I thought, I might be able to make it
through this vacation on the 80% charge that I had left.  But I didn&#8217;t
want to have to worry about taking too many pictures on a
once-in-a-lifetime trip, and I would need a new charger anyway.  So I
ordered a charger and spare battery from Amazon, and they promised to have
them delivered on Wednesday.</p>

<p>To Amazon&#8217;s credit, they delivered the charger as promised, an hour before
we left for a sunset tour.  In the 36 hours before I got the new charger
one simple decision and one camera setting allowed me to take as many
pictures as I normally would without having to worry about running out of
juice even if the new charger never came.</p>

<h2>Battery Saving Tips</h2>

<p>There are two functions of a modern digital camera that need a lot of
power.  The first is the on-camera flash.  Fortunately for me, I had an
external flash that had its own power source: four AA batteries.  Using
the external flash exclusively meant that the camera battery didn&#8217;t have
to throw all the light required for those backlit shots of the family with
a brightly-lit canyon in the background.  Also, AA batteries are easy to
find at any gas station or general store.</p>

<p>The second function that taxes the camera&#8217;s battery is the display on the back -
the monitor.  On my digital SLR, by default the monitor displays the
photograph just taken for 10 seconds.  I had already set this to the
minimum value of 4 seconds.  Minimizing the amount of time that the
monitor is in use can greatly improve your battery&#8217;s performance.</p>

<h2>Morals Of The Story</h2>

<ol>
<li><p>When you&#8217;re on the road for an important photo shoot, keep a spare,
fully-charged battery.  You may never need to use it, but if you do, you&#8217;ll
be glad you have it.</p></li>
<li><p>Use an external flash if at all possible - It will prolong your battery
life and give you the option to try out multiple-flash photographs.</p></li>
<li><p>Don&#8217;t waste your battery browsing through pictures on your camera if
you don&#8217;t need to.  Minimize the time spent using your monitor to maximize
your battery life.</p></li>
<li><p>When you&#8217;re on vacation with family, when you&#8217;re not a Pro shooting for
a client, remember that it&#8217;s just a camera.  The vacation can be fun even
if you don&#8217;t take any pictures.  You&#8217;re in a beautiful place with the most
important people in your life.  Enjoy yourself and make some memories that
everyone will share fondly.</p></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Stopping by the Streets on a Snowy Evening]]></title>
    <link href="http://aijazansari.com/2012/01/20/stopping-by-the-streets/"/>
    <updated>2012-01-20T18:50:58-06:00</updated>
    <id>http://aijazansari.com/2012/01/20/stopping-by-the-streets</id>
    <content type="html"><![CDATA[<!-- ai l /images/201201/ChiSnow2.jpg /images/201201/ChiSnowS2.jpg 240 320 LaSalle St. -->




<div style="float: right">
Whose streets these are I think I know.<br>
<!-- more -->
The brave commuters of Chicago-o;<br>
They wonder why I&#8217;m standing here<br>
To watch the streets fill up with snow.<br>
<br>
The hurried folk must think it queer<br>
To stop without a shelter here<br>
Between the Loop and frozen lake<br>
The darkest evening of the year.<br>
<br>
The give my lazy butt a shake<br>
To ask if there is some mistake. <br>
The only other sound&#8217;s the sweep <br>
Of easy wind and downy flake.<br>
<br>
The Streets are lovely, dark and deep<br>
But I have promises to keep,<br>
And miles to go before I sleep,<br>
And miles to go before I sleep.<br>
<br>
<br>
With apologies to <a href="http://www.poetryfoundation.org/poem/171621">Robert Frost</a>.
</div>




<div style="clear: both; margin-bottom: 1em;">&nbsp; </div>




<!-- ai c /images/201201/ChiSnow3.jpg /images/201201/ChiSnow3.jpg 720 960 Canal St. -->

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[One-legged Medicine Ball Burpees]]></title>
    <link href="http://aijazansari.com/2012/01/10/one-legged-medicine-ball-burpees/"/>
    <updated>2012-01-10T07:00:00-06:00</updated>
    <id>http://aijazansari.com/2012/01/10/one-legged-medicine-ball-burpees</id>
    <content type="html"><![CDATA[<p>After only being able to do a single one-legged medicine ball burpee last week, I was able to do 12 last night.  Here&#8217;s the trick:</p>

<!-- more -->


<p>The X2 Core workout of P90X2 is all about core strength and balance.  Having
completed P90X twice, I&#8217;ve found this workout intimidating but not impossible.
The exception is the one-legged medicine ball burpee.  The workout calls for a
single set of 12, but on the first day I was only able to do 1.</p>

<p>Last night, on the second day of X2 Core I was able to do all 12.  It&#8217;s not
that I got that much better over 7 days.  The trick was that I stopped and
really watched how the people in the video were doing this exercise.  I was
doing it wrong.  My mistake was that I had the medicine ball at shoulder level
when I was doing a one-legged push-up on it.  This made it very difficult to
balance.</p>

<p>Simply moving the medicine ball &#8216;down&#8217; to solar-plexus level helped immensely.
This way I was more balanced and my arms were perpendicular to the ground, and
I was able to keep my elbows in.  It was still very difficult, but I was able
to hammer out 12 ugly reps.  Now that I understand the form I can work on
perfecting it and working on 12 slow, solid reps.</p>

<p>So, if you&#8217;re doing P90X2 now, and find one-legged med-ball burpees as
difficult as I did, have another look at your form and make sure you&#8217;re not
putting the ball to much in front of you, instead of directly under you.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Tag Clouds With Octopress]]></title>
    <link href="http://aijazansari.com/2012/01/07/tag-clouds-with-octopress/"/>
    <updated>2012-01-07T06:00:00-06:00</updated>
    <id>http://aijazansari.com/2012/01/07/tag-clouds-with-octopress</id>
    <content type="html"><![CDATA[<p>In this post I&#8217;ll show you how I added tag clouds to my Octopress blog.</p>

<!-- more -->


<p>Before I go any further I want to stress something: <strong>While this is a robust
solution, it&#8217;s not the optimal solution, and not a permanent solution.</strong>  I
don&#8217;t know whether it&#8217;s particularly elegant, either.  It&#8217;s not ugly, but it isn&#8217;t beautiful.  There
is <a href="https://github.com/imathis/octopress/pull/282">at least one</a> project in the
works to add tags to Octopress.  When that&#8217;s pulled into the main Octopress
repository, it will probably be the way tag clouds ought to be done.  Despite that
I came up with my own way to do it for the following reasons:</p>

<ul>
<li>I don&#8217;t know Ruby yet.  I&#8217;m learning, but I don&#8217;t feel comfortable
incorporating so much code I don&#8217;t understand.</li>
<li>I don&#8217;t want to re-invent the wheel in Ruby.  Ted Kulp, the author of the
commit shown above, seems to have done all the heavy lifting.  I look forward
to incorporating his changes once they&#8217;re in Octopress proper.  My solution&#8217;s
written in Perl, and as far as I&#8217;m concerned, my solution is a short-term
one.</li>
</ul>


<p>Having said that, read on to see how I got the tag clouds that you see in this blog working.</p>

<p>There are three parts to this problem:</p>

<ol>
<li>Displaying a list of tags applied to the current post at the bottom of each
post.</li>
<li>Clicking through from a tag name in that list to a tag page that lists all
posts with that tag.</li>
<li>Generating and displaying the tag cloud.</li>
</ol>


<h2>Displaying a list of tags</h2>


<p>This was pretty easy to get right.  I modified <code>source/_layouts/post.html</code> to include a new file called <code>tags.html</code>:</p>

<figure class='code'><figcaption><span>source/_layouts/post.html </span><a href='https://github.com/aijaz/octopress/commit/d72ad36b52d278f189260f80fb355c01e60542b8#diff-6'>View in GitHub</a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>...
</span><span class='line'>       {% include post/author.html %}
</span><span class='line'>       {% include post/date.html %}{% if updated %}{{ updated }}{% else %}{{ time }}{% endif %}
</span><span class='line'>       {% include post/categories.html %}
</span><span class='line'>+      {% include post/tags.html %}
</span><span class='line'>     <span class="nt">&lt;/p&gt;</span>
</span><span class='line'>     {% unless page.sharing == false %}
</span><span class='line'>       {% include post/sharing.html %}
</span><span class='line'>...
</span></code></pre></td></tr></table></div></figure>


<p>I then created <code>source/_includes/post/tags.html</code> which is shown in it&#8217;s entirety here:</p>

<figure class='code'><figcaption><span>source/_includes/post/tags.html </span><a href='https://github.com/aijaz/octopress/commit/d72ad36b52d278f189260f80fb355c01e60542b8#diff-5'>View in GitHub </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;tag_list&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    Tags:
</span><span class='line'>    <span class="nt">&lt;ul</span> <span class="na">id=</span><span class="s">&quot;tags_ul&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>{% for t in page.tags  %}
</span><span class='line'>        <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/tags/{{t}}/&quot;</span><span class="nt">&gt;</span>{{t}}<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>{% endfor %}
</span><span class='line'>    <span class="nt">&lt;/ul&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>I chose to display tags as a list so that screen readers and other renderers
interpret this correctly as a list of entries, rather than a sentence where
each word is an anchor. Finally I added the appropriate CSS to display the tag
list properly in the browser.</p>

<figure class='code'><figcaption><span>sass/custom/_styles.css  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">div</span><span class="nf">#tag_list</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">font-size</span><span class="o">:</span> <span class="m">12pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nf">#tags_ul</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nf">#tags_ul</span> <span class="nt">li</span><span class="nd">:last-child:after</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">content</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nf">#tags_ul</span> <span class="nt">li</span><span class="nd">:after</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">content</span><span class="o">:</span> <span class="s2">&quot;, &quot;</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nf">#tags_ul</span> <span class="nt">li</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">display</span><span class="o">:</span> <span class="k">inline</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<h2>Generating the tag files and tag cloud</h2>


<p>This was the most involved step of all. I wrote a script called <code>tagify.pl</code>
that generates the tag markdown files as well as a file containing the HTML
markup for the tag cloud.  I started off parsing the markdown files with a YAML
parser and gathering the tags from there.  But then I realized that for each
tag&#8217;s page I would have had to know the URL of the posts that are marked with
that tag.  If I only have access to the markdown then I would have to duplicate
Octopress&#8217;s code that determines a location for a post in the public directory
- the <em>/yyyy/mm/dd/modified-file-name.html</em> logic.</p>

<p>Rather than do that and tightly couple my hack with Octopress&#8217;s code I decided
to parse the generated HTML instead.  Therefore, my script would have to be run
after <code>rake generate</code> is called.  <em>But!</em> My script has to generate tag
files and tag clouds that get pulled into asides in the sidebar!  That means
that <code>rake generate</code> has to be called after my script as well - a second
time.  Now do you believe me when I say that this is a temporary solution?  It
works, but it&#8217;s not very efficient.</p>

<p>But you know what?  I&#8217;m happy with it.  I could have waited until I was done
learning Ruby, and done learning the Liquid Template Manager, and done learning
Octopress&#8217;s idioms and then started with this project.  I could have waited
until Ted Kulp&#8217;s changes were pulled into the master Octopress branch.  But I
know what I want, and I know I can write decent code.  It took a few hours, but
I was able to get tag clouds done and move on.  I&#8217;m not emotionally attached to
this code and will gladly abandon it when something better comes along.   The
way I&#8217;ve designed it, it will be easy to pull it out - instead of running</p>

<pre><code>rake generate
./tagify.pl
rake generate
</code></pre>

<p>I&#8217;ll just run</p>

<pre><code>rake generate
</code></pre>

<p>Since <code>tagify.pl</code> is rather long (307 lines with comments), I&#8217;ll include it
in the Appendix at the bottom of this post, and just
<a href="http://aijazansari.com/downloads/code/tags/tagify.pl">link to it</a> here.</p>

<p>What&#8217;s important to remember is that <code>tagify.pl</code> does 3 things:</p>

<ul>
<li>It creates a single file called <code>source/_includes/custom/tag_cloud.html</code> that looks like this</li>
</ul>


<figure class='code'><figcaption><span>source/_includes/custom/tag_cloud.html  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&#39;tag_cloud&#39;</span><span class="nt">&gt;</span>
</span><span class='line'><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/tags/Editors/&quot;</span> <span class="na">title=</span><span class="s">&quot;6 entries&quot;</span> <span class="na">class=</span><span class="s">&quot;tag_10&quot;</span><span class="nt">&gt;</span>Editors<span class="nt">&lt;/a&gt;</span>
</span><span class='line'><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;/tags/Firefox/&quot;</span> <span class="na">title=</span><span class="s">&quot;2 entries&quot;</span> <span class="na">class=</span><span class="s">&quot;tag_3&quot;</span><span class="nt">&gt;</span>Firefox<span class="nt">&lt;/a&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The title is included for accessibility, and the classes <code>tag_1</code>
through <code>tag_10</code> are used to display the tags in the appropriate size.</p>

<ul>
<li><p>For each tag it creates a file that lists all the posts tagged with that tag in reverse chronological order.  For the tag <code>Editors</code> it would create <code>source/tags/Editors/index.markdown</code></p></li>
<li><p>It creates one file called <code>source/tags/index.markdown</code> that includes the <code>tag_cloud.html</code> file in the main article area.</p></li>
</ul>


<h2>Displaying the tag cloud</h2>


<p>To display the tag cloud in the right sidebar I added a default aside in <code>_config.yaml</code>:</p>

<pre><code>default_asides: [asides/recent_posts.html, asides/twitter.html, asides/tag_cloud.html]
</code></pre>

<p>I then created the file <code>source/_includes/asides/tag_cloud.html</code>.  This
file includes the <code>source/_includes/custom/tag_cloud.html</code> file that was
generated by <code>tagify.pl</code>above.</p>

<figure class='code'><figcaption><span>source/_includes/asides/tag_cloud.html  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;section&gt;</span>
</span><span class='line'>    <span class="nt">&lt;h1&gt;</span>Tags<span class="nt">&lt;/h1&gt;</span>
</span><span class='line'>    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;tag_cloud&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>     {% include custom/tag_cloud.html %}
</span><span class='line'>    <span class="nt">&lt;/div&gt;</span>
</span><span class='line'><span class="nt">&lt;/section&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>I then modified sass/custom/_styles.css to include the css for each of the 10 tag &#8216;buckets&#8217;:</p>

<figure class='code'><figcaption><span>sass/custom/_styles.css  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nc">.tag_1</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">font-weight</span><span class="o">:</span> <span class="m">200</span><span class="p">;</span>
</span><span class='line'>    <span class="k">font-size</span><span class="o">:</span> <span class="m">10pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nc">.tag_2</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">font-weight</span><span class="o">:</span> <span class="m">200</span><span class="p">;</span>
</span><span class='line'>    <span class="k">font-size</span><span class="o">:</span> <span class="m">12pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="o">...</span>
</span><span class='line'><span class="nc">.tag_10</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">font-weight</span><span class="o">:</span> <span class="m">900</span><span class="p">;</span>
</span><span class='line'>    <span class="k">font-size</span><span class="o">:</span> <span class="m">24pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Finally, I added a line to <code>source/_includes/custom/navigation.html</code> to link to the main Tags page:</p>

<figure class='code'><figcaption><span>source/_includes/custom/navigation.html </span><a href='https://github.com/aijaz/octopress/commit/d72ad36b52d278f189260f80fb355c01e60542b8#diff-3'>View in GitHub </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>...
</span><span class='line'>   <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/&quot;</span><span class="nt">&gt;</span>Home<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>   <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/about/&quot;</span><span class="nt">&gt;</span>About Me<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>   <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/categories/&quot;</span><span class="nt">&gt;</span>Categories<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>+  <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/tags/&quot;</span><span class="nt">&gt;</span>Tags<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>   <span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">&quot;/blog/archives&quot;</span><span class="nt">&gt;</span>Archives<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
</span><span class='line'>...
</span></code></pre></td></tr></table></div></figure>




<h2>Summary</h2>


<p>It bears mentioning that you don&#8217;t always need to run <code>tagify.pl</code>.  You
only need to run it if you&#8217;ve updated the tags on a post.  If you have changed
a tag, you must run <code>rake generate</code> before and after running
<code>tagify.pl</code>.  If you&#8217;re just working on edits to a post before publishing
it, you don&#8217;t need to run <code>tagify.pl</code> every time you want to view your post
on your local machihne . <code>rake generate</code> is enough.</p>

<p>I&#8217;m glad to say that I was able to get tags to work with Octopress exactly the
way I wanted. It was pretty quick, too.  It took me longer to write this blog
post than to actually do the work.  If you like this post, please let me know
on Twitter, where I&#8217;m <a href="https://twitter.com/#!/_aijaz_">@_aijaz_</a>.  Thanks.</p>

<h2>Appendix - tagify.pl</h2>


<p>This is what <code>tagify.pl</code> looks like.  I describe the code in the comments within the file.</p>

<figure class='code'><figcaption><span>tabify.pl  (tagify.pl)</span> <a href='http://aijazansari.com/downloads/code/tags/tagify.pl'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
<span class='line-number'>124</span>
<span class='line-number'>125</span>
<span class='line-number'>126</span>
<span class='line-number'>127</span>
<span class='line-number'>128</span>
<span class='line-number'>129</span>
<span class='line-number'>130</span>
<span class='line-number'>131</span>
<span class='line-number'>132</span>
<span class='line-number'>133</span>
<span class='line-number'>134</span>
<span class='line-number'>135</span>
<span class='line-number'>136</span>
<span class='line-number'>137</span>
<span class='line-number'>138</span>
<span class='line-number'>139</span>
<span class='line-number'>140</span>
<span class='line-number'>141</span>
<span class='line-number'>142</span>
<span class='line-number'>143</span>
<span class='line-number'>144</span>
<span class='line-number'>145</span>
<span class='line-number'>146</span>
<span class='line-number'>147</span>
<span class='line-number'>148</span>
<span class='line-number'>149</span>
<span class='line-number'>150</span>
<span class='line-number'>151</span>
<span class='line-number'>152</span>
<span class='line-number'>153</span>
<span class='line-number'>154</span>
<span class='line-number'>155</span>
<span class='line-number'>156</span>
<span class='line-number'>157</span>
<span class='line-number'>158</span>
<span class='line-number'>159</span>
<span class='line-number'>160</span>
<span class='line-number'>161</span>
<span class='line-number'>162</span>
<span class='line-number'>163</span>
<span class='line-number'>164</span>
<span class='line-number'>165</span>
<span class='line-number'>166</span>
<span class='line-number'>167</span>
<span class='line-number'>168</span>
<span class='line-number'>169</span>
<span class='line-number'>170</span>
<span class='line-number'>171</span>
<span class='line-number'>172</span>
<span class='line-number'>173</span>
<span class='line-number'>174</span>
<span class='line-number'>175</span>
<span class='line-number'>176</span>
<span class='line-number'>177</span>
<span class='line-number'>178</span>
<span class='line-number'>179</span>
<span class='line-number'>180</span>
<span class='line-number'>181</span>
<span class='line-number'>182</span>
<span class='line-number'>183</span>
<span class='line-number'>184</span>
<span class='line-number'>185</span>
<span class='line-number'>186</span>
<span class='line-number'>187</span>
<span class='line-number'>188</span>
<span class='line-number'>189</span>
<span class='line-number'>190</span>
<span class='line-number'>191</span>
<span class='line-number'>192</span>
<span class='line-number'>193</span>
<span class='line-number'>194</span>
<span class='line-number'>195</span>
<span class='line-number'>196</span>
<span class='line-number'>197</span>
<span class='line-number'>198</span>
<span class='line-number'>199</span>
<span class='line-number'>200</span>
<span class='line-number'>201</span>
<span class='line-number'>202</span>
<span class='line-number'>203</span>
<span class='line-number'>204</span>
<span class='line-number'>205</span>
<span class='line-number'>206</span>
<span class='line-number'>207</span>
<span class='line-number'>208</span>
<span class='line-number'>209</span>
<span class='line-number'>210</span>
<span class='line-number'>211</span>
<span class='line-number'>212</span>
<span class='line-number'>213</span>
<span class='line-number'>214</span>
<span class='line-number'>215</span>
<span class='line-number'>216</span>
<span class='line-number'>217</span>
<span class='line-number'>218</span>
<span class='line-number'>219</span>
<span class='line-number'>220</span>
<span class='line-number'>221</span>
<span class='line-number'>222</span>
<span class='line-number'>223</span>
<span class='line-number'>224</span>
<span class='line-number'>225</span>
<span class='line-number'>226</span>
<span class='line-number'>227</span>
<span class='line-number'>228</span>
<span class='line-number'>229</span>
<span class='line-number'>230</span>
<span class='line-number'>231</span>
<span class='line-number'>232</span>
<span class='line-number'>233</span>
<span class='line-number'>234</span>
<span class='line-number'>235</span>
<span class='line-number'>236</span>
<span class='line-number'>237</span>
<span class='line-number'>238</span>
<span class='line-number'>239</span>
<span class='line-number'>240</span>
<span class='line-number'>241</span>
<span class='line-number'>242</span>
<span class='line-number'>243</span>
<span class='line-number'>244</span>
<span class='line-number'>245</span>
<span class='line-number'>246</span>
<span class='line-number'>247</span>
<span class='line-number'>248</span>
<span class='line-number'>249</span>
<span class='line-number'>250</span>
<span class='line-number'>251</span>
<span class='line-number'>252</span>
<span class='line-number'>253</span>
<span class='line-number'>254</span>
<span class='line-number'>255</span>
<span class='line-number'>256</span>
<span class='line-number'>257</span>
<span class='line-number'>258</span>
<span class='line-number'>259</span>
<span class='line-number'>260</span>
<span class='line-number'>261</span>
<span class='line-number'>262</span>
<span class='line-number'>263</span>
<span class='line-number'>264</span>
<span class='line-number'>265</span>
<span class='line-number'>266</span>
<span class='line-number'>267</span>
<span class='line-number'>268</span>
<span class='line-number'>269</span>
<span class='line-number'>270</span>
<span class='line-number'>271</span>
<span class='line-number'>272</span>
<span class='line-number'>273</span>
<span class='line-number'>274</span>
<span class='line-number'>275</span>
<span class='line-number'>276</span>
<span class='line-number'>277</span>
<span class='line-number'>278</span>
<span class='line-number'>279</span>
<span class='line-number'>280</span>
<span class='line-number'>281</span>
<span class='line-number'>282</span>
<span class='line-number'>283</span>
<span class='line-number'>284</span>
<span class='line-number'>285</span>
<span class='line-number'>286</span>
<span class='line-number'>287</span>
<span class='line-number'>288</span>
<span class='line-number'>289</span>
<span class='line-number'>290</span>
<span class='line-number'>291</span>
<span class='line-number'>292</span>
<span class='line-number'>293</span>
<span class='line-number'>294</span>
<span class='line-number'>295</span>
<span class='line-number'>296</span>
<span class='line-number'>297</span>
<span class='line-number'>298</span>
<span class='line-number'>299</span>
<span class='line-number'>300</span>
<span class='line-number'>301</span>
<span class='line-number'>302</span>
<span class='line-number'>303</span>
<span class='line-number'>304</span>
<span class='line-number'>305</span>
<span class='line-number'>306</span>
<span class='line-number'>307</span>
<span class='line-number'>308</span>
<span class='line-number'>309</span>
<span class='line-number'>310</span>
<span class='line-number'>311</span>
<span class='line-number'>312</span>
<span class='line-number'>313</span>
<span class='line-number'>314</span>
<span class='line-number'>315</span>
<span class='line-number'>316</span>
<span class='line-number'>317</span>
<span class='line-number'>318</span>
</pre></td><td class='code'><pre><code class='perl'><span class='line'><span class="c1">#!/usr/bin/perl</span>
</span><span class='line'>
</span><span class='line'><span class="k">use</span> <span class="n">strict</span><span class="p">;</span>
</span><span class='line'><span class="k">use</span> <span class="n">warnings</span><span class="p">;</span>
</span><span class='line'><span class="k">use</span> <span class="nn">File::</span><span class="n">Find</span><span class="p">;</span>
</span><span class='line'><span class="k">use</span> <span class="nn">HTML::</span><span class="n">TreeBuilder</span><span class="p">;</span>
</span><span class='line'><span class="k">use</span> <span class="nn">Getopt::</span><span class="n">Long</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">my</span> <span class="nv">$octopress_root</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">my</span> <span class="nv">$options_read</span> <span class="o">=</span> <span class="n">GetOptions</span><span class="p">(</span><span class="s">&quot;dir=s&quot;</span><span class="p">,</span> <span class="o">\</span><span class="nv">$octopress_root</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">############################################################</span>
</span><span class='line'><span class="k">unless</span> <span class="p">(</span><span class="nv">$options_read</span> <span class="o">&amp;&amp;</span> <span class="nv">$octopress_root</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;usage: tagify.pl --dir d\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;where d is the root octopress directory\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;   - the parent of source, public, etc.\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">exit</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># The tag cloud HTML gets saved into this file.</span>
</span><span class='line'><span class="c1"># This file is included by two others: </span>
</span><span class='line'><span class="c1">#  a) The file used for the sidebar aside</span>
</span><span class='line'><span class="c1">#  b) The page used to display all tags </span>
</span><span class='line'><span class="c1">#     (accessible as /tags/index.html)</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">my</span> <span class="nv">$custom_file</span> <span class="o">=</span> <span class="s">&quot;$octopress_root/source/_includes&quot;</span><span class="o">.</span>
</span><span class='line'>                  <span class="s">&quot;/custom/tag_cloud.html&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># This is the data structure that contains all the tag </span>
</span><span class='line'><span class="c1"># data parsed by the HTML files.</span>
</span><span class='line'><span class="c1"># It&#39;s key is the tag name (not case-normalized).</span>
</span><span class='line'><span class="c1"># The value is another hash.  That hash has 2 keys:</span>
</span><span class='line'><span class="c1">#  count - number of pages with that tag</span>
</span><span class='line'><span class="c1">#  range_num - a number from 1 - 10 indicating </span>
</span><span class='line'><span class="c1">#              popularity (see below)</span>
</span><span class='line'><span class="c1">#  pages - an array of hashes</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="c1">#  Each hash in the pages array has 3 keys: </span>
</span><span class='line'><span class="c1">#  title - the HTML title of the post</span>
</span><span class='line'><span class="c1">#  file  - the full file name of the HTML file</span>
</span><span class='line'><span class="c1">#  categories - yet another hash</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="c1">#  The categories hash has two keys: </span>
</span><span class='line'><span class="c1">#  href - the url to the category page (as determined</span>
</span><span class='line'><span class="c1">#         by OctoPress)</span>
</span><span class='line'><span class="c1">#  text - the name of the category (as displayed by </span>
</span><span class='line'><span class="c1">#         Octopress)</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">my</span> <span class="nv">$tag_data</span>      <span class="o">=</span> <span class="p">{</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># This function populates the tag_data data structure</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="n">find</span><span class="p">(</span><span class="o">\&amp;</span><span class="n">getTags</span><span class="p">,</span> <span class="s">&quot;$octopress_root/public&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Find the number of times the most popular tag is used</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">my</span> <span class="nv">$max</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>  <span class="c1"># start with 1, not 0 to prevent a </span>
</span><span class='line'>              <span class="c1"># divide-by-zero error later</span>
</span><span class='line'>              <span class="c1"># if none of the posts have tags</span>
</span><span class='line'><span class="k">foreach</span> <span class="k">my</span> <span class="nv">$tag</span> <span class="p">(</span><span class="nb">keys</span> <span class="nv">%$tag_data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">count</span><span class="p">}</span> <span class="o">=</span> <span class="nb">scalar</span><span class="p">(</span><span class="nv">@</span><span class="p">{</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">pages</span><span class="p">}});</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">count</span><span class="p">}</span> <span class="o">&gt;</span> <span class="nv">$max</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$max</span> <span class="o">=</span> <span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">count</span><span class="p">};</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Assign each tag a range number from 1 - 10</span>
</span><span class='line'><span class="c1"># based on popularity.  This range number will</span>
</span><span class='line'><span class="c1"># be used along with CSS to print tags with</span>
</span><span class='line'><span class="c1"># the appropriate size.</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">foreach</span> <span class="k">my</span> <span class="nv">$tag</span> <span class="p">(</span><span class="nb">keys</span> <span class="nv">%$tag_data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">range_num</span><span class="p">}</span> <span class="o">=</span>
</span><span class='line'>      <span class="nb">int</span><span class="p">((</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">count</span><span class="p">}</span> <span class="o">/</span> <span class="nv">$max</span><span class="p">)</span>
</span><span class='line'>          <span class="o">*</span> <span class="mi">10</span>
</span><span class='line'>          <span class="o">+</span> <span class="mf">0.5</span><span class="p">);</span> <span class="c1"># nearest whole number</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">range_num</span><span class="p">}</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">range_num</span><span class="p">}</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>        <span class="c1"># we want 1-10, not 0-10</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Write the tag cloud file</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="nb">open</span> <span class="p">(</span><span class="n">O</span><span class="p">,</span> <span class="s">&quot;&gt;$custom_file&quot;</span><span class="p">)</span> <span class="o">||</span> <span class="nb">die</span><span class="p">;</span>
</span><span class='line'><span class="k">print</span> <span class="n">O</span> <span class="s">&quot;&lt;div id=&#39;tag_cloud&#39;&gt;\n&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># sort by tag name, case insensitive</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">foreach</span> <span class="k">my</span> <span class="nv">$tag</span> <span class="p">(</span><span class="nb">sort</span> <span class="p">{</span> <span class="nb">lc</span><span class="p">(</span><span class="nv">$a</span><span class="p">)</span> <span class="ow">cmp</span> <span class="nb">lc</span><span class="p">(</span><span class="nv">$b</span><span class="p">)}</span>
</span><span class='line'>                      <span class="nb">keys</span> <span class="nv">%$tag_data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># give each tag anchor a title, </span>
</span><span class='line'>    <span class="c1"># for screen readers and the like</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$plural</span> <span class="o">=</span> <span class="s">&quot;y&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">count</span><span class="p">}</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$plural</span> <span class="o">=</span> <span class="s">&#39;ies&#39;</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[&lt;a href=&quot;/tags/$tag/&quot; ]</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[title=&quot;$tag_data-&gt;{$tag}-&gt;{count} entr$plural&quot; ]</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[class=&quot;tag_$tag_data-&gt;{$tag}-&gt;{range_num}&quot;&gt;]</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[$tag]</span><span class="p">;</span>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[&lt;/a&gt;\n]</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">print</span> <span class="n">O</span> <span class="s">&quot;&lt;/div&gt;\n&quot;</span><span class="p">;</span>
</span><span class='line'><span class="nb">close</span> <span class="n">O</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># Now save the individual tag files</span>
</span><span class='line'><span class="c1"># First, clear out the directory because we&#39;re gonna </span>
</span><span class='line'><span class="c1"># regenerate all the files.</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">my</span> <span class="nv">$tag_dir</span> <span class="o">=</span> <span class="s">&quot;$octopress_root/source/tags&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># If source/tags exists but is a file</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="nb">die</span> <span class="s">&quot;source/tags is a file&quot;</span> <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="n">f</span> <span class="nv">$tag_dir</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Create the directory if it doesn&#39;t exist</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="o">!-</span><span class="n">d</span> <span class="nv">$tag_dir</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nb">mkdir</span> <span class="nv">$tag_dir</span><span class="p">;</span>
</span><span class='line'>    <span class="n">createTagsIndexMarkdown</span><span class="p">(</span><span class="nv">$tag_dir</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1"># Delete all directories under source/tags.</span>
</span><span class='line'>    <span class="c1"># We don&#39;t want to delete everything because we </span>
</span><span class='line'>    <span class="c1"># need to preserve tags/index.markdown in case </span>
</span><span class='line'>    <span class="c1"># something was modified there.</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$dirs</span> <span class="o">=</span> <span class="sb">`find $tag_dir/* -type d`</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">my</span> <span class="nv">@dirs</span> <span class="o">=</span> <span class="nb">split</span><span class="p">(</span><span class="sr">/[\r\n]+/</span><span class="p">,</span> <span class="nv">$dirs</span><span class="p">);</span>
</span><span class='line'>    <span class="k">foreach</span> <span class="k">my</span> <span class="nv">$dir</span> <span class="p">(</span><span class="nv">@dirs</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="sb">`/bin/rm -rf $dir`</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1"># Make a file for each tag.</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">foreach</span> <span class="k">my</span> <span class="nv">$tag</span> <span class="p">(</span><span class="nb">keys</span> <span class="nv">%$tag_data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">makeTagFile</span><span class="p">(</span><span class="nv">$tag</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="c1">##  ####################################################</span>
</span><span class='line'><span class="c1">##  Functions</span>
</span><span class='line'><span class="c1">##  ####################################################</span>
</span><span class='line'>
</span><span class='line'><span class="k">sub </span><span class="nf">makeTagFile</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="nb">shift</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">mkdir</span> <span class="s">&quot;source/tags/$tag&quot;</span>
</span><span class='line'>      <span class="o">||</span>
</span><span class='line'>      <span class="nb">die</span> <span class="s">&quot;Couldn&#39;t make directory source/tags/$tag&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nb">open</span> <span class="p">(</span><span class="n">O</span><span class="p">,</span> <span class="s">&quot;&gt; source/tags/$tag/index.markdown&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="o">||</span>
</span><span class='line'>      <span class="nb">die</span> <span class="s">&quot;Can&#39;t open source/tags/$tag/index.markdown&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq^---</span>
</span><span class='line'><span class="sx">layout: page</span>
</span><span class='line'><span class="sx">title: Tag&amp;#58; $tag</span>
</span><span class='line'><span class="sx">footer: false</span>
</span><span class='line'><span class="sx">---</span>
</span><span class='line'>
</span><span class='line'><span class="sx">&lt;div id=&quot;blog-archives&quot; class=&quot;category&quot;&gt;</span>
</span><span class='line'><span class="sx">^</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$year</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Sort by file name descending</span>
</span><span class='line'>    <span class="c1"># This is the same as sorting by date descending</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">foreach</span> <span class="k">my</span> <span class="nv">$file</span> <span class="p">(</span>
</span><span class='line'>               <span class="nb">sort</span> <span class="p">{</span> <span class="nv">$b</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">file</span><span class="p">}</span> <span class="ow">cmp</span> <span class="nv">$a</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">file</span><span class="p">}</span> <span class="p">}</span>
</span><span class='line'>                    <span class="nv">@</span><span class="p">{</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">pages</span><span class="p">}})</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1"># Get the year month and date</span>
</span><span class='line'>        <span class="c1">#</span>
</span><span class='line'>        <span class="k">my</span> <span class="p">(</span><span class="nv">$yyyy</span><span class="p">,</span> <span class="nv">$mm</span><span class="p">,</span> <span class="nv">$dd</span><span class="p">)</span> <span class="o">=</span> <span class="nv">$file</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">file</span><span class="p">}</span> <span class="o">=~</span>
</span><span class='line'>            <span class="sr">m!(\d\d\d\d)/(\d\d)/(\d\d)/!</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1"># The HTML and associated logic here mimics</span>
</span><span class='line'>        <span class="c1"># the HTML of the category pages - print </span>
</span><span class='line'>        <span class="c1"># a H2 for every new year</span>
</span><span class='line'>        <span class="c1">#</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nv">$yyyy</span> <span class="o">!=</span> <span class="nv">$year</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nv">$year</span> <span class="o">=</span> <span class="nv">$yyyy</span><span class="p">;</span>
</span><span class='line'>            <span class="k">print</span> <span class="n">O</span> <span class="s">&quot;&lt;h2&gt;$year&lt;/h2&gt;\n&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1"># Construct the URL &amp; date string</span>
</span><span class='line'>        <span class="c1">#</span>
</span><span class='line'>        <span class="k">my</span> <span class="nv">$url</span> <span class="o">=</span> <span class="nv">$file</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">file</span><span class="p">};</span>
</span><span class='line'>        <span class="nv">$url</span> <span class="o">=~</span> <span class="sr">s/^$octopress_root\/public//</span><span class="p">;</span>
</span><span class='line'>        <span class="k">my</span> <span class="nv">$title</span> <span class="o">=</span> <span class="nv">$file</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">title</span><span class="p">};</span>
</span><span class='line'>        <span class="k">my</span> <span class="nv">@months</span> <span class="o">=</span> <span class="sx">qw ( </span><span class="n">x</span> <span class="n">Jan</span> <span class="n">Feb</span> <span class="n">Mar</span> <span class="n">Apr</span> <span class="n">May</span> <span class="n">Jun</span>
</span><span class='line'>                          <span class="n">Jul</span> <span class="n">Aug</span> <span class="n">Sep</span> <span class="n">Oct</span> <span class="n">Nov</span> <span class="n">Dec</span> <span class="p">);</span>
</span><span class='line'>        <span class="k">my</span> <span class="nv">$mon</span> <span class="o">=</span> <span class="nv">$months</span><span class="p">[</span><span class="nv">$mm</span> <span class="o">*</span> <span class="mi">1</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[</span>
</span><span class='line'><span class="sx">&lt;article&gt;</span>
</span><span class='line'><span class="sx">&lt;h1&gt;&lt;a href=&quot;$url&quot;&gt;$title&lt;/a&gt;&lt;/h1&gt;</span>
</span><span class='line'><span class="sx">&lt;time datetime=&quot;$yyyy-$mm-${dd}T00:00:00-06:00&quot; pubdate&gt;&lt;span class=&#39;month&#39;&gt;$mon&lt;/span&gt; &lt;span class=&#39;day&#39;&gt;$dd&lt;/span&gt; &lt;span class=&#39;year&#39;&gt;$yyyy&lt;/span&gt;&lt;/time&gt;</span>
</span><span class='line'><span class="sx">&lt;footer&gt;</span>
</span><span class='line'><span class="sx">&lt;span class=&quot;categories&quot;&gt;posted in </span>
</span><span class='line'><span class="sx">]</span><span class="p">;</span>
</span><span class='line'>        <span class="c1"># Print each category, separated by commas</span>
</span><span class='line'>        <span class="c1">#</span>
</span><span class='line'>        <span class="k">print</span> <span class="n">O</span> <span class="nb">join</span><span class="p">(</span><span class="s">&quot;, &quot;</span><span class="p">,</span>
</span><span class='line'>            <span class="nb">map</span> <span class="p">{</span> <span class="s">&quot;&lt;a href=&#39;$_-&gt;{href}&#39;&gt;$_-&gt;{text}&lt;/a&gt;&quot;</span> <span class="p">}</span>
</span><span class='line'>                <span class="nv">@</span><span class="p">{</span><span class="nv">$file</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">categories</span><span class="p">}}</span>
</span><span class='line'>            <span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[&lt;/span&gt;</span>
</span><span class='line'><span class="sx">&lt;/footer&gt;</span>
</span><span class='line'><span class="sx">&lt;/article&gt;</span>
</span><span class='line'><span class="sx">]</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="s">&quot;&lt;/div&gt;\n&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">close</span> <span class="n">O</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="k">sub </span><span class="nf">getTags</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$file</span> <span class="o">=</span> <span class="nv">$</span><span class="nn">File::Find::</span><span class="nv">name</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Only parse files that look like posts</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">unless</span> <span class="nv">$file</span> <span class="o">=~</span><span class="sr"> /\.html$/</span><span class="p">;</span>
</span><span class='line'>    <span class="k">return</span> <span class="k">unless</span> <span class="nv">$file</span> <span class="o">=~</span><span class="sr"> </span>
</span><span class='line'><span class="sr">          /^$octopress_root\/public\/\d{4}\/\d{2}\/\d{2}\//</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Read the contents of the HTML file</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="nb">open</span> <span class="p">(</span><span class="n">HTML</span><span class="p">,</span> <span class="nv">$_</span><span class="p">)</span> <span class="o">||</span> <span class="nb">die</span> <span class="s">&quot;Can&#39;t open $file&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$contents</span> <span class="o">=</span> <span class="nb">join</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="sr">&lt;HTML&gt;</span><span class="p">);</span>
</span><span class='line'>    <span class="nb">close</span> <span class="n">HTML</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$tree</span> <span class="o">=</span> <span class="nn">HTML::</span><span class="n">TreeBuilder</span><span class="o">-&gt;</span><span class="k">new</span><span class="p">();</span>
</span><span class='line'>    <span class="nv">$tree</span><span class="o">-&gt;</span><span class="n">parse</span><span class="p">(</span><span class="nv">$contents</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Get the title</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$title</span> <span class="o">=</span> <span class="nv">$tree</span><span class="o">-&gt;</span><span class="n">look_down</span><span class="p">(</span><span class="n">_tag</span>  <span class="o">=&gt;</span> <span class="s">&quot;h1&quot;</span><span class="p">,</span>
</span><span class='line'>                                 <span class="n">class</span> <span class="o">=&gt;</span> <span class="s">&quot;entry-title&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="nv">$title</span> <span class="o">=</span> <span class="nv">$title</span><span class="o">-&gt;</span><span class="n">as_trimmed_text</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Get the categories</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$category_ent</span> <span class="o">=</span> <span class="nv">$tree</span><span class="o">-&gt;</span><span class="n">look_down</span><span class="p">(</span><span class="n">_tag</span>  <span class="o">=&gt;</span> <span class="s">&quot;span&quot;</span><span class="p">,</span>
</span><span class='line'>                                        <span class="n">class</span> <span class="o">=&gt;</span> <span class="s">&quot;categories&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">@as</span> <span class="o">=</span> <span class="nv">$category_ent</span><span class="o">-&gt;</span><span class="n">look_down</span><span class="p">(</span><span class="n">_tag</span>  <span class="o">=&gt;</span> <span class="s">&quot;a&quot;</span><span class="p">,</span>
</span><span class='line'>                                      <span class="n">class</span> <span class="o">=&gt;</span> <span class="s">&quot;category&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">@categories</span> <span class="o">=</span> <span class="p">();</span>
</span><span class='line'>    <span class="k">foreach</span> <span class="k">my</span> <span class="nv">$a</span> <span class="p">(</span><span class="nv">@as</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nb">push</span><span class="p">(</span><span class="nv">@categories</span><span class="p">,</span>
</span><span class='line'>            <span class="p">{</span> <span class="n">href</span> <span class="o">=&gt;</span> <span class="nv">$a</span><span class="o">-&gt;</span><span class="n">attr</span><span class="p">(</span><span class="s">&#39;href&#39;</span><span class="p">),</span>
</span><span class='line'>              <span class="n">text</span> <span class="o">=&gt;</span> <span class="nv">$a</span><span class="o">-&gt;</span><span class="n">as_trimmed_text</span>
</span><span class='line'>            <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Get the tags</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$ul</span> <span class="o">=</span> <span class="nv">$tree</span><span class="o">-&gt;</span><span class="n">look_down</span><span class="p">(</span><span class="s">&quot;_tag&quot;</span><span class="p">,</span> <span class="s">&quot;ul&quot;</span><span class="p">,</span>
</span><span class='line'>                              <span class="s">&quot;id&quot;</span>  <span class="p">,</span> <span class="s">&quot;tags_ul&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nv">$ul</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">my</span> <span class="nv">@items</span> <span class="o">=</span> <span class="nv">$ul</span><span class="o">-&gt;</span><span class="n">look_down</span><span class="p">(</span><span class="s">&quot;_tag&quot;</span> <span class="o">=&gt;</span> <span class="s">&quot;li&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="k">foreach</span> <span class="k">my</span> <span class="nv">$item</span> <span class="p">(</span><span class="nv">@items</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">my</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="nv">$item</span><span class="o">-&gt;</span><span class="n">as_trimmed_text</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1"># Finally, populate the data structure</span>
</span><span class='line'>            <span class="c1">#</span>
</span><span class='line'>            <span class="nb">push</span> <span class="p">(</span><span class="nv">@</span><span class="p">{</span><span class="nv">$tag_data</span><span class="o">-&gt;</span><span class="p">{</span><span class="nv">$tag</span><span class="p">}</span><span class="o">-&gt;</span><span class="p">{</span><span class="n">pages</span><span class="p">}},</span>
</span><span class='line'>                <span class="p">{</span> <span class="n">title</span>      <span class="o">=&gt;</span> <span class="nv">$title</span><span class="p">,</span>
</span><span class='line'>                  <span class="n">file</span>       <span class="o">=&gt;</span> <span class="nv">$file</span><span class="p">,</span>
</span><span class='line'>                  <span class="n">categories</span> <span class="o">=&gt;</span> <span class="o">\</span><span class="nv">@categories</span>
</span><span class='line'>          <span class="p">}</span> <span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1"># no tags in this document</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="nv">$tree</span><span class="o">-&gt;</span><span class="nb">delete</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># This function creates a default </span>
</span><span class='line'><span class="c1"># source/tags/index.markdown</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">sub </span><span class="nf">createTagsIndexMarkdown</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$tag_dir</span> <span class="o">=</span> <span class="nb">shift</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">open</span> <span class="p">(</span><span class="n">O</span><span class="p">,</span> <span class="s">&quot;&gt;$tag_dir/index.markdown&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="k">print</span> <span class="n">O</span> <span class="sx">qq[---</span>
</span><span class='line'><span class="sx">layout: page</span>
</span><span class='line'><span class="sx">title: Tags</span>
</span><span class='line'><span class="sx">footer: false</span>
</span><span class='line'><span class="sx">---</span>
</span><span class='line'>
</span><span class='line'><span class="sx">&lt;div class=&quot;tag_page&quot;&gt;</span>
</span><span class='line'><span class="sx"> {% include custom/tag_cloud.html %}</span>
</span><span class='line'><span class="sx">&lt;/div&gt;</span>
</span><span class='line'><span class="sx">]</span><span class="p">;</span>
</span><span class='line'>    <span class="nb">close</span> <span class="n">O</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Shell Tricks - Extracting A Column From A Text File]]></title>
    <link href="http://aijazansari.com/2012/01/04/extracting-a-column-from-a-text-file/"/>
    <updated>2012-01-04T21:25:00-06:00</updated>
    <id>http://aijazansari.com/2012/01/04/extracting-a-column-from-a-text-file</id>
    <content type="html"><![CDATA[<p>There have been times when I&#8217;ve had to extract a particular column from a
tab-separated or comma-separated file.  The best way to do this is to use the
shell command <code>cut</code>.  Let&#8217;s say I have a file named <code>input.txt</code> that looks like this:</p>

<!-- more -->




<figure class='code'><figcaption><span> (input.txt)</span> <a href='http://aijazansari.com/downloads/code/cut/input.txt'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='apacheconf'><span class='line'><span class="nb">First</span> Name,Last Name,User Id,Quota,Used,Last Login
</span><span class='line'><span class="err">Aijaz,Ansari,aijaz,5000,2200,2011/12/23</span> <span class="err">14:23</span>
</span><span class='line'><span class="err">John,Smith,js,7500,3300,2012/01/04</span> <span class="err">15:23</span>
</span><span class='line'><span class="err">Shilpa,Gupta,guptas,3000,1500,2010/10/25</span> <span class="err">12:00</span>
</span></code></pre></td></tr></table></div></figure>


<p>If I want to extract just the <code>User Id</code> column, I could type in the following:</p>

<pre><code>cut -d ',' -f 3 input.txt
</code></pre>

<p>Here the <code>-d</code> option specifies the delimeter and the <code>-f</code> option specifies the field(s) to be extracted.
The command above would generate the following output:</p>

<pre><code>User Id
aijaz
js
guptas
</code></pre>

<p>If I want to include line numbers, I can use the <code>nl</code> shell filter:</p>

<pre><code>$ cut -d ',' -f 3 input.txt | nl -ba
     1  User Id
     2  aijaz
     3  js
     4  guptas
$ 
</code></pre>

<p>If I want the <code>User Id</code> and <code>Used</code> columns, I could do:</p>

<pre><code>$ cut -d ',' -f 3,5 input.txt 
User Id,Used
aijaz,2200
js,3300
guptas,1500
$ 
</code></pre>

<p>As one would expect, I can change the order in which fields appear by using <code>-f 3,5,1</code>, for instance.</p>

<p>Look at the <em>man</em> page for <code>cut</code> for more options, including how to extract specific bytes from each line.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Excluding Yourself From Google Analytics]]></title>
    <link href="http://aijazansari.com/2011/12/20/excluding-yourself-from-google-analytics/"/>
    <updated>2011-12-20T17:56:00-06:00</updated>
    <id>http://aijazansari.com/2011/12/20/excluding-yourself-from-google-analytics</id>
    <content type="html"><![CDATA[<p>In <a href="http://aijazansari.com/2011/12/12/switching-to-octopress/">my last post</a> I wrote that I followed some instructions to
exclude myself from Google Analytics&#8217; reports on my Octopress blog.  There was an error in the
Javascript that was preventing the required cookie from being set.  Here&#8217;s what I did
that finally worked:</p>

<!--more-->


<p>The instructions that I found in Google&#8217;s <a href="http://support.google.com/googleanalytics/bin/answer.py?hl=en&amp;answer=55481">support forum</a>
correctly show how to set a filter to exclude any requests where the client has a custom cookie set.
However, the javascript code that&#8217;s supposed to generate the cookie gave me a &#8216;variable not defined&#8217; error.
<a href="http://www.google.com/support/forum/p/Google%20Analytics/thread?tid=251cc127a52875ef&amp;hl=en">This page</a>
had the instructions that worked for me.  For completeness, here&#8217;s the current version of the HTML file
I use to exclude myself from the reports:</p>

<figure class='code'><figcaption><span> (exclude.html)</span> <a href='http://aijazansari.com/downloads/code/octopress/exclude.html'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="cp">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
</span><span class='line'><span class="nt">&lt;html</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;head&gt;</span>
</span><span class='line'>    <span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;content-type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html;charset=iso-8859-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;title&gt;</span>Excluded from Google Analytics<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>    <span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/javascript&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">_gaq</span> <span class="o">=</span> <span class="nx">_gaq</span> <span class="o">||</span> <span class="p">[];</span>
</span><span class='line'>      <span class="nx">_gaq</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">&#39;_setAccount&#39;</span><span class="p">,</span> <span class="s1">&#39;UA-XXXXXXXX-X&#39;</span><span class="p">]);</span>
</span><span class='line'>      <span class="nx">_gaq</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">&#39;_trackPageview&#39;</span><span class="p">]);</span>
</span><span class='line'>      <span class="nx">_gaq</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">&#39;_setVar&#39;</span><span class="p">,</span> <span class="s1">&#39;excludeMePlease&#39;</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'>      <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">ga</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">&#39;script&#39;</span><span class="p">);</span> <span class="nx">ga</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="s1">&#39;text/javascript&#39;</span><span class="p">;</span> <span class="nx">ga</span><span class="p">.</span><span class="nx">async</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'>        <span class="nx">ga</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;https:&#39;</span> <span class="o">==</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span> <span class="o">?</span> <span class="s1">&#39;https://ssl&#39;</span> <span class="o">:</span> <span class="s1">&#39;http://www&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;.google-analytics.com/ga.js&#39;</span><span class="p">;</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">&#39;script&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span> <span class="nx">s</span><span class="p">.</span><span class="nx">parentNode</span><span class="p">.</span><span class="nx">insertBefore</span><span class="p">(</span><span class="nx">ga</span><span class="p">,</span> <span class="nx">s</span><span class="p">);</span>
</span><span class='line'>      <span class="p">})();</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;/script&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/head&gt;</span>
</span><span class='line'>  <span class="nt">&lt;body&gt;</span>
</span><span class='line'>    You have been excluded from Google Analytics.
</span><span class='line'>  <span class="nt">&lt;/body&gt;</span>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Essentially, I moved the line that sets the cookie from the <code>body</code> tag to line 11.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Switching To Octopress]]></title>
    <link href="http://aijazansari.com/2011/12/12/switching-to-octopress/"/>
    <updated>2011-12-12T08:19:00-06:00</updated>
    <id>http://aijazansari.com/2011/12/12/switching-to-octopress</id>
    <content type="html"><![CDATA[<p>Over this past weekend I switched my blog over from WordPress to
Octopress.  In this post I write about why I did it, what exactly I did
to get the blog just the way I wanted, and what I plan to do in the
future.</p>

<!--more-->


<p>If you were to ask me what&#8217;s the difference between the two,
the first thing I would tell you is that Octopress serves static HTML.
The blog is generated on my local machine (usually my laptop) and then
the static files are uploaded to the server.  This is also called
&#8216;baking the site.&#8217;</p>

<p>While I&#8217;m not an &#8216;A-list&#8217; blogger and don&#8217;t have to worry about my site
being Fireballed or Slashdotted (or JessicaHisched or SwissMissed) it&#8217;s
comforting to know that my blog is being served as efficiently as it can
be.</p>

<p>A lot has been said about the virtues of baking your own blogs, so I&#8217;m
not gonna repeat them here.  You can
<a href="http://mattgemmell.com/2011/09/12/blogging-with-octopress/">read what Matt Gemmell had to say about it</a> and also
what Brent Simmons wrote about it in
<a href="http://inessential.com/2009/01/30/new_publishing_system_tour_of_my_head">these</a>
<a href="http://inessential.com/2011/03/16/a_plea_for_baked_weblogs">three</a>
<a href="http://inessential.com/2011/03/17/more_on_baked_blogs">articles</a>.</p>

<p>For me, though, the biggest motivating factor was that I didn&#8217;t like
using the Wordpress website to create and edit blog posts.  The web
interface is just not natural.  Yes, there are apps like MarsEdit that
simplify the process, but that&#8217;s still one more layer of abstraction
than I care to interact with.  I want the experience of writing to be as
close to the metal as possible: I use a <a href="http://aijazansari.com/2010/01/26/why-text-editors-matter">text editor</a>
to edit text - I should be able to use any text editor to edit my blog.</p>

<p>Enter Octopress and its support of <a href="http://daringfireball.net/projects/markdown/">Markdown</a>.  I set up Octopress
per <a href="http://daringfireball.net/projects/markdown/">Matt&#8217;s recommendations</a> and with some minor hacking I was able
to migrate the blog over the course of one weekend.  In what&#8217;s left of
this post I&#8217;ll write about what changes I made to the system to get the
blog &#8216;just right&#8217; and what changes I would like to make in the future.</p>

<h3>Floating Images</h3>

<p>Octopress has a nice shorthand for specifying images:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>{&#037; img [class names] /path/to/image [width] [height] [title text [alt text]] &#037;}</span></code></pre></td></tr></table></div></figure>


<p>Using the proper class names one can have the image float left or right
or otherwise set its alignment.  However, I like having captions under
my images.  This requires a floating div that would contain both the image
and the caption under it.  For best results, the div would have to be
about as wide as the image.</p>

<p>Octopress is based on <a href="http://jekyllrb.com">Jekyll</a> that supports the
<a href="http://liquidmarkup.org/">Liquid template engine written in ruby</a>.<br/>
I could probably have written a Liquid
plugin to do this, but I don&#8217;t know Ruby (yet) and so I had to come up
with another solution.</p>

<p>To get this to work I created my own markup that would be inserted into
the markdown text as an HTML comment.  Markdown would preserve the HTML
comment, and it would show up in the HTML file after <code>rake generate</code>
was called.  I wrote a small shell script call <code>generate</code> that calls
<code>rake generate</code> and then invokes the perl script <code>imageCaption.pl</code> on every generated html file:</p>

<figure class='code'><figcaption><span> (generate)</span> <a href='http://aijazansari.com/downloads/code/octopress/generate'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'>rake generate
</span><span class='line'>
</span><span class='line'>find /Users/aijaz/octopress/public <span class="se">\</span>
</span><span class='line'>     -type f <span class="se">\</span>
</span><span class='line'>     -name <span class="s1">&#39;*.html&#39;</span> <span class="se">\</span>
</span><span class='line'>     -exec /Users/aijaz/octopress/imageCaption.pl <span class="s1">&#39;{}&#39;</span> <span class="s1">&#39;;&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>And, here&#8217;s <code>imageCaption.pl</code>.  It searches for the markup and
replaces it with the appropriate HTML.</p>

<figure class='code'><figcaption><span> (imageCaption.pl)</span> <a href='http://aijazansari.com/downloads/code/octopress/imageCaption.pl'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
</pre></td><td class='code'><pre><code class='perl'><span class='line'><span class="c1">#!/usr/bin/perl</span>
</span><span class='line'>
</span><span class='line'><span class="k">use</span> <span class="n">strict</span><span class="p">;</span>
</span><span class='line'><span class="k">use</span> <span class="n">warnings</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># The file that was specified on the command line</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">my</span> <span class="nv">$file</span> <span class="o">=</span> <span class="nb">shift</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Read all lines from the file into a list named &#39;lines&#39;</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="nb">open</span> <span class="p">(</span><span class="n">I</span><span class="p">,</span> <span class="nv">$file</span><span class="p">)</span> <span class="o">||</span> <span class="nb">die</span><span class="p">;</span>
</span><span class='line'><span class="k">my</span> <span class="nv">@lines</span> <span class="o">=</span> <span class="sr">&lt;I&gt;</span><span class="p">;</span>
</span><span class='line'><span class="nb">close</span> <span class="n">I</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Scan each line for our special markup: </span>
</span><span class='line'><span class="c1"># a comment that starts with ai and then has upto 6</span>
</span><span class='line'><span class="c1"># space-separated components</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="c1"># For each such line, call makeDiv on the components and </span>
</span><span class='line'><span class="c1"># replace the markup with the output of that function</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="k">foreach</span> <span class="k">my</span> <span class="nv">$line</span> <span class="p">(</span><span class="nv">@lines</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nv">$line</span> <span class="o">=~</span> <span class="n">s</span><span class="o">^&lt;!--</span> <span class="n">ai</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">\</span><span class="n">S</span><span class="o">+</span><span class="p">)</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">\</span><span class="n">S</span><span class="o">+</span><span class="p">)</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">\</span><span class="n">S</span><span class="o">+</span><span class="p">)</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">\</span><span class="n">d</span><span class="o">+</span><span class="p">)</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">\</span><span class="n">d</span><span class="o">+</span><span class="p">)</span><span class="o">\</span><span class="n">s</span><span class="o">+</span><span class="p">(</span><span class="o">.*</span><span class="p">?)</span><span class="o">\</span><span class="n">s</span><span class="o">*--&gt;^</span><span class="n">makeDiv</span><span class="p">(</span><span class="nv">$1</span><span class="p">,</span> <span class="nv">$2</span><span class="p">,</span> <span class="nv">$3</span><span class="p">,</span> <span class="nv">$4</span><span class="p">,</span> <span class="nv">$5</span><span class="p">,</span> <span class="nv">$6</span><span class="p">)</span><span class="o">^</span><span class="ow">ge</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Save the possibly modified contents of the &#39;lines&#39; array</span>
</span><span class='line'><span class="c1"># back to the original file</span>
</span><span class='line'><span class="c1">#</span>
</span><span class='line'><span class="nb">open</span> <span class="p">(</span><span class="n">O</span><span class="p">,</span> <span class="s">&quot;&gt;$file&quot;</span><span class="p">)</span> <span class="o">||</span> <span class="nb">die</span><span class="p">;</span>
</span><span class='line'><span class="k">print</span> <span class="n">O</span> <span class="nb">join</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="nv">@lines</span><span class="p">);</span>
</span><span class='line'><span class="nb">close</span> <span class="n">O</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="k">sub </span><span class="nf">makeDiv</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># The enclosing div should be this much bigger</span>
</span><span class='line'>    <span class="c1"># than the image.  This accounts for the white margin</span>
</span><span class='line'>    <span class="c1"># that octopress puts around the image</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$width_inc</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># The 6 components in our markup are</span>
</span><span class='line'>    <span class="c1"># align:   &#39;l&#39;, &#39;c&#39; or &#39;r&#39;.  Used to specify the</span>
</span><span class='line'>    <span class="c1">#          css class</span>
</span><span class='line'>    <span class="c1"># target:  The href of the a tag that&#39;s put around</span>
</span><span class='line'>    <span class="c1">#          the image</span>
</span><span class='line'>    <span class="c1"># image:   The URL of the image </span>
</span><span class='line'>    <span class="c1"># width:   The width of the image</span>
</span><span class='line'>    <span class="c1"># height:  The height of the image</span>
</span><span class='line'>    <span class="c1"># caption: This is used as the alt tag of the image, </span>
</span><span class='line'>    <span class="c1">#          the title of the a tag as well as the </span>
</span><span class='line'>    <span class="c1">#          caption that&#39;s displayed under the image.</span>
</span><span class='line'>    <span class="c1">#          This field may be blank, but don&#39;t do that </span>
</span><span class='line'>    <span class="c1">#          because really, that&#39;s the whole point of </span>
</span><span class='line'>    <span class="c1">#          this exercise.</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">my</span> <span class="p">(</span><span class="nv">$align</span><span class="p">,</span> <span class="nv">$target</span><span class="p">,</span> <span class="nv">$image</span><span class="p">,</span>
</span><span class='line'>        <span class="nv">$width</span><span class="p">,</span> <span class="nv">$height</span><span class="p">,</span> <span class="nv">$caption</span><span class="p">)</span> <span class="o">=</span> <span class="nv">@_</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">my</span> <span class="nv">$div_width</span> <span class="o">=</span> <span class="nv">$width</span> <span class="o">+</span> <span class="nv">$width_inc</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1"># Construct the html.  Note that the css class is</span>
</span><span class='line'>    <span class="c1"># &#39;ai&#39; followed by the value of the &#39;align&#39; component.</span>
</span><span class='line'>    <span class="c1">#</span>
</span><span class='line'>    <span class="k">return</span> <span class="nb">join</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">,</span>
</span><span class='line'>        <span class="sx">qq^&lt;div class=&quot;ai$align&quot; style=&quot;width:${div_width}px&quot;&gt;^</span><span class="p">,</span>
</span><span class='line'>            <span class="sx">qq^&lt;a href=&quot;$target&quot; title=&quot;$caption&quot;&gt;^</span><span class="p">,</span>
</span><span class='line'>                <span class="sx">qq^&lt;img src=&quot;$image&quot; ^</span><span class="p">,</span>
</span><span class='line'>                    <span class="sx">qq^width=&quot;$width&quot; ^</span><span class="p">,</span>
</span><span class='line'>                    <span class="sx">qq^height=&quot;$height&quot; ^</span><span class="p">,</span>
</span><span class='line'>                    <span class="sx">qq^alt=&quot;$caption&quot; ^</span><span class="p">,</span>
</span><span class='line'>                    <span class="sx">qq^border=0&gt;&lt;/a&gt;&lt;br&gt;^</span><span class="p">,</span>
</span><span class='line'>            <span class="sx">qq^$caption&lt;/div&gt;^</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>In order to tie this all together, I had to define the css classes for
the various &#8216;ai&#8230;&#8217; classes.  I added the following code to <code>sass/custom/_styles.scss</code>:</p>

<figure class='code'><figcaption><span> (_styles.scss)</span> <a href='http://aijazansari.com/downloads/code/octopress/_styles.scss'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
</pre></td><td class='code'><pre><code class='scss'><span class='line'><span class="c1">// This File is imported last, and will override other styles in the cascade</span>
</span><span class='line'><span class="c1">// Add styles here to make changes without digging in too much</span>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.ail</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'>    <span class="na">float</span><span class="o">:</span> <span class="no">left</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-size</span><span class="o">:</span> <span class="mi">12</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'>    <span class="na">color</span><span class="o">:</span> <span class="mh">#808080</span><span class="p">;</span>
</span><span class='line'>    <span class="na">padding-right</span><span class="o">:</span> <span class="mi">1</span><span class="kt">em</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-style</span><span class="o">:</span> <span class="no">italic</span><span class="p">;</span>
</span><span class='line'>    <span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
</span><span class='line'>    <span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">1</span><span class="kt">em</span><span class="p">;</span>
</span><span class='line'>    <span class="na">line-height</span><span class="o">:</span> <span class="mi">16</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.air</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'>    <span class="na">float</span><span class="o">:</span> <span class="no">right</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-size</span><span class="o">:</span> <span class="mi">12</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'>    <span class="na">color</span><span class="o">:</span> <span class="mh">#808080</span><span class="p">;</span>
</span><span class='line'>    <span class="na">padding-left</span><span class="o">:</span> <span class="mi">1</span><span class="kt">em</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-style</span><span class="o">:</span> <span class="no">italic</span><span class="p">;</span>
</span><span class='line'>    <span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
</span><span class='line'>    <span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">1</span><span class="kt">em</span><span class="p">;</span>
</span><span class='line'>    <span class="na">line-height</span><span class="o">:</span> <span class="mi">16</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.aic</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-size</span><span class="o">:</span> <span class="mi">12</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'>    <span class="na">color</span><span class="o">:</span> <span class="mh">#808080</span><span class="p">;</span>
</span><span class='line'>    <span class="na">font-style</span><span class="o">:</span> <span class="no">italic</span><span class="p">;</span>
</span><span class='line'>    <span class="na">text-align</span><span class="o">:</span> <span class="no">center</span><span class="p">;</span>
</span><span class='line'>    <span class="na">margin-bottom</span><span class="o">:</span> <span class="mi">2</span><span class="kt">em</span><span class="p">;</span>
</span><span class='line'>    <span class="na">margin-left</span><span class="o">:</span> <span class="no">auto</span><span class="p">;</span>
</span><span class='line'>    <span class="na">margin-right</span><span class="o">:</span> <span class="no">auto</span><span class="p">;</span>
</span><span class='line'>    <span class="na">line-height</span><span class="o">:</span> <span class="mi">16</span><span class="kt">pt</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.air</span> <span class="nt">img</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.ail</span> <span class="nt">img</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="nt">div</span><span class="nc">.aic</span> <span class="nt">img</span> <span class="p">{</span>
</span><span class='line'>    <span class="na">max-width</span><span class="o">:</span> <span class="mi">100</span><span class="kt">%</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Note that I added <code>max-width:100%</code> for all the divs and images -
this ensures that the images won&#8217;t get cropped when the page is
displayed on a smaller, mobile display.</p>

<p>You can see an example of these aligned images in my post on <a href="http://aijazansari.com/2010/01/23/how-camera-lenses-work/">how lenses work</a>.</p>

<h3>Web Server Optimizations</h3>

<p>I host my site on an Apache 2 web server.  <a href="http://aijazansari.com/2010/04/10/google-now-considers-website-speed-in-its-ranking/#optimizing">As I had done with my taskforest website</a> ,
I decided to optimize the site and get a high score from
<a href="http://code.google.com/speed/page-speed/">PageSpeed</a>.  I enabled
compression of html files, and turned on KeepAlive.</p>

<p>I also had to change my site redirections.  Originally, I was
redirecting <a href="http://aijazansari.com/">aijazansari.com</a> to
<a href="http://www.aijazansari.com/">www.aijazansari.com</a>.  However, I noticed
that my site was not being displayed correctly on Windows Internet
Explorer Version 8.  As <a href="https://github.com/imathis/octopress/issues/89">this page</a> shows,
it&#8217;s probably due to
poorly-implemented restrictions to prevent cross-site scripting.  I
changed the redirections to be the other way around, and then the site
worked fine on IE8.  I&#8217;ve included the relevant part of my <code>httpd.conf</code>
file below:</p>

<figure class='code'><figcaption><span> (httpd.conf)</span> <a href='http://aijazansari.com/downloads/code/octopress/httpd.conf'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class='apacheconf'><span class='line'><span class="nt">&lt;VirtualHost</span> <span class="s">216.139.228.44</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nb">ServerName</span>        aijazansari.com
</span><span class='line'>    <span class="nb">DocumentRoot</span>      <span class="s2">&quot;/home/aijaz/aijazansari.com&quot;</span>
</span><span class='line'>    <span class="nb">FileEtag</span>          <span class="k">None</span>
</span><span class='line'>    <span class="nb">ExpiresActive</span>     <span class="k">On</span>
</span><span class='line'>    <span class="nb">ExpiresDefault</span>    A3600
</span><span class='line'>    <span class="nb">CustomLog</span>        logs/access_log_blog combined
</span><span class='line'>    <span class="nb">KeepAlive</span>        <span class="k">On</span>
</span><span class='line'>    <span class="nb">ErrorDocument</span>    <span class="m">404</span> <span class="sx">/404.html</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># 1 Week</span>
</span><span class='line'>    <span class="nt">&lt;FilesMatch</span> <span class="s">&quot;\.(ico|gif|jpe?g|png|flv|pdf|swf|mov|mp3|wmv|ppt)$&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nb">ExpiresDefault</span> A604800
</span><span class='line'>        <span class="nb">Header</span> append  Cache-Control <span class="s2">&quot;public&quot;</span>
</span><span class='line'>    <span class="nt">&lt;/FilesMatch&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># 1 Day</span>
</span><span class='line'>    <span class="nt">&lt;FilesMatch</span> <span class="s">&quot;\.(xml|txt|html|htm|js|css)$&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nb">SetOutputFilter</span> DEFLATE
</span><span class='line'>        <span class="nb">BrowserMatch</span>    ^Mozilla/4         gzip-only-text/html
</span><span class='line'>        <span class="nb">BrowserMatch</span>    ^Mozilla/4\.0[678] no-gzip
</span><span class='line'>        <span class="nb">BrowserMatch</span>    \bMSIE            !no-gzip !gzip-only-text/html
</span><span class='line'>        <span class="nb">ExpiresDefault</span>  A86400
</span><span class='line'>        <span class="nb">Header</span> append   Cache-Control <span class="s2">&quot;private, must-revalidate&quot;</span>
</span><span class='line'>    <span class="nt">&lt;/FilesMatch&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c"># Never cache</span>
</span><span class='line'>    <span class="nt">&lt;FilesMatch</span> <span class="s">&quot;\.(pl)$&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nb">ExpiresDefault</span> A0
</span><span class='line'>        <span class="nb">Header</span> set     Cache-Control <span class="s2">&quot;no-store, no-cache, must-revalidate, max-age=0&quot;</span>
</span><span class='line'>        <span class="nb">Header</span> set     Pragma <span class="s2">&quot;no-cache&quot;</span>
</span><span class='line'>    <span class="nt">&lt;/FilesMatch&gt;</span>
</span><span class='line'><span class="nt">&lt;/VirtualHost&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;VirtualHost</span> <span class="s">216.139.228.44</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nb">ServerName</span>    www.aijazansari.com
</span><span class='line'>    <span class="nb">RedirectMatch</span> (.*) http://aijazansari.com$1
</span><span class='line'><span class="nt">&lt;/VirtualHost&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Excluding Myself From Google Analytics Reports</h3>

<p>While I tweak this blog, I&#8217;ll be accessing it very often.  I don&#8217;t want
my accesses to influence the Google Analytics reports.  I followed the
advice on <a href="http://www.instantfundas.com/2009/01/how-to-stop-google-analytics-from.html">this page</a>
and set up Analytics to ignore the cookie that only I would have set.</p>

<p><strong>Update 2011/12/20 - </strong> These instructions didn&#8217;t work.  Read
<a href="http://aijazansari.com/2011/12/20/excluding-yourself-from-google-analytics/">my next post</a> to see how I got it to work.</p>

<h3>Can&#8217;t Forget The FavIcon</h3>

<p>Finally, I overwrote the default <code>favicon.png</code> with my own version.
It was the fininshing touch to get the blog &#8216;just right&#8217; (for now).</p>

<h3>Plans For The Future</h3>

<p>The first thing I want to change about my blog is the theme.  I think
the default Octopress theme is very good, but I personally prefer the
more minimalistic themes.  I used to use <a href="http://basicmaths.subtraction.com/">Basic Maths</a> on my WordPress
site.  I might have to learn some Ruby, and also learn about Liquid and
Jekyll, but I would like to make a theme that&#8217;s somewhere between
<a href="http://minimalmac.com/">Minimal Mac</a> and Basic Maths.  I&#8217;m also gonna
have to replace my Perl image alignment hack to a Liquid plugin soon.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How To Wrap Text In Vim]]></title>
    <link href="http://aijazansari.com/2011/12/07/how-to-wrap-text-in-vim/"/>
    <updated>2011-12-07T07:00:01-06:00</updated>
    <id>http://aijazansari.com/2011/12/07/how-to-wrap-text-in-vim</id>
    <content type="html"><![CDATA[<p>[Another in my <a href="http://aijazansari.com/2011/11/21/there-and-back-again-a-hackers-switch-from-emacs-back-to-vi/">series of posts on Vim</a>]</p>

<p>If you&#8217;re writing natural language text you may wish to format your paragraph
so that the text wraps before lines get too long. Here&#8217;s how you do it:</p>

<p>To set the maximum width of a line of text, go to Normal mode and enter</p>

<pre><code>:set textwidth=72
</code></pre>

<!--more-->


<p>This will set the maximum width of a line to 72.  If you want to reformat a
paragraph you have already typed, one easy way to do this is to type in <code>{gw}</code>.</p>

<p>The first <code>{</code> takes you to the beginning of the paragraph. <code>gw</code> formats all
the text between the current location and the point you would be taken to had
you typed in the motion command that follows the gq.  In this case the motion
command is <code>}</code> which means go to the beginning of the next paragraph.  So, <code>gw}</code>
formats the rest of the paragraph but leaves the cursor where it was.  If you
want to move the cursor to the the location indicated by the motion command,
then use <code>gq</code> instead of <code>gw</code>.</p>

<p>Why would you want to use <code>gq</code>?  Simple: when you have a bunch of paragraphs you
want to format or reformat, you can use <code>gq}</code> once and then hit <code>.</code> to repeat
the previous command over and over again.  There are other shortcuts to
reformat an entire file.  We&#8217;ll look into those later.</p>

<p>Like emacs, Vim has very powerful paragraph reformatting commands.  In future
blog posts we&#8217;ll look at some of them in more detail.  If you want to explore
them on your own, I would suggest you enter</p>

<pre><code>:help gq 
:help formatoptions
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Understanding Your Camera's Histogram]]></title>
    <link href="http://aijazansari.com/2011/12/05/understanding-your-cameras-histogram/"/>
    <updated>2011-12-05T17:00:58-06:00</updated>
    <id>http://aijazansari.com/2011/12/05/understanding-your-cameras-histogram</id>
    <content type="html"><![CDATA[<p>In a <a href="http://aijazansari.com/2011/11/30/what-is-a-histogram/">previous blog post</a> we learned what a histogram is.  In today’s post we’ll see
how to use histograms to help take properly-exposed photographs.  If you
haven’t read the previous post, or are not familiar with histograms, I would
recommend you read that post before continuing with this one.</p>

<!--more-->


<p>You may remember that in photography the term ‘exposure’ refers to the amount
of light that enters the lens.  A photograph that is considered to be
correctly exposed is neither too bright or too dark.  It’s just right.  An
underexposed picture is too dark - the dark areas are pure black, and
therefore lack detail. Similarly an overexposed picture is too bright - the
bright areas are pure white and therefore lack detail. Figure 1 shows an
underexposed picture, and Figure 2 shows an overexposed one.</p>

<!-- ai l /wp/underPlain.jpg /wp/underPlain-170x150.jpg 170 150 Figure 1 - An underexposed image -->




<!-- ai l /wp/overPlain.jpg /wp/overPlain-170x150.jpg 170 150 Figure 2 - An overexposed image -->


<p>Modern digital cameras, whether they are point-and-click models or SLRs, have
two main tools to help you determine the exposure of your pictures.  The first
is the light meter.  The light meter will tell you whether or not the camera
thinks your picture is well exposed.  It usually displays some sort of linear
indicator that ranges from “Very Underexposed” to “Very Overexposed.”</p>

<p>The second tool is the histogram.  The histogram graphs the distribution of
the different levels of light in the photograph (more on this later).  Most
cameras display the histogram on the LCD panel after you take the picture, but
some now display a live histogram even before you “press the button.”</p>

<h2>What Histograms Display</h2>

<p>In order to understand exactly what the histogram displays you first need to
consider the camera sensor (the CCD).  When you take a picture with a digital
camera, light enters the camera through the lens and falls on the the sensor.
A different amount of light falls on each ‘pixel’ of the sensor.  Each pixel
converts the light into a corresponding voltage.  This analog voltage is then
converted to a digital value which is usually 12 bits (between 1 and 4096).</p>

<p>The histogram displays how many pixels are at each of these 4096 levels.  The
x axis represents the brightness levels - from 1 to 4096, where 1 is “very
dark” and 4096 is “very bright.”  The y axis graphs the number of pixels at
each of these levels.</p>

<h2>Examples of histograms</h2>

<p>Each sensor has a range of how much light it can detect.  That range is
anywhere between 5 and 12 f-stops, depending on the sensor.  (If you remember
from this blog post, every lower f-stop doubles the amount of light entering
the lens.)  Now, if everything in your photo is at a brightness level that
falls within your sensor’s range, that’s a good thing.  Figure 3 is an example
of such a picture.</p>

<!-- ai c /wp/sea.png /wp/sea.png 620 520 Figure 3 - A properly exposed image -->


<p>If the scene you’re trying to photograph is too bright for the sensor, some
percentage of the pixels will have a brightness that is too high for the
sensor to measure, so all of those pixels will be assigned the maximum
brightness value (4096).  This is when you start having problems - if the
pixels in your image range in brightness equally from 3000 to 6000, every
pixel from 4096 to 6000 will show up with a value of 4096 (pure white).  So
what’s happened is that you’ve lost 1004 pixels’ worth of information.  All
the detail of the image between 4096 and 6000 is lost.  In that case you would
be better off decreasing the exposure by increasing the shutter speed or
decreasing the aperture (choosing a higher f-stop).  Figure 4 is an example of
such a picture.  Look at the right edge of the histogram - the high number of
pixels at the maximum level indicate ‘clipping’ of the histogram.  That’s your
data loss.  Compare it to the histogram for Figure 3, which tails off nicely
on the right end.  Once you get the all the pixels back within the 0-4096
range (as seen from the histogram) you’re back to no loss of data.</p>

<!-- ai c /wp/over.png /wp/over.png 620 520 Figure 4 - A overexposed image -->


<p>Now let’s look at the other scenario: If the scene you’re trying to photograph
is too dark for the sensor, some percentage of the pixels will have a
brightness that is too low for the sensor to measure, so all of those pixels
will be assigned the minimum brightness value (1).  If your range is 3000 (as
in the last example) a large number of pixels will show up as black.  Again,
you’ve lost data, and lost detail in the image.  In that case you would be
better off increasing the exposure by decreasing the shutter speed or
increasing the aperture (choosing a lower f-stop).  Figure 5 is an example of
such a picture.  Look at the left edge of the histogram - the large number of
pixels at the minimum level indicate ‘clipping’ of the histogram.  That’s your
data loss.  Compare it to the histogram for Figure 3, which tails off nicely
on the left end. Once you get the all the pixels back within the 0-4096 range
(as seen from the histogram) you’re back to no loss of data.</p>

<!-- ai c /wp/under.png /wp/under.png 620 520 Figure 5 - A underexposed image -->


<h2>What if the range is too large?</h2>

<p>Changing the exposure to get the histogram within the sensor’s range is a good
solution as long as the range of brightness in the scene is less than the
range of the sensor.  However, common scenes in real life often have ranges
higher than those of many of today’s best cameras.  We don’t notice it often
because our eyes have a ridiculously large range of about 10 f-stops, and when
they’re paired with the processing of our brains, we can see better than
cameras can.  Figure 6 is an example of an image whose range is more than that
of my camera.  Notice the clipping on both ends.  What should be done here?</p>

<!-- ai c /wp/range1.png /wp/range1.png 620 520 Figure 6 - An image with a wide range of brightness -->


<p>There are two things you can do here, and you should consider doing them both.
The first is biasing towards the highlights, and you do that while you’re on
the scene taking the pictures. The human eye tends to focus on the brighter
parts of the picture, and the brain expects shadows to be dark.  You can take
advantage of these expectations and expose your picture to minimize the
clipping on the bright end (the right end).  While that means you’ll get more
clipping on the darker end, you’ll have more detail and greater tonal range on
the brighter end.  It’s very subjective, but pictures like that tend to look
more natural and therefore better than pictures where the bright areas are
washed out.  You can see that this is what I did in Figure 7.</p>

<!-- ai c /wp/range2.png /wp/range2.png 620 520 Figure 7 - Exposing for the higlights -->


<p>The second thing you can do is post-process the image with image processing
software.  You do this after you import your picture into your computer.  Two
of the most popular image processing applications are Adobe’s Lightroom and
Apple’s Aperture.  If you’re shooting in RAW format (as you should be) there’s
a lot of data in the image for you to play with.   Post-processing images is a
topic for a future blog post, but Figure 8 shows how the image changed after I
took Figure 7 and increased the “Recovery” and added “Fill Light” in
Lightroom.  The histogram looks better now, but you can never get something
for nothing.  Look at the middle of the histogram - it’s gotten a flatter.
The shape’s changed and image is a little washed out, now.  Again, these are
subjective settings.  You need to play around with them until you get the kind
of picture you want.</p>

<!-- ai c /wp/range3.png /wp/range3.png 620 520 Figure 8 - After post-processing -->


<h2>What is the perfect histogram?</h2>

<p>After all this talk about clipping and how to avoid it, you may ask yourself
“What is the ideal histogram I should try to get in all my pictures?”  There
is none.  A histogram isn’t good or bad. It’s just a way of looking at your
picture.  You get to decide if the image that shows up on the LCD panel is the
image you want or not.  If it isn’t, then the histogram can help you determine
why.  If you’re not sure, the histogram can tell you whether or not you’ll
have room to play around with the settings once you start processing the
picture.  If there is no clipping you’ll have a lot of room to work with.</p>

<p>Figures 9 &amp; 10 are examples of histograms with a lot of clipping. I don’t
care, because these are exactly the pictures I was looking for - pictures with
a lot of contrast and a lot of specular highlights (brightness where a light
source is reflected off a shiny surface).  In many cases specular highlights
may be ignored - they’re actually good because they add to the ‘drama’ of the
shot.</p>

<!-- ai c /wp/noor.png /wp/noor.png 620 520 Figure 9 - An image with acceptable clipping on the right -->




<!-- ai c /wp/bean.png /wp/bean.png 620 520 Figure 10 - An image with acceptable clipping on both ends -->


<p>Many cameras have a setting where they will display overexposed pixels (those
where clipping occurs to the right) in flashing red.  This helps you determine
very easily just how much of your image has clipped.  The image post-
processing software allows you to do that as well.</p>

<h2>Summary</h2>

<p>Histograms are very powerful and easy-to-use tools.  Learn how to read them,
and then use them.  Set up your camera to display the histogram after every
shot is taken, for about 5 seconds.  A quick glance will let you know whether
or not you’ve “messed up the shot” and need to take it again. If your camera
supports it, also set it up to highlight overexposed areas.  I’ve found this
to be very useful as well.</p>

<p>In a future blog post we will complete our discussion about histograms – we’ll
learn how data is distributed on the histogram and how to maximize the data we
have for post-processing. Until then, keep taking pictures (and use the
histograms).</p>

<h2>References</h2>

<ul>
<li><a href="http://www.luminous-landscape.com/tutorials/understanding-series/understanding-histograms.shtml">Understanding Histograms</a> by the wonderful site <a href="http://www.luminous-landscape.com/">The Luminous Landscape</a>.</li>
<li>Chapter 2 of <a href="http://www.amazon.com/Mastering-Nikon-D700-Darrell-Young/dp/1933952237">Mastering the Nikon D700</a> by Darrell Young and James Johnson.</li>
</ul>


<p>Thanks to John Gallagher for reviewing an early draft of this post and giving
me his feedback.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Inspiration vs. Imitation]]></title>
    <link href="http://aijazansari.com/2011/12/05/inspiration-vs-imitation/"/>
    <updated>2011-12-05T06:13:18-06:00</updated>
    <id>http://aijazansari.com/2011/12/05/inspiration-vs-imitation</id>
    <content type="html"><![CDATA[<p>Jessica Hische has just published <a href="http://www.jessicahische.is/obsessedwiththeinternet/andbeingresponsivelyinspired/inspiration-vs-imitation-2">a very well written article</a> on &#8220;why it&#8217;s ok to copy people to learn, but
never ok to publish that work.&#8221;  I love the tone of her writing.  Even though
I&#8217;m not a designer and won&#8217;t ever be as good a letterer as she is, I hope to
be able to write as well as her.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How To Quickly Delete Words While In Insert Mode In Vim]]></title>
    <link href="http://aijazansari.com/2011/12/02/how-to-quickly-delete-words-while-in-insert-mode-in-vim/"/>
    <updated>2011-12-02T09:00:52-06:00</updated>
    <id>http://aijazansari.com/2011/12/02/how-to-quickly-delete-words-while-in-insert-mode-in-vim</id>
    <content type="html"><![CDATA[<p>[Another in my <a href="http://aijazansari.com/2011/11/21/there-and-back-again-a-hackers-switch-from-emacs-back-to-vi/">series of posts on Vim</a>]</p>

<p>Sometimes when you&#8217;re typing natural language text, you find yourself wanting
to rephrase the sentence you&#8217;ve written so far.  You could hit backspace many
times to delete the characters to the left of the cursor, or you could type
Ctrl-W.  When you&#8217;re in Insert mode, Ctrl-W will delete from the cursor to the
beginning of the previous word.</p>

<!--more-->


<p>If, instead, you type in Ctrl-U, you will delete everything to the left of the
cursor on that line (everything before it), and preserve everything to the
right of the cursor (everything after it).</p>

<p>Let&#8217;s try this out.  Open a test file in Vim and enter Insert mode by hitting
<code>a</code> or <code>i</code> or <code>o</code>.  Then type in the following sentence (don&#8217;t hit <code>&lt;ESC&gt;</code>):</p>

<pre><code>A slow brown dog lazed 
</code></pre>

<p>Then hit <code>Ctrl-W</code> twice.  You&#8217;ll see that each time you hit <code>Ctrl-W</code>, you delete
the word to the left of the cursor.  After hitting <code>Ctrl-W</code> twice, you should
see:</p>

<pre><code>A slow brown 
</code></pre>

<p>Then continue with the rest of the sentence.  Type in &#8216;fox jumps over a lazy
dog.&#8217;  After typing that in, still in Insert mode, use the arrow keys to move
your cursor just before the &#8216;b&#8217; in &#8216;brown&#8217;:</p>

<pre><code>A slow brown fox jumps over a lazy dog
       ^
       Your cursor should be just to the left of the 'b'
</code></pre>

<p>The hit <code>Ctrl-U</code>.  Everything to the left of the cursor will be deleted, leaving
you with:</p>

<pre><code>brown fox jumps over a lazy dog
</code></pre>

<p>Then you an continue typing in &#8216;The quick&#8217; , which will get you:</p>

<pre><code>The quick brown fox jumps over a lazy dog
</code></pre>

<p>I&#8217;ve found that learning these little shortcuts really helps me type
efficiently and keep my typing in sync with my thoughts.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What Is A Histogram?]]></title>
    <link href="http://aijazansari.com/2011/11/30/what-is-a-histogram/"/>
    <updated>2011-11-30T20:16:45-06:00</updated>
    <id>http://aijazansari.com/2011/11/30/what-is-a-histogram</id>
    <content type="html"><![CDATA[<p>A key aspect of good photography is exposure - the amount of light that enters
the lens.  One of the most useful tools a digital cameras has to help you
measure a photograph&#8217;s exposure is the histogram. In order to learn how to use
it, you must first learn understand what a histogram is.</p>

<p>Let&#8217;s pretend I teach a class of 20 students. One day I decide to give the
students a test in which they can score anywhere from 0 to 100 points.  After
grading the tests I want to see how the population of students did.  So I
graph the scores in a histogram. A histogram displays the distribution of
measured values across a population.  Let&#8217;s make one now.</p>

<!--more-->


<p>The following table lists my fictional students&#8217; scores:</p>

<pre><code>Alice       82
Bob         79
Chetan      88
Darla       94
Evan       100
Fatima      89
Gerard      96
Harry       43
Ibtissam    68
Jack        56
Kate        93
Labiba      70
Mary        76
Noreen      83
Ophelia     92
Pablo       63
Qazveen     84
Rick        89
Sophia      73
Taline      89
</code></pre>

<p>The first thing I do is make a bunch of &#8216;buckets&#8217; of values into which each
score should go.  The larger the bucket size the more scores it will have.
The smaller the bucket size the fewer scores it will have.  I choose a bucket
size of 5 points because that seems like a nice level of granularity.  5
points gives me the following 20 buckets:</p>

<pre><code>0-5
6-10
11-15
16-20
21-25
26-30
31-35
36-40
41-45
46-50
51-55
56-60
61-65
66-70
71-75
76-80
81-85
86-90
91-95
96-100
</code></pre>

<p>I draw these buckets horizontally because that&#8217;s how histograms are almost
always drawn:</p>

<pre><code>| | | | | | | | | | | | | | | | | | | | |
0 5 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1
    0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0
                                        0
</code></pre>

<p>The next thing I do is go through the list of scores and put each score in its
appropriate bucket.  I do this by marking an X in the appropriate bucket.
Alice scored 82, so I mark an X in the bucket between 80 and 85.  Bob got 79,
so I put an X in the bucket between 75 and 80.  When I&#8217;m done, the histogram
looks like this:</p>

<pre><code>                                  X
                                X X X
                            X X X X X X
                 X     X X X X X X X X X
| | | | | | | | | | | | | | | | | | | | |
0 5 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 1
    0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0
                                        0
</code></pre>

<p>The x axis of this histogram has the ranges of values (scores) and the y axis
represents the number of data points that have that value.</p>

<p>If you think about it, this histogram has less data than the original table
did - It doesn&#8217;t map a student&#8217;s name to their score.  However, it does
illustrate the distribution of the scores in a manner that isn&#8217;t obvious from
the table: Looking at this histogram you can see that most students scored 75
or higher, and that more students scored in the 85-90 bucket than in any other
bucket.  We call distributions that look like this &#8216;skewed to the right&#8217; -
most of the data points are towards the right end of the histogram.</p>

<p>Now that you know what histograms are, you&#8217;re ready to use them to take better
photos.  I&#8217;ll cover that in Monday&#8217;s blog post.</p>

<h2>References</h2>

<p><a href="http://en.wikipedia.org/wiki/Histogram">Wikipedia entry on histograms.</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How To Insert A Line Of Dashes In Vim]]></title>
    <link href="http://aijazansari.com/2011/11/28/how-to-insert-a-line-of-dashes-in-vim/"/>
    <updated>2011-11-28T23:02:08-06:00</updated>
    <id>http://aijazansari.com/2011/11/28/how-to-insert-a-line-of-dashes-in-vim</id>
    <content type="html"><![CDATA[<p>[Another in my <a href="http://aijazansari.com/2011/11/21/there-and-back-again-a-hackers-switch-from-emacs-back-to-vi/">series of posts on Vim</a>]</p>

<p>If you&#8217;re a developer, you will often find yourself having to insert a line of
dashes or hashes (#) or asterisks into your comments.  In this post I&#8217;ll show
you how to do this quickly.  Memorize this because you&#8217;ll wind up doing this
often.  Position the cursor to the beginning of a blank like (in command mode)
and enter the following:</p>

<pre><code>80a#&lt;ESC&gt;
</code></pre>

<!--more-->


<p>The &#8216;80&#8217; tells Vim that you want to repeat the next command 80 times.  The
command immediately follows: <code>a#</code>.  This command instructs vi to add a hash
character to the right of the cursor.  You terminate the command with the
<code>&lt;ESC&gt;</code>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How To Subtract One File From Another]]></title>
    <link href="http://aijazansari.com/2011/11/23/how-to-subtract-one-file-from-another/"/>
    <updated>2011-11-23T14:45:26-06:00</updated>
    <id>http://aijazansari.com/2011/11/23/how-to-subtract-one-file-from-another</id>
    <content type="html"><![CDATA[<p>Let&#8217;s say you have two text files, FileA and FileB.  You want a file that has
all the lines of FileA that are<em> not</em> in FileB.  How do you do that?</p>

<p>The simple answer is <code>grep</code>. The <code>-v</code> option inverts the search, and only prints
lines that do not match.  The <code>-f</code> option is used to specify a file that
contains a list of all the patterns for which to look - one pattern per line.</p>

<!--more-->


<p>Let&#8217;s say FileA looks like this:</p>

<pre><code>1 Alice 10
2 Bob   15
3 Alice 16
4 Carl  10
5 Dave  20
</code></pre>

<p>and FileB looks like this:</p>

<pre><code>2 Bob   15
4 Carl  10
</code></pre>

<p>Then, you can use the following command to print out all lines from FileA that
are not in FileB:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>    <span class="nv">$ </span>grep -vf FileB FileA
</span><span class='line'>    1 Alice 10
</span><span class='line'>    3 Alice 16
</span><span class='line'>    5 Dave  20
</span><span class='line'>    <span class="nv">$ </span>
</span></code></pre></td></tr></table></div></figure>


<p>You could, alternatively, have gotten the same results if FileB looked like
this:</p>

<pre><code>.*Bob.*
.*Carl.*
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Different Kind Of Running]]></title>
    <link href="http://aijazansari.com/2011/11/22/a-different-kind-of-running/"/>
    <updated>2011-11-22T15:33:02-06:00</updated>
    <id>http://aijazansari.com/2011/11/22/a-different-kind-of-running</id>
    <content type="html"><![CDATA[<p>I don&#8217;t like running unless I&#8217;m running towards something or away from
something.  But I do run often because of the health benefits. I&#8217;ve always
thought the right way to run was to land on my heel and then transfer the
weight to the ball of my foot, and finally the toes.  Now according to <a href="http://www.nytimes.com/2011/11/06/magazine/running-christopher-mcdougall.html">this article</a> and <a href="http://www.posetech.com/pose_method/pose-method.html">this site</a> I may have been doing it wrong.</p>

<!--more-->


<p>The key here is to land on the balls of your feet and not extend the ankle
past the knee.  I&#8217;ve started trying it out this week, and so far I can feel a
difference.  Yesterday at the end of a 3 mile run I started feeling a slight
pain in the tendons below the knee.  Slowing down and focusing on keeping my
form as described in the attached links eliminated the pain immediately.
Today I ran for just 1.5 miles, but I made sure I followed the prescribed form
very carefully.  The run was easier than normal.  Slower than normal, but it
felt less strenuous.</p>

<p>With only two data points I&#8217;m not ready to say that this system works for me,
but I&#8217;ll keep trying it out and let you know how it goes. I don&#8217;t know how to
evaluate success, since I&#8217;m not an avid runner, and can&#8217;t really compare it to
previous results.  I&#8217;ll keep reading and running and we&#8217;ll see.</p>

<!-- ai c /wp/corniche.jpg /wp/corniche.jpg 612 612 The Sharjah Corniche - A Nice Place For A Morning Run -->

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[There and Back Again - A Hacker's Switch from Emacs Back to Vi]]></title>
    <link href="http://aijazansari.com/2011/11/21/there-and-back-again-a-hackers-switch-from-emacs-back-to-vi/"/>
    <updated>2011-11-21T14:55:49-06:00</updated>
    <id>http://aijazansari.com/2011/11/21/there-and-back-again-a-hackers-switch-from-emacs-back-to-vi</id>
    <content type="html"><![CDATA[<p>When I first learned how to exist on UNIX, in 1988, I used
<a href="http://en.wikipedia.org/wiki/Vi">vi</a> as my primary editor. During the next
nine years I taught myself how to become a power user - migrating from the
simple motion and copy and paste to more complex skills like marks and named
registers. When I started graduate school I saw many of the professors and
grad students using <a href="http://www.gnu.org/s/emacs/">emacs</a>.  I tried it out a
couple of times, but it was not until 1997 that I decided to take the time to
stick with emacs and take the time to learn the right way to do things even
when I could get the job done faster in vi.</p>

<!--more-->


<p>I used emacs almost exclusively after that. I got myself a couple of books,
browsed the gnu.emacs newsgroup and wrote my own elisp code for matching HTML
tags, among other things. For a while I used rmail from within emacs as my
primary news client, used org-mode as an issue and task manager and even
flirted with the idea of using emacs as a web browser. I used emacs for half a
generation and didn&#8217;t think I would switch back to vi for daily work.</p>

<p>But switch back I did, in November of 2011.  After Richard Stallman, the
inventor of emacs made some controversial comments about the passing of Steve
Jobs, the angered Mac and iOS developer community starting posting some of the
more polarizing of his writings.  Reading them I realized that Stallman and I
held conflicting opinions about some issues I consider very important - namely
the importance of one&#8217;s family and the relative importance of emacs in the
Grand Scheme Of Things.</p>

<p>I was surprised by my reaction to Stallman&#8217;s opinions.  Like him, I care
deeply about the skill of editing text. But I could not separate my dislike
for Stallman&#8217;s worldview from my enthusiasm towards the platform. To me it was
inevitable that I would switch away from emacs. I wanted to show myself that
to me, at least, emacs was never a religion - it was never the One True Way.
It is a fantastic editor, but no more. I wanted to convince myself that there
could be life after emacs - that Stallman was wrong - that I could continue to
be productive and excel with an editor other than emacs. So I decided to
switch to <a href="http://www.vim.org">vim</a>.</p>

<p>As I relearn vi through vim I&#8217;ll post what I learn here.  If you&#8217;re a vim
user, please join the discussion and post your comments, suggestions,
disagreements, etc.  That will not just help you and me, but others who happen
upon this page while trying to learn something.</p>

<h2>The First Vim Tip</h2>

<p>I&#8217;ll start off with a discussion how to do something in vim that I could never
do in vi, and that I did all the time in emacs - rectangular selections. In my
line of work I often need to select a rectangle of text and operate upon it; I
may need to delete the rectangle of text, or I may have to append something to
either of the two edges, or delete something from either of the two edges.  In
emacs I would use C-x r k and C-x r y to kill and yank, for example.  In vim
we can use visual mode.</p>

<p>There are three different kinds of visual modes.  Each operates on text
differently, and each is invoked differently.  To get to &#8216;normal&#8217; visual mode,
hit &#8216;v&#8217; when in command mode. To get to the &#8216;rectangular&#8217; visual mode, hit C-v
(hit Shift-V for line visual mode).  This will allow you to use your cursor to
highlight a rectangle of text and easily see the scope of your next commands.</p>

<p>Once you have the proper rectangle highlighted, you can delete it by hitting
&#8216;d&#8217;.  You can insert text to the left edge of every line by hitting &#8216;I&#8217; and
inserting the text.  You will have to end with an ESC, and not enter any
newlines (or else the editor will treat it like a normal insertion).  You can
also insert text to the right edge of every line by hitting I and inserting
the text.  Again you will have to end with an ESC, for the same reasons as
before.  You can copy (yank) the rectangle by hitting &#8216;y&#8217;.</p>

<p>[Update 11/29 - Changed header to &#8220;The first Vim Tip&#8221;]</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Taking Back My Relationships]]></title>
    <link href="http://aijazansari.com/2011/07/09/taking-back-my-relationships/"/>
    <updated>2011-07-09T18:59:15-05:00</updated>
    <id>http://aijazansari.com/2011/07/09/taking-back-my-relationships</id>
    <content type="html"><![CDATA[<p>I&#8217;m trying to formulate a sensible strategy to overhaul my net presence. The
rough plan so far:</p>

<ul>
<li>Change my 12-year-old email address that is on every spammer&#8217;s short list</li>
<li> Extract friends&#8217; contact info from Facebook</li>
<li>Delete Facebook account.</li>
<li>Import FB contacts into Google &amp; Mac</li>
<li>Redirect facebook friends to current tech blog (aijazansari.com) and new personal blog.</li>
<li>Find out if FB friends can subscribe to an RSS feed of my blog somehow (doesn&#8217;t seem possible any more)</li>
<li>Pick up the phone and actually talk to friends more often.</li>
</ul>


<p>The goal&#8217;s pretty obvious - I want to reclaim my data.  I think <em>I</em> own my
relationships, not FB, not Twitter, and not Google+.  So far, G+ may be the
most accommodating network out there - if I can export my G+ presence as
easily as I can export my G+ contacts, we might have a good candidate here.</p>

<p>If you have any ideas or comments or experience with this, please let me know.</p>

<p>I&#8217;ll keep you posted.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Glen Ellyn Volunteer Fire Company]]></title>
    <link href="http://aijazansari.com/2011/07/01/glen-ellyn-volunteer-fire-company/"/>
    <updated>2011-07-01T19:50:31-05:00</updated>
    <id>http://aijazansari.com/2011/07/01/glen-ellyn-volunteer-fire-company</id>
    <content type="html"><![CDATA[<!-- ai c /wp/GlenEllynVolFireDept.jpg /wp/GlenEllynVolFireDept-440x440.jpg 440 440 Glen Ellyn Volunteer Fire Company -->


<blockquote><p>Fire marks were used in the 1700s to designate homes or buildings protected
by the fire insurance companies. They were generally oval plates placed on the
outside of a structure to let volunteer fire brigades know which buildings
carried a &#8220;reward&#8221; if saved.</p></blockquote>

<p>You can read more on this <a href="http://glenellynfire.com/tsv.shtml">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Implementing Inertial Scrolling in iOS]]></title>
    <link href="http://aijazansari.com/2011/04/25/implementing-inertial-scrolling-in-ios/"/>
    <updated>2011-04-25T21:36:25-05:00</updated>
    <id>http://aijazansari.com/2011/04/25/implementing-inertial-scrolling-in-ios</id>
    <content type="html"><![CDATA[<p>I hadn&#8217;t really given much thought to how the iPhone handles scrolling until I
recently had to implement it myself. I needed to add vertical scrolling to a
UIView that models a real-life metaphor. In my particular case I feel using a
UIScrollView would break the metaphor - the user would &#8220;snap out&#8221; of the
immersive app and realize they&#8217;re merely using an iPhone app with a pretty
skin. So the natural solution was to implement scrolling myself. This is how
it went from simple, unnatural scrolling to its current state of acceptable
inertial scrolling.</p>

<!--more-->


<h2>Version 1 - Hit By The Ugly Stick</h2>

<p>I started off with my view controller&#8217;s existing implementations of <code>touchesBegan:withEvent:</code>, <code>touchesMoved:withEvent:</code> and <code>touchesEnded:withEvent:</code>.
In <code>touchesBegan</code> I saved the starting y location of the view controller
(<code>self.frame.origin.y</code>) into an instance variable. I also saved the total amount
moved in another variable:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'>    <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">touchesBegan:</span><span class="p">(</span><span class="n">NSSet</span> <span class="o">*</span><span class="p">)</span><span class="n">touches</span> <span class="nl">withEvent:</span><span class="p">(</span><span class="n">UIEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">event</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">lastFrameOriginY</span> <span class="o">=</span> <span class="n">canvasView</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>In <code>touchesMoved</code> I tracked the location of the touch in the view, as well as
the location of the previous touch in the view.  Subtracting one from the
other I was able to see how much the touch had moved in between invocations
and in what direction:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'>    <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">touchesMoved:</span><span class="p">(</span><span class="n">NSSet</span> <span class="o">*</span><span class="p">)</span><span class="n">touches</span> <span class="nl">withEvent:</span><span class="p">(</span><span class="n">UIEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">event</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSObject</span> <span class="o">*</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">touches</span> <span class="n">anyObject</span><span class="p">];</span>
</span><span class='line'>        <span class="n">CGPoint</span> <span class="n">p</span><span class="err">     </span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">locationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>        <span class="n">CGPoint</span> <span class="n">o</span><span class="err">     </span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">previousLocationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>        <span class="c1">// Translation only, not real distance between points</span>
</span><span class='line'>        <span class="c1">//</span>
</span><span class='line'>        <span class="kt">int</span> <span class="n">deltay</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">o</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>        <span class="c1">// This is how much we have moved since we started dragging</span>
</span><span class='line'>        <span class="c1">// defined as an integer property of the view controller</span>
</span><span class='line'>        <span class="c1">//</span>
</span><span class='line'>        <span class="p">[</span><span class="n">self</span> <span class="nl">setCumulativeDeltaY:</span> <span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span> <span class="o">+</span> <span class="n">deltay</span><span class="p">];</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">!=</span> <span class="n">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">CGRect</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="n">canvasView</span> <span class="n">frame</span><span class="p">];</span>
</span><span class='line'>            <span class="c1">// Move the view according to how much the touch has moved</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="n">r</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">lastFrameOriginY</span> <span class="o">+</span> <span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span><span class="p">;</span>
</span><span class='line'>            <span class="p">[</span><span class="n">canvasView</span> <span class="nl">setFrame:</span><span class="n">r</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>I didn&#8217;t really need to implement <code>touchesEnded</code> because by the time the touches
ended, the view was already where it needed to be.  That&#8217;s the whole point of
dragging, right?  Well, yeah, but just leaving the view where it was made for
a very abrupt and unnatural stop.  There was no gentle stop. Ironically, the
immediate stop made the application feel more sluggish than if I had the
inertial stop we&#8217;re all used to with UIScrollView.  Clearly it was time for
plan B.</p>

<h2>Plan B - Well, At Least Your Intentions Were Honorable.</h2>

<p>How difficult can it be?  Just implement a <code>touchesEnded:withEvent:</code> and use
animation to move the view a certain distance before stopping, depending on
how fast it was going in the first place.</p>

<p>This is where I donned my Engineer hat and told myself &#8220;Obviously, speed is
distance divided by time so, I need to find the distance moved so far and
divide it by the time between when the touchdown event and the touchup event,
and (as my music teacher would say) Viola! That&#8217;s my speed.&#8221;</p>

<p>Turns out that&#8217;s wrong.  I looked at the UIScrollView, and what matters is not
how fast you got from touchdown to touchup, but how fast you were moving right
before touchup.  Okay, we have a really good approximation of that already -
that&#8217;s the distance between locationInView and previousLocationInView (what I
call deltay).  So that was chosen to be my speed.  I decide to choose
reasonable approximations rather than model the physics perfectly.  The
scrolling just needs to &#8216;look right&#8217; and it should not slow the app down or be
computationally intensive.  Here&#8217;s what it looked like:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'>    <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">touchesEnded:</span><span class="p">(</span><span class="n">NSSet</span> <span class="o">*</span><span class="p">)</span><span class="n">touches</span> <span class="nl">withEvent:</span><span class="p">(</span><span class="n">UIEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">event</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSObject</span> <span class="o">*</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">touches</span> <span class="n">anyObject</span><span class="p">];</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">!=</span> <span class="n">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">CGPoint</span> <span class="n">p</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">locationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>            <span class="n">CGPoint</span> <span class="n">o</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">previousLocationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>            <span class="c1">// Translation only, not real distance between points</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">deltay</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">o</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// This is how much we have moved since we started dragging</span>
</span><span class='line'>            <span class="c1">// defined as an integer property of the view controller</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="p">[</span><span class="n">self</span> <span class="nl">setCumulativeDeltaY:</span><span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span> <span class="o">+</span> <span class="n">deltay</span><span class="p">];</span>
</span><span class='line'>            <span class="n">CGRect</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="n">canvasView</span> <span class="n">frame</span><span class="p">];</span>
</span><span class='line'>            <span class="c1">// Put a cap on what the speed can be, so we</span>
</span><span class='line'>            <span class="c1">// don&#39;t have to deal with absurdly fast flicks.</span>
</span><span class='line'>            <span class="c1">// Also, treat a tiny move as no move at all - you don&#39;t want a</span>
</span><span class='line'>            <span class="c1">// tiny move causing a large drift.</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">maxSpeed</span> <span class="o">=</span> <span class="mi">80</span><span class="p">;</span>
</span><span class='line'>             <span class="k">if</span><span class="err">     </span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&gt;</span> <span class="n">maxSpeed</span><span class="p">)</span><span class="err">        </span> <span class="p">{</span> <span class="n">deltay</span> <span class="o">=</span><span class="err"> </span> <span class="n">maxSpeed</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&lt;</span> <span class="o">-</span><span class="n">maxSpeed</span><span class="p">)</span><span class="err">       </span> <span class="p">{</span> <span class="n">deltay</span> <span class="o">=</span> <span class="o">-</span><span class="n">maxSpeed</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">5</span> <span class="o">&amp;&amp;</span> <span class="n">deltay</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="kt">double</span> <span class="n">duration</span> <span class="o">=</span> <span class="mf">0.5</span><span class="p">;</span>
</span><span class='line'>             <span class="c1">// Chose 10 after trial and error because</span>
</span><span class='line'>             <span class="c1">// the results &#39;looked right&#39;</span>
</span><span class='line'>             <span class="c1">//</span>
</span><span class='line'>             <span class="kt">int</span> <span class="n">finalDistance</span> <span class="o">=</span> <span class="n">deltay</span> <span class="o">*</span> <span class="mi">10</span><span class="p">;</span>
</span><span class='line'>             <span class="n">r</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span> <span class="o">+=</span> <span class="n">finalDistance</span><span class="p">;</span>
</span><span class='line'>             <span class="c1">// Animate the view with an EaseOut curve so that it slows down.</span>
</span><span class='line'>             <span class="c1">//</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">beginAnimations:</span><span class="err">@</span><span class="s">&quot;inertialSlide&quot;</span> <span class="nl">context:</span><span class="nb">NULL</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">setAnimationDuration:</span><span class="n">duration</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">setAnimationCurve:</span><span class="n">UIViewAnimationCurveEaseOut</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">canvasView</span> <span class="nl">setFrame:</span><span class="n">r</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="n">commitAnimations</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>Now that&#8217;s better!  The scrolling came to a gentle stop as I gingerly tested
it.  Then I tried a few fast flicks of the view, and the scrolling just
stopped abruptly (see Ugly Stick).  There was no inertia here.  It was like
the fast flicks were being treated as really slow scrolls.</p>

<p>Sure enough, when I started debugging, the value of <code>deltay</code> inexplicably moved
to -2 or 2 when the scrolling was really fast.  <a href="http://opetopic.com/blog/2010/05/26/implementing-drag-and-throw-behavior-with-touches/">This post at Opetopic Blog</a> confirmed my suspicions: the events were happening so
fast that <code>previousLocationInView</code> could not be trusted.</p>

<p>So then I decided to go with a hybrid solution - Keep what I have for slow
scrolls, and use something else for fast scrolls.  First, I would need to know
how to differentiate between slow and fast scrolls.  Then I would need to
figure out how to handle fast scrolls.  Here&#8217;s what I did:</p>

<h2>Final Version: That&#8217;s More Like It</h2>

<p>I added two new instance variables to my view controller: <code>startTime</code> and
<code>endTime</code>, whose difference would give me the duration between the touchdown and
touchup events.  I also added a CGPoint called <code>previousLocation</code> that saved the
starting location of the touchdown event.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'>    <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">touchesBegan:</span><span class="p">(</span><span class="n">NSSet</span> <span class="o">*</span><span class="p">)</span><span class="n">touches</span> <span class="nl">withEvent:</span><span class="p">(</span><span class="n">UIEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">event</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">lastFrameOriginY</span> <span class="o">=</span> <span class="n">canvasView</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>        <span class="c1">// Save the time at which the touches started</span>
</span><span class='line'>        <span class="c1">//</span>
</span><span class='line'>        <span class="n">startTime</span> <span class="o">=</span> <span class="n">CACurrentMediaTime</span><span class="p">();</span>
</span><span class='line'>        <span class="n">NSObject</span> <span class="o">*</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">touches</span> <span class="n">anyObject</span><span class="p">];</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">!=</span> <span class="n">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Save the location at which the touches started</span>
</span><span class='line'>            <span class="c1">// (in the parent view)</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="n">previousLocation</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">locationInView:</span> <span class="n">bgView</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>Now that the starting location and time are saved, we can use these variables
to figure out whether the flick was &#8216;too fast.&#8217;</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
</pre></td><td class='code'><pre><code class='cpp'><span class='line'>    <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">touchesEnded:</span><span class="p">(</span><span class="n">NSSet</span> <span class="o">*</span><span class="p">)</span><span class="n">touches</span> <span class="nl">withEvent:</span><span class="p">(</span><span class="n">UIEvent</span> <span class="o">*</span><span class="p">)</span><span class="n">event</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSObject</span> <span class="o">*</span> <span class="n">obj</span> <span class="o">=</span> <span class="p">[</span><span class="n">touches</span> <span class="n">anyObject</span><span class="p">];</span>
</span><span class='line'>        <span class="c1">// The time at which the touches ended</span>
</span><span class='line'>        <span class="c1">//</span>
</span><span class='line'>        <span class="n">endTime</span> <span class="o">=</span> <span class="n">CACurrentMediaTime</span><span class="p">();</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">obj</span> <span class="o">!=</span> <span class="n">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">CGPoint</span> <span class="n">p</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">locationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>            <span class="n">CGPoint</span> <span class="n">o</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">previousLocationInView:</span> <span class="n">canvasView</span><span class="p">];</span>
</span><span class='line'>            <span class="c1">// Translation only, not real distance between points</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">deltay</span> <span class="o">=</span> <span class="n">p</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">o</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// This is how much we have moved since we started dragging</span>
</span><span class='line'>            <span class="c1">// defined as an integer property of the view controller</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="p">[</span><span class="n">self</span> <span class="nl">setCumulativeDeltaY:</span><span class="n">self</span><span class="p">.</span><span class="n">cumulativeDeltaY</span> <span class="o">+</span> <span class="n">deltay</span><span class="p">];</span>
</span><span class='line'>            <span class="n">CGRect</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[</span><span class="n">canvasView</span> <span class="n">frame</span><span class="p">];</span>
</span><span class='line'>            <span class="c1">// Put a cap on what the speed can be, so we</span>
</span><span class='line'>            <span class="c1">// don&#39;t have to deal with absurdly fast flicks.</span>
</span><span class='line'>            <span class="c1">// Also, treat a tiny move as no move at all - you don&#39;t want a</span>
</span><span class='line'>            <span class="c1">// tiny move causing a large drift.</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="kt">int</span> <span class="n">maxSpeed</span> <span class="o">=</span> <span class="mi">80</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// Find out the how long the touches lasted</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="kt">float</span> <span class="n">timeDifference</span> <span class="o">=</span> <span class="n">endTime</span> <span class="o">-</span> <span class="n">startTime</span><span class="p">;</span>
</span><span class='line'>            <span class="c1">// Chose 0.35 after some trial and error.  It seemed like the most</span>
</span><span class='line'>            <span class="c1">// natural amount</span>
</span><span class='line'>            <span class="c1">//</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">timeDifference</span> <span class="o">&lt;</span> <span class="mf">0.35</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="c1">// The flick was really fast.  Use Distance/Time to</span>
</span><span class='line'>                <span class="c1">// calculate speed.  It will likely be accurate.  </span>
</span><span class='line'>                <span class="c1">// Get the current location in the parent view</span>
</span><span class='line'>                <span class="c1">//</span>
</span><span class='line'>                <span class="n">o</span> <span class="o">=</span> <span class="p">[(</span><span class="n">UITouch</span> <span class="o">*</span><span class="p">)</span><span class="n">obj</span> <span class="nl">locationInView:</span> <span class="n">bgView</span><span class="p">];</span>
</span><span class='line'>                <span class="c1">// Calculate the speed as distance/time.  Use some scaling</span>
</span><span class='line'>                <span class="c1">// to get the speed to be comparable to a normal flick.</span>
</span><span class='line'>                <span class="c1">//</span>
</span><span class='line'>                <span class="n">deltay</span> <span class="o">=</span> <span class="p">(</span><span class="n">o</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">previousLocation</span><span class="p">.</span><span class="n">y</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">timeDifference</span> <span class="o">*</span> <span class="mi">10</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>             <span class="k">if</span><span class="err">     </span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&gt;</span> <span class="n">maxSpeed</span><span class="p">)</span><span class="err">        </span> <span class="p">{</span> <span class="n">deltay</span> <span class="o">=</span><span class="err"> </span> <span class="n">maxSpeed</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&lt;</span> <span class="o">-</span><span class="n">maxSpeed</span><span class="p">)</span><span class="err">       </span> <span class="p">{</span> <span class="n">deltay</span> <span class="o">=</span> <span class="o">-</span><span class="n">maxSpeed</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">deltay</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">5</span> <span class="o">&amp;&amp;</span> <span class="n">deltay</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>             <span class="kt">double</span> <span class="n">duration</span> <span class="o">=</span> <span class="mf">0.5</span><span class="p">;</span>
</span><span class='line'>             <span class="c1">// Chose 10 after trial and error because</span>
</span><span class='line'>             <span class="c1">// the results &#39;looked right&#39;</span>
</span><span class='line'>             <span class="c1">//</span>
</span><span class='line'>             <span class="kt">int</span> <span class="n">finalDistance</span> <span class="o">=</span> <span class="n">deltay</span> <span class="o">*</span> <span class="mi">10</span><span class="p">;</span>
</span><span class='line'>             <span class="n">r</span><span class="p">.</span><span class="n">origin</span><span class="p">.</span><span class="n">y</span> <span class="o">+=</span> <span class="n">finalDistance</span><span class="p">;</span>
</span><span class='line'>             <span class="c1">// Animate the view with an EaseOut curve so that it slows down.</span>
</span><span class='line'>             <span class="c1">//</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">beginAnimations:</span><span class="err">@</span><span class="s">&quot;inertialSlide&quot;</span> <span class="nl">context:</span><span class="nb">NULL</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">setAnimationDuration:</span><span class="n">duration</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="nl">setAnimationCurve:</span><span class="n">UIViewAnimationCurveEaseOut</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">canvasView</span> <span class="nl">setFrame:</span><span class="n">r</span><span class="p">];</span>
</span><span class='line'>             <span class="p">[</span><span class="n">UIView</span> <span class="n">commitAnimations</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>With these new changes the speed is calculated acceptably well in both cases -
slow scrolls and super-fast flicks.  Note that I used trial and error to come
up with the 0.35 second threshold and also to calculate the speed (<code>deltay</code>) in
that case. These values work on the device that I have tested with, but more
testing will be needed to see if this is a solution that will work for all the
devices out there.</p>

<h2>Summary</h2>

<p>I was certainly surprised at how important the &#8216;little&#8217; things like inertial
scrolling are to a satisfying user experience.  While my crude attempt at
implementing it may not be technically accurate, it appears to be good enough.
And that&#8217;s really what I&#8217;m looking for.  If I&#8217;ve done my job well, no one will
notice the scrolling.  I&#8217;m not designing a user interface toolkit; I just
don&#8217;t want it to stick out like a sore thumb.  Please keep in mind that this
isn&#8217;t exactly the code that&#8217;s in my app - I&#8217;ve modified it for display here.
I may have introduced some minor syntax errors while formatting the code for
this blog post.  Also, I can&#8217;t stress enough that this isn&#8217;t a default
solution.  Whenever possible, use the UIScrollView.  It&#8217;s there because it
works.  It&#8217;s Apple&#8217;s gift to you.  If you can use it, don&#8217;t roll your own
implementation.  Just use UIScrollView.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA["Hello, World" on the iPhone]]></title>
    <link href="http://aijazansari.com/2010/09/19/hello-world-on-the-iphone/"/>
    <updated>2010-09-19T20:26:11-05:00</updated>
    <id>http://aijazansari.com/2010/09/19/hello-world-on-the-iphone</id>
    <content type="html"><![CDATA[<!-- ai l /wp/iPhoneHelloWorld.jpg /wp/iPhoneHelloWorld-233x285.jpg 233 285 Hello World on the iPhone -->


<p>Yesterday I started learning how to write applications for the iPad and the
iPhone.  There are so many books that promise to teach you everything you need
to know that picking one or two (or three) can be very difficult.  While I
normally like to learn new skills by reading a good book, I think for iOS
development a more dynamic source would be a better choice.</p>

<!--more-->


<p>The <a href="http://developer.apple.com/devcenter/ios/index.action">iOS Developer Center from Apple</a> is the best
source of current, complete documentation for the iPhone and iPad development.
This is especially important as the developer tools are updated and new
toolkits are introduced, making printed books obsolete.  While there are
literally thousands of tutorial documents and videos, and because there are so
many it&#8217;s very difficult to decide where to start.</p>

<p>The best tutorial I have found so far is the <em>iPhone Application Development</em>
class (CS193P) taught at Stanford University in the Winter of 2010.   This is
an actual course taught at Stanford, available on iTunes for free.  Most of
the lectures are taught by iPhone engineers.  The video of every lecture is
available online on iTunes (search for &#8220;CS193P&#8221;), as are class slides.
There&#8217;s also a <a href="http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter">Downloads web page</a> that has source code, assignments and other
supporting files.  If you&#8217;re considering taking this class download these
files as soon as possible, because the next time this class is offered those
files may be deleted off the web server. If by the time you read this it&#8217;s too
late, let me know, and I can send you the copies I downloaded.</p>

<p>As if to illustrate just how quickly information becomes outdated, even some
key parts of the course&#8217;s videos are no longer accurate.  In Lecture 1,
actions and outlets for the controller class are set in the Class Inspector.
As <a href="http://developer.apple.com/library/mac/#releasenotes/DeveloperTools/RN-InterfaceBuilder/index.html">this post</a> shows, as of version 3.2 of the Interface
Builder, there is a new tab in the Library window called &#8220;Classes.&#8221;  The
&#8220;Classes&#8221; tab is where you should now go to manage actions and outlets.</p>
]]></content>
  </entry>
  
</feed>

