<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Neil Ang</title>
    <link>http://neilang.com</link>
    <description>Neil Ang Feed</description>
    <language>en-us</language>
    <generator>Symphony (build 1701)</generator>
    <item>
      <title>Generating a calendar using XSLT</title>
      <link>http://neilang.com/entries/generating-a-calendar-using-xslt/</link>
      <pubDate>Sun, 16 Nov 2008 07:43:00 GMT</pubDate>
      <guid>http://neilang.com/entries/generating-a-calendar-using-xslt/</guid>
      <description>&lt;p&gt;Recently I was tasked to build an interactive calendar in XSLT. I wanted the calendar to always start on a Sunday as well as have clean markup. I couldn't find any good examples on the web while I was building it, so I decided to post the base of my solution.&lt;/p&gt;

&lt;p&gt;
	&lt;img src="http://neilang.com/workspace/upload/calendar.png" alt="Picture of final product" /&gt;
&lt;/p&gt;

&lt;p&gt;Insert the following variables and templates into your stylesheet:&lt;/p&gt;

&lt;code&gt;&amp;lt;xsl:variable name="DisplayDate" select="date:date()"/&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="Year" select="date:year($DisplayDate)"/&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="Month" select="date:month-in-year($DisplayDate)"/&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="MonthName" select="date:month-name($DisplayDate)" /&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="NumberOfDaysInMonth"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="DaysInMonth"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="month" select="$Month" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="year" select="$Year" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/xsl:call-template&amp;gt; &lt;br /&gt; &amp;lt;/xsl:variable&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="FirstDayInWeekForMonth" select="date:day-in-week(date:date(concat($Year,'-', $Month, '-01')))" /&amp;gt; &lt;br /&gt; &amp;lt;xsl:variable name="WeeksInMonth"&amp;gt;&amp;lt;xsl:value-of select="($NumberOfDaysInMonth + $FirstDayInWeekForMonth - 1) div 7" /&amp;gt;&amp;lt;/xsl:variable&amp;gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;xsl:template name="DaysInMonth"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="month"&amp;gt;&amp;lt;xsl:value-of select="$Month" /&amp;gt;&amp;lt;/xsl:param&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="year"&amp;gt;&amp;lt;xsl:value-of select="$Year" /&amp;gt;&amp;lt;/xsl:param&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:choose&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:when test="$month = 1 or $month = 3 or $month = 5 or $month = 7 or $month = 8 or $month = 10 or $month = 12"&amp;gt;31&amp;lt;/xsl:when&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:when test="$month=2"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:choose&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:when test="$year mod 4 = 0"&amp;gt;29&amp;lt;/xsl:when&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:otherwise&amp;gt;28&amp;lt;/xsl:otherwise&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:choose&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:when&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:otherwise&amp;gt;30&amp;lt;/xsl:otherwise&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/xsl:choose&amp;gt; &lt;br /&gt; &amp;lt;/xsl:template&amp;gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;xsl:template name="Calendar"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;table summary="Monthly calendar"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;caption&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:value-of select="$MonthName" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:text&amp;gt; &amp;lt;/xsl:text&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:value-of select="$Year" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/caption&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;tr&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Sunday"&amp;gt;Sun&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Monday"&amp;gt;Mon&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Tuesday"&amp;gt;Tue&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Wednesday"&amp;gt;Wed&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Thursday"&amp;gt;Thu&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Friday"&amp;gt;Fri&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;th abbr="Saturday"&amp;gt;Sat&amp;lt;/th&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/tr&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="CalendarWeek"/&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/table&amp;gt; &lt;br /&gt; &amp;lt;/xsl:template&amp;gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;xsl:template name="CalendarWeek"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="week"&amp;gt;1&amp;lt;/xsl:param&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="day"&amp;gt;1&amp;lt;/xsl:param&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;tr&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="CalendarDay"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="day" select="$day" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:call-template&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/tr&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:if test="$WeeksInMonth &amp;amp;gt; $week"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="CalendarWeek"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="week" select="$week + 1" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="day" select="$week * 7 - ($FirstDayInWeekForMonth - 2)" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:call-template&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/xsl:if&amp;gt; &lt;br /&gt; &amp;lt;/xsl:template&amp;gt; &lt;br /&gt; &lt;br /&gt; &amp;lt;xsl:template name="CalendarDay"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="count"&amp;gt;1&amp;lt;/xsl:param&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:param name="day" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;xsl:choose&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:when test="($day = 1 and $count != $FirstDayInWeekForMonth) or $day &amp;amp;gt; $NumberOfDaysInMonth"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;td class="empty"&amp;gt;&amp;lt;xsl:text disable-output-escaping="yes"&amp;gt;&amp;amp;amp;nbsp;&amp;lt;/xsl:text&amp;gt;&amp;lt;/td&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:if test="$count &amp;amp;lt; 7"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="CalendarDay"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="count" select="$count + 1" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="day" select="$day" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:call-template&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:if&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:when&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:otherwise&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;td&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:value-of select="$day" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/td&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:if test="$count &amp;amp;lt; 7"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:call-template name="CalendarDay"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="count" select="$count + 1" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;xsl:with-param name="day" select="$day + 1" /&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:call-template&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:if&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/xsl:otherwise&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;lt;/xsl:choose&amp;gt; &lt;br /&gt; &amp;lt;/xsl:template&amp;gt;&lt;/code&gt;

