<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PIBlog</title>
	<atom:link href="http://blog.paulbonser.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.paulbonser.com</link>
	<description>Paul Bonser's blog about programming, technology, and other stuff</description>
	<lastBuildDate>Sun, 28 Jun 2009 19:04:36 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Failed half-hour project</title>
		<link>http://blog.paulbonser.com/2009/06/25/failed-half-hour-project/</link>
		<comments>http://blog.paulbonser.com/2009/06/25/failed-half-hour-project/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 05:56:32 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[comicml]]></category>
		<category><![CDATA[half hour challenge]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=318</guid>
		<description><![CDATA[My attempt at a half-hour project before going to sleep failed. It took a little more than a half-hour, and my input of the following:


      version proto

      character paul
        image paul.png
      end

  [...]]]></description>
			<content:encoded><![CDATA[<p>My attempt at a half-hour project before going to sleep failed. It took a little more than a half-hour, and my input of the following:</p>

<pre>
      version proto

      character paul
        image paul.png
      end

      character angie
        image angie.png
      end

      angie says I thought you were going to bed!
      paul say But I really wanted to try and write a comic markup language prototype.
      angie says What? What the heck is wrong with you? Go to sleep.
      paul says Just give me a half hour.
      angie says Ok, fine, but only a half hour. Crazy person.
</pre>

<p>only resulted in the following output:</p>

<pre>
Unrecognized command at line 3: "character"
</pre>

<p>Ah well, there&#8217;s always tomorrow&#8230;</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F06%2F25%2Ffailed-half-hour-project%2F';
  addthis_title  = 'Failed+half-hour+project';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/06/25/failed-half-hour-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nitrogen module auto-reloading</title>
		<link>http://blog.paulbonser.com/2009/06/20/nitrogen-module-auto-reloading/</link>
		<comments>http://blog.paulbonser.com/2009/06/20/nitrogen-module-auto-reloading/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 00:27:14 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[mochiweb]]></category>
		<category><![CDATA[nitrogen]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=312</guid>
		<description><![CDATA[This is a really simple tip, but it was handy for me, and it could be helpful for someone else, too.

While playing around with Nitrogen, which is a great project by the way (more in a later blog post, I guarantee it), I noticed that I had to restart the server to re-load modules as [...]]]></description>
			<content:encoded><![CDATA[<p>This is a really simple tip, but it was handy for me, and it could be helpful for someone else, too.</p>

<p>While playing around with <a href="http://nitrogenproject.com/">Nitrogen</a>, which is a great project by the way (more in a later blog post, I guarantee it), I noticed that I had to restart the server to re-load modules as I changed them (or I could manually, reload them, I know, I know..).</p>

<p>Since I was using <a href="http://code.google.com/p/mochiweb/">Mochiweb</a> as my backend, and I&#8217;m used to the development version of Mochiweb auto-reloading modules as you recompile, I wanted the same functionality here.</p>

<p>Turns out it&#8217;s as simple as changing the default start.sh from</p>


<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">#!/bin/sh
cd `dirname $0`
&nbsp;
echo Starting Nitrogen.
erl \
	-name nitrogen@localhost \
	-pa ./ebin -pa ./include \
	-s make all \
	-eval &quot;application:start(appname)&quot;</pre></div></div>


<p>to this</p>


<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">#!/bin/sh
cd `dirname $0`
&nbsp;
echo Starting Nitrogen.
erl \
	-name nitrogen@localhost \
	-pa ./ebin -pa ./include \
	-s make all \
	-s reloader \
	-eval &quot;application:start(appname)&quot;</pre></div></div>


<p>&#8230; and bam, modules now reload as you recompile them.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F06%2F20%2Fnitrogen-module-auto-reloading%2F';
  addthis_title  = 'Nitrogen+module+auto-reloading';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/06/20/nitrogen-module-auto-reloading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>simple textarea auto-resizer</title>
		<link>http://blog.paulbonser.com/2009/04/24/simple-textarea-auto-resizer/</link>
		<comments>http://blog.paulbonser.com/2009/04/24/simple-textarea-auto-resizer/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 07:15:08 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[resizer]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[textarea]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=290</guid>
		<description><![CDATA[Today I was having issues with a textarea resizer (a hacked-up version of SmartArea) that I had been using for a while in a work project. It was working fine for textareas of a certain width, but it got less and less useful as the textareas got less wide, not wrapping lines until it already [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was having issues with a textarea resizer (a hacked-up version of <a href="http://www.ajaxbestiary.com/2007/11/14/smart-area-a-lightweight-resizing-text-area-plugin-for-jquery/">SmartArea</a>) that I had been using for a while in a work project. It was working fine for textareas of a certain width, but it got less and less useful as the textareas got less wide, not wrapping lines until it already had scrollbars for a word or two.</p>

<p>It seemed to me that it needn&#8217;t be as complex as it was, so I decided to try and write my own, and here&#8217;s what I came up with:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> growTextArea<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">clientHeight</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scrollHeight</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">-=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">clientHeight</span> <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scrollHeight</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">+=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>A working example, embedded using jQuery:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#example-resizing-textarea'</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">keyup</span><span style="color: #009900;">&#40;</span>growTextArea<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keyup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Type some text in here:
<textarea id="example-resizing-textarea2" rows="1" cols="10">
</textarea></p>

<h3>Compatibility</h3>

<p>This works for me in Firefox, IE6, IE7, Chrome and Chromium, Safari (for Windows, testing in a Windows VM along with the IEs and Chrome), and Opera 9.62. As you may have noticed I&#8217;ve avoided using any JS-library or browser-specific code, so this should work equally well with jQuery, Prototype, or with no library at all.</p>

<p>IE actually <a href="http://www.quirksmode.org/dom/w3c_cssom.html#t36">gives incorrect values</a> for scrollHeight, but that is easily made up for by using &#8220;this.clientHeight >= this.scrollHeight&#8221; in the first while loop rather than &#8220;this.clientHeight == this.scrollHeight&#8221;</p>

<h3>Minimum and Maximum rows</h3>

<p>If you want to set a minimum and maximum height, it takes a little more work:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> sizeTextArea<span style="color: #009900;">&#40;</span>min<span style="color: #339933;">,</span> max<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&lt;</span> min<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">=</span> min<span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">clientHeight</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scrollHeight</span> 
                <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&lt;=</span> max<span style="color: #009900;">&#41;</span> 
               <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&gt;</span> max<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">-=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">clientHeight</span> <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scrollHeight</span> 
                <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&lt;</span> min<span style="color: #009900;">&#41;</span> 
               <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">&lt;</span> max<span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">+=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">rows</span> <span style="color: #339933;">==</span> max
            <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">clientHeight</span> <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scrollHeight</span><span style="color: #009900;">&#41;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">overflow</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'auto'</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">overflow</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'hidden'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>Another example, limited to having between 4 and 8 rows:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sizer48 <span style="color: #339933;">=</span> sizeTextArea<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#example-resizing-textarea'</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #660066;">keyup</span><span style="color: #009900;">&#40;</span>sizer48<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">keyup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>


<p>Type some text in here, too:
<textarea id="example-resizing-textarea" rows="4" cols="10">
</textarea></p>

<script type="text/javascript" src="http://paulbonser.com/files/resizer/resizer.js"></script>

<p>Possible modifications could include using pixel sizes instead of changing the &#8220;row&#8221; attribute and animating the resizing.</p>

<p>This could easily be packaged into a plugin for jQuery or Prototype, and I might just do that, but right now it&#8217;s getting late, so I&#8217;m going to sleep instead.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F04%2F24%2Fsimple-textarea-auto-resizer%2F';
  addthis_title  = 'simple+textarea+auto-resizer';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/04/24/simple-textarea-auto-resizer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I got hacked, via RoundCube</title>
		<link>http://blog.paulbonser.com/2009/04/23/i-got-hacked-via-roundcube/</link>
		<comments>http://blog.paulbonser.com/2009/04/23/i-got-hacked-via-roundcube/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 07:10:32 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Other Stuff]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[botnet]]></category>
		<category><![CDATA[ddos]]></category>
		<category><![CDATA[hacked]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=285</guid>
		<description><![CDATA[So for the last couple of weeks or so, there has been potentially participating in DDOS attacks (more likely it was sending spam, actually), unbeknownst to me until today. Well, it explains some of the server instability I&#8217;ve been having lately.

For some reason, Apache had been dying on me every few days.

I finally looked in [...]]]></description>
			<content:encoded><![CDATA[<p>So for the last couple of weeks or so, there has been potentially participating in DDOS attacks (more likely it was sending spam, actually), unbeknownst to me until today. Well, it explains some of the server instability I&#8217;ve been having lately.</p>

<p>For some reason, Apache had been dying on me every few days.</p>

<p>I finally looked in my error.log file, and saw the output of wget, downloading a file called k.c from http://66.90.103.116/k.c (they&#8217;ve taken it down since, sometime within the last couple of hours. Perhaps they noticed my poking around at their server). Anyway, somehow they were getting in through apache somewhere, downloading this file, compiling it, and running it.</p>

<p><a href="paulbonser.com/files/hack/k.c">The code itself</a> (a derivative of <a href="http://packetstormsecurity.nl/irc/kaiten.c">kaiten.c</a> logs into an IRC server and watches for commands on which servers to attack or commands to run.</p>

<p>I eventually located the <a href="http://trac.roundcube.net/ticket/1485618">point of entry</a> as a bug in the version of Roundcube webmail I was running. I was running a really old version of it (something like version 0.1 beta, I think), and all it took was an apt-get install of the latest version and the security hole is gone.</p>

<p>I&#8217;m going to add the news feeds of any software I&#8217;m using on this server to my RSS reader in the hopes that I will find out about such security holes (or at least software updates) a bit sooner in the future. I&#8217;ll also try to make it a habit to do a apt-get upgrade more often as well.</p>

<p>EDIT: I&#8217;ve set up cron-apt as suggested, so that should help me keep things up to date.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F04%2F23%2Fi-got-hacked-via-roundcube%2F';
  addthis_title  = 'I+got+hacked%2C+via+RoundCube';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/04/23/i-got-hacked-via-roundcube/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>q, textual queue manager</title>
		<link>http://blog.paulbonser.com/2009/04/21/q-textual-queue-manager/</link>
		<comments>http://blog.paulbonser.com/2009/04/21/q-textual-queue-manager/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 05:36:48 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[organization]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[todo]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=278</guid>
		<description><![CDATA[I wanted a quick, command-line way to handle a list of to-do items and to show me the next item that I want to work on, so I hacked together a quick little program that manages queues for you.

It&#8217;s handy for those times where I think of something to do while working on a project, [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted a quick, command-line way to handle a list of to-do items and to show me the next item that I want to work on, so I hacked together a quick little program that manages queues for you.</p>

<p>It&#8217;s handy for those times where I think of something to do while working on a project, but I am already working on something. With this I can just append it to the end of my queue for that project and forget about it until later.</p>

<p>The code can be gotten <a href="http://bitbucket.org/pib/q/overview/">from bitbucket</a>, if you are interested.</p>

<p>You can use it like so:</p>

<p>Push items to the top of a queue:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ q todo push <span style="color: #ff0000;">'do that one thing'</span>
<span style="color: #000000; font-weight: bold;">do</span> that one thing
$ q todo push <span style="color: #ff0000;">'do that other thing'</span>
<span style="color: #000000; font-weight: bold;">do</span> that other thing</pre></div></div>


<p>See what&#8217;s at the top of a queue:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ q todo
<span style="color: #000000; font-weight: bold;">do</span> that other thing</pre></div></div>


<p>Pop items from the top of a queue</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ q todo pop
<span style="color: #000000; font-weight: bold;">do</span> that one thing</pre></div></div>


<p>Append items to the end of a queue:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ q todo append <span style="color: #ff0000;">'do some more things'</span>
<span style="color: #000000; font-weight: bold;">do</span> that one thing</pre></div></div>


<p>The help q prints out if you call it with no parameters:</p>

<pre>
$ ./q.py 
usage: ./q.py queuename [command [params]]
  commands:
    push       Add one or more lines to the queue
    all        Show all the items in the queue
    append     Add one or more lines to the end of the queue
    pop        Remove the top item from the specified queue and push it onto the .done queue for that file
    next       (default) Return the top item in the queue
</pre>

<p>Other commands I plan on adding include &#8220;rot&#8221; to swap the current top item with the next item (or with a numerical parameter to move it even further down).</p>

<p>I&#8217;ve been experimenting around with <a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>, and since that was also written in Python, I was wondering what it would take to rewrite this as a hg plugin. It could be handy to use something like this to manage a todo file. It could add some output to show what todo items were marked as done for each commit and perhaps also do a pre-commit hook where it pulls any new lines starting with &#8220;TODO:&#8221; and adds them to the todo file.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F04%2F21%2Fq-textual-queue-manager%2F';
  addthis_title  = 'q%2C+textual+queue+manager';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/04/21/q-textual-queue-manager/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Untiny that url!</title>
		<link>http://blog.paulbonser.com/2009/04/11/untiny-that-url/</link>
		<comments>http://blog.paulbonser.com/2009/04/11/untiny-that-url/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 01:36:21 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=248</guid>
		<description><![CDATA[<strong>Since most URL shortening services use an HTTP redirect to do their job, all it takes is a HEAD request to the tiny URL in question, and then a look at whatever "Location:" header is returned to see what the real URL is.</strong> In fact, you don't even really need to do a HEAD request in most cases, since most URL shortening services don't return any body, since they are just redirecting you anyway.]]></description>
			<content:encoded><![CDATA[<p>There has been some <a href="http://shiflett.org/blog/2009/apr/save-the-internet-with-rev-canonical">talk about</a> and <a href="http://benramsey.com/archives/a-revcanonical-rebuttal/">arguments against</a> and <a href="http://shiflett.org/blog/2009/apr/a-rev-canonical-http-header">responses to issues</a> about using <a href="http://revcanonical.appspot.com/">rev=&#8221;cononical&#8221;</a> for referencing shorter URLs instead of the automated use of TinyURL when posting to sites like Twitter.</p>

<p>I must say that I agree with Ben Ramsey (see &#8220;arguments agains&#8221; above) in suggesting we use rel=&#8221;alternate shorter&#8221; instead.</p>

<p>I also like the idea that Chris Shiflett had of using a HTTP header and a HEAD request to make it so you neither have to retrieve the entire requested page nor parse any HTML. I&#8217;d stick with Ben&#8217;s suggestion, however, and make the header something like &#8220;X-Alternate-Shorter:&#8221;, rather than &#8220;X-Rev-Canonical&#8221;. What&#8217;s the harm in calling it something that actually makes sense?</p>

<p>The idea of using HTTP HEAD requests to solve the problem inspired me to come up with a more immediate solution to one of the problems introduced by using url shortening services: uncertainty about where a URL leads.</p>

<p>This problem can be solved on the client side, which requires no work on the part of Twitter (meaning this is more likely to be put into use sooner).</p>

<p><strong>Since most URL shortening services use an HTTP redirect to do their job, all it takes is a HEAD request to the tiny URL in question, and then a look at whatever &#8220;Location:&#8221; header is returned to see what the real URL is.</strong> In fact, you don&#8217;t even really need to do a HEAD request in most cases, since most URL shortening services don&#8217;t return any body, since they are just redirecting you anyway.</p>

<p>Read on for more information and implementations of an untinyurl function in various languages.</p>

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

<p>There&#8217;s actually already a site online that offers the service of un-shortening URLs for you at <a href="http://untinyurl.com/">UnTinyURL.com</a>, but I wouldn&#8217;t suggest using that in any sort of automated system, and it&#8217;s of limited usefulness since you don&#8217;t really want to have to go to this site just to see what site you&#8217;re about to go to. Most people will just click a link, even if it means they might get RickRolled.</p>

<p>For those comfortable with the commandline, a simple curl call can give you the same basic info:</p>


<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">curl -I http://tinyurl.com/c8f5bz
HTTP/1.1 301 Moved Permanently
X-Powered-By: PHP/5.2.9
Location: http://blog.paulbonser.com/2009/04/11/untiny-that-url/
Content-type: text/html
Date: Sun, 12 Apr 2009 01:26:08 GMT
Server: TinyURL/1.6</pre></div></div>


<p>Toss in a grep and an awk, and you get your URL in a single line, perfect if you&#8217;re handing shortened URLs in a shell script for some reason:</p>


<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">$ curl -s -I http://tinyurl.com/c8f5bz | grep Location | awk '{print $2}'
http://blog.paulbonser.com/2009/04/11/untiny-that-url/</pre></div></div>


<p>Here&#8217;s untinyurl in Python:</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urlparse</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> untinyurl<span style="color: black;">&#40;</span>tinyurl<span style="color: black;">&#41;</span>:
    url = <span style="color: #dc143c;">urlparse</span>.<span style="color: black;">urlsplit</span><span style="color: black;">&#40;</span>tinyurl<span style="color: black;">&#41;</span>
    req = <span style="color: #dc143c;">urlparse</span>.<span style="color: black;">urlunsplit</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>, <span style="color: #483d8b;">''</span>, url.<span style="color: black;">path</span>, url.<span style="color: black;">query</span>, url.<span style="color: black;">fragment</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    con = <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPConnection</span><span style="color: black;">&#40;</span>url.<span style="color: black;">netloc</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        con.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'HEAD'</span>, req<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span>
    response = con.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> response.<span style="color: black;">getheader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Location'</span>, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span></pre></div></div>


<p>And here&#8217;s a version in PHP. It&#8217;s a bit longer and uglier than the Python version because I&#8217;m using the low-level fsockopen function to do my HTTP request rather than using cUrl or the HTTP extension. The reason I did this is because every PHP install will have fsockopen, whereas not every install will have cUrl or the HTTP extension.</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> untinyurl<span style="color: #009900;">&#40;</span><span style="color: #000088;">$tinyurl</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #990000;">parse_url</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tinyurl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$host</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'host'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$port</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'port'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'port'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">80</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'query'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'?'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'query'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$fragment</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fragment'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'#'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'fragment'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$sock</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">fsockopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$host</span><span style="color: #339933;">,</span> <span style="color: #000088;">$port</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$sock</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$tinyurl</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$url</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$url</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'path'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$query</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$fragment</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;HEAD <span style="color: #006699; font-weight: bold;">{$url}</span> HTTP/1.0<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>Host: <span style="color: #006699; font-weight: bold;">{$host}</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>Connection: Close<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sock</span><span style="color: #339933;">,</span> <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sock</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$response</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sock</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">128</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$lines</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$lines</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'location:'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$location</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #990000;">ltrim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$location</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$tinyurl</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>I&#8217;m not too familiar with Ruby, but after poking around for a little bit, I came up with this Ruby version. Holy crap, Ruby, that was easy and short!</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/http'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'uri'</span>
<span style="color:#9966CC; font-weight:bold;">def</span> untinyurl<span style="color:#006600; font-weight:bold;">&#40;</span>tinyurl<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#6666ff; font-weight:bold;">Net::HTTP</span>.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">URI</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>tinyurl<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'location'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">or</span> tinyurl
<span style="color:#9966CC; font-weight:bold;">rescue</span>
  tinyurl
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>And one more, and Erlang implementation (that &lt;SEMI&gt; is supposed to be a semicolon, but something is wrong with the syntax highlighter Erlang plugin). Be sure you call &#8220;inets:start()&#8221; before calling this function.</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>untinyurl<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>untinyurl<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #ff3c00;">untinyurl</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TinyUrl</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">http</span>:<span style="color: #ff3c00;">request</span><span style="color: #109ab8;">&#40;</span>head<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">TinyUrl</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>autoredirect<span style="color: #6bb810;">,</span> false<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_Status</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Headers</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Body</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff4e18;">proplists</span>:<span style="color: #ff3c00;">get_value</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;location&quot;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Headers</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">TinyUrl</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #45b3e6;">TinyUrl</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>


<p>Interesting how the Erlang and Ruby implementations look pretty similar.</p>

<p>I&#8217;ve made the source code available <a href="http://github.com/pib/untinyurl/tree/master">at GitHub</a>.
If you would like to contribute an untinyurl implementation in another language or have a bug-fix or suggestion for an improvement of one of the implementations I have so far, either email me, send me a pull request on GitHub, or post a comment here.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F04%2F11%2Funtiny-that-url%2F';
  addthis_title  = 'Untiny+that+url%21';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/04/11/untiny-that-url/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>The Tiniest GIF Ever</title>
		<link>http://blog.paulbonser.com/2009/03/15/the-tiniest-gif-ever/</link>
		<comments>http://blog.paulbonser.com/2009/03/15/the-tiniest-gif-ever/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 07:14:30 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[gif]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[tiniest]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=226</guid>
		<description><![CDATA[Yesterday I was base64-encoding an image so I could send it to CouchDB to test some code I&#8217;m working on for a client. It reminded me of something I did a while back to set cookies on a remote server.

Basically, a small PHP script was put on the remote server which took a couple of [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I was base64-encoding an image so I could send it to CouchDB to test some code I&#8217;m working on for a client. It reminded me of something I did a while back to set cookies on a remote server.</p>

<p>Basically, a small PHP script was put on the remote server which took a couple of GET parameters and set some cookies based on their values. The script then output a 1&#215;1 transparent GIF. A PHP script on the local server generated an IMG tag which linked to this image and set the parameters based on the COOKIES on the local server.</p>

<p>This process also had to happen in the reverse direction, so I had to send the script to developers on the other side. I wanted to keep it as simple as possible, so I put the actual image contents in the PHP file as a base64 encoded string. I used the GIMP to generate the smallest transparent GIF I could manage so there wouldn&#8217;t be <em>too</em> huge of a nasty string in the file. I came up with something like the following:</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">setcookie</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'foo'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'foo'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: image/gif'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">base64_decode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>


<p>Remembering this got me to wondering, how small could you make a GIF? The file generated by the GIMP was only 43 bytes, but it seemed to be that you should be able to make a file which is representing a single pixel a bit smaller than that.</p>

<p>So, with equal parts of determination and derangement, I set about finding out.</p>

<p>Though of somewhat dubious usefulness, I managed to generate a perfectly valid GIF of only 26 bytes in length, which has the potential to display completely differently in various different software.</p>

<p>Read on to see how I found my way to this point.</p>

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

<h3>Starting point: the GIF89a specification</h3>

<p>The file generated by the GIMP, as I said, was 43 bytes long. You can find it here: <a href="http://blog.paulbonser.com/wp-content/uploads/2009/03/tinytrans.gif">tinytrans.gif</a></p>

<p>To understand what was taking up all those bytes, I read through the <a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt">GIF89a Spec</a>. The file tinytrans.gif above consists of the following sections:</p>

<ul>
<li><p><strong>Header</strong>, 6 bytes: Consists of the bytes &#8220;GIF&#8221; and the version number, which is usually &#8220;89a&#8221;.</p></li>
<li><p><strong>Logical Screen Descriptor</strong>, 7 bytes: Without going into too much detail, this section of the file indicates the following:</p>

<ul>
<li>The file is 1&#215;1 pixels in size</li>
<li>There is a global color table</li>
<li>There are 2 colors in the global color table, the second one should be used as the background color</li>
</ul></li>
<li><p><strong>Global Color Table</strong>, 6 bytes: Consists of 3 bytes per color, a byte for red, green, and blue, respectively. In our file, the first color is white an the second color is black.</p></li>
<li><p><strong>Graphic Control Extension</strong>, 8 bytes: Used to indicate that the second color in the color table should be treated as transparent (can also be used for animation parameters, but isn&#8217;t in this file)</p></li>
<li><p><strong>Image Descriptor</strong>, 10 bytes: A GIF file can actually contain multiple &#8220;images&#8221; within it, which keeps you from having to specify image data for parts of the image which have the same color as the background color. Each image block has a position and size within the overall image size. In the above file, the position is 0,0 and the size is 1&#215;1.</p></li>
<li><p><strong>Image Data</strong>, 5 bytes: One <a href="http://en.wikipedia.org/wiki/Lempel-Ziv-Welch">LZW-encoded</a> block of image data. It takes 5 bytes to represent the single pixel the image has in it. The compression algorithm wasn&#8217;t designed to compress a single byte very well.</p></li>
<li><p><strong>GIF Trailer</strong>, 1 byte: A single byte with a hex value of 3B (&#8221;;&#8221; in ASCII) indicates the end of the GIF.</p></li>
</ul>

<h3>Making a smaller GIF</h3>

<p>Based on the required structures for a transparent GIF, it turns out that 43 bytes is pretty close to as small as you can get.</p>

<p><strong>But</strong>, I managed to figure out one trick to make it a bit smaller. It&#8217;s mentioned in the standard that it is optional to have a global color table. Of course, it&#8217;s undefined as to what happens when you make a GIF without a color table at all (there are also optional local color tables per image block).</p>

<p>When you have a color table index defined as transparent, however, GIF decoders don&#8217;t seem to care that there isn&#8217;t actually a color table.</p>

<p>So I changed the logical screen descriptor to indicate there was no global color table and removed the table itself, saving a total of six bytes, bringing the file size down to a mere 37 bytes.</p>

<p>Here it is in all its glory: <a href="http://blog.paulbonser.com/wp-content/uploads/2009/03/handtinytrans.gif">handtinytrans.gif</a></p>

<p>Interestingly enough, Wordpress gave me a lovely list of error messages of GD complaining that this isn&#8217;t a valid GIF file, despite the fact that Firefox and the GIMP both open and display (is it &#8220;displayed&#8221; when it&#8217;s transparent?) the file just fine.</p>

<p>So there you go, the tiniest <strong>transparent</strong> GIF possible (if you can make one smaller, let me know).</p>

<p>But of course, there&#8217;s room still for the tiniest <em>GIF</em> ever.</p>

<h3>Even smaller, no longer transparent</h3>

<p>To make it even smaller, I looked to the biggest remaining &#8220;optional&#8221; block in the image, the graphic control extension. If you don&#8217;t need transparency, this block is no longer needed, and that&#8217;s another 8 bytes you can take away.</p>

<p>Sadly, I wanted a whilte image, and I couldn&#8217;t get it to come out white without adding the global color table back in, so I only managed to trim 2 bytes off of the file.</p>

<p>Still, 35 bytes is indeed smaller: <a href="http://blog.paulbonser.com/wp-content/uploads/2009/03/handtinywhite.gif">handtinywhite.gif</a></p>

<h3>The tiniest possible GIF</h3>

<p>If I remove the constraint of having the image be white (or any color I choose), I can make it even smaller, though admittedly this becomes much less useful.</p>

<p>I removed both the global image table and the graphic control extension, and then no matter what color the pixel originally was, it comes out black. From there, I took it a step further, because the standard never says you have to actually set any pixels in the image, I removed the LZW encoded image data. I left the required lzw code-size header and block terminator, because without those Firefox and the GIMP both complained it wasn&#8217;t a valid GIF, and then I had it.</p>

<p>The tiniest GIF ever, 26 bytes: <a href="http://blog.paulbonser.com/wp-content/uploads/2009/03/handtinyblack.gif">handtinyblack.gif</a></p>

<p>Despite the fact that this is called &#8220;handtinyblack.gif&#8221;, black is just the color that the GIMP chooses to display when there&#8217;s no global color table. It&#8217;s stated in the spec &#8220;If no color table is available at all, the decoder is free to use a system color table or a table of its own.&#8221;</p>

<p>This means that any GIF decoder is free to pick whatever color it wants for this image. Opening this image in Firefox at various different times, it has show up as shades of blue, green and brown, as well as transparent if set as a background image.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F03%2F15%2Fthe-tiniest-gif-ever%2F';
  addthis_title  = 'The+Tiniest+GIF+Ever';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/03/15/the-tiniest-gif-ever/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>First steps to an Erlang OpenID consumer</title>
		<link>http://blog.paulbonser.com/2009/01/21/first-steps-to-an-erlang-openid-consumer/</link>
		<comments>http://blog.paulbonser.com/2009/01/21/first-steps-to-an-erlang-openid-consumer/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 08:18:14 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[openid]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=181</guid>
		<description><![CDATA[I&#8217;m working on a little project in Erlang and I wanted to use only OpenID for my authentication. It turns out there is currently no Erlang OpenID consumer library (or if there is, I couldn&#8217;t find it).

So I&#8217;ve started writing my own. So far I&#8217;ve got the first necessary step complete: HTML-based discovery.

I&#8217;m starting with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a little project in Erlang and I wanted to use only OpenID for my authentication. It turns out there is currently no Erlang OpenID consumer library (or if there is, I couldn&#8217;t find it).</p>

<p>So I&#8217;ve started writing my own. So far I&#8217;ve got the first necessary step complete: HTML-based discovery.</p>

<p>I&#8217;m starting with version 1.1, simply because it is shorter and requires less (I don&#8217;t want to implement the XRI or Yadis protocols just yet).</p>

<p>It turns out that mochiweb <a href="http://www.rsaccon.com/2007/11/mochiweb-got-html-parser.html">comes with an HTML parser</a>, so I used that, since I&#8217;m using mochiweb for my application. The parsed HTML comes back as a series of nested tuples of the format {&lt;&lt;&#8221;tag&#8221;>>, Attributes, Children}, where &#8220;tag&#8221; is the tagname (the root will be &lt;&lt;&#8221;html&#8221;>>, for example), Attributes is a <a href="http://www.erlang.org/doc/man/proplists.html">proplist</a> of that tag&#8217;s attributes, and Children is a list of more tuples of the same format and/or binaries with the contents of text nodes. Everything is represented as binaries, so I use those directly rather than converting between strings and binaries.</p>

<p>Here&#8217;s the code which finds the link tags with rel=&#8221;openid.server&#8221; and rel=&#8221;openid.delegate&#8221; (if it is there):</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff3c00;">get_openid_server</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Identifier</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">NormalizedIdentifier</span> <span style="color: #014ea4;">=</span> <span style="color: #ff3c00;">normalize_identifier</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Identifier</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">http</span>:<span style="color: #ff3c00;">request</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">NormalizedIdentifier</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span>ok<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_Status</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Headers</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Body</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #45b3e6;">HtmlTokens</span> <span style="color: #014ea4;">=</span> mochiweb_html:<span style="color: #ff3c00;">parse</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Body</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
            <span style="color: #ff3c00;">find_openid_tags</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">HtmlTokens</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> http_error<span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">normalize_identifier</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Ident</span> <span style="color: #014ea4;">=</span> <span style="color: #ff7800;">&quot;http://&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">_Rest</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #45b3e6;">Ident</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">normalize_identifier</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Ident</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff7800;">&quot;http://&quot;</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Ident</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">find_openid_tags</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">HtmlTokens</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;head&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">HtmlTokens</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        <span style="color: #109ab8;">&#123;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;head&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Attrs</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Rest</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #186895;">case</span> <span style="color: #ff3c00;">find_tag_with_attr</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;link&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;rel&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;openid.server&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
                not_found <span style="color: #6bb810;">-&gt;</span>
                    <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> openid_server_not_found<span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
                <span style="color: #45b3e6;">ServerAttrs</span> <span style="color: #6bb810;">-&gt;</span>
                    <span style="color: #45b3e6;">Server</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">proplists</span>:<span style="color: #ff3c00;">get_value</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;href&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">ServerAttrs</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
                    <span style="color: #186895;">case</span> <span style="color: #ff3c00;">find_tag_with_attr</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;link&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;rel&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;openid.delegate&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
                        not_found <span style="color: #6bb810;">-&gt;</span>
                            <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>server<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Server</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">;</span>
                        <span style="color: #45b3e6;">DelegateAttrs</span> <span style="color: #6bb810;">-&gt;</span>
                            <span style="color: #45b3e6;">Delegate</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">proplists</span>:<span style="color: #ff3c00;">get_value</span><span style="color: #109ab8;">&#40;</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;href&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">DelegateAttrs</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
                            <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>server<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Server</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>delegate<span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Delegate</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span>
                    <span style="color: #186895;">end</span>
            <span style="color: #186895;">end</span><span style="color: #6bb810;">;</span>
        not_found <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #109ab8;">&#123;</span>error<span style="color: #6bb810;">,</span> no_head_tag<span style="color: #109ab8;">&#125;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_TagName</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">not_found</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attributes</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#125;</span> | <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attributes</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_OtherTag</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Attributes</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #109ab8;">&#125;</span> | <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_Other</span> | <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">find_tag_with_attr</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">_TagName</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_AttrKey</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_AttrVal</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #006600;">not_found</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">find_tag_with_attr</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attr</span> <span style="color: #014ea4;">=</span> <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">AttrKey</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">AttrVal</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tags</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff3c00;">find_tag</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Tags</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        not_found <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #006600;">not_found</span><span style="color: #6bb810;">;</span>
        <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attributes</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#125;</span> <span style="color: #6bb810;">-&gt;</span>
            <span style="color: #186895;">case</span> <span style="color: #ff4e18;">proplists</span>:<span style="color: #ff3c00;">get_value</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">AttrKey</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attributes</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
                <span style="color: #45b3e6;">AttrVal</span> <span style="color: #6bb810;">-&gt;</span>
                    <span style="color: #45b3e6;">Attributes</span><span style="color: #6bb810;">;</span>
                <span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span> 
                    <span style="color: #ff3c00;">find_tag_with_attr</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">TagName</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Attr</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">Children</span> <span style="color: #014ea4;">++</span> <span style="color: #45b3e6;">Rest</span><span style="color: #109ab8;">&#41;</span> 
            <span style="color: #186895;">end</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>


<p>(the &lt;PIPE&gt;s above should be &#8220;|&#8221;s and the &lt;SEMI&gt;s should be &#8220;;&#8221;s. Not sure why the syntax highlighter is doing that to them&#8230;</p>

<p>Assuming the above code is put into a module called &#8220;openid&#8221;, you get the following:</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff9600;">1</span><span style="color: #014ea4;">&gt;</span> openid:<span style="color: #ff3c00;">get_openid_server</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;blog.paulbonser.com&quot;</span><span style="color: #109ab8;">&#41;</span>
<span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>server<span style="color: #6bb810;">,</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;http://www.livejournal.com/openid/server.bml&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
 <span style="color: #109ab8;">&#123;</span>delegate<span style="color: #6bb810;">,</span><span style="color: #ee3800;">&lt;&lt;</span><span style="color: #ff7800;">&quot;http://misterpib.livejournal.com/&quot;</span><span style="color: #ee3800;">&gt;&gt;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span>
<span style="color: #ff9600;">2</span><span style="color: #014ea4;">&gt;</span></pre></div></div>


<p>As I said, this is the first step. Hopefully I&#8217;ll have some time very soon to get on with the next couple of steps, and then I&#8217;ll be done.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2009%2F01%2F21%2Ffirst-steps-to-an-erlang-openid-consumer%2F';
  addthis_title  = 'First+steps+to+an+Erlang+OpenID+consumer';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2009/01/21/first-steps-to-an-erlang-openid-consumer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EmotionML</title>
		<link>http://blog.paulbonser.com/2008/11/25/emotionml/</link>
		<comments>http://blog.paulbonser.com/2008/11/25/emotionml/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 04:14:43 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Other Stuff]]></category>
		<category><![CDATA[emotionml]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=170</guid>
		<description><![CDATA[
&#60;emotionml xmlns=&#34;http://www.w3.org/2008/11/emotionml&#34;&#62;
    &#60;emotion&#62;
        &#60;intensity value=&#34;0.4&#34;/&#62;
        &#60;category set=&#34;everydayEmotions&#34; name=&#34;surprise&#34;/&#62;
        &#60;link uri=&#34;http://www.w3.org/2005/Incubator/emotion/&#34; role=&#34;triggeredBy&#34;/&#62;
        &#60;link uri=&#34;http://blog.paulbonser.com/2008/11/25/emotionml/&#34; role=&#34;expressedBy&#34;/&#62;
     &#60;/emotion&#62;
    &#60;emotion&#62;
  [...]]]></description>
			<content:encoded><![CDATA[<pre>
&lt;emotionml xmlns=&quot;http://www.w3.org/2008/11/emotionml&quot;&gt;
    &lt;emotion&gt;
        &lt;intensity value=&quot;0.4&quot;/&gt;
        &lt;category set=&quot;everydayEmotions&quot; name=&quot;surprise&quot;/&gt;
        &lt;link uri=&quot;<a href="http://www.w3.org/2005/Incubator/emotion/">http://www.w3.org/2005/Incubator/emotion/</a>&quot; role=&quot;triggeredBy&quot;/&gt;
        &lt;link uri=&quot;<a href="http://blog.paulbonser.com/2008/11/25/emotionml/">http://blog.paulbonser.com/2008/11/25/emotionml/</a>&quot; role=&quot;expressedBy&quot;/&gt;
     &lt;/emotion&gt;
    &lt;emotion&gt;
        &lt;intensity value=&quot;0.7&quot;/&gt;
        &lt;category set=&quot;everydayEmotions&quot; name=&quot;amusement&quot;/&gt;
        &lt;link uri=&quot;<a href="http://www.w3.org/2005/Incubator/emotion/">http://www.w3.org/2005/Incubator/emotion/</a>&quot; role=&quot;triggeredBy&quot;/&gt;
        &lt;link uri=&quot;<a href="http://blog.paulbonser.com/2008/11/25/emotionml/">http://blog.paulbonser.com/2008/11/25/emotionml/</a>&quot; role=&quot;expressedBy&quot;/&gt;
     &lt;/emotion&gt;
&lt;/emotionml&gt;
</pre>

<p>Don&#8217;t complain if it doesn&#8217;t conform, because it&#8217;s not a fixed standard yet. <img src='http://blog.paulbonser.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2008%2F11%2F25%2Femotionml%2F';
  addthis_title  = 'EmotionML';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2008/11/25/emotionml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A prefix notation programming language</title>
		<link>http://blog.paulbonser.com/2008/11/16/a-prefix-notation-programming-language/</link>
		<comments>http://blog.paulbonser.com/2008/11/16/a-prefix-notation-programming-language/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 01:53:01 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Programming Language]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[polish]]></category>
		<category><![CDATA[prefix]]></category>

		<guid isPermaLink="false">http://blog.paulbonser.com/?p=148</guid>
		<description><![CDATA[Prefix notation?

Have you ever dreamed of a language which uses strictly prefix (a.k.a. polish, Łukasiewicz) notation?

No? Well, I can&#8217;t say I&#8217;m surprised. Lisp is often called a prefix notation language, but I&#8217;ll let you in on a secret, it&#8217;s not purely prefix notation. It uses another notation you&#8217;ve probably never heard of: outfix notation.

Outfix notation?

I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<h2>Prefix notation?</h2>

<p>Have you ever dreamed of a language which uses strictly prefix (a.k.a. polish, Łukasiewicz) notation?</p>

<p>No? Well, I can&#8217;t say I&#8217;m surprised. Lisp is often called a prefix notation language, but I&#8217;ll let you in on a secret, it&#8217;s not <em>purely</em> prefix notation. It uses another notation you&#8217;ve probably never heard of: <em>outfix</em> notation.</p>

<h2>Outfix notation?</h2>

<p>I&#8217;d say I made outfix notation up, but I found a <a href="http://www.abstractmath.org/MM/MMFunctionValue.htm#_Outfix_notation">reference</a> to it on abstractmath.org, so I at least have something to back this claim up with. Basically, the parentheses are a function which says, &#8220;put these items into a list.&#8221;</p>

<p>Of course, Lisp uses lists for everything, so you can hardly call it a prefix notation language any more.</p>

<h2><em>Real</em> prefix notation</h2>

<p>Now, how about making a <em>real</em> prefix notation language? A <em>real</em> prefix notation language needs no parentheses because it knows how many arguments each function takes, so it can simply pull in the next two expressions following the function name.</p>

<p>A <em>real</em> prefix notation language is a piece of cake to implement, as long as every function has a fixed arity and that arity is known at compile time. Of course, then how do we represent things such as lists with varying amounts of items. How do we pass a variable number of arguments to a function?</p>

<p>The same way Lisp does, we use a list.</p>

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

<h2>Using lists without list syntax</h2>

<p>Of course, we have to encode our list a bit differently. For example, take the following simple Lisp snippet:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> numbers '<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>The set function takes a fixed number of arguments, so that&#8217;s not a problem. The list at the end, how do we do that? Well, if we assume we have standard lisp functions, we do this:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #b1b100;">setq</span> numbers <span style="color: #b1b100;">cons</span> <span style="color: #cc66cc;">1</span> <span style="color: #b1b100;">cons</span> <span style="color: #cc66cc;">2</span> <span style="color: #b1b100;">cons</span> <span style="color: #cc66cc;">3</span> <span style="color: #b1b100;">nil</span></pre></div></div>


<p>Now that wouldn&#8217;t look half bad if it weren&#8217;t for the conses of doom at the end there. So what can we do? Well, Lisp has these handy things called macros. Compile-time functions, basically.</p>

<h2>Compile time functions</h2>

<p>Of course, since we don&#8217;t know ahead of time how many items are going to be in the list. Lisp hands macros a list of the arguments to the macro based on what was in the parentheses with the macro name, but once again, we don&#8217;t have (or really want, honestly. I&#8217;m trying to do something <em>new</em> here!) the parentheses, so this is where we must start deviating from Lisp a bit.</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #b1b100;">setq</span> numbers <span style="color: #b1b100;">list</span> <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">.</span></pre></div></div>


<p>What&#8217;s happening here, is that list is a compile-time function which simply requests items from the reader (the thing that takes characters and interprets them into symbols, numbers, and strings) until it gets back the &#8216;.&#8217; symbol. If it&#8217;s anything else, it just has to tell the compiler to compile it as it would a normal expression. This means that we can call functions as we please. The difference between this an a &#8220;normal&#8221; outfix operator is that it is controlled by the code itself, rather than built into the compiler. The idea is that you could define your own compile-time functions to extend or change the &#8220;syntax&#8221; as you see fit.</p>

<p>For example, if you think the above list function is a bit too wordy:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;">def-compile <span style="color: #66cc66;">&#40;</span> <span style="color: #66cc66;">:</span> 
  <span style="color: #555;">list-while</span> /<span style="color: #66cc66;">=</span> <span style="color: #b1b100;">setq</span> token reader-next
                   '<span style="color: #66cc66;">&#41;</span>
    compile token</pre></div></div>


<p>Assuming &#8220;list-while&#8221; is a function which will build a list with the value of each iteration, this code does the following:</p>

<ul>
<li>Define a compile-time function bound to the symbol &#8220;(&#8221; which does the following:

<ul>
<li>Read the next token</li>
<li>If the token is not &#8220;)&#8221;, have the compiler compile the token as usual, returning the result</li>
<li>If the token is &#8220;)&#8221;, then we are done.</li>
</ul></li>
</ul>

<p>With this new compile time function, we can write nested lists as easily as we can in lisp:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #b1b100;">setq</span> nested-numbers <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">3</span> <span style="color: #cc66cc;">4</span> <span style="color: #cc66cc;">5</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">6</span> <span style="color: #cc66cc;">7</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #cc66cc;">8</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Well, that&#8217;s almost as easy as lisp, there&#8217;s one problem: those spaces are mandatory. Since &#8220;(&#8221; and &#8220;)&#8221; are just plain old symbols, the whole thing would be read as one symbol if we took the spaces out. This can be solved by modifying the reader to recognize &#8220;(&#8221; and &#8220;)&#8221; as complete symbols.</p>

<h2>Reprogramming the reader</h2>

<p>Without going into too many specifics of how the reader is implemented, making it possible to leave out the spaces around parentheses would be something like the following:</p>


<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;">push-reader <span style="color: #66cc66;">&#40;</span>
  expr <span style="color: #ff0000;">&quot;(&quot;</span> <span style="color: #66cc66;">&#40;</span> add-char output-<span style="color: #b1b100;">symbol</span> 
    push-reader <span style="color: #66cc66;">&#40;</span>
      expr <span style="color: #ff0000;">&quot;)&quot;</span> <span style="color: #66cc66;">&#40;</span> add-char output-<span style="color: #b1b100;">symbol</span> pop-reader <span style="color: #66cc66;">&#41;</span>
      <span style="color: #b1b100;">symbol</span> <span style="color: #ff0000;">&quot;)&quot;</span> <span style="color: #66cc66;">&#40;</span> output-<span style="color: #b1b100;">symbol</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>This makes the reader treat a single &#8220;(&#8221; as a symbol when it&#8217;s expecting an expression, and also pushes a new reader state including &#8220;)&#8221; onto the reader stack. This is popped off when a &#8220;)&#8221; is found. This means that &#8220;)&#8221; will stop being special once the one matching the first &#8220;(&#8221; is reached. This shows a bit of the power of the reader implementation, allowing the syntax to be extended for just a portion of the compilation.</p>

<p>For example, something like the following wouldn&#8217;t be too hard to implement using this system:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">setq json<span style="color: #339933;">-</span>snippet json <span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;a&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
  <span style="color: #3366CC;">&quot;b&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;x&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;y&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;z&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
  <span style="color: #3366CC;">&quot;foo&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;bar&quot;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>


<p>It would simply have to modify the reader to recognize &#8220;{&#8221;, &#8220;}&#8221;, &#8220;[", "]&#8220;, &#8220;,&#8221;, and &#8220;:&#8221; as separate symbols with or without whitespace, and add functions for &#8220;{&#8221; and &#8220;[&#8221; which also take the commas and colons into account.</p>

<h2>No longer lisp, but lisp-like</h2>

<p>At this point what we&#8217;ve got probably can&#8217;t be called &#8220;a Lisp&#8221; anymore.</p>

<p>There are some things that this language will need that Lisp doesn&#8217;t. One thing is that it will need to keep track of functions as they are defined in the code, noting how many arguments they take so it can handle them being called later on. When a function is passed as an argument to another function, it will need to be called using something along the lines of <em>funcall</em> or be given a manual arity hint if you want to call it like other functions.</p>

<p>The &#8220;everything is a list&#8221; feature of Lisp is kind of lost, though the internal representation could end up being basically the same.</p>

<h2>This language doesn&#8217;t exist &#8230; <strong>yet</strong></h2>

<p>This is something which is more concept in my brain and on paper at the moment. I&#8217;ve done some prototype implementations of the reader, some prototype implementations of the prefix notation function calling, and some prototype compile-time functions (implemented in the host language, however).</p>

<p>What&#8217;s left now is to put the whole thing together into a system in which every part is well defined and accessible from within the language itself.</p>

<p>I&#8217;m also thinking that I&#8217;d like to build this thing from the ground up with an underlying object-oriented system. Not class-oriented, mind you, just objects. Something prototype-based I&#8217;m thinking, like JavaScript, Io, Pepsi, and so on. In the end a user-mutable object-functional language is what I think I&#8217;ll end up with.</p>

<p>Any comments, suggestions, ridicules, etc&#8230; would be well appreciated. Also, if anyone has seen anything like this already in existence from which I could draw inspiration and ideas, please let me know. I&#8217;ve already looked at Cola/Coke/Pepsi and gotten some good ideas from there.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.paulbonser.com%2F2008%2F11%2F16%2Fa-prefix-notation-programming-language%2F';
  addthis_title  = 'A+prefix+notation+programming+language';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.paulbonser.com/2008/11/16/a-prefix-notation-programming-language/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
