<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Ardekantur</title>
	
	<link>http://blog.ardekantur.com</link>
	<description>Computer Science, Ruby, and Software Engineering.</description>
	<lastBuildDate>Wed, 15 Apr 2009 20:14:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Ardekantur" /><feedburner:info uri="ardekantur" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://blog.ardekantur.com</link><url>http://blog.ardekantur.com/feedicon.png</url><title>Ardekantur</title></image><item>
		<title>From Code to Design Document: A Play in Four Acts</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/uk1cnKVRmrE/</link>
		<comments>http://blog.ardekantur.com/2009/04/from-code-to-design-document-a-play-in-four-acts/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 20:09:49 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Code Projects]]></category>
		<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Projects I Support]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[amorfus]]></category>
		<category><![CDATA[asciidoc]]></category>
		<category><![CDATA[autodia]]></category>
		<category><![CDATA[dia]]></category>
		<category><![CDATA[nokogiri]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/?p=219</guid>
		<description><![CDATA[Act One: The Code and The Motivation

Here&#8217;s the first player, our code.

    % ls Repository/trunk/clementine/interfaces/gesture
    CLGestureCue.cxx           CLGestureCueAppearance.h   CLGestureListener.cxx      CLGestureParser.h
    CLGestureCue.h          [...]]]></description>
			<content:encoded><![CDATA[<h2>Act One: The Code and The Motivation</h2>

<p>Here&#8217;s the first player, our code.</p>

<pre><code>    % ls Repository/trunk/clementine/interfaces/gesture
    CLGestureCue.cxx           CLGestureCueAppearance.h   CLGestureListener.cxx      CLGestureParser.h
    CLGestureCue.h             CLGestureInterface.cxx     CLGestureListener.h        CLGestureTrainer.cxx
    CLGestureCueAppearance.cxx CLGestureInterface.h       CLGestureParser.cxx        CLGestureTrainer.h

    % cat CLGestureListener.h
    #ifndef __CLEMENTINE_INTERFACES_GESTURE_CLGESTURELISTENER_H__
    #define __CLEMENTINE_INTERFACES_GESTURE_CLGESTURELISTENER_H__

    #include "CLGestureParser.h"
    #include &lt;string&gt;

    /**
     * CLGestureListener is responsible for listening on the CLGestureInterface
     * for a single gesture type.
     */
    class CLGestureListener
    {
            public:
                    /**
                     * Instantiate the listener.
                     * @param gestureName the name of the gesture
                     * (and consequently, the filename to parse) that this object is created to listen for.
                     */
                    CLGestureListener(std::string gestureName);
    ... etc
</code></pre>

<p>It&#8217;s a whole bunch of header and implementation files for a C++ project I&#8217;m involved with. This project requires the use of thorough documentation, but our design documents are hundreds of revisions behind our code. While it&#8217;s important to have gone through initial designs, our code at this point is miles removed from those designs. It would be nice to be able to automagically update our design document to be kept current on what is occurring in the code. <strong>This will not make up our entire design document</strong>. It is meant to be used in conjunction with manual, hand-written and hand-proofed analysis of the larger architecture.</p>

<p>The second player is <a href="http://www.methods.co.nz/asciidoc/">AsciiDoc</a>, a wonderful formatting and markup system. You may know it from the <a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html">Git User&#8217;s Manual</a>. AsciiDoc affords us several advantages.</p>

<ul>
<li>It is in plain text, which means it can sit in source control, right alongside our code, and diffs are easily viewable.</li>
<li>It is a templating language, which allows output into HTML, PDF, you name it. With enough hacking, you can produce really distinct output for webpages and PDF readers.</li>
<li>It allows division of sections into different files, so authors can focus on the sections that concern them without being overwhelmed by the text they&#8217;re editing.</li>
</ul>

<h2>Act Two: The Tools</h2>

<p>We want the comments in our code to be part of the documentation, but that&#8217;s not all. Since UML is the standard when it comes to software engineering description, it would be nice to have UML diagrams in our output as well. The ubiquitous free diagramming tool <a href="http://live.gnome.org/Dia">Dia</a> provides, with its invocation, command line arguments to convert Dia diagrams into images. It goes like this, where you wish the output to be <code>image_name.png</code>:</p>

<pre><code>    dia -t png -e image_name.png diagram_name.dia
</code></pre>

<p>So this part will be simple. Generating the Dia diagrams from code is already taken care of for us. Aaron Trevena has written an excellent script called <a href="http://www.aarontrevena.co.uk/opensource/autodia/">AutoDia</a> which provides this functionality. All we need to do is put these pieces together, along with writing the functionality to extract the comments we want to become documentation.</p>

<h2>Act Three: The Program</h2>

<p>I am calling it <a href="http://gist.github.com/95979">Amorfus</a>, because I think client-side applications should start getting into the Web 2.0 naming crazes.</p>

<p>How do you use it?</p>

<ol>
<li>Create a new <code>CommentDocParser</code>, with these parameters: a string pointing to the subdirectory of your trunk that you wish to document, a string containing the conceptual name of the code in that directory, and a string containing your trunk directory. You can leave this last one out, and it will default to <code>'.'</code>.</li>
<li>Run <code>#parse</code> on that parser.</li>
<li>Create a file handle, and output the return value of <code>#to_asciidoc</code> to that file.</li>
<li>That&#8217;s it!</li>
</ol>

<p>Here&#8217;s an example:</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;">'amorfus'</span>
	DIRECTORY_HEADER_LEVEL = <span style="color:#006666;">1</span> <span style="color:#008000; font-style:italic;"># This will become the section depth, in AsciiDoc, for each individual class we find</span>
	r = CommentDocParser.<span style="color:#9900CC;">new</span> <span style="color:#996600;">'interfaces/gesture'</span>, <span style="color:#996600;">'Gesture Interface'</span>, <span style="color:#996600;">'Repository/trunk'</span>
	r.<span style="color:#9900CC;">parse</span>
	t = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'output.txt'</span>, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	t.<span style="color:#9900CC;">write</span> r.<span style="color:#9900CC;">to_asciidoc</span>
	t.<span style="color:#9900CC;">close</span></pre></div></div>


<p>What does it do in the background?</p>

<ol>
<li>It uses a dumb regex based heurestic to determine if a comment has value.</li>
<li>It classifies methods by what it can find of their name.</li>
<li>It generates Dia diagrams whenever it can find an object.</li>
<li>When generating images, it parses Dia diagrams using Nokogiri and removes irrelevant objects from that diagram,
so that only the featured object shows up in the image.</li>
</ol>

<p>Finally, we&#8217;ll need to make a small patch to AutoDia to make it recognize structs as equally valid objects. This is extremely hackish (see the Epilogue), but it manages to work for now.</p>


<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">--- Autodia-<span style="">2.03</span>/lib/Autodia/Handler/Cpp.pm     <span style="">2009</span>-04-<span style="">15</span> 01:<span style="">10</span>:<span style="">46.000000000</span> -0400
<span style="color: #888822;">+++ Autodia-2.03.orig/lib/Autodia/Handler/Cpp.pm        <span style="">2005</span>-04-<span style="">15</span> 08:02:<span style="">49.000000000</span> -0400</span>
<span style="color: #440088;">@@ -<span style="">72</span>,<span style="">7</span> +<span style="">72</span>,<span style="">7</span> @@</span>
          $i++;
&nbsp;
          # check for class declaration
<span style="color: #991111;">-         if <span style="">&#40;</span>$line =~ m/^\s*<span style="">&#40;</span>?:class|struct<span style="">&#41;</span>\s+<span style="">&#40;</span>\w+<span style="">&#41;</span>/<span style="">&#41;</span></span>
<span style="color: #00b000;">+         if <span style="">&#40;</span>$line =~ m/^\s*class\s+<span style="">&#40;</span>\w+<span style="">&#41;</span>/<span style="">&#41;</span></span>
            <span style="">&#123;</span>
&nbsp;
 #            print &quot;found class : $line \n&quot;;</pre></div></div>


<h2>Act Four: The Results</h2>

<p>The resultant HTML looks like this:</p>

<p><img src="http://blog.ardekantur.com/wp-content/uploads/2009/04/amorfusexamplehtml.png" alt="Example of Amorfus-generated documentation" /></p>

<p>From our previous example, this can be generated on the command line like so:</p>

<pre><code>    % asciidoc --unsafe -e data-uri output.txt
</code></pre>

<p>The <code>--unsafe</code> and <code>-e data-uri</code> allows AsciiDoc to embed the images you&#8217;ve created directly into the HTML, instead of referencing them externally. This makes the document self-contained, in a sense. You can ignore these flags if you wish. In that case, standard <code>&lt;img&gt;</code> tags will be generated.</p>

<h2>Epilogue: Warnings</h2>

<p>This functionality was hacked together in about two hours. It does horrible things to Dia&#8217;s XML documents, it guesses at what the current spec for AsciiDoc is, and requires a hastily applied patch to a third party tool, AutoDia, in order to accomplish its goals. Because of it&#8217;s nature, I can&#8217;t make any guarantees as to how effectively it will work, what circumstances it will work under, and the like. If you have any suggestions or improvements, I implore you to fork the code (currently hosted at <a href="http://gist.github.com/95979">this Gist</a>) and see what you can come up with. For example:</p>

<ul>
<li>I don&#8217;t even think it recognizes variables correctly. You might want to fix this. </li>
<li>It ignores <code>public:</code>, <code>private:</code>, and <code>protected:</code>. You might want to fix this, but it is meant for design documents, so all methods should be documented.</li>
<li>If a class has more than one constructor, only one will be displayed in the documentation. You might want to fix this.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/04/from-code-to-design-document-a-play-in-four-acts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/04/from-code-to-design-document-a-play-in-four-acts/</feedburner:origLink></item>
		<item>
		<title>TextMate, Markdown, and following hyperlinks</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/skM5yqJG5ps/</link>
		<comments>http://blog.ardekantur.com/2009/03/textmate-markdown-and-following-hyperlinks/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 21:29:47 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Tweaking]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[hyperlinks]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[plain text wiki]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/03/textmate-markdown-and-following-hyperlinks/</guid>
		<description><![CDATA[I&#8217;m using Matt Webb&#8217;s excellent Plain Text Wiki TextMate bundle for gathering my thoughts, and needed a really basic way to quickly open hyperlinks I&#8217;ve saved without copying/pasting and all that nonsense. So, I added this command to the Plain Text Wiki bundle. I&#8217;m sure you could get it to work in Markdown&#8217;s bundle, as [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m using Matt Webb&#8217;s excellent <a href="http://interconnected.org/home/more/2007/05/textmate-wiki/">Plain Text Wiki</a> TextMate bundle for gathering my thoughts, and needed a really basic way to quickly open hyperlinks I&#8217;ve saved without copying/pasting and all that nonsense. So, I added this command to the Plain Text Wiki bundle. I&#8217;m sure you could get it to work in Markdown&#8217;s bundle, as well. All you have to do is be in the hyperlink portion of a link you&#8217;ve formatted like this:</p>

<pre><code>    (This is a link)[http://www.google.com]
</code></pre>

<p>Then press the shortcut key you&#8217;ve assigned to it. I use <code>^↘</code>.</p>

<p>I don&#8217;t know if it handles other hyperlink markup Markdown offers. Enjoy!</p>

<script src="http://gist.github.com/87524.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/03/textmate-markdown-and-following-hyperlinks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/03/textmate-markdown-and-following-hyperlinks/</feedburner:origLink></item>
		<item>
		<title>Multiruby and its Rubygems Mirror</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/o1bhl6Bi3iM/</link>
		<comments>http://blog.ardekantur.com/2009/03/multiruby-and-its-rubygems-mirror/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 17:02:00 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[multiruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/03/multiruby-and-its-rubygems-mirror/</guid>
		<description><![CDATA[# multiruby_setup update:rubygems
      Determining latest version for rubygems
    /opt/local/lib/ruby/1.8/net/http.rb:560:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
                    from ...
            [...]]]></description>
			<content:encoded><![CDATA[<pre><code># multiruby_setup update:rubygems
      Determining latest version for rubygems
    /opt/local/lib/ruby/1.8/net/http.rb:560:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED)
                    from ...
            from /opt/local/bin/multiruby_setup:19:in `load'
            from /opt/local/bin/multiruby_setup:19
</code></pre>

<p>Multiruby embeds the name of a specific Rubygems mirror, <code>http://files.rubyforge.vm.bytemark.co.uk/rubygems</code>, into its code. This isn&#8217;t a horrible thing, since we can use an environment variable to overwrite it if that mirror stops responding; however, it may be a better idea to use the RubyForge mirror selector as that URL permanently. Until then,</p>

<pre><code># GEM_URL=http://master.mirror.rubyforge.org/rubygems/ multiruby_setup rubygems:update
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/03/multiruby-and-its-rubygems-mirror/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/03/multiruby-and-its-rubygems-mirror/</feedburner:origLink></item>
		<item>
		<title>Should Canticore Have a Web-based Editor? and Other Thoughts</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/cR461cK-in8/</link>
		<comments>http://blog.ardekantur.com/2009/03/should-canticore-have-a-web-based-editor-and-other-thoughts/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 03:43:43 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Code Projects]]></category>
		<category><![CDATA[Concepts]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Web Design]]></category>
		<category><![CDATA[Web Programming]]></category>
		<category><![CDATA[canticore]]></category>
		<category><![CDATA[web interface]]></category>
		<category><![CDATA[web ui]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/03/should-canticore-have-a-web-based-editor-and-other-thoughts/</guid>
		<description><![CDATA[So my school term is coming to a close very soon, and I&#8217;ll be able to get a little bit more work done on Canticore, which I&#8217;ve decided is one of my important projects that deserves my attention. I&#8217;ll be happy if I can add 50% more tests to the existing functionality, add a couple [...]]]></description>
			<content:encoded><![CDATA[<p>So my school term is coming to a close very soon, and I&#8217;ll be able to get a little bit more work done on Canticore, which I&#8217;ve decided is one of my <strong>important projects</strong> that deserves my attention. I&#8217;ll be happy if I can add 50% more tests to the existing functionality, add a couple of important features, and solidify it all. The transition to Sinatra 0.9 allowed me to really clean up the code base, and I intend on continuing that refactoring until I&#8217;m satisfied with it.</p>

<p>Two threads of thought have occupied my attention since I stopped working on Canticore. They both have to do with perception and functionality of blogging engines, and they both kind of merge into each other. The first is the decision whether or not to include an web-based interface for writing, editing, and managing posts. Just like one of NetNewsWire&#8217;s design goals was to allow a person to literally have a coffee in one hand and read the news with the other, one of my design goals is to allow people to interact with Canticore in a comfortable environment. The song-and-dance of working in your favorite text editor and then copying and pasting your output to the web-based interface is anachronistic. We have our text editor, we have XML-RPC. Theoretically there should be nothing stopping us from keeping an arm&#8217;s length from the administrative process inherent in a web interface.</p>

<p>And if Canticore starts becoming a publishing platform instead of just a blog engine through its plugins, there&#8217;s nothing stopping plugin editors from defining mini-specs that would interface with a canticore command-line executable. Suppose, for example, a plugin existed that created a &#8216;featured&#8217; list of articles like you see on many pages &#8212; an series of images and blurbs that transition from one to the next indefinitely. Ignoring for now the problem of uploading the media, the plugin could define a namespaced XML-RPC request that took a set of arguments. For our purposes, a 3-tuple of arguments for each &#8216;feature&#8217; article will suffice:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#006600; font-weight:bold;">&#91;</span>
    <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:image</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'garden.png'</span>, <span style="color:#ff3333; font-weight:bold;">:blurb</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Lorem ipsum...'</span>, <span style="color:#ff3333; font-weight:bold;">:link_to_article</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">14</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#008000; font-style:italic;"># ...</span>
  <span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>


<p>Canticore already contains an XML generator for the most-used data types in Ruby, so if these 3-tuples were defined in a YAML document, we could perform something like the following:</p>

<pre><code>$ cat features.yml
--- 
- :image: garden.png
  :blurb: An article about gardens...
  :link_to_article: 1
- :image: cleaning.png
  :blurb: An article about cleaning...
  :link_to_article: 4
$ canticore --blog myblog --post pluginName.sendFeatures &lt; features.yml
</code></pre>

<p>And we could receive a status message from the plugin as to if the features list was well-formed, if it could find all the necessary images and articles, and so on.</p>

<p>Now we&#8217;ve managed to segue into the second train of thought: a canticore command-line client. It would help generate blogs, retrieve information about them, and allow people to automate any task necessary for blog maintenance. It would include a Ruby API so it could be called from Rake scripts and the like, and we could throw it into <code>crontab</code>s whenever necessary, constantly building on the software that works well and already exists instead of trying to reinvent the wheel. The practical upshot of this is that people would have the ability to keep their articles locally, under source control, and even provide post-commit hooks for publishing, like some prominent content publishers in the Ruby arena seem to focus on (Jekyll, in particular).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/03/should-canticore-have-a-web-based-editor-and-other-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/03/should-canticore-have-a-web-based-editor-and-other-thoughts/</feedburner:origLink></item>
		<item>
		<title>Features Gist Still Needs</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/C8x7SxU1hC8/</link>
		<comments>http://blog.ardekantur.com/2009/02/features-gist-still-needs/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 16:12:06 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Observations]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/02/features-gist-still-needs/</guid>
		<description><![CDATA[
Tagging
Most Popular / Most Forked Gists


If these both existed, it would be a cinch to use Gist as the de facto repository for all the Rails Templates we&#8217;ll start seeing when 2.3 gets released for reals.
]]></description>
			<content:encoded><![CDATA[<ul>
<li>Tagging</li>
<li>Most Popular / Most Forked Gists</li>
</ul>

<p>If these both existed, it would be a cinch to use Gist as the <em>de facto</em> repository for all the Rails Templates we&#8217;ll start seeing when 2.3 gets released for reals.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/02/features-gist-still-needs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/02/features-gist-still-needs/</feedburner:origLink></item>
		<item>
		<title>Sinatra 0.9 and Pre-RSpec Modifications</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/G1oG3trYIW8/</link>
		<comments>http://blog.ardekantur.com/2009/02/sinatra-09-and-pre-rspec-modifications/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 05:16:32 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Code Projects]]></category>
		<category><![CDATA[Observations]]></category>
		<category><![CDATA[Projects I Support]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[0.9]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[sinatra]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/02/sinatra-09-and-pre-rspec-modifications/</guid>
		<description><![CDATA[I have no idea if this is the right way to do this, but it certainly works. Say you&#8217;re working in Sinatra 0.9, and have an application that subclasses Sinatra::Base. Call it AwesomeApp. What if you want to fiddle around with it &#8212; in my case, set application options &#8212; before RSpec starts running with [...]]]></description>
			<content:encoded><![CDATA[<p>I have no idea if this is the right way to do this, but it certainly works. Say you&#8217;re working in Sinatra 0.9, and have an application that subclasses <code>Sinatra::Base</code>. Call it <code>AwesomeApp</code>. What if you want to fiddle around with it &#8212; in my case, set application options &#8212; before RSpec starts running with it? Well, you do something like this:</p>

<p><strong><code>spec_helper.rb</code></strong></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;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'my_sinatra_app'</span>
&nbsp;
AwesomeApp.<span style="color:#9900CC;">set</span> <span style="color:#ff3333; font-weight:bold;">:custom_option</span>, <span style="color:#996600;">&quot;wopphta&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@app</span> = Sinatra.<span style="color:#9900CC;">new</span> AwesomeApp</pre></div></div>


<p>Then, you can make sure it exists:</p>

<p><strong><code>awesome_app.rb</code></strong></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;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'sinatra/base'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> AwesomeApp <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Sinatra::Base</span>
  get <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#6666ff; font-weight:bold;">Sinatra::Application</span>.<span style="color:#9900CC;">custom_option</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>It&#8217;s my fervent hope that I can use this abstract option-setting for individual instances of the <code>AwesomeApp</code> class in production mode. If that&#8217;s not the case, then oh well, but at least I have a way of setting test-specific options in the app.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/02/sinatra-09-and-pre-rspec-modifications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/02/sinatra-09-and-pre-rspec-modifications/</feedburner:origLink></item>
		<item>
		<title>Spaces Application Assignments are too Literal</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/brecIETy-7Q/</link>
		<comments>http://blog.ardekantur.com/2009/01/spaces-application-assignments-are-too-literal/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 06:49:00 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Observations]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[leopard]]></category>
		<category><![CDATA[spaces]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/01/spaces-application-assignments-are-too-literal/</guid>
		<description><![CDATA[

Here was my original configuration. Two columns of spaces, three rows. Note the application assignments. I&#8217;ve asked Mail.app to stay on Space 5.



This is my new configuration. Three by three spaces. The application assignments haven&#8217;t changed, but they&#8217;ve changed in spirit. Where I was consigning Mail.app to the bottom left corner, it now sits right [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.ardekantur.com/wp-content/uploads/2009/01/2-by-3-spaces.png" alt="2 by 3 Spaces" /></p>

<p>Here was my original configuration. Two columns of spaces, three rows. Note the application assignments. I&#8217;ve asked Mail.app to stay on Space 5.</p>

<p><img src="http://blog.ardekantur.com/wp-content/uploads/2009/01/3-by-3-spaces.png" alt="3 by 3 Spaces" /></p>

<p>This is my new configuration. Three by three spaces. The application assignments haven&#8217;t changed, but they&#8217;ve changed in spirit. Where I was consigning Mail.app to the bottom left corner, it now sits right in the middle. Apple already has a plan for when the number of spaces are reduced &#8211; push everything from the removed ones onto the remaining ones. Shouldn&#8217;t there be a smarter way to handle the addition of spaces? If something&#8217;s in a corner, keep it there. If something&#8217;s on the top row, keep it there. I doubt there&#8217;s an intuitive way to both do this and keep the numbering system Leopard uses for designating spaces, but if anyone can do it, it&#8217;s Apple.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/01/spaces-application-assignments-are-too-literal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/01/spaces-application-assignments-are-too-literal/</feedburner:origLink></item>
		<item>
		<title>Canticore has Filters! Making Markdown Work for Us</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/Mxz16wFgWYM/</link>
		<comments>http://blog.ardekantur.com/2009/01/canticore-has-filters-making-markdown-work-for-us/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 04:28:33 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Code Projects]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[canticore]]></category>
		<category><![CDATA[filters]]></category>
		<category><![CDATA[markdown]]></category>
		<category><![CDATA[rdiscount]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2009/01/canticore-has-filters-making-markdown-work-for-us/</guid>
		<description><![CDATA[I was going to create a new repo on GitHub to show off this awesomeness, but then I figured, why not just show everyone how to use the new filter functionality?

Minus all the cruft of being a gem, this is the only code you&#8217;ll write to create a Markdown plugin for your Canticore blog.


require 'canticore/plugin'
require [...]]]></description>
			<content:encoded><![CDATA[<p>I was going to create a new repo on GitHub to show off this awesomeness, but then I figured, why not just show everyone how to use the new filter functionality?</p>

<p>Minus all the cruft of being a gem, this is the only code you&#8217;ll write to create a Markdown plugin for your Canticore blog.</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;">'canticore/plugin'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rdiscount'</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Canticore::PluginGem::Create</span> <span style="color:#996600;">'markdown'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  enhances <span style="color:#ff3333; font-weight:bold;">:all</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> to_markdown_formatted_html data
    RDiscount.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_html</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  filter <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:post</span>, <span style="color:#ff3333; font-weight:bold;">:body</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:to_markdown_formatted_html</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>That <code>filter</code> command does exactly what you expect it to. Every time it comes across a post body, it sends it as the parameter to the function <code>to_markdown_formatted_html</code>! Simple as that.</p>

<p>Theme designers, take note: Filters are not applied automatically! The HAML line <code>= post.body</code> will still output the plain post body, and not spin up the filter function at all. The line <code>= post.filtered(:body)</code>, however, will!</p>

<p>I haven&#8217;t yet decided if filters can be arbitrarily ordered. I think that&#8217;s needless complexity and I can&#8217;t think of a good reason to do so.</p>

<p>Interested in developing Canticore or for Canticore? There hasn&#8217;t been a better time to get started! Send a message to my <a href="http://github.com/ardekantur/">GitHub profile</a> if you&#8217;d like to contribute, and I&#8217;ll point you towards some thing that needs to be done. I have a fucking laundry list, here.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2009/01/canticore-has-filters-making-markdown-work-for-us/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2009/01/canticore-has-filters-making-markdown-work-for-us/</feedburner:origLink></item>
		<item>
		<title>Canticore – A new look at blogging engines.</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/GRtZsHy6bPY/</link>
		<comments>http://blog.ardekantur.com/2008/12/canticore-a-new-look-at-blogging-engines/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 17:05:08 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Code Projects]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[canticore]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/2008/12/canticore-a-new-look-at-blogging-engines/</guid>
		<description><![CDATA[Canticore, the project I've been working on for a month, finally receives an introduction to the world.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d like to talk about blogging for a bit. I know, it&#8217;s a horrible subject that&#8217;s been done to death, but I began working on a project recently that I hope will try to provide a clean, simple, robust solution for the next generation of bloggers and programmers.</p>

<p>It&#8217;s called <a href="http://github.com/ardekantur/canticore">Canticore</a>. It&#8217;s written in Ruby, and has the features I want in it, but this feature list may be common to a lot of people.</p>

<ul>
<li>(Multi)Markdown support</li>
<li>Aggressive Caching</li>
<li>Threaded comments</li>
<li>Multiple users</li>
<li>Painless upgrade</li>
<li>Rich RSS (by category, post, tag, comment)</li>
<li>Static pages</li>
<li>Support for common blogging APIs (Blogger, metaWeblog, Movable Type)</li>
<li>Syntax Highlighting</li>
<li>Trackbacks</li>
<li>Web administration</li>
</ul>

<p>The most important feature is one that I think will make the difference. <strong>Plugins and themes are RubyGems</strong>. That&#8217;s it. That&#8217;s the killer thing. That&#8217;s what&#8217;s most important to me. I sat down and knew I wanted hooks and filters, themes, all that good stuff, but as I worked on the domain for those things, I realized RubyGems did everything I wanted my plugins and themes to do: simple versioning, metadata, easy installation and painless upgrading. So that became my new goal.</p>

<p>At this point, the codebase is a bit of an uncommented mess, but it has everything in place to make my goals work. This early announcement was pre-empted by two things: Matt&#8217;s removal of themes from wordpress.org, and GitHub&#8217;s announcement of their new feature, GitHub Pages: the former, because theme and plugin submissions on canticore.org will be provided with <strong>the ability to choose a license</strong> upon submission, and the latter because people might flock to that instead of looking for alternatives :-)</p>

<p><a href="http://github.com/ardekantur/canticore">The repository</a> is available at GitHub, along with the official website repository, some plugins to ensure certain functionality is baked in, and the first theme, called <code>default</code>.</p>

<p>I&#8217;ve secured a <a href="http://canticore.org">gorgeous place</a> for people to upload gems that they create. I was considering creating a sub-reddit for this purpose, and not do any of this work, but I also wanted a demo server for people to try out themes that interest them. If you&#8217;re interested in contributing, or <a href="http://github.com/ardekantur/canticore/wikis/home">having a say</a> in the next feature, or want to <a href="http://ardekantur.lighthouseapp.com/projects/21587-canticore">file bugs</a> or tests, join the conversation! I want to make something exciting and beautiful, but I know I may not have the time to do it alone, anymore.</p>

<p>For people interested in how it works for plugin and theme developers, keep reading.</p>

<h2>Plugins</h2>

<p>Imagine being able to write a blog plugin with proper object-orientation! :-) Plugins have an extremely simple syntax that you can pick up just from reading a sample.</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;">'canticore/plugin'</span>
&nbsp;
  <span style="color:#6666ff; font-weight:bold;">Canticore::Plugin::Create</span> <span style="color:#996600;">'theme-changer'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    enhances <span style="color:#ff3333; font-weight:bold;">:index</span>
    variable <span style="color:#ff3333; font-weight:bold;">:before_text</span>, 
      <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:summary</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Dropdown Prefix Text&quot;</span>, 
          <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Text to display before the drop-down.&quot;</span>,
          <span style="color:#ff3333; font-weight:bold;">:default</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Change Theme: &quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> output
      haml <span style="color:#ff3333; font-weight:bold;">:output</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    hook <span style="color:#ff3333; font-weight:bold;">:body</span>, <span style="color:#ff3333; font-weight:bold;">:output</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<p>The <code>#enhances</code> block tells the blog what pages the plugin should be enabled on: <code>:index</code> just means it will be enabled on the landing page, and not archive pages, individual post pages, static pages, et cetera. You can also use <code>enhances :all</code> for a blanket enabling.</p>

<p>Each variable you want the user to change and be able to save to the database begins with a <code>#variable</code> function. Give it a name and a list of options.</p>

<p>Hooks are where you attach your functionality to Canticore. Right now there&#8217;s only a few, <code>:body</code> being one of them. The line <code>hook :body, :output</code> tells Canticore to attach the output of the function called <code>:output</code> to the body hook. You can use HAML for your plugins, in this case the function output looks for a file called <code>views/output.haml</code> in your plugin gem to render.</p>

<p>Filters are coming.</p>

<h2>Themes</h2>

<p>Themes are designed in HAML and can use SASS and plain old CSS. You need certain layout pages for your theme to be valid:</p>

<ul>
<li><code>archive.haml</code> for archive listings.</li>
<li><code>index.haml</code> for the landing page of your blog.</li>
<li><code>layout.haml</code> for the global layout.</li>
<li><code>page.haml</code> for static page content.</li>
<li><code>post.haml</code> for individual post pages.</li>
<li><code>_entry.haml</code> for what a post will look like when displayed in a listing.</li>
</ul>

<p>And that&#8217;s it! Static content goes in your gem under <code>static</code>, and stylesheets go under <code>stylesheets</code>, whether or not they&#8217;re SASS or CSS. Canticore is smart enough to figure it out. The name <code>static/snapshot.png</code> is reserved for the screenshot you want to take of your theme to display to users on canticore.org and in Canticore&#8217;s administration panel.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2008/12/canticore-a-new-look-at-blogging-engines/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2008/12/canticore-a-new-look-at-blogging-engines/</feedburner:origLink></item>
		<item>
		<title>Looks Like Spammers Don’t Write Tests</title>
		<link>http://feedproxy.google.com/~r/Ardekantur/~3/NB1JFpC83QU/</link>
		<comments>http://blog.ardekantur.com/2008/12/looks-like-spammers-dont-write-tests/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 18:14:42 +0000</pubDate>
		<dc:creator>Ardekantur</dc:creator>
				<category><![CDATA[Observations]]></category>
		<category><![CDATA[lol]]></category>
		<category><![CDATA[spam]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.ardekantur.com/?p=188</guid>
		<description><![CDATA[Nicked from a spam harvest on my blog.]]></description>
			<content:encoded><![CDATA[<p>Nicked from a spam harvest on my blog:</p>

<pre><code>    =======================================================
    Report on Comment number 1 (id=2390)
    Comment Author: FIELD_NICKNAME
    Comment Content: 
    -----------------------------------------
    FIELD_MESSAGE_cnaroronoo
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.ardekantur.com/2008/12/looks-like-spammers-dont-write-tests/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.ardekantur.com/2008/12/looks-like-spammers-dont-write-tests/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 0.737 seconds -->