&lt;p&gt;For this code to work, you need to be using &lt;a href="http://exslt.org/"&gt;exslt&lt;/a&gt;.&lt;/p&gt;

&lt;code&gt;&amp;lt;xsl:stylesheet version="1.0" &lt;br /&gt; &amp;nbsp;&amp;nbsp;xmlns:xsl="http://www.w3.org/1999/XSL/Transform" &lt;br /&gt; &amp;nbsp;&amp;nbsp;xmlns:exslt="http://exslt.org/common" &lt;br /&gt; &amp;nbsp;&amp;nbsp;xmlns:date="http://exslt.org/dates-and-times"&amp;gt;&lt;/code&gt;

&lt;p&gt;Once you have added the templates you can call the calendar like this: &lt;/p&gt;

&lt;code&gt;&amp;lt;xsl:call-template name="Calendar" /&amp;gt;&lt;/code&gt;

&lt;p&gt;Finally add some CSS to the page so your calendar looks more presentable:&lt;/p&gt;

&lt;code&gt;&amp;lt;style type="text/css" media="screen"&amp;gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;table{ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border:1px solid #CCC; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border-collapse: collapse; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp;caption{ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-weight:bold; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;font-size:120%; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;margin-bottom:8px; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp; &lt;br /&gt; &amp;nbsp;&amp;nbsp;td,th{ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text-align:center; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vertical-align:middle; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;width:36px; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:34px; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;border:1px solid #CCC; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;padding:0; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp; &lt;br /&gt; &amp;nbsp;&amp;nbsp;th{ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;height:inherit; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp; &lt;br /&gt; &amp;nbsp;&amp;nbsp;.empty{ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;background-color:#EEE; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;lt;/style&amp;gt; &lt;br /&gt; &lt;br /&gt; &lt;/code&gt;

&lt;p&gt;This is only the base of the calendar I built, and you can expand this to make it browse-able. But I will leave that for another post. &lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/generating-a-calendar-using-xslt/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>The New MacBook "Felt" (running Hyperspaces)</title>
      <link>http://neilang.com/entries/the-new-macbook-felt-running-hyperspaces/</link>
      <pubDate>Fri, 31 Oct 2008 22:10:00 GMT</pubDate>
      <guid>http://neilang.com/entries/the-new-macbook-felt-running-hyperspaces/</guid>
      <description>&lt;p&gt;Apple are secretly working on a new line of laptops to replace the "Airs". As awesome developers, Apple sent us some preview hardware to see how &lt;a href="http://hyperspacesapp.com"&gt;Hyperspaces&lt;/a&gt; performed on the new systems. I know Apple like to keep their products secret, but I say "NDA... ND-Shmay" - here is the new line, the Macbook "Felt".&lt;/p&gt;

&lt;div style="text-align:center"&gt;
&lt;object codebase="http://www.apple.com/qtactivex/qtplugin.cab" width="320" height="256"&gt;&lt;param name="src" value="/workspace/upload/MacBook.mov" /&gt;&lt;param name="controller" value="true" /&gt;&lt;param name="autoplay" value="false" /&gt;&lt;param name="scale" value="tofit" /&gt;&lt;param name="volume" value="100" /&gt;&lt;param name="loop" value="false" /&gt;&lt;embed pluginspage="http://www.apple.com/quicktime/download/" type="video/quicktime" class="mov" width="320" height="256" src="/workspace/upload/MacBook.mov" controller="true" autoplay="false" scale="tofit" volume="100" loop="false"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;Here are the new features expected in this model:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;This is the lightest notebook ever made by Apple.&lt;/li&gt;
	&lt;li&gt;The screen is carved from felt, which has no glare.&lt;/li&gt;
	&lt;li&gt;Due to the flammable nature of felt, all parts have been removed. This has resulted in a 98% reduction in heating.&lt;/li&gt;
	&lt;li&gt;There are no ports, which gives smooth looking edges.&lt;/li&gt;
	&lt;li&gt;New efficient 26 character keyboard.&lt;/li&gt;
&lt;/ul&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/the-new-macbook-felt-running-hyperspaces/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Hyperspaces ...Hyperawesome</title>
      <link>http://neilang.com/entries/hyperspaces-hyperawesome/</link>
      <pubDate>Sat, 18 Oct 2008 10:06:00 GMT</pubDate>
      <guid>http://neilang.com/entries/hyperspaces-hyperawesome/</guid>
      <description>&lt;p&gt;My most anticipated software release of this year is &lt;a href="http://tonyarnold.com"&gt;Tony Arnold's&lt;/a&gt; "Hyperspaces". This new application extends Leopards built-in Spaces application to add features that you would expect out-of-the-box for a multiple desktop program. Hyperspaces lets you set custom backgrounds, colours and labels on each desktop, giving each space its own special "flavour" (why would you want four identical desktops??). The application also allows you to set custom hot keys to quickly add and remove more rows of spaces as you need them.&lt;/p&gt;

&lt;p&gt;I was lucky enough to be on the early beta program for this app, and I have been really impressed by what Tony has been able to do and how well  Hyperspaces has been built. Why Apple didn't ship these features with Spaces originally is a mystery to me, as these set of features substantially improves the user experience of Spaces.&lt;/p&gt;

&lt;p&gt;My favourite feature of the app is the colour blends. I've set a different colour tint and label on each desktop. The colours blend with my wallpaper to give a distinct variation on every desktop.&lt;/p&gt;

&lt;p&gt;I would highly recommend &lt;a href="http://hyperspacesapp.com"&gt;trying out this app&lt;/a&gt;.&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/hyperspaces-hyperawesome/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>How to setup virtual hosts on Mac OS X 10.5 (Leopard)</title>
      <link>http://neilang.com/entries/how-to-setup-virtual-hosts-on-mac-os-x-105-leopar/</link>
      <pubDate>Sat, 20 Sep 2008 04:29:00 GMT</pubDate>
      <guid>http://neilang.com/entries/how-to-setup-virtual-hosts-on-mac-os-x-105-leopar/</guid>
      <description>&lt;p&gt;Whilst developing a new project it can be convenient to setup a virtual host on your local machine. For example, if I wanted to have a local development/demonstration version of a website I'm developing (e.g. &lt;a href="http://learnhowtojuggle.info"&gt;http://learnhowtojuggle.info&lt;/a&gt;), I could setup the following virtual host: &lt;a href="http://learnhowtojuggle.dev" rel="nofollow"&gt;http://learnhowtojuggle.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;N.B. Only follow this tutorial if you are comfortable with editing system configurations and are aware of the risks. If you have &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; installed, you can click the file path links in these instructions to quickly open them on your local computer (&lt;a href="http://manual.macromates.com/en/using_textmate_from_terminal.html"&gt;More Information&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;1. Modify the virtual hosts configuration&lt;/h3&gt;

&lt;p&gt;Use terminal to find and modify your virtual hosts configuration file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mate &lt;a href="txmt://open/?url=file:///private/etc/apache2/extra/httpd-vhosts.conf" class="textmate"&gt;/private/etc/apache2/extra/httpd-vhosts.conf&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Append to this bottom of this file an entry for your virtual domain:&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt; &lt;br /&gt; ServerAdmin webmaster@learnhowtojuggle.dev &lt;br /&gt; DocumentRoot "/Users/neil/Sites/learnhowtojuggle" &lt;br /&gt; ServerName learnhowtojuggle.dev &lt;br /&gt; ServerAlias learnhowtojuggle.dev &lt;br /&gt; ErrorLog "/private/var/log/apache2/learnhowtojuggle.dev-error_log" &lt;br /&gt; &amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;Make sure the &lt;kbd&gt;DocumentRoot&lt;/kbd&gt; you enter actually exists. For convenience, I've placed mine in my Site folder. You can now save and close this file.&lt;/p&gt;

&lt;h3&gt;2. Check Apache knows about virtual hosts&lt;/h3&gt;

&lt;p&gt;Next we will need to modify the Apache configuration file to make sure it includes the virtual hosts file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mate &lt;a href="txmt://open/?url=file:///private/etc/apache2/httpd.conf&amp;amp;line=460" class="textmate"&gt;/private/etc/apache2/httpd.conf&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Locate the following line and remove the # sign (also known as an "octothorpe" ) from in front of it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Include /private/etc/apache2/extra/httpd-vhosts.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Save and close this file as well.&lt;/p&gt;

&lt;h3&gt;3. Restart Apache&lt;/h3&gt;

&lt;p&gt;For any changes to take effect on the Apache server, you will need to restart it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo httpd -k restart&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;4. Update hosts file&lt;/h3&gt;

&lt;p&gt;Finally, the easiest way to let our browser know to use our local server when it get a request for our virtual host is to modify the hosts file. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;mate &lt;a href="txmt://open/?url=file:///private/etc/hosts" class="textmate"&gt;/private/etc/hosts&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following entry:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;127.0.0.1	learnhowtojuggle.dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After you save and close this file, navigate to &lt;a href="http://learnhowtojuggle.dev" rel="nofollow"&gt;http://learnhowtojuggle.dev&lt;/a&gt; in your browser to see the newly created virtual host on your local machine. &lt;/p&gt;


&lt;h3&gt;Additional Configuration&lt;/h3&gt;

&lt;p&gt;Since I am serving my new virtual host out of my Sites folder, and I want to use my .htacess file for URL rewriting, I had to update the Apache configuration again to allow permission for this.&lt;/p&gt;

&lt;p&gt;The configuration for my Site folder was located at &lt;kbd&gt;/private/etc/apache2/users/neil.conf&lt;/kbd&gt; (yours will be different based on your system profile name). I then set my permissions to be pretty loose since it is only my local machine.&lt;/p&gt;

&lt;p&gt;Example configuration: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Directory "/Users/neil/Sites/"&amp;gt; &lt;br /&gt; Options Indexes FollowSymLinks MultiViews &lt;br /&gt; AllowOverride All &lt;br /&gt; Order allow,deny &lt;br /&gt; Allow from all &lt;br /&gt; &amp;lt;/Directory&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After you update your directory permissions, you will need to restart apache again for these to changes to take effect.&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/how-to-setup-virtual-hosts-on-mac-os-x-105-leopar/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Things to know before going to WWDC</title>
      <link>http://neilang.com/entries/things-to-know-before-going-to-wwdc/</link>
      <pubDate>Sat, 21 Jun 2008 06:59:00 GMT</pubDate>
      <guid>http://neilang.com/entries/things-to-know-before-going-to-wwdc/</guid>
      <description>&lt;p&gt;As most of you know I spent last week in San Francisco attending WWDC ‘08. I had a great time thanks to the &lt;a href="http://www.auc.edu.au/"&gt;AUC&lt;/a&gt;, and highly encourage others to attend this conference next year if they have the opportunity. It is worth it. &lt;/p&gt;

&lt;p&gt;Here are some tips for anyone who is thinking of going in 2009:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Bring a list of issues you want solved&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The conference has sessions that run all day, but they also have labs where you can get Apple engineers to help solve issues with your software. These labs gave me a chance to talk with the actual engineers who work in the field of my software problems. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Take business cards&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I didn’t take any business cards with me, but a few people asked for my email address and it would of been perfect if I had a business card to give them. You don’t need a business to have a business card. Just include your name, email address and website (if you have one).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Take your equipment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one is pretty much a given, but if you have a laptop, take it along. If you have an iphone or ipod touch, take that as well. Apple set up a convenient website for the attendees with the latest session updates and news which I checked everyday. They also had a version of the site that worked on the iphone. Very handy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Partition your hard drive&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before I left Australia, I backed up and formatted my hard drive to clear up some space. I also made a separate partition incase we got new software. After I got a copy of snow leopard I was able to install it straight away alongside leopard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. See San Francisco while you are there&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.auc.edu.au/"&gt;AUC&lt;/a&gt; had arranged a bus tour for the Australian delegates, and we had an awesome day seeing all the highlights of the area. We checked out the Googleplex, Apple HQ and the computer history museum. Silicon valley is a great place for nerds to site see.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. File bug reports before you attend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A common response to questions in sessions and labs was “file a bug report”. The engineers are not able to fix things on the spot, so if you have found a major problem with an API or system, its better to file a bug report before you attend. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Prepare to get up early&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jet-lag along with early morning sessions and late nights out will leave you feeling tired most of the week. Luckily there are plenty of starbuck stores around and other coffee outlets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Attend parties&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;During the week parties are held by various organisations to celebrate WWDC. If you are thinking of attending any, make sure you RSVP. I would also recommend going to the “Stump the experts” event and the Apple design awards. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Don’t be afraid to meet people&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the conference you are surrounded by developers, engineers and Apple enthusiasts. It is a great chance to make contacts and spread your own name as well (again, take business cards). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Don’t feel bad about missing sessions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A lot of interesting sessions and labs are run concurrently at the conference which means you will miss sessions that you wanted to attend. If there is a conflicting lab and session, attend the lab as the sessions become available on video after the conference. &lt;/p&gt;

&lt;p&gt;And finally, enjoy the time there as much as possible and take lots of photos. The week will go by very quickly. &lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/things-to-know-before-going-to-wwdc/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Converting seconds into a readable format in Perl</title>
      <link>http://neilang.com/entries/converting-seconds-into-a-readable-format-in-perl/</link>
      <pubDate>Wed, 18 Jun 2008 09:49:00 GMT</pubDate>
      <guid>http://neilang.com/entries/converting-seconds-into-a-readable-format-in-perl/</guid>
      <description>&lt;p&gt;Here is a short and easy Perl function to convert the difference between two time stamps, into something that is more human readable. There are Perl modules that can do this as well, however I thought I would share what I wrote incase someone finds it useful.&lt;/p&gt;

&lt;code&gt;#!/usr/bin/env perl -w &lt;br /&gt; &lt;br /&gt; sub convert_time { &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $time = shift; &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $days = int($time / 86400); &lt;br /&gt; &amp;nbsp;&amp;nbsp; $time -= ($days * 86400); &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $hours = int($time / 3600); &lt;br /&gt; &amp;nbsp;&amp;nbsp; $time -= ($hours * 3600); &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $minutes = int($time / 60); &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $seconds = $time % 60; &lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$days = $days &amp;lt; 1 ? '' : $days .'d '; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$hours = $hours &amp;lt; 1 ? '' : $hours .'h '; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$minutes = $minutes &amp;lt; 1 ? '' : $minutes . 'm '; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$time = $days . $hours . $minutes . $seconds . 's'; &lt;br /&gt; &amp;nbsp;&amp;nbsp;return $time; &lt;br /&gt; }&lt;/code&gt;

&lt;p&gt;When using this function, these are the outputs you should see:&lt;/p&gt;

&lt;code&gt;print convert_time(1); # result: 1s &lt;br /&gt; print convert_time(61); # result: 1m 1s &lt;br /&gt; print convert_time(3661); # result: 1h 1m 1s &lt;br /&gt; print convert_time(90061); # result: 1d 1h 1m 1s&lt;/code&gt;

&lt;p&gt;This code can easily be modified to output other formats as well. Let me know if you come up with something different.&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/converting-seconds-into-a-readable-format-in-perl/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Title case names in perl</title>
      <link>http://neilang.com/entries/title-case-names-in-perl/</link>
      <pubDate>Tue, 17 Jun 2008 09:58:00 GMT</pubDate>
      <guid>http://neilang.com/entries/title-case-names-in-perl/</guid>
      <description>&lt;p&gt;While I was at work today I came across a script I wrote a couple of years ago to title case names in perl. This script will transform names to a nice, readable title case equivalent. E.g. "JOHN SMITH" to "John Smith", "JOHN O'BRIAN" to "John O'Brian" and "JOHN MCCOOL" to "John McCool" etc.&lt;/p&gt;

&lt;code&gt;#!/usr/bin/env perl &lt;br /&gt; &lt;br /&gt; use strict; &lt;br /&gt; &lt;br /&gt; sub title_case_name { &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $person = shift; &lt;br /&gt; &amp;nbsp;&amp;nbsp;my ($word, $subWord); &lt;br /&gt; &amp;nbsp;&amp;nbsp; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$person =~ s/\s+/ /g; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$person =~ s/^\s+//; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$person =~ s/\s+$//; &lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;my @namesArray = split(/ /, $person); &lt;br /&gt; &amp;nbsp;&amp;nbsp;$person = ''; &lt;br /&gt; &amp;nbsp;&amp;nbsp;foreach $word (@namesArray){ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$word = title_case($word); &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if($word =~ /-/){ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;my @subWordsArray = split(/-/, $word); &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$word = ''; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach $subWord (@subWordsArray){ &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$subWord = title_case($subWord); &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$word .= $subWord.'-'; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;chop($word); &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$person .= $word.' '; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &amp;nbsp;&amp;nbsp;chop($person); &lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;return $person; &lt;br /&gt; } &lt;br /&gt; &lt;br /&gt; sub title_case { &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $name = shift; &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $temp_str1 = ''; &lt;br /&gt; &amp;nbsp;&amp;nbsp;my $temp_str2 = ''; &lt;br /&gt; &amp;nbsp;&amp;nbsp;$name = lc($name); &lt;br /&gt; &amp;nbsp;&amp;nbsp;$name = ucfirst($name); &lt;br /&gt; &amp;nbsp;&amp;nbsp;$temp_str1 = substr($name, 0, 2); &lt;br /&gt; &amp;nbsp;&amp;nbsp;$temp_str2 = substr($name, 2); &lt;br /&gt; &amp;nbsp;&amp;nbsp;if($temp_str1 eq 'Mc' || $temp_str1 eq "O'") { &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$temp_str2 = ucfirst($temp_str2); &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$name = $temp_str1 . $temp_str2; &lt;br /&gt; &amp;nbsp;&amp;nbsp;} &lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;return $name; &lt;br /&gt; } &lt;br /&gt; &lt;br /&gt; print title_case_name('JOHN SMITH') . "\n"; &lt;br /&gt; print title_case_name('JOHN O\'BRIAN') . "\n"; &lt;br /&gt; print title_case_name('JOHN MCCOOL') . "\n";&lt;/code&gt;

&lt;p&gt;&lt;a href="/workspace/upload/title_case_names.zip"&gt;Download this script.&lt;/a&gt;&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/title-case-names-in-perl/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Auto-respond FAIL</title>
      <link>http://neilang.com/entries/auto-respond-fail/</link>
      <pubDate>Sun, 08 Jun 2008 00:28:25 GMT</pubDate>
      <guid>http://neilang.com/entries/auto-respond-fail/</guid>
      <description>&lt;p&gt;Before I left for San Francisco last Friday, I thought I would be smart and write an auto-response rule in Apple Mail instead of Groupwise. I set my mail rule to send an auto-response message to any email received in my Groupwise inbox that was addressed to me. This worked, but a little too well. What I should of done is made the rule send an auto-response message to any &lt;strong&gt;new&lt;/strong&gt; email received. Oops. There are 5900+ emails in my inbox. I think Apple Mail sent a message to all of them.&lt;/p&gt;

&lt;p&gt;So sorry to everyone who has been getting heaps of auto-response messages from me lately. I've turned the rule off, and won't be setting another one anytime soon.&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/auto-respond-fail/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>White whale: A blog undesigned</title>
      <link>http://neilang.com/entries/white-whale-a-blog-undesigned/</link>
      <pubDate>Tue, 03 Jun 2008 08:30:00 GMT</pubDate>
      <guid>http://neilang.com/entries/white-whale-a-blog-undesigned/</guid>
      <description>&lt;p&gt;Relaunching a site is usually about enhancements to design. Well, I've never been one to follow the herd: I'm shaking up the mix by undesigning my blog. Say &lt;em&gt;hahlo&lt;/em&gt; to my new design the "White Whale".&lt;/p&gt;

&lt;p&gt;For some time now, I've been pondering how to make &lt;a href="http://neilang.com"&gt;neilang.com&lt;/a&gt; a better site for users. My thoughts on this have been many, but I keep coming back to the same three goals:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Accessibility;&lt;/li&gt;
  &lt;li&gt;Speed;&lt;/li&gt;
  &lt;li&gt;Navigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I realised that over-designing my site was hindering these goals, not helping them. From this was born the White Whale - a clean, stripped-back, easily navigable design with super-fast loading time and scalability across a range of different platforms.&lt;/p&gt;

&lt;p&gt;But how, you say? Read on...&lt;/p&gt;

&lt;p&gt;By reducing images, enabling gzip compression and reducing white space from mark-up, I was able to reduce the site size to a miniscule 17KB, reducing the load size by 92%. I rock.&lt;/p&gt;

&lt;p&gt;By using the WAI guidelines as the basis of my design, I was able to greatly increase my site's compliance with accessibility standards.&lt;/p&gt;

&lt;p&gt;By allowing all posted content (e.g. articles, categories, comments) of my site to be fed directly to a user's RSS reader, I can offer users the ability to select only the elements that they want to read.&lt;/p&gt;

&lt;p&gt;With the sites reduced size and increased accessibility, it should view well on an iPhone. But if you are still stuck in the middle ages (like me), and have a Sony Ericsson or Nokia, I've made you &lt;a href="http://m.neilang.com"&gt;m.neilang.com&lt;/a&gt;. This is a super cut-down valid WAP 1.0 version of my site.&lt;/p&gt;

&lt;p&gt;Thoughts?&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/white-whale-a-blog-undesigned/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
    <item>
      <title>Intelleject: An experiment in Cocoa</title>
      <link>http://neilang.com/entries/intelleject-an-experiment-in-cocoa/</link>
      <pubDate>Sun, 23 Mar 2008 00:45:00 GMT</pubDate>
      <guid>http://neilang.com/entries/intelleject-an-experiment-in-cocoa/</guid>
      <description>&lt;p&gt;Earlier this year I was lucky enough to attend a workshop on cocoa (which was kindly sponsored by the &lt;a href="http://www.auc.edu.au/"&gt;AUC&lt;/a&gt;). It was a great 3 days of programming and introduction into the world of cocoa. Since then I have been playing around with ideas for mac applications.&lt;/p&gt;

&lt;p&gt;A crazy app idea I had a while ago was an assistant service to remove mounted volumes. Thanks to the training provided by the &lt;a href="http://www.auc.edu.au/"&gt;AUC&lt;/a&gt; and the advanced assistance that &lt;a href="http://tonyarnold.com"&gt;Tony Arnold&lt;/a&gt; has provided me, I have been able to write my first cocoa application.&lt;/p&gt;

&lt;p style="text-align:center;"&gt;&lt;img src="http://www.neilang.com/workspace/upload/screen-capture-1.png" alt="Intelleject Screen Shot" /&gt;&lt;/p&gt;

&lt;p&gt;Intelleject might not look like much, but I had to learn a lot to create it. It's a service that you call through the shortcut ⌘-e, to visually review and eject (by single clicking) volumes. &lt;em&gt;My aim was to make it simple&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Features:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Core Animation - It uses leopards implicit animations to visual change the number of volumes&lt;/li&gt;
	&lt;li&gt;System notifications - The app listens for mount/unmount notifications to detect if it needs to update its display&lt;/li&gt;
	&lt;li&gt;Bindings - Tricky for a beginner, but great when you work them out.&lt;/li&gt;
	&lt;li&gt;Global shortcut key - Globally binding it to ⌘-e was the most difficult task. I wanted the application to override the default eject shortcut key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would like to invite you all to &lt;a href="http://www.neilang.com/workspace/upload/Intelleject.app.zip" title="Download Intelleject"&gt;try it out&lt;/a&gt;, and let me know what you think of my first applicaiton ;)&lt;/p&gt;
					     &lt;p&gt;&lt;a title="What are you, chicken?!" href="http://neilang.com/entries/intelleject-an-experiment-in-cocoa/#comment"&gt;Please post a comment&lt;/a&gt;&lt;/p&gt;
					   </description>
    </item>
  </channel>
</rss>
