<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://www.h3rald.com/</id>
  <title>H3RALD - Tag 'opensource' (Atom Feed)</title>
  <updated>2010-09-03T17:45:00Z</updated>
  <link href="http://www.h3rald.com" rel="alternate"/>
  <link href="http://www.h3rald.com/tags/opensource/atom/" rel="self"/>
  <author>
    <name>Fabio Cevasco</name>
    <uri>http://www.h3rald.com</uri>
  </author>
  <entry>
    <id>tag:www.h3rald.com,2010-09-03:/articles/glyph-040-released/</id>
    <title>Glyph 0.4.0 Released</title>
    <published>2010-09-03T17:45:00Z</published>
    <updated>2010-09-03T18:31:10Z</updated>
    <link href="http://www.h3rald.com/articles/glyph-040-released/" rel="alternate"/>
    <category term="glyph" scheme="http://www.h3rald.com/tags/glyph/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[

		<div class="section">
<p>This new release of Glyph introduces an unusually large number of features, improvements and bugfixes. Not so much in terms of new macros maybe (no index or bibliography support for now, but it will come, don&#8217;t worry!), but rather&#8230; pretty much everything else!</p>

<div class="section">
<h3 id="h_1">Web Output</h3>
<p>By far the biggest feature of this release is support for multi-file output, i.e. the possibility to transform your book into a web site. You&#8217;ve asked for it, I needed it too, and now it&#8217;s finally here.</p>
<p>An example? Sure. Take the <a href="http://github.com/downloads/h3rald/glyph/glyph.pdf">Glyph Book</a> (now a 98-page <span class="caps">PDF</span> file) for instance. My only regret was that a long <span class="caps">PDF</span> is quite heavy to digest and peruse, especially if you&#8217;re in a hurry. It would be so much nice to have it available online, in chunks of more manageable size.</p>
<p>Well, <a href="/glyph/book/">here it is</a>. That&#8217;s the very same document, split in several <span class="caps">HTML</span> files with a custom layout that matches this site&#8217;s. The good news is that you can do it too:</p>
	
<div class="code">
<pre>
<code>
section[
  @title[This title is compulsory]
  @id[random_section]	
  @src[topic_file.glyph]
]
</code>
</pre>
</div>
	<p>Note the <code>@src</code> attribute? It basically includes the specified topic file. So by creating a <code>document.glyph</code> file like <a href="http://github.com/h3rald/glyph/blob/master/book/document.glyph">this</a>, you can create a tidy table of contents (not a single <code>include</code> macro) <em>and</em> get a website for free. Glyph, as usual, takes care of anything for you, especially links between topics. Just link away like you did so far, nothing changes from previous versions, it will just work as expected (<a href="/glyph/book/compiling/compiling.html#web_output">read more</a>).</p>

</div>
<div class="section">
<h3 id="h_2">HTML5 Output</h3>
<p>Compared to Web output, HTML5 support was trivial and only took a few hours to implement and test. You can now produce single-file HTML5-compliant documents (<code>html5</code> output format) or even HTML5-compliant web sites (<code>web5</code> output). Just using <code>section</code> tags instead of <code>div</code> tags made it worth it.</p>
<p>Of course, the default <span class="caps">CSS</span> files have been updated to be compatible with HTML5 output too.</p>

</div>
<div class="section">
<h3 id="h_3">Project Statistics</h3>
<p>Anoher big thing was a shiny new command, <code>glyph stats</code>, which brings &#8212; guess &#8212; stats. No more chasing after bookmark references, just type <code>glyph stats --bookmark=#web_output</code> and you&#8217;ll know where the <code>#web_output</code> bookmark was defined <em>and</em> what links to it. Similar stats are available for:</p>
<ul>
	<li>macros</li>
	<li>links</li>
	<li>files</li>
	<li>snippets</li>
</ul>
<p><code>glyph stats -m</code> tells me that I used 3236 macro instances throughout the Glyph book. Just so you know.</p>

</div>
<div class="section">
<h3 id="h_4">Custom tasks and commands</h3>
<p>&#8220;Glyph is extensible&#8221;, &#8220;Glyph lets you create your own macros&#8221;, &#8230;great, but kinda limited right? No more. Glyph now lets you create <em>custom Rake tasks</em> and even <em>custom commands</em>.</p>
<p>Have a look at <a href="/glyph/book/extending/commands_tasks.html">this page</a> for more information on what you can do and how. You can now extend Glyph in any way you like (including adding custom output formats) without having to touch its core, just do it <em>within your own project</em>.</p>

</div>
<div class="section">
<h3 id="h_5">wkhtmltopdf</h3>
<p>Last but not least, you no longer need Prince <span class="caps">XML</span> to produce <span class="caps">PDF</span> file. Granted, Prince is awesome and the <span class="caps">PDF</span> it produces are very, very nice&#8230; but if you want to produce PDFs commercially and want to same some money, you can now use <a href="http://code.google.com/p/wkhtmltopdf/">wkhtmltopdf</a>: it&#8217;s <em>free</em> and <em>open source</em>, and it keeps getting better and better.</p>

</div>
<div class="section">
<h3 id="h_6">...and more to come!</h3>
<p>After this release I&#8217;m going to take a small break from Glyph. Nothing major, I just want to redesign my site (again) and find the time to write a proper Glyph tutorial. This doesn&#8217;t mean that development will be halted or anything, just that it will take a few months for Glyph 0.5.0 to come out.</p>
<p>Meanwhile, there may be bugfix releases (depends how many bugs turn up). It would be a good time to come out of the closet and propose/vote on new <a href="http://github.com/h3rald/glyph/issues">features</a>!</p>
<p>Hope you enjoy using Glyph 0.4.0, and if you need anything or feel social, remember that the doors of the <a href="http://groups.google.com/group/glyph-framework">Glyph User Group</a> are always open!</p>

</div>

</div>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2010-06-13:/articles/glyph-030-released/</id>
    <title>Glyph 0.3.0 Released</title>
    <published>2010-06-13T12:10:00Z</published>
    <updated>2010-06-14T09:14:23Z</updated>
    <link href="http://www.h3rald.com/articles/glyph-030-released/" rel="alternate"/>
    <category term="glyph" scheme="http://www.h3rald.com/tags/glyph/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[

		<div class="section">
<p>The third release of <a href="/glyph/">Glyph</a> is out!</p> 

<p>For those checking it out for the first time, Glyph is a <em>Rapid Document Authoring Framework</em> focused on extensibility and content reuse. For an example of what Glyph can do, have a look at Glyph's <a href="http://github.com/h3rald/glyph/raw/master/book/output/pdf/glyph.pdf">free PDF book</a>.</p>

<p>This release brings more stability to Glyph, more speed, and features affecting Glyph's core functionality. As a consequence, some <a href="http://github.com/h3rald/glyph/issues/closed#issue/121">incompatibilities</a> had to be introduced &ndash; but after all, better now than later.</p> 

<div class="section">
<h3 id="h_1">New parser and performance improvements</h3>
<p>This release's big news is the brand new <a href="http://yardoc.org/docs/h3rald-glyph/glyph/parser">Glyph Parser</a>. Until this release, Glyph relied on the awesome <a href="http://treetop.rubyforge.org/">Treetop</a> library for parsing Glyph language. Treetop is great when it comes to creating language parsers effortlessly, but it can add quite a bit of an overhead especially when using <a href="http://groups.google.com/group/treetop-dev/browse_thread/thread/15ff7659b2efbeed">dot star</a> patterns.</p>

	<p>So I ran a few benchmarks and in the end decided to write my very own (first!) parser from scratch using just the <a href="http://ruby-doc.org/core/classes/StringScanner.html">StringScanner</a> class, which is part of Ruby Standard Library. It took me a bit to get used to it, but in the end I managed to create something able to produce an Abstract Syntax Tree exactly the way I wanted.</p>

	<p>After adding the new parser, Glyph became significantly faster. This doesn't mean it's as fast as, say, RedCloth, but I it can be used to process long books in just a few <em>seconds</em> rather than <em>minutes</em>.</p>

</div>

<div class="section">
<h3 id="h_2">Macro Attributes</h3>
<p>Glyph now supports named attributes as well as positional parameters. This is particularly handy when you want to create macros with a lot of optional arguments: in this case, positional parameters are not great. As a result, for example, the <code>section</code> macro now takes an optional <code>title</code> and <code>id</code> attributes, rather than two parameters</p>
	
	<p>Attributes look like macros, but they all start with a <code>@</code> character. For example, see the the following image, showing this very section:</p>
	
	<img alt="-" src="/img/pictures/updated_glyph_syntax.png" />

</div>

<div class="section">
<h3 id="h_3">Full XML support</h3>
<p>Once macro attributes became available at parser level, having Glyph to produce arbitrary XML code became extremely easy. By default, now if Glyph doesn't find a macro it assumes you're inputting an XML tag of some kind, so you can write:</p>

	<div class="CodeRay">
  <div class="code"><pre>p[This is a paragraph with some em[emphasized] text.]
img[
  @alt[Glyph Code]
  @width[50%]
  @height[50%]
  @src[glyph_code.png]
]</pre></div>
</div>


	<p>And get the following HTML code back:</p>
	
	<div class="CodeRay">
  <div class="code"><pre><span class="ta">&lt;p&gt;</span>This is a paragraph with some <span class="ta">&lt;em&gt;</span>emphasized<span class="ta">&lt;/em&gt;</span> text.<span class="ta">&lt;/p&gt;</span>
<span class="ta">&lt;img</span> 
  <span class="an">alt</span>=<span class="s"><span class="dl">&quot;</span><span class="k">Glyph Code</span><span class="dl">&quot;</span></span>
  <span class="an">width</span>=<span class="s"><span class="dl">&quot;</span><span class="k">50%</span><span class="dl">&quot;</span></span>
  <span class="an">height</span>=<span class="s"><span class="dl">&quot;</span><span class="k">60%</span><span class="dl">&quot;</span></span>
  <span class="an">src</span>=<span class="s"><span class="dl">&quot;</span><span class="k">glyph_code.png</span><span class="dl">&quot;</span></span>  
<span class="ta">/&gt;</span></pre></div>
</div>


  <p>...and none of the macros used in the previosu Glyph code snippet are actually defined in Glyph. Among other things, this means that <em>you don't have to</em> use Textile or Markup within your Glyph code unless you absolutely need to (e.g. for lists, which would be a bit verbose to create using just Glyph markup).</p>

</div>

<div class="section">
<h3 id="h_4">Improved <code>include</code> macro and "safe mode"</h3>
<p>The <code>include</code> macro now <em>must</em> take an path to a file relative to the <code>text/</code> directory of your project, <em>or</em> it can also be used to include (and <em>evaluate</em>) ruby code within your <code>lib/</code> directory. Moreover, you can now use the <code>include</code> macro even when compiling single Glyph files.</p>

	<p>Now, while evaluating Ruby code in an external file can be quite handy, is also quite insecure. For this reason, it is now possible to use Glyph programmatically in "safe mode", thereby forbidding the usage of certain <em>unsafe</em> macros.</p>

</div>

<div class="section">
<h3 id="h_5">What's next?</h3>
<p>Sooner or later I'll have to implement support for generating multiple files in output. This would make it possible to make the  <a href="http://github.com/h3rald/glyph/raw/master/book/output/pdf/glyph.pdf">Glyph book</a> available online as a collection of separate HTML file, for example, or, later on, maybe even compiled into a (ugh!) CHM file.</p>

	<p>Additionally, HTML5 support is also on the horizon: given the current Glyph architecture, it will be relatively easy to have Glyph macros to produce HTML5 code instead of XHTML. LaTeX support, on the other hand, is a completely different game, mainly because I'm not familiar with it, so if anyone feels creative and would like an easier way to produce reusable LaTeX code, <a href="http://github.com/h3rald/glyph/">get forking</a> and contact me!</p>

</div>

</div>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2010-05-09:/articles/glyph-020-released/</id>
    <title>Glyph 0.2.0 Released</title>
    <published>2010-05-09T15:00:00Z</published>
    <updated>2010-06-13T12:53:48Z</updated>
    <link href="http://www.h3rald.com/articles/glyph-020-released/" rel="alternate"/>
    <category term="glyph" scheme="http://www.h3rald.com/tags/glyph/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[

		<div class="section">
<p>I am very pleased to announce the second release of the <a href="/glyph/">Glyph Document Authoring Framework</a>. For those who don&#8217;t know, Glyph is a pure-Ruby, extensible solution to author documents like books or articles using a simple, fully-customizable markup language.</p>
<p>Since the <a href="/articles/introducing-glyph/">first release</a>, came out, last month, a lot happened. Plenty of bugs were fixed and new features implemented, as shown by the <a href="http://github.com/h3rald/glyph/blob/master/CHANGELOG.textile">changelog</a>. Here&#8217;s a brief rundown of the most notable changes.</p>
<div class="section">
<h3 id="h_1">What Glyph code looks like</h3>
<p>Earlier this week I <a href="http://blog.h3rald.com/making-a-custom-vim-syntax-file">blogged</a> about my new <a href="http://github.com/h3rald/stash/blob/master/.vim/syntax/glyph.vim">Glyph vim syntax file</a>. I&#8217;ve been using it for a while, and all I can say is that it really helps! Here&#8217;s what it looks like:</p>
<p><img alt="-" src="/img/pictures/glyph_syntax.png" /></p>
<p>I&#8217;m sorry for the Emacs and TextMate folks, but I only use Vim, so I only made a Vim syntax file. Anyhow, Glyph grammar is very simple, so rolling out your own syntax file for your favorite editor shouldn&#8217;t be too hard.</p>
</div>
<div class="section">
<h3 id="h_2">Notable features</h3>
<div class="section">
<h4 id="h_3">Single-file compilation</h4>
<p>Perhaps the most life-changing feature in this release is the possibility of compiling a single Glyph source file into an <span class="caps">HTML</span> or <span class="caps">PDF</span> file. This means you no longer need to create a full-blown project for writing a short article: just create a file anywhere and run <code>glyph compile filename.glyph</code>on it!</p>
<p>The good thing is that with this new release you can also define snippets, configuration settings, and even macros right into your Glyph files, so you can do almost anything without having to create a project or fiddle with <span class="caps">YAML</span> files.</p>
</div>
<div class="section">
<h4 id="h_4">Programmatic usage</h4>
<p>The second most notable feature is the possibility to use Glyph as a Ruby library, i.e. as you&#8217;d use a filter like RedCloth or MarkDown. Additionally, it is also possible to compile single files programmatically, so you can, for example, create <span class="caps">PDF</span> files for your articles from the same source file. Don&#8217;t believe me? Feel free to click the <em>Download <span class="caps">PDF</span></em> and <em>View Source</em> links on this very page to see for yourself&#8230;</p>
<p>For those of you using the awesome <a href="http://nanoc.stoneship.org">nanoc</a> static site generator, here&#8217;s a few source files you may want to take a look at:</p>
<ul>
	<li><a href="http://github.com/h3rald/h3rald/blob/master/lib/glyph-data.rb">lib/glyph-data.rb</a> &#8212; How to update configuration settings.</li>
	<li><a href="http://github.com/h3rald/h3rald/blob/master/lib/glyph-filter.rb">lib/glyph-data.rb</a> &#8212;  a simple Glyph filter.</li>
	<li><a href="http://github.com/h3rald/h3rald/blob/master/Rules">Rules</a> &#8212; a rule using the <code>Glyph#compile</code> method to generate <span class="caps">PDF</span> files.</li>
</ul>
</div>
<div class="section">
<h4 id="h_5">Auto-regeneration</h4>
<p>Another very interesting feature is the possibility to auto-regenerate your output files automatically whenever a source file is changed. Just run <code>glyph compile --auto</code> and you&#8217;re away. I&#8217;d like to thank <a href="http://koraktor.github.com">Sebastian Staudt</a> for proposing, implementing, and testing this feature.</p>
</div>
<div class="section">
<h4 id="h_6">Conditional macros</h4>
<p>Finally, although it may worry some, I added the possibility to evaluate conditional expressions directly in Glyph. The syntax is a bit verbose due to the extreme simplicity of Glyph parser, but it does the job:</p>
<p><code>?[and[
    eq[$[document.output]|pdf]|
    eq[$[tools.pdf_generator]|prince]
    ]|
  style[pagination.css]]</code></p>
<p>The snippet above can be used to include the <code>pagination.css</code> stylesheet only when generating a <span class="caps">PDF</span> file with Prince <span class="caps">XML</span>.</p>
</div>
</div>
<div class="section">
<h3 id="h_7">What&#8217;s next?</h3>
<p>Release 0.3.0 is currently being planned, and so are its <a href="http://github.com/h3rald/glyph/issues">features</a>. For now, I&#8217;d like to thank the following individuals for contributing to Glyph:</p>
<ul>
	<li><a href="http://www.jabbslad.com">Jamie Atkinson</a> (Jabbslad), for spotting and fixing some bugs and providing feedback.</li>
	<li><a href="http://koraktor.github.com">Sebastian Staudt</a> (koraktor), for spotting and fixing some bugs, proposing and implementing new features.</li>
</ul>
<p>In particular, Sebastian is working on <a href="http://wiki.github.com/h3rald/glyph/feature-bibliography-support">bibliogaphy support</a> for Glyph, looking forward to it!</p>
<p>Although still in its infancy, Glyph is becoming more and more usable everyday. If you are interested, you can contribute in many different ways to the project, such as:</p>
<ul>
	<li>By participating to discussions on the <a href="http://groups.google.com/group/glyph-framework">user group</a> (it&#8217;s a bit quiet of there for now&#8230;)</li>
	<li>By spreading the word on Twitter, on your blog, or wherever you like.</li>
	<li>By installing it, using it, reporting bugs and proposing new features (it&#8217;s just a <code>gem install glyph</code> away!).</li>
	<li>By actually contributing to its development (it&#8217;s <a href="http://wiki.github.com/h3rald/glyph/contribution-guidelines">easy</a>!).</li>
</ul>
<p>Additionally, if you don&#8217;t like coding:</p>
<ul>
	<li>feedback on the current documentation and on the <a href="http://github.com/h3rald/glyph/raw/master/book/output/pdf/glyph.pdf">Glyph book</a> is appreciated</li>
	<li>if you are good with <span class="caps">CSS</span>, I&#8217;m looking for some nice new <span class="caps">CSS</span> styles to include in the standard Glyph distribution.</li>
	<li>if you&#8217;re good with graphics, Glyph needs a good-looking logo&#8230;</li>
</ul>
<p>Any form of contribution will be credited in some way, e.g. by links and tweets.</p>
</div>

</div>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2009-03-01:/articles/rawline-030/</id>
    <title>RawLine 0.3.0 released &#8212; now with Readline emulation</title>
    <published>2009-03-01T06:47:00Z</published>
    <updated>2009-09-06T18:10:52Z</updated>
    <link href="http://www.h3rald.com/articles/rawline-030/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="rawline" scheme="http://www.h3rald.com/tags/rawline/"/>
    <content type="html">
<![CDATA[
<p><a href="/rawline">RawLine</a> 0.3.0 has been <a href="http://rubyforge.org/projects/rawline">released</a>. This new milestones fixes some minor bugs and adds some new functionalities, must notably:</p>
<ul>
	<li>Ruby 1.9 support</li>
	<li>A filename completion function</li>
	<li>A new <span class="caps">API</span> very similar to the one exposed by the Ruby wrapper for <span class="caps">GNU</span> Readline</li>
</ul>
<p>Some of you asked for Readline compatibility/emulation and that was actually not too difficult to implement: all the bricks were already there, I just had to put them together in the right place.</p>
<p>The <code>RawLine</code> module (you can spell it &#8220;Rawline&#8221; as well, if you wish) now behaves like <code>Readline</code>. This means that you can now use RawLine like this (taken from examples/readline_emulation.rb):</p>
<div class="highlight"><pre><span class="kp">include</span> <span class="no">Rawline</span>

<span class="nb">puts</span> <span class="s2">&quot;*** Readline Emulation Test Shell ***&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press CTRL+X to exit&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press &lt;TAB&gt; for file completion&quot;</span>

<span class="no">Rawline</span><span class="o">.</span><span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:ctrl_x</span><span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span><span class="p">;</span> <span class="nb">puts</span> <span class="s2">&quot;Exiting...&quot;</span><span class="p">;</span> <span class="nb">exit</span> <span class="p">}</span>

<span class="no">Dir</span><span class="o">.</span><span class="n">chdir</span> <span class="s1">&#39;..&#39;</span>

<span class="kp">loop</span> <span class="k">do</span>
	<span class="nb">puts</span> <span class="s2">&quot;You typed: [</span><span class="si">#{</span><span class="nb">readline</span><span class="p">(</span><span class="s2">&quot;=&gt; &quot;</span><span class="p">,</span> <span class="kp">true</span><span class="p">)</span><span class="o">.</span><span class="n">chomp!</span><span class="si">}</span><span class="s2">]&quot;</span>
<span class="k">end</span>
</pre>
</div><p>Basically you get a <code>readline</code> method, a <code>HISTORY</code> constant like the one exposed by Readline (Rawline&#8217;s is a RawLine::HistoryBuffer object though &mdash; much more manageable), and a <code>FILENAME_COMPLETION_PROC</code> constant, which provides basic filename completion. Here it is:</p>
<div class="highlight"><pre>	<span class="k">def</span> <span class="nf">filename_completion_proc</span>
			<span class="nb">lambda</span> <span class="k">do</span> <span class="o">|</span><span class="n">word</span><span class="o">|</span>
				<span class="n">dirs</span> <span class="o">=</span> <span class="vi">@line</span><span class="o">.</span><span class="n">text</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
					<span class="n">path</span> <span class="o">=</span> <span class="vi">@line</span><span class="o">.</span><span class="n">text</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sr">/^\/|[a-zA-Z]:\//</span><span class="p">)</span> <span class="p">?</span> <span class="s2">&quot;/&quot;</span> <span class="p">:</span> <span class="no">Dir</span><span class="o">.</span><span class="n">pwd</span><span class="o">+</span><span class="s2">&quot;/&quot;</span>
				<span class="k">if</span> <span class="n">dirs</span><span class="o">.</span><span class="n">length</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">then</span> <span class="c1"># starting directory</span>
					<span class="n">dir</span> <span class="o">=</span> <span class="n">path</span>
				<span class="k">else</span>
					<span class="n">dirs</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">dirs</span><span class="o">.</span><span class="n">last</span><span class="p">)</span> <span class="k">unless</span> <span class="no">File</span><span class="o">.</span><span class="n">directory?</span><span class="p">(</span><span class="n">path</span><span class="o">+</span><span class="n">dirs</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">))</span>
					<span class="n">dir</span> <span class="o">=</span> <span class="n">path</span><span class="o">+</span><span class="n">dirs</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
				<span class="k">end</span>
				<span class="no">Dir</span><span class="o">.</span><span class="n">entries</span><span class="p">(</span><span class="n">dir</span><span class="p">)</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">(</span><span class="n">e</span> <span class="o">=~</span> <span class="sr">/^\./</span> <span class="o">&amp;&amp;</span> <span class="vi">@match_hidden_files</span> <span class="o">&amp;&amp;</span> <span class="n">word</span> <span class="o">==</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">e</span> <span class="o">=~</span> <span class="sr">/^</span><span class="si">#{</span><span class="n">word</span><span class="si">}</span><span class="sr">/</span> <span class="o">&amp;&amp;</span> <span class="n">e</span> <span class="o">!~</span> <span class="sr">/^\./</span><span class="p">)</span> <span class="p">}</span>
			<span class="k">end</span>
		<span class="k">end</span>
</pre>
</div><p>You can find this function as part of the <code>RawLine::Editor</code> class. The result is not exactly the same Readline, because completion matches are not displayed underneath the line but inline and can be cycled through &mdash; which is one of Readline&#8217;s completion modes anyway.</p>
<p>A few methods of the <code>RawLine::Editor</code> class can now be accessed directly from the <code>RawLine</code> module, like with Readline:</p>
<ul>
	<li><code>Rawline.completion_proc</code> &mdash; the Proc object used for <span class="caps">TAB</span> completion (defaults to FILENAME_COMPLETION_PROC).</li>
	<li><code>Rawline.completion_matches</code> &mdash; an array of completion matches.</li>
	<li><code>Rawline.completion_append_char</code> &mdash; a character to append after a successful completion.</li>
	<li><code>Rawline.basic_word_break_characters</code> &mdash; a String listing all the characters used as word separators.</li>
	<li><code>Rawline.completer_word_break_characters</code> &mdash; same as above.</li>
	<li><code>Rawline.library_version</code> &mdash; the current version of the Rawline library.</li>
	<li><code>Rawline.clear_history</code> &mdash; to clear the current history.</li>
	<li><code>Rawline.match_hidden_files</code> &mdash; whether FILENAME_COMPLETION_PROC matches hidden files and folders or not.</li>
</ul>
<p>I bet you didn&#8217;t know these methods were even in the Readline wrapper, did you? Probably because of lack of documentation.<br />
Anyhow, another very important difference beween Rawline and Readline is <code>Rawline.editor</code>, i.e. the default instance of RawLine::Editor used by the Rawline module itself.</p>
<p>This makes things easier if you want more control over the line which is being edited and the previously-edited lines. Sure, <code>Readline#completion_proc</code> exposes the current <em>word</em> being typed before hitting tab, and so does <code>Rawline#completion_proc</code> the difference is that if you access <code>Rawline.editor.line</code> you get a <code>RawLine::Line</code> object with all the information you could possibly need about the current line: the position of the cursor, the text, the order the characters were entered, etc. etc. <br />
Now you can imagine why it took me a few minutes to write the <code>filename_completion_proc</code> method (and why it will take you even less time to write your own similar method if you wanna do something different): you can access not only the last word being typed but also the current <em>and previous</em> lines (through <code>Rawline.editor.history</code> or just <code>Rawline::HISTORY</code>)!</p>
<p>It must be said, as usual, that Rawline is <em>not</em> a complete replacement for the Readline library yet (and it will probably never be, as Readline is huge!), but it&#8217;s a good cross-platform, more Ruby-esque alternative to what&#8217;s currently available by the Readline wrapper for Ruby.</p>
<p>It&#8217;s not as fast, of course, especially when completing long words, but it&#8217;s quite usable. The following libraries are not required but recommended:</p>
<ul>
	<li><code>win32console</code> (on Windows)</li>
	<li><code>termios</code> (on *nix)</li>
</ul>
<p>They basically make Rawline faster. If you don&#8217;t use them, Rawline will fall back on its pure-Ruby implementation to move left and right (i.e. printing backspaces and spaces character codes instead of <span class="caps">ASCII</span> escape codes).</p>
<p>Unfortunately, there&#8217;s no <code>vi_editing_mode</code> or <code>emacs_editing_mode</code> yet (for time constraints: they <em>can</em> be implemented!) but patches are very welcome. Also, if you need more features, all you have to do is ask :-)</p>
<p>P.S.: Check out the new <a href="/rawline">Project Page</a> and especially its Resources section!</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2008-04-02:/articles/rawline-020/</id>
    <title>New Release: RawLine 0.2.0</title>
    <published>2008-04-02T03:33:00Z</published>
    <updated>2009-09-06T18:10:51Z</updated>
    <link href="http://www.h3rald.com/articles/rawline-020/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="rawline" scheme="http://www.h3rald.com/tags/rawline/"/>
    <content type="html">
<![CDATA[
<p><del>InLine</del> RawLine 0.2.0 is out!</p>
<p>*Raw*Line is the new name for InLine, in case you didn&#8217;t guess. The name was changed to avoid name collision problems with the RubyInline project.</p>
<p>Here&#8217;s what&#8217;s new:</p>
<ul>
	<li>Added /examples and /test directory to gem.</li>
	<li>Escape codes can now be used in prompt.</li>
	<li>It is now possible to use bind(key, &amp;block) with a String as key, even if the corresponding escape sequence is not defined.</li>
	<li>Added Editor#write_line(string) to print a any string (and &#8220;hit return&#8221;).</li>
	<li>Library name changed to &#8220;RawLine&#8221; to avoid name collision issues (Bug <a href="http://rubyforge.org/tracker/?func=detail&amp;aid=18879&amp;group_id=5622&amp;atid=21788">18879</a>).</li>
	<li>Provided alternative implementation for left and right arrows if terminal<br />
supports escape sequences (on Windows, it requires the Win32Console gem).</li>
</ul>
<p>In particular, I decided to provide an &#8220;optimized implementation&#8221; for the left and right arrows using escape sequences rather than shameful hacks. This is now possible because the Win32Console gem now enables <span class="caps">ANSI</span> escape sequences on Windows as well (weehee!).</p>
<p>So:</p>
<ul>
	<li>If you&#8217;re on *nix all good, your terminal is smart and can understand escape sequences =&gt; the new implementation will be used.</li>
	<li>If you&#8217;re on Windows and you installed Win32Console, your termnal is smart and can understand escape sequences =&gt; the new implementation will be used.</li>
	<li>If you&#8217;re on Windows and you didn&#8217;t install Win32Console, then your terminal is stupid and it doesn&#8217;t understand escape sequences, so the old implementation will be used.</li>
</ul>
<p>The new implementation is significantly faster than the old one, on Windows at least, and the cursor now blinks properly when left or right arrows are pressed.</p>
<p>I re-emplemented only cursor movement because I&#8217;m still having some problems in getting the delete/insert escapes to work properly (or better: how I want them to work!).</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2008-03-27:/articles/inline-name-change/</id>
    <title>InLine name change: what's your opinion?</title>
    <published>2008-03-27T05:30:00Z</published>
    <updated>2009-09-06T18:10:50Z</updated>
    <link href="http://www.h3rald.com/articles/inline-name-change/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="rawline" scheme="http://www.h3rald.com/tags/rawline/"/>
    <content type="html">
<![CDATA[
<p>I&#8217;ve been kindly asked by the lead developer of <a href="http://www.zenspider.com/ZSS/Products/RubyInline/">RubyInLine</a> to change the name of my <a href="http://rubyforge.org/projects/inline/">InLine</a> project, due to potential confusion and conflicts.</p>
<p>This makes sense, and I&#8217;m ready to change the name of my project, although I&#8217;m not that good at choosing original and <em>smart</em> names, so well, any suggestion is more than welcome!</p>
<p>I was thinking of something like:</p>
<ul>
	<li>RawLine</li>
	<li>EditLine</li>
	<li>RawInput</li>
	<li>RubyInput</li>
	<li>RubyLine</li>
</ul>
<p>I personally think that <strong>RawLine</strong> is probably the best option, but please, if have any better idea just speak up!</p>
<p>P.S.: &#8220;RedLine&#8221; is taken, unfortunately, otherwise it would have been my first choice since the beginning.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2008-03-10:/articles/inline-introduction/</id>
    <title>RawLine - a 100% Ruby solution for console inline editing</title>
    <published>2008-03-10T05:59:00Z</published>
    <updated>2009-09-06T18:10:49Z</updated>
    <link href="http://www.h3rald.com/articles/inline-introduction/" rel="alternate"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="programming" scheme="http://www.h3rald.com/tags/programming/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="rawline" scheme="http://www.h3rald.com/tags/rawline/"/>
    <content type="html">
<![CDATA[
<p>One of the many things I like about Ruby is its cross-platform nature: as a general rule, Ruby code runs on everything which supports Ruby, regardless of its architecture and platform (yes, there are quite a few exceptions, but let&#8217;s accept this generalization for now).</p>
<p>More specifically, I liked the fact that I could use the <a href="http://tiswww.case.edu/php/chet/readline/rltop.html"><span class="caps">GNU</span> Readline library</a> with Ruby seamlessly on both Windows and Linux.<br />
Readline offers quite a lot of features which are useful for those people like me who enjoy creating command-line scripts, in a nutshell, it provides:</p>
<ul>
	<li>File/Word completion</li>
	<li>History support</li>
	<li>Custom key bindings which can be modified via .inputrc</li>
	<li>Emacs and Vi edit modes</li>
</ul>
<p>Basically it makes your command-line interface fast and powerful, and that&#8217;s not an overstatement. Ruby&#8217;s own <span class="caps">IRB</span> can be enhanced by enabling readline and completion, and it works great &#8212; at least on *nix systems.</p>
<p>For some weird reason, some people had problems with Readline on Windows: in particular, things get nasty when you start editing long lines. Text gets garbled, the cursor goes up one or two lines and doesn&#8217;t come back, and other similar leprechaun&#8217;s tricks, which are not that funny after a while.</p>
<p>Apparently there&#8217;s no alternative to Readline in the Ruby world. If you wan&#8217;t tab completion that&#8217;s it, you&#8217;re stuck. Would it be difficult to implement <em>some</em> of Readline functionality natively in Ruby? Maybe, but the problem is that for some reason the Ruby Standard Library doesn&#8217;t have low level methods to operate on keystrokes&#8230;</p>
<p>&#8230;but luckily, the <a href="http://highline.rubyforge.org/">HighLine</a> gem does! James Edward Gray II keeps pointing out here and here that HighLine&#8217;s own <code>get_character</code> method does just that: it returns the corresponding character code(s) right when a key is pressed, unlike <code>IO#gets()</code> which waits for the user to press <span class="caps">ENTER</span>.</p>
<p>Believe it or not, that tiny method can do wonders&#8230;h2. Reverse-engineering escape codes</p>
<p>So here&#8217;s a little script which uses <code>get_character()</code> in an endless loop, diligently printing the character codes corresponding to a keystroke:</p>
<div class="highlight"><pre><span class="c1">#!/usr/local/bin/ruby -w</span>

<span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;highline/system_extensions&#39;</span>

<span class="kp">include</span> <span class="no">HighLine</span><span class="o">::</span><span class="no">SystemExtensions</span>

<span class="nb">puts</span> <span class="s2">&quot;Press a key to view the corresponding ASCII code(s) (or CTRL-X to exit).&quot;</span>

<span class="kp">loop</span> <span class="k">do</span>

	<span class="nb">print</span> <span class="s2">&quot;=&gt; &quot;</span>
	<span class="n">char</span> <span class="o">=</span> <span class="n">get_character</span>
	<span class="k">case</span> <span class="n">char</span>
	<span class="k">when</span> <span class="sc">?\C-x</span><span class="p">:</span> <span class="nb">print</span> <span class="s2">&quot;Exiting...&quot;</span><span class="p">;</span> <span class="nb">exit</span><span class="p">;</span>
	<span class="k">else</span> <span class="nb">puts</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">char</span><span class="o">.</span><span class="n">chr</span><span class="si">}</span><span class="s2"> [</span><span class="si">#{</span><span class="n">char</span><span class="si">}</span><span class="s2">] (hex: </span><span class="si">#{</span><span class="n">char</span><span class="o">.</span><span class="n">to_s</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span><span class="si">}</span><span class="s2">)&quot;</span><span class="p">;</span>
	<span class="k">end</span>
	
<span class="k">end</span>
</pre>
</div><p>A pretty harmless little thing. Try to run it and press some keys, and see what you get:</p>
<div style="font-family: Monospace">
<p>Press a key to view the corresponding <span class="caps">ASCII</span> code(s) (or <span class="caps">CTRL</span>-X to exit).</p>
<p>=&gt; a <sup class="footnote" id="fnr96"><a href="#fn96">96</a></sup> (hex: 61)</p>
<p>=&gt; 1 <sup class="footnote" id="fnr49"><a href="#fn49">49</a></sup> (hex: 31)</p>
<p>=&gt; Q <sup class="footnote" id="fnr81"><a href="#fn81">81</a></sup> (hex: 51)</p>
<p>=&gt; &alpha; <sup class="footnote" id="fnr224"><a href="#fn224">224</a></sup> (hex: e0)</p>
<p>=&gt; K <sup class="footnote" id="fnr75"><a href="#fn75">75</a></sup> (hex: 4b)</p>
</div>
<p>Hang on, what are the last two codes? <em>A left arrow key on Windows</em>, apparently.</p>
<p><strong>Welcome to the wonderful world of input escape sequences!</strong></p>
<p>To cut a long story short, both Windows and *nix system &#8220;terminals&#8221; translate special keystrokes into sequences of two or more codes. This applies to things like <span class="caps">DEL</span>, <span class="caps">INSERT</span>, arrows, etc. etc.<br />
For some ideas, check out:</p>
<ul>
	<li><a href="http://www.microsoft.com/whdc/device/input/Scancode.mspx">Windows Scancodes</a> (Thanks <a href="http://64.223.189.234/node/92">Huff</a>)</li>
	<li><a href="http://www.connectrf.com/Documents/vt220.html">VT220 Terminal Input Sequences</a> (Thanks <a href="http://www.grayproductions.net/">James</a>)</li>
</ul>
<p>Let&#8217;s now assume that we&#8217;re smart and we can write a program which can parse keystroke properly, including handling different input escape sequences according to the OS, what can it be used for?<br />
Well:</p>
<ul>
	<li>For normal characters, just print them back to the screen (<code>get_character</code> doesn&#8217;t print anything, it &#8220;steals&#8221; the keystroke)</li>
	<li>For special characters, do something nice!</li>
</ul>
<p>We could setup <span class="caps">TAB</span> to auto-complete the current word according to an array of matches, or bind the up arrow to load the last line typed in by the user, for example, that&#8217;s basically something Readline does, right?</p>
<h2>RawLine: how it works and what it does</h2>
<p>I created a small project on RubyForge called <a href="http://rubyforge.org/projects/rawline/">RawLine</a> (not to be confused with RubyInline, a completely different thing altogether, sorry about that) to play around with the possibilities offered by the <code>get_character</code> method. The library is just a preview of things which can be done, but it&#8217;s already usable, provided that you&#8217;re brave enough to try it out, that is.</p>
<p>The basic idea behind RawLine is to be able to parse keystrokes properly on different platforms and re-bind them to a set of predefined, cross-platform actions or a user-defined code block.</p>
<h3>Basic line-editing operations</h3>
<p>The first challenge was to re-invent the wheel, i.e. re-bind keystrokes to their typical actions: a left arrow moves the cursor left, a backspace deletes the character at the left of the cursor and so on. Yes, because <code>get_characters</code> gives you the right character codes at the price of <em>cancelling their normal effects</em>, which is a great thing, as you&#8217;ll soon find out.</p>
<p>Printing a character on the screen was one of the easiest tasks (at first). <code>IO#putc</code> does the job pretty well: it prints a character out.<br />
What about moving left? Easy: print a non-descructive backspace (\b) and hope it is really not destructive. I did some tests and it seems to do as it&#8217;s told and move the cursor back by one position.</p>
<p>Moving right was a little trickier: the easiest thing I found was to re-print the character under the cursor, which will then move the cursor forward (as naive as it may seem, it does the job!). If there&#8217;s nothing under the cursor, then we must be at the end of the line and it shouldn&#8217;t move anywhere, so there we go.</p>
<p>What if I move left a bit and then start typing normal characters? Well, everything is rewritten of course: this will be our &#8220;character replace mode&#8221;. Unfortunately users don&#8217;t like this behavior that much, so what I did was this:</p>
<ol>
	<li>Copy all characters from the one at the left of the cursor till the end of the line</li>
	<li>Print the character to be inserted</li>
	<li>Re-print the previously-copied characters</li>
	<li>Move the cursor back at the right place</li>
</ol>
<p>Again, a primitive solution which works seamlessly on all platforms, and yes, it&#8217;s fast enough that you don&#8217;t notice the difference.</p>
<p>As you may have guessed, this of course means that I always had to keep track of:</p>
<ul>
	<li>The cursor position within the line</li>
	<li>The text currently printed to the screen</li>
</ul>
<p>Backspace and delete were implemented in a similar way, you can figure it out yourself or look at the source code: I won&#8217;t bore you any further!</p>
<h3>History management</h3>
<p>The next step was to implement a history for both the characters inputted by the user (to allow undoing and redoing operations) and for the whole lines. This was just an ordinary programming exercise: a simple buffer with some extra controls here and there, nothing too scary.</p>
<p>So every &#8220;modification&#8221; to the current line being typed is saved in a line history buffer and all the lines entered are saved in another history buffer. All is left is to allow users to navigate through these buffers back and forth. <br />
Nothing impossible: all I had to do was keeping track of the current element of the history being retrieved and then overwrite the current line with a new line stored in the buffer? How&#8217;s this line overwriting done? Same old:</p>
<ol>
	<li>Move the cursor to the beginnig of the line</li>
	<li>Print X spaces, where X is the line length, so that the characters are no longer displayed in the console</li>
	<li>Move the cursor back to the beginning of the line</li>
	<li>Print the new line.</li>
</ol>
<p>Easy and naive, as usual. But again, it works well enough.</p>
<h3>Word completion</h3>
<p>The other challange was word completion. The current implementation can be summarized as follows:</p>
<ul>
	<li>If <span class="caps">TAB</span> (or another character, if you wish) is pressed, call a user-defined <code>completion_proc</code> method which returns an array and show the first element of the array (in this case I actually used a cyclic RawLine::HistoryBuffer, not an array)</li>
	<li>If the user presses <span class="caps">TAB</span> again, show another match, and so <em>ad infinitum</em> if the user keeps pressing <span class="caps">TAB</span>.</li>
	<li>If the user presses another key, accept the default completion and move on.</li>
</ul>
<p>Obviously this means that:</p>
<ul>
	<li>RawLine has to keep track of the current &#8220;word&#8221;. A word is everything separated by a user defined <code>word_separator</code>, which can obviously modified at runtime, with care.</li>
	<li>Regarding the <code>completion_proc</code>, typically you may want to return only the elements matching the word which is currently being written, so that&#8217;s given as default parameter for your proc. Exactly like with ReadLine, the only difference is that you can access other things like <em>the whole line</em> and <em>the whole history</em> in real time, which can be really handy at times!</li>
</ul>
<p>Here&#8217;s a simple example:</p>
<div class="highlight"><pre><span class="n">editor</span><span class="o">.</span><span class="n">completion_proc</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="k">do</span> <span class="o">|</span><span class="n">word</span><span class="o">|</span>
	<span class="k">if</span> <span class="n">word</span>
		<span class="o">[</span><span class="s1">&#39;select&#39;</span><span class="p">,</span> <span class="s1">&#39;update&#39;</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">,</span> <span class="s1">&#39;debug&#39;</span><span class="p">,</span> <span class="s1">&#39;destroy&#39;</span><span class="o">].</span><span class="n">find_all</span>	<span class="p">{</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sr">/^</span><span class="si">#{</span><span class="no">Regexp</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">word</span><span class="p">)</span><span class="si">}</span><span class="sr">/</span><span class="p">)</span> <span class="p">}</span>
	<span class="k">end</span>
<span class="k">end</span>
</pre>
</div><h3>Custom key bindings</h3>
<p>All these pretty things are obviously bound to some keystrokes. If the key corresponds to only one code, everything is fine, but because special keys typically aren&#8217;t so it was necessary to implement a mechanism to track an escape key (e.g. 0xE0 and 0 on Windows and \e on Linux) and listen to further characters, in case a known sequence is found. Anyhow, the final result of the method used for character binding is the following:</p>
<p><code>bind(key, &amp;block)</code></p>
<p>Where key can be:</p>
<ul>
	<li>A <code>Fixnum</code> corresponding to a single character code</li>
	<li>An <code>Array</code> of one or more character codes</li>
	<li>A <code>String</code> corresponding to an escape sequence</li>
	<li>A <code>Symbol</code> corresponding to a known escape sequence or key</li>
	<li>A <code>Hash</code> to define a new key or escape sequences</li>
</ul>
<p>So, in the end you can do things like this:</p>
<div class="highlight"><pre><span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:left_arrow</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">move_left</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\e</span><span class="s2">test&quot;</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">overwrite_line</span><span class="p">(</span><span class="s2">&quot;Test!!&quot;</span><span class="p">)</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="sc">?\C-z</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">undo</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="o">[</span><span class="mi">24</span><span class="o">]</span><span class="p">)</span> <span class="p">{</span> <span class="nb">exit</span> <span class="p">}</span>
</pre>
</div><p>Which, for Rubyists, it&#8217;s far sexier and more flexible than editing an .inputrc file.</p>
<h3>How do I use it, anyway?</h3>
<p>A code example is better than a thousand words, right? So here you are:</p>
<div class="highlight"><pre><span class="c1">#!/usr/local/bin/ruby -w</span>

<span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;rawline&#39;</span>

<span class="nb">puts</span> <span class="s2">&quot;*** Inline Editor Test Shell ***&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press CTRL+X to exit&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press CTRL+C to clear command history&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press CTRL+D for line-related information&quot;</span>
<span class="nb">puts</span> <span class="s2">&quot; * Press CTRL+E to view command history&quot;</span>

<span class="n">editor</span> <span class="o">=</span> <span class="no">RawLine</span><span class="o">::</span><span class="no">Editor</span><span class="o">.</span><span class="n">new</span>

<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:ctrl_c</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">clear_history</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:ctrl_d</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">debug_line</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:ctrl_e</span><span class="p">)</span> <span class="p">{</span> <span class="n">editor</span><span class="o">.</span><span class="n">show_history</span> <span class="p">}</span>
<span class="n">editor</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="ss">:ctrl_x</span><span class="p">)</span> <span class="p">{</span> <span class="nb">puts</span><span class="p">;</span> <span class="nb">puts</span> <span class="s2">&quot;Exiting...&quot;</span><span class="p">;</span> <span class="nb">exit</span> <span class="p">}</span>

<span class="n">editor</span><span class="o">.</span><span class="n">completion_proc</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="k">do</span> <span class="o">|</span><span class="n">word</span><span class="o">|</span>
	<span class="k">if</span> <span class="n">word</span>
		<span class="o">[</span><span class="s1">&#39;select&#39;</span><span class="p">,</span> <span class="s1">&#39;update&#39;</span><span class="p">,</span> <span class="s1">&#39;delete&#39;</span><span class="p">,</span> <span class="s1">&#39;debug&#39;</span><span class="p">,</span> <span class="s1">&#39;destroy&#39;</span><span class="o">].</span><span class="n">find_all</span>	<span class="p">{</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sr">/^</span><span class="si">#{</span><span class="no">Regexp</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">word</span><span class="p">)</span><span class="si">}</span><span class="sr">/</span><span class="p">)</span> <span class="p">}</span>
	<span class="k">end</span>
<span class="k">end</span>

<span class="kp">loop</span> <span class="k">do</span>
	<span class="nb">puts</span> <span class="s2">&quot;You typed: [</span><span class="si">#{</span><span class="n">editor</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&quot;=&gt; &quot;</span><span class="p">)</span><span class="o">.</span><span class="n">chomp!</span><span class="si">}</span><span class="s2">]&quot;</span>
<span class="k">end</span>
</pre>
</div><p>This example can be found in examples/rawline_shell.rb within the RawLine source code or gem package.</p>
<h2>Current status and availability</h2>
<p>I currently <a href="http://rubyforge.org/forum/forum.php?forum_id=22543">released</a> RawLine 0.1.0 on <a href="http://rubyforge.org/projects/rawline">SourceForge</a>, and it can be installed via:</p>
<p><code>gem install -r rawline</code></p>
<p>The RDoc documentation is available <a href="http://rawline.rubyforge.org/">here</a>.</p>
<p>Feel free to try it out. First of all try the <code>rawline_shell.rb</code> example, and see if it works on your machine. If it doesn&#8217;t than maybe you try re-binding some keys (use <code>key_tester.rb</code> to &#8220;reverse-engineer&#8221; your terminal&#8217;s input escape sequences), and let me know!</p>
<p>Status information and limitations:</p>
<ul>
	<li>It has been tested on Windows (XP, using the usual command prompt) and on Linux (ZenWalk, using <span class="caps">XFCE</span> Terminal).</li>
	<li>It can handle lines no longer than the maximum terminal width &#8211; 2. This is to ensure that the cursor never &#8220;falls down&#8221; to the next line.</li>
	<li>On Windows, the cursor doesn&#8217;t blink immedialy when moving left, but it moves, don&#8217;t worry.</li>
	<li>On Linux, you should really consider installing the <a href="http://raa.ruby-lang.org/project/ruby-termios/">Termios</a> library for a faster experience (otherwise <code>get_character</code> won&#8217;t parse characters correctly if you press and hold a key, and that, trust me, is a real mess!).</li>
	<li>RawLine is very far from being a complete replacement for the ReadLine library, and it is currently in alpha stage.</li>
	<li>Release 0.1.0 has been created after 2 weeks of sporadic coding during lunch breaks and week-ends.</li>
</ul>
<p>For any ideas on where to go from here, comments and feedback, just reply below or send an email to my usual email address.</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2007-12-16:/articles/redbook-050-released/</id>
    <title>Announcement: RedBook v0.5.0 released</title>
    <published>2007-12-16T07:07:00Z</published>
    <updated>2009-09-06T18:10:48Z</updated>
    <link href="http://www.h3rald.com/articles/redbook-050-released/" rel="alternate"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="productivity" scheme="http://www.h3rald.com/tags/productivity/"/>
    <category term="redbook" scheme="http://www.h3rald.com/tags/redbook/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <content type="html">
<![CDATA[
<p>This new beta release of RedBook introduces quite a few changes when it comes to configuration and setup. Here&#8217;s some highlights&#8230;h3. Regexp changes</p>
<p>It is now necessary to enter &#8220;proper&#8221; regular expressions for <code>:select</code>. Proper means between slashes, like the following:</p>
<ul>
	<li>/Work Day/</li>
	<li>/mail/i</li>
</ul>
<p>I changed this in order to support case-insensitive searches using the <code>i</code> switch. This makes queries much more powerful.</p>
<h3>Variables</h3>
<p>A new, interesting feature I decided to introduce in this release is <em>variables</em>. For now you define them inside your rbconfig.yml file, like this:</p>
<div class="highlight"><pre>:var_monday_morning: &quot;monday at 8 am&quot;

:var_friday_evening: &quot;friday at 8 pm&quot;

:var_week_report: &quot;:select :duration :from :%monday_morning :to :%friday_evening&quot; 
</pre>
</div><p>In this way, every time you type in :%week_report in RedBook, it will expand to: <code>:select :duration :from monday at 8 am :to friday at 8 pm</code>. By the way, completion is supported, so you&#8217;ll only have to type in something like <code>:%we</code> and hit <tab>.</p>
<p>It is possible to define variables as <code>:var_&lt;something&gt;</code> in the rbconfig.yml file and then used them inside RedBook as <code>:%&lt;something&gt;</code>.</p>
<h3>New Operations</h3>
<p>Five new operations have been added:</p>
<h4>:blank</h4>
<p>This will blank your current log after asking you if you really want to do so.</p>
<h4>:restore</h4>
<p>This operation will overwrite your current log with the last saved backup. Like with the <code>:blank</code> operation, you&#8217;re asked if you really want to proceed or not.</p>
<h4>:archive</h4>
<p>By typing <code>:archive</code>, the current log file will be archived to your <code>:archives_folder:</code> directory specified in the rbconfig.yml file (similarly, it is now possible to specify a :backups_folder: for your logs&#8217; backup files).</p>
<h4>:dataset</h4>
<p>A simple operation to display the messages inthe current dataset.</p>
<h4>:dump</h4>
<p>This operation will dump the output of the last <code>:select</code> operation to a text file. Useful for saving the average, total time and duration of a set of activities.</p>
<h3>Portable edition</h3>
<p>Some Windows users will definitely love this. I finally found an easy way to run RedBook confined within the current directory, by using a simple <code>start.bat</code> batch file to set the <span><span class="caps">INPUTRC</span></span> and <span><span class="caps">HOME</span></span> variables temporarily to the path to the .inputrc file and the directory of RedBook executable. This makes RedBook 100% portable and suitable to be used on <span class="caps">USB</span> sticks &amp;similar.</p>
<p style="text-align:center;"><strong><a href="http://redbook.googlecode.com/files/RedBook-0.5_Win32-portable.zip">Get RedBook Portable</a></strong></p>
<h3>New Development Page</h3>
<p>I decided to move the primary RedBook repository from <a href="http://www.assembla.org">Assembla</a> to Google Code. Why? Well, nothing wrong with Assembla per se, I still think it&#8217;s an excellent free service to host your public <em>and private</em> projects, but Google Code is faster and offers only the features I need:</p>
<ul>
	<li>Public <span class="caps">SVN</span> repository access</li>
	<li>Simple-to-use issue tracker</li>
	<li>Very nicely developed downloads section, with download counts, and &#8220;normal&#8221; filenames.</li>
</ul>
<p>So here&#8217;s the new RedBook Development Home:</p>
<p style="text-align:center;"><strong><a href="http://code.google.com/p/redbook/">http://code.google.com/p/redbook/</a></strong></p>
<p>Additionally I also setup a <a href="http://groups.google.com/group/redbook-support/">RedBook Support Google Group</a>, so if you have any question concerning the program, you know where to go!</p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2007-11-28:/articles/redbook-040-released/</id>
    <title>Announcement: RedBook v0.4.0 released</title>
    <published>2007-11-28T07:34:00Z</published>
    <updated>2009-09-06T18:10:47Z</updated>
    <link href="http://www.h3rald.com/articles/redbook-040-released/" rel="alternate"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <category term="productivity" scheme="http://www.h3rald.com/tags/productivity/"/>
    <category term="redbook" scheme="http://www.h3rald.com/tags/redbook/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <content type="html">
<![CDATA[
<p>I&#8217;m pleased to announce a new release of the RedBook daily logging and time tracking script. This release introduces two new operations, four stats-related directives and a brand new Windows Installer able to setup RedBook in a blink, with (almost) no configuration at all.</p>
<p>Let&#8217;s have a closer look&#8230;h2. New Operations</p>
<p>Suppose that you just logged a message and you noticed one of these two things happened:</p>
<ul>
	<li>You didn&#8217;t really wanted to log it</li>
	<li>You made a silly typo in the message or in the tags</li>
</ul>
<p>What can you do about it? Up to RedBook 0.3, the only solution was to open the <span class="caps">YAML</span> file and correct the mistake manually. From now on there&#8217;s also another simpler way to operate in such situations: using the :update and :delete operations!</p>
<h3>:update</h3>
<p>This operation can be used to update the message and or the tags of a previously-logged activity. The usage is simple: load a dataset first, and then execute an <code>:update</code> command like:</p>
<p><code>:update 4 :message My updated message :with new_tag1 new_tag2</code></p>
<p>This will update the 4th message of the dataset modifying its message and tags. Of course you can update either of the two things or both; the timestamp of the activity will not be changed.</p>
<h3>:delete</h3>
<p>The delete operation can be used to completely delete a message from the log. Just load a dataset using a <code>:select</code> operation and then execute a <code>:delete</code> command, e.g.:</p>
<ul>
	<li><code>:delete 1</code> <em>(will delete the first activity)</em></li>
	<li><code>:delete 4 2 7 9</code> <em>(will delete activity #2, #4, #7 and #9)</em></li>
	<li><code>:delete</code> <em>(will delete the entire dataset)</em></li>
</ul>
<p>A confirmation message will appear before deleting the message(s).</p>
<p><strong><span class="caps">IMPORTANT</span></strong><br />
<em>Due to the architecture of the application, whenever an <code>:update</code> or <code>:delete</code> occurs the log file will be reloaded in memory and completely overwritten. This doesn&#8217;t cause problems, although for big log files (10,000+ activities) this may take a few seconds.</em></p>
<h2>Statistics</h2>
<p>Another important new feature introduced by this release is <em>time tracking</em>. It was actually already there, kind of: the <code>:calc</code> operation was already able to calculate the time elapsed between two activities&#8230; however, this is not really practical.</p>
<p>Since last release, it is possible to log the completion of an activity using the <code>:finish</code> command. This will basically re-log the same activity prepending <em>[<span class="caps">COMPLETED</span>]</em> to its message.<br />
If you started using the <code>:finish</code> command to complete your activities, RedBook can now calculate the following stats for you:</p>
<ul>
	<li>Count the number of messages in a dataset</li>
	<li>Calculate the average time spent for the completed activities in a dataset</li>
	<li>Calculate the total time spent for the completed activities in a dataset</li>
	<li>Calculate the duration of each completed activity in a dataset</li>
</ul>
<p>Each of these calculations is performed by adding special directive to a <code>:select</code> command, as explained in the following sections.</p>
<h3>:count</h3>
<p>This directive can be added to a <code>:select</code> command to return just the number of message of the loaded dataset. <br />
In other words, executing the following:</p>
<p><code>:select :count :with mail !work</code></p>
<p>&#8230;will return the number of activities tagged with <em>mail</em> but not with <em>personal</em>, without listing all the activities.</p>
<h3>:avg</h3>
<p>The <code>:avg</code> directive can be used to calculate the average time spent on activities matching certain criteria, for example:</p>
<p><code>:select Status Meeting :avg :with meeting</code></p>
<p>&#8230;will return the average time spent on activities whose messages matches <em>/Status Meeting/</em> and are tagged with <em>meeting</em>.</p>
<h3>:total</h3>
<p>Similarly, <code>:total</code> can be used to return the total time spent on activities matching certain criteria, e.g.:</p>
<p><code>:select :total :with mail work</code></p>
<p>&#8230;will return the total time spent on activities tagged with <em>mail</em> and <em>work</em>.</p>
<h3>:duration</h3>
<p>Lastly, <code>:duration</code> will print each completed task along with its duration. The syntax is similar to the others:</p>
<p><code>:select :duration :with break</code></p>
<p>This will print each completed activity tagged with <em>break</em> along with its duration.</p>
<h3>:nodiff and _concurrent</h3>
<p>The logic behind the above-mentioned directives may seem trivial to implement, but it is not. The fun part was telling RedBook to subtract the duration of each sub-activity contained in another activity&#8230; a feature I considered necessary for time tracking purpose. However, if you start your work day with a <em>Working Day</em> activity and you complete that activity using the <code>:finish</code> command, when calculating the duration of the working day RedBook will subtract the duration of <em>all the completed sub-activities</em> from the duration of <em>Working Day</em>. This is not OK, so I added the directive <code>:nodiff</code> which can be used to prevent RedBook from calculating the difference between the parent activity&#8217;s duration and the duration of each of its child activity.</p>
<p>What if you&#8217;re doing two things at once? use the special <code>_concurrent</code> tag, and that activity will be considered symultaneous to its parent activity for time tracking purposes.</p>
<h2>Activity Status Filters</h2>
<p>RedBook is now fully aware of the &#8220;status&#8221; of each activity, so it is possible to display only activities in a certain status using the following directives:</p>
<h3>:plain</h3>
<p>Executing <code>:select :plain :from today</code> will return all the activities logged today, omitting their completions (if any), i.e. any activity beginning with <em>[<span class="caps">COMPLETED</span>]</em>.</p>
<h3>:pending</h3>
<p>Executing <code>:select :pending :from today</code> will return all the activities logged today which have not been completed yet. Again, this was not too trivial to implement, but it seems to work (it also smart enough to detect if the same activity has been relogged etc. etc.).</p>
<p><strong><span class="caps">WARNING</span>:</strong> <br />
<em>Using this directive with a large dataset may cause RedBook to take some time before delivering the result, due to the amount of iterations to perform. Use with care.</em></p>
<h3>:completed</h3>
<p>Executing <code>:select :completed :from today</code> will return all the activities logged today which have been completed.</p>
<h2>Windows Installer</h2>
<p>I decided to spend some time (half an hour) and create a proper setup file for Windows using InnoSetup. The setup will take care of almost everything for you, so you have no excuse not to try RedBook because it&#8217;s not user-friendly to install!</p>
<p>Check out the <a href="http://redbook.h3rald.com">manual</a> for more details.</p>
<h2>RubyForge Project</h2>
<p>Finally, I registered a new <a href="http://rubyforge.org/projects/redbook/">RubyForge Project</a> for RedBook, which include a public <span class="caps">SVN</span> repository updated every week (Assembla doesn&#8217;t allow anonymous checkouts, unfortunately).<br />
This project will also host the official RedBook Gem, scheduled for the 1.0 release.</p>
<p style="text-align:center;"><strong><a href="http://www.assembla.com/spaces/files/redbook"><span class="caps">DOWNLOAD</span></a> | <a href="http://redbook.h3rald.com/"><span class="caps">MANUAL</span></a></strong></p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2007-11-17:/articles/textlinkads_sidebar_v01/</id>
    <title>Text Link Ads sidebar for Typo</title>
    <published>2007-11-17T03:47:00Z</published>
    <updated>2009-09-06T18:10:46Z</updated>
    <link href="http://www.h3rald.com/articles/textlinkads_sidebar_v01/" rel="alternate"/>
    <category term="rails" scheme="http://www.h3rald.com/tags/rails/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[
<p>I thought it would be nice to share the code of the sidebar I created to display <a href="http://www.text-links-ads.com">Text Link Ads</a> sponsor links on my Typo powered blog.</p>
<p>There&#8217;s actually another <a href="http://blog.nanorails.com/articles/2006/10/01/a-new-rails-plugin-for-textlinkads-including-support-for-feedvertising">plugin</a> which was made for Typo 2.6, but unfortunately it doesn&#8217;t work with Typo 4.1.1.</p>
<h3>Installation</h3>
<p>Just unzip it inside your vendor/plugins directory. The new sidebar should appear in the list of your available sidebars in the Typo&#8217;s administration area.</p>
<h3>Configuration</h3>
<p>In Typo&#8217;s administration area, configure the following settings for this sidebar:</p>
<ul>
	<li><strong>Title</strong>: The title of the sidebar</li>
	<li><strong><span class="caps">KEY</span></strong>: Your TLA&#8217;s <span class="caps">XML</span> key</li>
	<li><strong>Affiliate ID</strong>: Your TLA&#8217;s affiliate ID</li>
	<li><strong>Advertise Here</strong>: A message shown when no links are displayed.</li>
</ul>
<p><strong><a href="/files/textlinkads_sidebar_v0.2.zip">Download Text Links Ads Sidebar v0.2</a></strong></p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2007-10-25:/articles/redbook-030-released/</id>
    <title>Announcement: RedBook v0.3.0 released</title>
    <published>2007-10-25T05:18:00Z</published>
    <updated>2009-09-06T18:10:45Z</updated>
    <link href="http://www.h3rald.com/articles/redbook-030-released/" rel="alternate"/>
    <category term="redbook" scheme="http://www.h3rald.com/tags/redbook/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="productivity" scheme="http://www.h3rald.com/tags/productivity/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[
<p>It&#8217;s time for a new beta release of RedBook. This was actually going to be a fairly modest release in terms of features, but I actually ended up implementing a lot more than expected, even things which were planned for the first production release 1.0. So, let&#8217;s see what&#8217;s new</p>
<h3>New operation names <em>(which break compatibility with previous versions)</em></h3>
<p>I had a look at the names I choose for the operations and I noticed that they were either not intuitive enough or too verbose. So I decided to change a fair few of them (thus breaking compatibility with previous versions, but after all that&#8217;s what beta releases are for, right?):</p>
<table>
	<tr>
		<th><span class="caps">OLD</span> </th>
		<th><span class="caps">NEW</span> </th>
	</tr>
	<tr>
		<td> :complete </td>
		<td> :finish </td>
	</tr>
	<tr>
		<td> :load </td>
		<td> :select </td>
	</tr>
	<tr>
		<td> :load_config </td>
		<td> :config </td>
	</tr>
	<tr>
		<td> :load_log </td>
		<td> :refresh </td>
	</tr>
	<tr>
		<td> :timecalc </td>
		<td> :calc </td>
	</tr>
	<tr>
		<td> :stop </td>
		<td> :quit </td>
	</tr>
</table>
<h3>New Manual/Home Page</h3>
<p>A while ago I discovered <a href="http://www.tiddlywiki.com/">TiddlyWiki</a>, but as a matter of fact I never used it for anything practical. From last week though, I started using it a work for taking notes and create short memos, and then I thought of using it to replace RedBook&#8217;s standard <span class="caps">README</span> file (which was made in a hurry and was kinda cryptical). Now a brand new &#8220;manual.html&#8221; ships with RedBook &#8212; 308 KB (30 of actual docs and 278 of Javascript/<span class="caps">HTML</span>/<span class="caps">CSS</span> magic) with everything you need to know about it. Additionally, an online version is available at the following address:</p>
<p style="text-align:center;"><strong><a href="http://redbook.h3rald.com">redbook.h3rald.com</a></strong></p>
<h3>Removed Win32::Console Library</h3>
<p>OK this is not good news for people (like me) who use RedBook on Windows, but I promise you&#8217;ll forgive me when you read about the other new features below. I discovered by chance that the Win32::Console library (which was used to get colors working on Windows) seems not to handle international characters properly and also seems to be conflicting in some way with the Readline library I decided to include (see below). I don&#8217;t know whether this is a problem of the actual library or just of the gem used to pack it.</p>
<h3>rbconfig.yml</h3>
<p>The <code>config.yml</code> file has been renamed to <code>rbconfig.yml</code>. Additionally, if you place a file with this name in your $<span class="caps">HOME</span> directory it will override the one in your RedBook folder (This was done in preparation for the RedBook RubyGem).</p>
<h3>New operations</h3>
<p>The following new operations are available:</p>
<ul>
	<li><a href="http://redbook.h3rald.com/#%3Arelog">:relog</a> &#8212; Re-logs a previously-logged message (keeping the same tags and updating the timestamp)</li>
	<li><a href="http://redbook.h3rald.com/#%3Aclear">:clear</a> &#8212; Clears the screen.</li>
	<li><a href="http://redbook.h3rald.com/#%3Aruby">:ruby</a> &#8212; Evaluates arbitrary Ruby code outputting the result (use with care&#8230;)</li>
</ul>
<h3>Auto-completion</h3>
<p>Some Mac users originally complained that the backspace key wasn&#8217;t working in RedBook (and it didn&#8217;t in Linux either). Fortunately the solution to this was easy enough: include the <span class="caps">GNU</span> <a href="http://tiswww.case.edu/php/chet/readline/rltop.html">Readline</a> library. <br />
Readline is now being used in RedBook to:</p>
<ul>
	<li>Provide basic (Emacs-style) bindings</li>
	<li><strong>Auto-completion</strong> for keywords <em>and tags</em></li>
	<li>Allow the user to automatically customize key bindings via an <a href="http://redbook.h3rald.com/#.inputrc">.inputrc</a> file placed in their $<span class="caps">HOME</span> directory (on Windows you&#8217;ll have to define a <span><span class="caps">HOME</span></span> environment variable pointing to a directory of your choice). An example .inputrc file is distributed with RedBook with some specific key bindings.</li>
</ul>
<h3>Support for international characters</h3>
<p>Finally, I decided to implement another feature which was originally planned for the 1.0 release: international characters support. This is possible using the Iconv Ruby extension (requires <a href="http://www.gnu.org/software/libiconv/"><span class="caps">GNU</span> libiconv</a>) which can convert strings between different character sets. The character sets needs to be configured via the <a href="http://redbook.h3rald.com/#rbconfig.yml">rbconfig.yml</a> file.</p>
<p>For more information, check out the <a href="http://redbook.h3rald.com/#ChangeLog">ChangeLog</a></p>
<p style="text-align:center;"><strong><a href="http://www.assembla.com/spaces/files/bWE7NkzCqr3k25abIlDkbG">Download RedBook</a></strong></p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2007-10-08:/articles/redbook-020-released/</id>
    <title>Announcement: RedBook v0.2.0 released</title>
    <published>2007-10-08T03:05:00Z</published>
    <updated>2009-09-06T18:10:44Z</updated>
    <link href="http://www.h3rald.com/articles/redbook-020-released/" rel="alternate"/>
    <category term="redbook" scheme="http://www.h3rald.com/tags/redbook/"/>
    <category term="ruby" scheme="http://www.h3rald.com/tags/ruby/"/>
    <category term="productivity" scheme="http://www.h3rald.com/tags/productivity/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[
<blockquote>
<p><em>&#8220;Release Early, Release Often&#8221;</em></p>
<p>&#8212; Eric S. Raymond, <a href="http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s04.html">The Cathedral and the Bazaar</a></p>
</blockquote>
<p>In other words, time for another (early) release of <a href="http://www.assembla.com/space/redbook">RedBook</a>. There are quite a few new features which are worth examining, in particular:</p>
<h3>Regexp search for messages</h3>
<p>This was actually already available before, just if you inputted a search string which was not a regexp, you&#8217;d get an unhandled exception (more or less). This exception is now handled propertly so you get a pretty message instead, if an error occurs when parsing the search string.</p>
<h3>Log Backup</h3>
<p>A new <strong>&#58;backup</strong> keyword is available to quickly backup your log file. Here&#8217;s what it does:</p>
<ul>
	<li>Loads all messages silently</li>
	<li>Writes them to a file in the same directory as the original log file named &lt;log-alias&gt;.bkp.yml.</li>
</ul>
<p>Handy, especially if there was a similar keyword to restore the last backup, which is planned for <a href="http://www.assembla.com/spaces/milestones/index/bWE7NkzCqr3k25abIlDkbG?spaces_tool_id=ceS8UazCqr3k25abIlDkbG">later on</a>.</p>
<h3>Support for multiple log files</h3>
<p>This is perhaps the most important feature introduced by this release. It is now possible to configure more than one log file by adding any number of <strong>&#58;data_&lt;alias&gt;&#58;</strong> settings inside your config.yml file, where alias is the name of your log file. So, for example, if your config.yml file contains the following:</p>
<p><strong>&#58;data_test&#58; &#8220;testlog.yml&#8221;</strong></p>
<p>You can load the &#8220;test&#8221; log by typing</p>
<p><strong>&#58;use test</strong></p>
<p>(&#58;use is a shorthand for &#58;load_log). Similarly, another new keyword <strong>&#58;dest</strong> has been introduced to be able to log a message to a different log file without loading it into memory, like this:</p>
<p><strong>&#58;log This message will be saved to testlog.yml &#58;dest test</strong></p>
<p>Finally, a <strong>&#58;refresh</strong> keyword has been introduced as an alias to reloading the current log.</p>
<h3>(Almost) automatic log of completed activities</h3>
<p>Right when I was coding the <strong>&#58;timecalc</strong> operation, I thought it would be nice to be able to log the start and end of a task without having to type it twice. Now this is possible using the <strong>&#58;complete</strong> keyword:</p>
<p>&#58;log Testing feature X in product Y</p>
<p>&#58;complete</p>
<p><strong>&#58;complete</strong> will re-log the last message prepended with [<span class="caps">COMPLETED</span>]:</p>
4 Mon Oct 08 2007 &#8211; 10:47:45 AM Testing feature X in product Y
5 Mon Oct 08 2007 &#8211; 10:54:31 AM [<span class="caps">COMPLETED</span>] Testing feature X in product Y
<p>What if I start another task before completing the first one? No problem, it is sufficient to load the last activities using a <strong>&#58;load</strong> command and then issuing <strong>&#58;complete &lt;number&gt;</strong> where &lt;number&gt; is the index of the loaded activity. <br />
This nifty little feature will become more and more important when (starting from release 0.4) I&#8217;ll implement more time tracking functions, and it will be possible to track completed tasks in a specific timeframe and/or marked with a specific tag.</p>
<h3>Easy integration with launchers like Launchy and QuickSilver</h3>
<p>To conclude, as someone pointed out that it would be cool to use RedBook from launchers like Launchy or Quicksilver, I made another standalone script (redbooklet.rb or redbooklet.exe) which is just able to parse a log command and write a message to the specified log file.<br />
To use it with Launchy, for example, all you have to do is the following:</p>
<ol>
	<li>Create a shortcut to redbooklet.exe (or to a way to execute the corresponding ruby script) named &#8220;log&#8221;.</li>
	<li>Copy the &#8220;log&#8221; shortcut anywhere in your start menu</li>
	<li>Bring up launchy (ALT+SPACE) and type in &#8220;log&#8221;</li>
	<li>Hit tab</li>
	<li>Type in your log message, optionally with the any &#58;tags or &#58;dest keywords.</li>
	<li>The message will be logged to your default log file or to the log you specified using the &#58;dest keyword. If an error occurs, it will appear in a command line window for 15 seconds before the program is closed.</li>
</ol>
<p>That&#8217;s all folks! As usual, if you have any comment or suggestion feel free to reply to this post or email me. For a list of the planned features and releases, check out the <a href="http://www.assembla.com/spaces/milestones/index/bWE7NkzCqr3k25abIlDkbG?spaces_tool_id=ceS8UazCqr3k25abIlDkbG">Milestones</a> page.</p>
<p style="text-align:center;"><strong><a href="http://www.assembla.com/spaces/files/bWE7NkzCqr3k25abIlDkbG"><span class="caps">DOWNLOAD</span> <span class="caps">HERE</span></a></strong></p>]]>
    </content>
  </entry>
  <entry>
    <id>tag:www.h3rald.com,2005-12-10:/articles/project-windstone/</id>
    <title>CyberArmy Presents: Project WindStone</title>
    <published>2005-12-10T11:59:23Z</published>
    <updated>2009-09-06T18:10:43Z</updated>
    <link href="http://www.h3rald.com/articles/project-windstone/" rel="alternate"/>
    <category term="internet" scheme="http://www.h3rald.com/tags/internet/"/>
    <category term="opensource" scheme="http://www.h3rald.com/tags/opensource/"/>
    <content type="html">
<![CDATA[
I think most of the people who currently use the Internet have tried Microsoft Hotmail[1] at least once. Many of you probably don't use it anymore because you found something better, but the point is that Hotmail has been around for a long time, and so has its authentication method, MSN Passport, which is a universal login system used not only for Hotmail but also for many other non-Microsoft websites and services.<br />
If you don't like the idea of using Microsoft-owned technology as an authentication system, we have an alternative for you... <strong>Show me your Passport</strong><br />
<fieldset><blockquote>"Create your sign-in credentials (e-mail and password) once, then use them everywhere on the Microsoft Passport Network. You can even set the site to remember your credentials for you!"</blockquote></fieldset><br />
<br />
This is what the MSN Passport does, in a nutshell: it provides a <em>universal</em> login system so that members only need to remember their email address and one password in order to be authenticated on every site that uses the Passport technology.  It has been adopted quite happily by some websites and portals[3], and particularly by merchant sites, who liked the idea of making life easier for their users. So far, so good.<br />
<br />
Like nearly every Microsoft technology seems to at one point or another, the MSN Passport became an object of criticism and concern, as shown in a 2002 MIT document[4]. The main problem is this: among the data collected by Microsoft upon a user's registration is a significant amount of personal information (such as age, date of birth, and addresses) which is stored on the Microsoft servers. What if someone gains access to that information? Who guarantees that that information will not be used by third parties? <br />
<br />
Aside from the privacy issues, some people are concerned about the system's internal security and by the fact that the system is entirely dependent on Microsoft servers to work:<br />
<br />
<fieldset><blockquote>"As more services and components depend on remote servers, functionality can grind to a halt if there is a failure on the centralized Passport system."[5]</blockquote></fieldset><br />
<br />
People have concerns, but what has been done? Are there any alternatives? Well, yes and no. Apparently the <em>Liberty Alliance Project</em>[6] was created to offer a valid and perhaps more democratic alternative to the Microsoft Passport:<br />
<br />
<fieldset><blockquote>"The Liberty Alliance Project was formed in September 2001 to serve as the premier open standards organization for federated identity and identity-based services. The Alliance is delivering specifications and guidelines to enable a complete network identity infrastructure that will resolve many of the technology and business issues hindering the deployment of identity-based Web services."[7]</blockquote></fieldset><br />
<br />
The project's founders (160 IT organizations, including Sun Microsystems and VeriSign) aim to create a <em>distributed</em> authentication system, as opposed to the <em>centralized</em> MSN Passport. This will undoubtedly solve some of the problems, but the system is still under development.<br />
<br />
<strong>Introducing Project Windstone</strong><br />
CyberArmy[8] is obviously like neither Microsoft or Sun Microsystems; it's a community of volunteers whose aim is sharing their knowledge and making the Internet a better place. Volunteers don't get paid, but sometimes something gets done, and some projects are released to the general public. Among these is a system for (if you haven't guessed already)a system for universal user authentication, called Project Windstone[9].<br />
<br />
Project Windstone was developed by SoundWave on behalf of Special Operations and Security[10] to provide a universal authentication system that is easy to use and deploy on websites and in applications. Furthermore, the Windstone protocol is language-independent and functions via HTTP POST transactions between clients and the Windstone server, so virtually any website coded in any language or any application able to communicate with a web server can implement it.<br />
<br />
It seems great so far, but what can Windstone be used for? As previously said, it is a system to allow users to authenticate themselves with the same credentials on many different websites and share profiles and information between those websites at the same time. Furthermore, users can send each other private messages that can be retrieved on any website that implements Windstone, with the added benefit of all transactions taking place in a secure and private environment.<br />
<br />
On second thought, Windstone features seem to lead to some perplexity, especially among users who are particularly concerned about their own privacy: apparently a single centralized server is involved, and users can share their profile and send messages with each other, so what warranties does Windstone offers as far as privacy/security goes?  Here's something which should reassure most of us:<br />
<br />
[list]<br />
<li>The information provided by users in their public profiles is entirely up to their discretion: in other words, it's up to the user if they want to list their credit card numbers on their profile or talk about their cat, as the Windstone server itself does not require any specific personal information in order to create a profile.<br />
</li><li>The username can be any valid email address submitted by the user.<br />
</li><li>User profiles are available only after authentication with the Windstone server, and only if the person requesting the profile already knows the email address used by another user for Windstone services. Currently, Windstone does not implement any form of listing of existing users among the standard commands.<br />
</li><li>The password chosen for user authentication is NEVER saved in any form; not within the client applications, not on the central server, and not in cookies. <br />
</li><li> Data sent from client to server and vice-versa is encrypted.<br />
</li>[/list]<br />
<br />
<strong>Some more technical details</strong><br />
I am actually planning to implement the system on one of my sites, so I started reading the short but straightforward documentation[11] available on the Windstone site to learn more about how the system works, and it seems quite simple and able to do what it does in a logical way; the Windstone "standard" contains a bunch of commands[12] which are used by the clients (agents) and the server to request information exchange such as requests for initialization, possible server replies, and so on. Commands and data are sent using the following format (excerpt from the official documentation):<br />
<br />
<em><br />
The format of this command string is as follows:<br />
<br />
AAAA.*BBBBBBBBBB.*CCCC::DDDDDDDDDDDDDDDDDDDD::EEEE::FFFFFFFFFF<br />
<br />
A. This is the command. Commands tell us what kind of request or response is being made with the command string. It also lets us know how many elements of data to expect (see F).<br />
<br />
B. This is the agent system identifier. Each website or IEP receives a unique alphanumeric ten (10) character identifier upon registration, which is used to identify this system within the network.<br />
<br />
C. This is the protocol version number. Generally, the version number will not change much, if at all, but it must be present. The protocol version goes with all command strings to let other systems and the Windstone server know what version of the protocol you are using. If certain versions are incompatible with each other, or if there is an upgrade or change to the protocol you are using, the version number will be used to determine that.<br />
<br />
D. This is the transaction identifier. Usually, this is not used, so the default information that should go here is six zeros ("000000"). The transaction identifier helps to link command strings into groups for processing and is most often used during the user login process.<br />
<br />
E. This is the sequence number. The sequence number, in conjunction with the transaction identifier, is used to put grouped command strings into their logical order. The sequence numbers have no specified numbering sequence, default start value, or length limit: the only requirement is that a sequence number must be in order from lowest to highest. When not using a transaction identifier or sequence number, the default information that should go here is a simple "X" (note that when "X" is being used in a command string by itself, it should always be capitalized).<br />
<br />
F. This is the data section. The data section is the heart of the command string. It is important to note that, at the minimum, all data sections need to be base-64 encoded prior to transmission - at no time should there be information in plain text format in the data section.<br />
</em> <br />
<br />
Obviously, command strings can be manipulated to access each section separately and the manipulation can be done with virtually any programming language used on the client side. <br />
<br />
Normally, the client will send a command to the Windstone server to start the authentication process and then retrieve some information; the server will reply accordingly to the client's command strings with its own responses wrapped in command strings. Let's suppose a Windstone Agent is being used to perform the following actions:<br />
<br />
- Initialize the system<br />
- perform a login<br />
- retrieve user profile from the Windstone server <br />
<br />
In this simulation I will not use the actual command strings but just the codes for the various commands.<br />
<br />
<em><u>Agent</u>: 0000 :: SETUP_INITIALIZE</em> - The Windstone agent sends a request to the server to initialize the authentication process, supplying the software identifier, the software type ("PC-Based" or "Web-Based"), the command landing URL and the URL to redirect logins to.<br />
<br />
<em><u>Server</u>: 0002 :: SETUP_COMPLETE </em>- Everything looks good to the server, which replies with the following information:  Unique agent identifier, primary authentication token, secondary authentication token, activation key, security code, shared encryption key (255 random characters, non-binary), registration completion date and time (epoch). These parameters will be used by the agent afterwards and are necessary to identify the agent on the Windstone server.<br />
<br />
<em><u>Agent</u>: 1102 :: USER_LOGIN_REDIRECT</em> - The agent requests to start the authentication process and sends the email address of the user to the server along with the URL where the user's password will be entered.<br />
<br />
<br />
<em><u>Server</u>: 1105 :: USER_AUTH_SAVE</em> - User credentials are checked by the Windstone server. Everything is fine, so the server sends this response to the agent.  The response contains the authentication token which will be used to authenticate the user during the session, as well as the user's display name.<br />
<br />
<em><u>Agent</u>: 1107 :: USER_INFO</em> - The agent can now request the user's profile from the Windstone Server.<br />
<br />
<em><u>Server</u>: 1108 :: USER_PROFILE</em> - After checking the user's authentication token, the server can now send the following information to the agent: Email address, display name, user "About Me" text, last login date and time, account created date and time, online status.<br />
<br />
This is just a simple example of how the Windstone protocol can be used; as mentioned earlier, there are various other commands[12] which can be used to perform various actions.  <br />
<br />
<strong>Development and deployment</strong><br />
The Windstone protocol is fully operational and can be implemented on any website or application able to communicate with a web server. The developer made a very basic PHP-based example of an Agent system available online[13]; it may not be a masterpiece of PHP coding (as the developer himself pointed out), but it can be useful in understanding how to develop a Windstone Agent System.<br />
<br />
If you'd like to start developing your own Agent System or you just want to create a Windstone account, it can be done on the Windstone registration page[14]: you'll be asked to provide an email address, a display name and a profile (the last two can be modified afterwards). Then the system will prompt you for a password, and an email will be sent to the address you provided to confirm and activate your account. Once you have an account, you can login to any website or application implementing the Windstone protocol, such as the Windstone website itself[15].<br />
<br />
Windstone is certainly not yet comparable to the MSN Passport technology - it's not used by a lot of important sites, and it's much simpler and offers fewer services, but it's undoubtedly an interesting approach to a free to use, secure and private system of universal user authentication.<br />
Check it out![9] <br />
<br />
<strong>Notes and Resources</strong><br />
[1] Microsoft Hotmail Service, <a href="http://www.hotmail.com">http://www.hotmail.com</a><br />
[2] MSN Passport Network: <a href="https://accountservices.passport.net/ppnetworkhome.srf?vv=320&amp;lc=1033">https://accountservices.passport.net/ppnetworkhome.srf?vv=320&amp;lc=1033</a><br />
[3] List of sites using MSN Passport, Passport@everything2: <a href="http://www.everything2.com/index.pl?node=passport">http://www.everything2.com/index.pl?node=passport</a><br />
[4] "Microsoft .NET Passport and Wallet: Approach with Caution!", <a href="http://web.mit.edu/ist/isnews/v17/n04/170408.html">http://web.mit.edu/ist/isnews/v17/n04/170408.html</a><br />
[5] "Microsoft Hailstorm and Passport", go-mono.com, <a href="http://www.go-mono.com/passport.html">http://www.go-mono.com/passport.html</a><br />
[6] Liberty Alliance Project, Official Page, <a href="http://www.projectliberty.org/index.php">http://www.projectliberty.org/index.php</a><br />
[7] Liberty Alliance Project, FAQs, <a href="http://www.projectliberty.org/about/faq.php">http://www.projectliberty.org/about/faq.php</a><br />
[8] CyberArmy, Official Page, <a href="http://www.cyberarmy.net/">http://www.cyberarmy.net/</a><br />
[9] Project Windstone, Official Page, <a href="http://windstone.x-mirror.com/v2/">http://windstone.x-mirror.com/v2/</a><br />
[10] Special Operations and Security, official website, <a href="http://sos.x-mirror.com/">http://sos.x-mirror.com/</a><br />
[11] Windstone Communications Protocol, Development Whitepaper, <a href="http://windstone.x-mirror.com/v2/development.php">http://windstone.x-mirror.com/v2/development.php</a><br />
[12] Windstone Protocol Commands, <a href="http://windstone.x-mirror.com/v2/commands.php">http://windstone.x-mirror.com/v2/commands.php</a><br />
[13] Example of PHP Agent System (ZIP file), <a href="http://windstone.x-mirror.com/v2/ws-testbed.zip">http://windstone.x-mirror.com/v2/ws-testbed.zip</a><br />
[14] Windstone Registration, <a href="http://windstone.x-mirror.com/v2/register.php">http://windstone.x-mirror.com/v2/register.php</a><br />
[15] Windstone Login Page, <a href="http://windstone.x-mirror.com/v2/login.php">http://windstone.x-mirror.com/v2/login.php</a>]]>
    </content>
  </entry>
</feed>
