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

<channel>
	<title>hasseg.org</title>
	<atom:link href="http://hasseg.org/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://hasseg.org/blog</link>
	<description></description>
	<lastBuildDate>Mon, 15 Aug 2011 22:38:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>jEdit Syntax Highlighting Mode for the Peg/Leg Parser Generator &#8216;Leg&#8217; Syntax</title>
		<link>http://hasseg.org/blog/post/651/jedit-syntax-highlighting-mode-for-the-pegleg-parser-generator-leg-syntax/</link>
		<comments>http://hasseg.org/blog/post/651/jedit-syntax-highlighting-mode-for-the-pegleg-parser-generator-leg-syntax/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 12:38:26 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[jEdit]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=651</guid>
		<description><![CDATA[I&#8217;ve been working on a fast and embeddable Markdown parser that can be used for syntax highlighting in editors, based on the PEG grammar from John MacFarlane&#8217;s peg-markdown compiler project. The grammar is written in leg, a syntax for the peg/leg parser generator by Ian Piumarta, and to make my work with this new syntax [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://hasseg.org/blog/wp-content/uploaded/2007/09/jediticon.jpeg" align="right" alt="jedit icon" width="53" height="53" /> I&#8217;ve been working on a fast and embeddable Markdown parser that can be used for syntax highlighting in editors, based on the <a href="http://en.wikipedia.org/wiki/Parsing_expression_grammar">PEG</a> grammar from John MacFarlane&#8217;s <a href="https://github.com/jgm/peg-markdown">peg-markdown</a> compiler project. The grammar is written in <strong><em>leg</em>, a syntax for the <a href="http://piumarta.com/software/peg/">peg/leg</a> parser generator</strong> by Ian Piumarta, and to make my work with this new syntax a bit more pleasant I implemented <strong>a jEdit mode for it</strong>.
</p>
<p><span id="more-651"></span></p>
<p>
<strong>Download the mode here:</strong> <a href="/stuff/jedit-modes/leg.xml">leg.xml</a>
</p>
<p>
Note that since the <em>leg</em> syntax uses curly brackets (<span style="font-family:monospace;">{}</span>) to delimit <a href="http://en.wikipedia.org/wiki/Syntax-directed_translation">actions</a> in the grammar, and those actions are written in C (which also uses curly brackets a lot), the mode has to somehow be able to match a certain number of balanced pairs of these brackets. As far as I know this is not directly supported in the jEdit syntax highlighting mode system but I was able to use the &#8220;delegates&#8221; mechanism to implement support for two levels of matched brackets, which should be enough for any reasonable use (in any case, it&#8217;s easy to add further levels of such support to the mode).
</p>
<p>
<strong>To install this mode</strong>, add the following to the <span style="font-family:monospace;">modes/catalog</span> file in your jEdit user settings directory (select <em>Utilities &rarr; Settings Directory</em> in jEdit to find this):
</p>
<div class="codecolorer-container xml mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;MODE</span> <span style="color: #000066;">NAME</span>=<span style="color: #ff0000;">&quot;leg&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; <span style="color: #000066;">FILE</span>=<span style="color: #ff0000;">&quot;leg.xml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; <span style="color: #000066;">FILE_NAME_GLOB</span>=<span style="color: #ff0000;">&quot;*.leg&quot;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">/&gt;</span></span></div></div>
<p>
Then copy the <span style="font-family:monospace;">leg.xml</span> file into the same directory with this file. See <a href="http://www.jedit.org/users-guide/installing-modes.html">the Installing Modes section</a> of the jEdit users&#8217; guide for more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/651/jedit-syntax-highlighting-mode-for-the-pegleg-parser-generator-leg-syntax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jEdit Macro for Opening the File Browser at Current Buffer&#8217;s &#8220;Project Root&#8221; Directory</title>
		<link>http://hasseg.org/blog/post/619/jedit-macro-for-opening-the-file-browser-at-current-buffers-project-root-directory/</link>
		<comments>http://hasseg.org/blog/post/619/jedit-macro-for-opening-the-file-browser-at-current-buffers-project-root-directory/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 15:26:01 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[jEdit]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=619</guid>
		<description><![CDATA[When I&#8217;m working with code in jEdit, my editor of choice, I like to keep the file browser open and docked to the left side of my editor window. When I&#8217;m switching between files &#8212; often belonging to different projects &#8212; I find myself reaching for the mouse in order to manually navigate the file [...]]]></description>
			<content:encoded><![CDATA[<p>
<img align="right" src="http://hasseg.org/blog/wp-content/uploaded/2007/09/jediticon.jpeg" alt="" width="53" height="53" /> When I&#8217;m working with code in jEdit, my editor of choice, I like to keep the file browser open and docked to the left side of my editor window. When I&#8217;m switching between files &#8212; often belonging to different projects &#8212; I find myself <strong>reaching for the mouse</strong> in order to manually navigate the file browser to the root folder of the project the currently open file belongs to. I started doing this so often that I decided to <strong>whip up a small macro to do it for me</strong>.
</p>
<div class="note">
<strong>Update (April 4, 2011):</strong> Set file browser to directory of current buffer if version control root cannot be found.
</div>
<p><span id="more-619"></span></p>
<p>
Since I don&#8217;t use the <a href="http://plugins.jedit.org/plugins/?ProjectViewer">ProjectViewer</a> plugin this macro has to have its own logic for determining where the &#8220;project root&#8221; is. The way it works is that it tries to <strong>find the root folder</strong> of the current project by way of <strong>searching for version control system folders</strong> (i.e. <span style="font-family:monospace">.git</span>, <span style="font-family:monospace">.hg</span>, <span style="font-family:monospace">.bzr</span>, <span style="font-family:monospace">_darcs</span>, <span style="font-family:monospace">.svn</span> or <span style="font-family:monospace">CVS</span>). The assumption is that as the script traverses the file system folder structure from the buffer&#8217;s location towards the root the <em>first</em> folder that has a Git, Mercurial, Bazaar or Darcs folder (or the <em>last</em> to have a Subversion or CVS folder) is the root. When the script finds the project root it switches the file browser to display it while keeping the UI focus in the editor field. If no project root can be found in this manner, the script sets the file browser to the directory that contains the currently open file.
</p>
<p>
<strong>Download</strong> the macro script itself here: <a href="/stuff/jEditMacros/Open_Root_of_Current_Project_in_File_Browser.bsh">Open_Root_of_Current_Project_in_File_Browser.bsh</a>
</p>
<p>
You install it by dropping it into your jEdit user settings directory&#8217;s <span style="font-family:monospace">/macros</span> folder (select <em>Utilities &rarr; Settings Directory</em> from the jEdit menu to find this location) and then running <em>Macros &rarr; Rescan Macros</em>. You can set a keyboard shortcut for this via the <em>Shortcuts</em> section of jEdit&#8217;s preferences and/or add a toolbar button via the <em>Tool Bar</em> section.
</p>
<p>Here is the macro source:</p>
<div class="codecolorer-container java mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000; font-style: italic; font-weight: bold;">/**<br />
&nbsp;* Tries to find the root of the 'current project', assuming<br />
&nbsp;* all project files live under the same directory structure<br />
&nbsp;* and that they are all under the same version control<br />
&nbsp;* repository.<br />
&nbsp;* <br />
&nbsp;* For Git, Mercurial and Bazaar (and it seems Darcs?) this is<br />
&nbsp;* easy since they only have their 'dot-directory' at the root<br />
&nbsp;* of the structure but Subversion (and I assume CVS) put them<br />
&nbsp;* everywhere so we have to find the _last_ directory to have<br />
&nbsp;* one.<br />
&nbsp;* <br />
&nbsp;*/</span><br />
<span style="color: #003399;">String</span> findProjectRoot<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; dir <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>buffer.<span style="color: #006633;">getDirectory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; previousDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">boolean</span> previousDirHasSvnDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">boolean</span> previousDirHasCvsDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>dir <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">boolean</span> hasSvnDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">boolean</span> hasCvsDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; list <span style="color: #339933;">=</span> dir.<span style="color: #006633;">list</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>childName <span style="color: #339933;">:</span> list<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hasSvnDir <span style="color: #339933;">&amp;&amp;</span> childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.svn&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasSvnDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hasCvsDir <span style="color: #339933;">&amp;&amp;</span> childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;CVS&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasCvsDir <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.git&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.hg&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.bzr&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> childName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_darcs&quot;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> dir.<span style="color: #006633;">getAbsolutePath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>previousDir <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>previousDirHasSvnDir <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>hasSvnDir<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>previousDirHasCvsDir <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>hasCvsDir<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> previousDir.<span style="color: #006633;">getAbsolutePath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; previousDirHasSvnDir <span style="color: #339933;">=</span> hasSvnDir<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; previousDirHasCvsDir <span style="color: #339933;">=</span> hasCvsDir<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; previousDir <span style="color: #339933;">=</span> dir<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; dir <span style="color: #339933;">=</span> dir.<span style="color: #006633;">getParentFile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
root <span style="color: #339933;">=</span> findProjectRoot<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>root <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; VFSBrowser.<span style="color: #006633;">browseDirectory</span><span style="color: #009900;">&#40;</span>view, buffer.<span style="color: #006633;">getDirectory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; view.<span style="color: #006633;">getEditPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">focusOnTextArea</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; view.<span style="color: #006633;">getStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setMessageAndClear</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Browser directory set to current buffer's location (cannot find project root.).&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">else</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; VFSBrowser.<span style="color: #006633;">browseDirectory</span><span style="color: #009900;">&#40;</span>view, root<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; view.<span style="color: #006633;">getEditPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">focusOnTextArea</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; view.<span style="color: #006633;">getStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setMessageAndClear</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Project root guessed; browser directory set to it.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/619/jedit-macro-for-opening-the-file-browser-at-current-buffers-project-root-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Events/Tasks From the OS X Calendar Store in a Custom Format like XML, CSV or LaTeX</title>
		<link>http://hasseg.org/blog/post/602/getting-eventstasks-from-the-os-x-calendar-store-in-a-custom-format-like-xml-csv-or-latex/</link>
		<comments>http://hasseg.org/blog/post/602/getting-eventstasks-from-the-os-x-calendar-store-in-a-custom-format-like-xml-csv-or-latex/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 14:49:41 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=602</guid>
		<description><![CDATA[Over the past couple of years I&#8217;ve gotten a few emails from users of icalBuddy who would like to somehow automate the task of generating CSV, XML/HTML or LaTeX output from the items in their calendar. Unfortunately icalBuddy isn&#8217;t set up to provide any kind of arbitrary output format (and I didn&#8217;t want to re-architect [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/08/PyCalXMLCSVLaTeX.png" alt="" width="106" height="83" align="right" /> Over the past couple of years I&#8217;ve gotten a few emails from users of <a href="/icalBuddy">icalBuddy</a> who would like to somehow automate the task of generating <em>CSV</em>, <em>XML/HTML</em> or <em>LaTeX</em> output from the items in their calendar. Unfortunately icalBuddy isn&#8217;t set up to provide any kind of arbitrary output format (and I didn&#8217;t want to re-architect it to do that) but a while ago I finally had the time and motivation to figure out a small solution for this: a Python helper class for writing scripts that produce whatever type of output your heart desires.
</p>
<p><span id="more-602"></span></p>
<p>
This class is called <a href="/calStoreHelper">CalStoreHelper</a> and it provides you with <a href="/calStoreHelper/CalStoreHelper.CalStoreHelper.html">two methods</a>: one for getting events and the other for getting tasks. An <a href="/hgweb/calStoreHelper/file/tip/example.py">example script</a> shows you concretely how to generate different kinds of output. Below is a small excerpt that shows how to generate CSV output:
</p>
<div class="codecolorer-container python mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">datetime</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> CalStoreHelper <span style="color: #ff7700;font-weight:bold;">import</span> *<br />
<span style="color: #ff7700;font-weight:bold;">from</span> CalendarStore <span style="color: #ff7700;font-weight:bold;">import</span> *<br />
<br />
<br />
c <span style="color: #66cc66;">=</span> CalStoreHelper<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># List of calendars to query (use None for all calendars)</span><br />
calendar_names <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'Home'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'Work'</span><span style="color: black;">&#93;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Start and end dates to get events between</span><br />
start_date <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span>.<span style="color: black;">now</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
delta <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">datetime</span>.<span style="color: black;">timedelta</span><span style="color: black;">&#40;</span>days<span style="color: #66cc66;">=</span><span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><br />
end_date <span style="color: #66cc66;">=</span> start_date + delta<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> example_CSV<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Example: get events + CSV formatting</span><br />
&nbsp; &nbsp; events <span style="color: #66cc66;">=</span> c.<span style="color: black;">getEvents</span><span style="color: black;">&#40;</span>calendar_names<span style="color: #66cc66;">,</span> start_date<span style="color: #66cc66;">,</span> end_date<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">from</span> UnicodeCSV <span style="color: #ff7700;font-weight:bold;">import</span> UnicodeWriter<br />
&nbsp; &nbsp; csv_writer <span style="color: #66cc66;">=</span> UnicodeWriter<span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/dev/stdout'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'wb'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> event <span style="color: #ff7700;font-weight:bold;">in</span> events:<br />
&nbsp; &nbsp; &nbsp; &nbsp; csv_writer.<span style="color: black;">writerow</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: #dc143c;">calendar</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">title</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: black;">title</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: black;">location</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: black;">startDate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">descriptionWithCalendarFormat_timeZone_locale_</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: black;">endDate</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">descriptionWithCalendarFormat_timeZone_locale_</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">None</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.<span style="color: black;">notes</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></div>
<p>
You can get the class by cloning the <a href="/calStoreHelper/#scmRepoInfo">version control repository</a> with <a href="http://mercurial.selenic.com/">Mercurial</a> or by downloading an archive from the <a href="/hgweb/calStoreHelper/">repository browser page</a> <em>(the bz2, zip and gz links at the top)</em>. Happy hacking.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/602/getting-eventstasks-from-the-os-x-calendar-store-in-a-custom-format-like-xml-csv-or-latex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use Unicode Emoji as Image-Free Icons in iOS Web Apps</title>
		<link>http://hasseg.org/blog/post/546/use-unicode-emoji-as-image-free-icons-in-ios-web-apps/</link>
		<comments>http://hasseg.org/blog/post/546/use-unicode-emoji-as-image-free-icons-in-ios-web-apps/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 22:59:37 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=546</guid>
		<description><![CDATA[In version 2.2 of iOS &#8212; Apple&#8217;s &#8220;mobile&#8221; operating system used in the iPhone, iPod Touch and iPad &#8212; support for Emoji was added. These small 12&#215;12 pixel icons are meant to be used in text messaging in Japan but because they&#8217;re implemented simply as unicode symbols in the device they can be used as [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/emoji-small.png" alt="" title="" width="57" height="57" align="right" /> In version 2.2 of <a href="http://en.wikipedia.org/wiki/IOS_(Apple)">iOS</a> &mdash; Apple&#8217;s &#8220;mobile&#8221; operating system used in the <em>iPhone</em>, <em>iPod Touch</em> and <em>iPad</em> &mdash; support for <a href="http://en.wikipedia.org/wiki/Emoji">Emoji</a> was added. These small 12&#215;12 pixel icons are meant to be used in text messaging in Japan but because they&#8217;re implemented simply as unicode symbols in the device <strong>they can be used as icons</strong> when we know they&#8217;re available.
</p>
<p><span id="more-546"></span></p>
<h2>Emoji and Unicode</h2>
<p>
Emoji is basically a Japanese term for emoticons used on mobile devices. <a href="http://en.wikipedia.org/wiki/Emoji">The Wikipedia article</a> has more information on the concept, but this part is the most interesting:
</p>
<blockquote><p>
When transmitted, emoji symbols are specified as a two-byte sequence, in the private-use range E63E through E757 in the Unicode character space, or F89F through F9FC for Shift-JIS.
</p></blockquote>
<p>
Now, that&#8217;s <em>not true</em> for Apple&#8217;s Emoji implementation &mdash; it&#8217;s apparently completely incompatible with the handsets from the Japanese carriers (see <a href="http://openradar.appspot.com/6402446">OpenRadar #6402446</a> for more info) &mdash; but the part about them being implemented as unicode symbols <em>is</em> still true in iOS, the code points used are just different.
</p>
<p>
I&#8217;ve made <a href="/stuff/ios-emoji/">this demo page</a> that <strong>lists unicode symbols and the hexadecimal code points for all the different Emoji that are available on my iPhone</strong> (iOS version 4). The demo page has a cache manifest so it should be available offline as well. If you&#8217;re currently on a desktop computer you won&#8217;t be able to see them so here&#8217;s a picture of what it looks like on the iPhone:
</p>
<div style="text-align:center;">
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/emoji-page.png" alt="" title="" width="229" height="335" />
</div>
<p>
In order to be able to use these icons you need to have easy access to the hexadecimal unicode code points so this page should come in handy. If you instead prefer a native app for this, there are <a href="http://www.google.com/search?q=site%3Aitunes.apple.com+inurl%3A%22%2Fapp%2F%22+unicode">many you can choose from</a>.
</p>
<h2>Using Emoji Symbols in HTML and CSS</h2>
<p>
User agent detection is usually cited as a bad thing, and with good reason &mdash; it&#8217;s often used when <a href="http://diveintohtml5.org/detect.html">feature detection</a> would be more appropriate, causing unexpected breakage in many edge conditions. When planning on using the iOS emoji on a web page, though, <strong>you really need to sniff the user agent</strong> in order to know whether the client is an iOS device and thus has a font that implements these unicode symbols in the expected way.
</p>
<p>
Here&#8217;s an example (in PHP) of how you&#8217;d detect iOS devices:
</p>
<div class="codecolorer-container php mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$is_iPhone</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'iPhone'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$is_iPod</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'iPod'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$is_iPad</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_USER_AGENT'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'iPad'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$is_iOS</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$is_iPad</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$is_iPod</span> <span style="color: #339933;">||</span> <span style="color: #000088;">$is_iPhone</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>
When you&#8217;ve detected the client to be an iOS device, you can <strong>offer them an additional stylesheet:</strong>
</p>
<div class="codecolorer-container php mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$is_iOS</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;iOS.css&quot; /&gt;'</span><span style="color: #339933;">;</span></div></div>
<p>
In this stylesheet you&#8217;ll then insert the Emoji symbols into whatever locations you&#8217;d like to use them in, and to do this you can use <a href="http://www.w3.org/TR/CSS2/generate.html">CSS2&#8242;s content generation mechanisms</a> (in the examples below, we use code point E00E, which is the &#8220;thumbs up&#8221; Emoji):
</p>
<div class="codecolorer-container css mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="css codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #cc00cc;">#someID</span><span style="color: #3333ff;">:before </span><span style="color: #00AA00;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">content</span><span style="color: #00AA00;">:</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\E00E</span>&quot;</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* thumbs up */</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">margin-right</span><span style="color: #00AA00;">:</span> <span style="color: #933;">5px</span><span style="color: #00AA00;">;</span><br />
<span style="color: #00AA00;">&#125;</span></div></div>
<p>
Containing all the iOS-specific embellishments in one separate CSS file is, I think, the way to go, but if you want you can also insert these symbols directly into your HTML as special entities:
</p>
<div class="codecolorer-container html4strict mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span>&gt;</span><span style="color: #ddbb00;">&amp;#xE00E;</span> Thumbs up!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></div></div>
<h2>Big Caveats to Consider</h2>
<p>
This is a great way to add little graphical cues to your web app <strong>without having to deal with images</strong> (i.e. making or obtaining them, serving them, having the app load them, possibly caching them) but of course the downside is that they are <strong>only available on Apple&#8217;s iOS devices</strong>, which makes this trick quite useless unless you&#8217;re concentrating completely on the iPhone/iPad/iPod Touch axis.
</p>
<p>
The key takeaway from this should be that there&#8217;s this <strong>neat trick</strong> you can use but <strong>if you <em>need</em> your icons to be visible in all clients</strong> you should forget about these and <strong>just use images for everyone</strong> (it&#8217;ll be much easier).
</p>
<div class="note" style="margin-bottom:50px;"><strong>Note:</strong> I&#8217;ve noticed that for some reason these emoji characters will <strong>fail to render on the iPad if the <span style="font-family:monospace;">text-rendering</span> CSS property is set to <span style="font-family:monospace;">optimizeLegibility</span></strong> <em>(this is on the iPad-specific build of iOS 3.2, MobileSafari Version/4.0.4 Mobile/7B367 Safari/531.21.10 and does not occur on my iPhone (which is running iOS 4.0.1))</em>.</div>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/546/use-unicode-emoji-as-image-free-icons-in-ios-web-apps/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How to Display Events or Tasks on Your Desktop With icalBuddy</title>
		<link>http://hasseg.org/blog/post/503/how-to-display-events-or-tasks-on-your-desktop-with-icalbuddy/</link>
		<comments>http://hasseg.org/blog/post/503/how-to-display-events-or-tasks-on-your-desktop-with-icalbuddy/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 23:30:38 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Miscallaneous]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=503</guid>
		<description><![CDATA[I don&#8217;t really have any statistics about this but I&#8217;m quite sure that an overwhelming majority of the users of my icalBuddy program are using it to display calendar data on their desktop via GeekTool. Several tutorials on how to get this done have been written by different people, mainly for relatively non-technical users, which [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/all-together.png" alt="icalBuddy, GeekTool, NerdTool icons" title="" width="129" height="131" align="right" /> I don&#8217;t really have any statistics about this but I&#8217;m quite sure that an overwhelming majority of the users of my <a href="/icalBuddy">icalBuddy</a> program are using it to <strong>display calendar data on their desktop</strong> via <a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a>. Several tutorials on how to get this done have been written by different people, mainly for relatively non-technical users, which I think is great. The problem seems to be that many people don&#8217;t know how to configure icalBuddy to give them the kind of output they&#8217;d like and end up copy-pasting the commands from these blogs (some of these blog posts also contain <em>outdated</em> information about a bunch of things). Hopefully this short tutorial (and the <a href="/icalBuddy/examples.html">usage examples page</a>) will offer an easy way to make a more informed decision about how to get this done.
</p>
<p><span id="more-503"></span></p>
<h3>Choose Between GeekTool and NerdTool</h3>
<p>
<a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a> and <a href="http://mutablecode.com/apps/nerdtool">NerdTool</a> are two programs that do the same thing: display stuff on your desktop. The choice between which one to use is up to you but allow me to give a few suggestions:
</p>
<ul>
<li><strong>If you want to change the text colors used in the display</strong>, choose NerdTool <em>(as far as I know, GeekTool can only change the default text color but not the actual colors used for &#8220;red&#8221;, &#8220;blue background&#8221;, &#8220;bright green&#8221; etc.)</em></li>
<li><strong>If you want to hack on the program yourself</strong>, choose NerdTool <em>(it&#8217;s open source)</em>.</li>
<li><strong>If you don&#8217;t care about any of the above</strong>, choose GeekTool.</li>
</ul>
<h3>Install the Apps</h3>
<p>
When you&#8217;ve chosen which one you&#8217;d like to use, <strong>download and install it</strong>. <a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a> is a <em>preference pane</em> so it lives in your System Preferences, while <a href="http://mutablecode.com/apps/nerdtool">NerdTool</a> is a regular application which you drag into your Applications folder.
</p>
<p>
In order to install icalBuddy, <a href="/icalBuddy">download</a> the latest version and unzip the package by double-clicking on it. Open the unzipped folder, <strong>double-click on install.command</strong> and follow the instructions (you&#8217;ll have to press return, input your password and icalBuddy will be installed).
</p>
<h3>Figure out Your icalBuddy Configuration</h3>
<p>
So now you need to figure out what to put into the <em>command</em> field in Geek-/NerdTool. <strong>First you need to go to the <a href="/icalBuddy/examples.html">icalBuddy Usage Examples</a> page and browse through it</strong> &#8212; you might find the kind of output you&#8217;re looking for right there, in which case <strong>you can just get the command you see there</strong> <em>(note that some of the examples require you to <a href="http://hasseg.org/icalBuddy/examples.html#Getting+Started+With+Custom+Output+Formatting">add something to the configuration file</a>)</em>.
</p>
<p>
If you&#8217;d like to take some of the examples and modify the output a bit, you can fire up your Terminal.app and start experimenting with <a href="/icalBuddy/man.html">different arguments</a>. In this case the <a href="/icalBuddy/#documentation">documentation links</a> will come in handy.
</p>
<h3>Add Your icalBuddy Command into GeekTool/NerdTool</h3>
<p>
Once you have your command, you can put it into the app by creating a new &#8220;shell&#8221; entry:</p>
<ul>
<li><strong>GeekTool:</strong> Drag the &#8220;Shell&#8221; geeklet icon (see below) onto your desktop. The properties window for this entry should appear.</li>
<p><img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/geektool-shell.png" alt="" title="" width="400" height="263" /></p>
<li><strong>NerdTool:</strong> Click the &#8220;plus&#8221; button (see below) and select &#8220;Shell&#8221; from the popup. A new entry is created into the list above.</li>
<p><img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/nerdtool-add.png" alt="" title="" width="400" height="382" />
</ul>
</p>
<p>
You can then <strong>insert your icalBuddy command into the command field</strong> in whichever app you&#8217;re using (and set the refresh interval in order to specify how often the command should be run):
</p>
<p><img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/geektool-and-nerdtool-command-fields.png" alt="" title="" width="470" height="334" /></p>
<p>
That&#8217;s it. You can then delve into the settings that both GeekTool and NerdTool offer you, like changing the colors and fonts used for the output.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/503/how-to-display-events-or-tasks-on-your-desktop-with-icalbuddy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Getting a List of Installed Fonts with Flash and Javascript</title>
		<link>http://hasseg.org/blog/post/526/getting-a-list-of-installed-fonts-with-flash-and-javascript/</link>
		<comments>http://hasseg.org/blog/post/526/getting-a-list-of-installed-fonts-with-flash-and-javascript/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 23:18:05 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Miscallaneous]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=526</guid>
		<description><![CDATA[When implementing the feature in the icalBuddy examples page where the font used for the output examples could be changed interactively I needed to get a list of all the fonts installed on the current user&#8217;s computer. This blog post from 2006 explains how to do it, but it refers to the deprecated ActionScript 2 [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/07/flash-fonts.png" alt="" title="" width="90" height="104" align="right" /> When implementing the feature in the <a href="/icalBuddy/examples.html">icalBuddy examples page</a> where the font used for the output examples could be changed interactively I needed to <strong>get a list of all the fonts installed on the current user&#8217;s computer</strong>. <a href="http://www.maratz.com/blog/archives/2006/08/18/detect-visitors-fonts-with-flash/">This blog post from 2006</a> explains how to do it, but it refers to the deprecated ActionScript 2 API so I had to figure out how to do it with AS3.
</p>
<p><span id="more-526"></span></p>
<h3>Demo</h3>
<p>
Here&#8217;s a small demo where you can see the feature at work: <a href="/stuff/fontList/example.html">Font List Example</a>. The sources shown below are used in this demo.
</p>
<h3>Implementation</h3>
<p>
We need <strong>a small Flash app and some Javascript</strong>. Below is the source code for the Flash app.
</p>
<p>
<em>Note that you don&#8217;t need the Flash authoring app from Adobe in order to compile this; you can simply use the <span style="font-family:monospace;">mxmlc</span> compiler in the <a href="http://opensource.adobe.com/wiki/display/flexsdk/">Flex SDK</a> (which is open source).</em>
</p>
<div class="codecolorer-container actionscript mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="actionscript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">// FontList.as</span><br />
package <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">display</span>.<span style="color: #006600;">Sprite</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #0066CC;">text</span>.<span style="color: #0066CC;">Font</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #0066CC;">text</span>.<span style="color: #006600;">FontType</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #0066CC;">text</span>.<span style="color: #006600;">FontStyle</span>;<br />
&nbsp; &nbsp; <span style="color: #0066CC;">import</span> flash.<span style="color: #006600;">external</span>.<span style="color: #006600;">ExternalInterface</span>;<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FontList <span style="color: #0066CC;">extends</span> Sprite<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> FontList<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ExternalInterface.<span style="color: #0066CC;">call</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'populateFontList'</span>, getDeviceFonts<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getDeviceFonts<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">Array</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> embeddedAndDeviceFonts:<span style="color: #0066CC;">Array</span> = <span style="color: #0066CC;">Font</span>.<span style="color: #006600;">enumerateFonts</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">true</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">var</span> deviceFontNames:<span style="color: #0066CC;">Array</span> = <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #b1b100;">each</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">font</span>:<span style="color: #0066CC;">Font</span> <span style="color: #b1b100;">in</span> embeddedAndDeviceFonts<span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">font</span>.<span style="color: #006600;">fontType</span> == FontType.<span style="color: #006600;">EMBEDDED</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">||</span> <span style="color: #0066CC;">font</span>.<span style="color: #006600;">fontStyle</span> <span style="color: #66cc66;">!</span>= FontStyle.<span style="color: #006600;">REGULAR</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">continue</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deviceFontNames.<span style="color: #0066CC;">push</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">font</span>.<span style="color: #006600;">fontName</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deviceFontNames.<span style="color: #0066CC;">sort</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> deviceFontNames;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<span style="color: #66cc66;">&#125;</span></div></div>
<p>
Notice how the Flash app calls a Javascript function <span style="font-family:monospace;">populateFontList()</span> via the ExternalInterface. Now we just need to implement that function in the page where we embed the Flash object:
</p>
<div class="codecolorer-container javascript mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> populateFontList<span style="color: #009900;">&#40;</span>fontArr<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> key <span style="color: #000066; font-weight: bold;">in</span> fontArr<span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> fontName <span style="color: #339933;">=</span> fontArr<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// trim</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fontName <span style="color: #339933;">=</span> fontName.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^\s\s*/</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\s\s*$/</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>fontName.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[_\-\s]Italic$/</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> fontName.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[_\-\s](Demi)?[Bb]old$/</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> fontName.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[_\-\s]Medium$/</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> fontName.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[_\-\s](Ultra)?[Ll]ight$/</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">||</span> fontName.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[_\-\s]Condensed$/</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// font is &quot;non-regular&quot; (i.e. bold, italic etc.)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// (do something here with fontName)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// font is &quot;regular&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// (do something here with fontName)</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/526/getting-a-list-of-installed-fonts-with-flash-and-javascript/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Prevent iTunes websites from opening the iTunes app using GlimmerBlocker</title>
		<link>http://hasseg.org/blog/post/441/prevent-itunes-websites-from-opening-the-itunes-app-using-glimmerblocker/</link>
		<comments>http://hasseg.org/blog/post/441/prevent-itunes-websites-from-opening-the-itunes-app-using-glimmerblocker/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 21:41:57 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Miscallaneous]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=441</guid>
		<description><![CDATA[A few minutes ago I clicked on an iTunes store link on a website and had to again completely lose it because of the iTunes app popping up without me asking it to. This is a common annoyance that people have found a bunch of different ways to combat, ranging from messing with the system&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>
<img align="right" src="http://hasseg.org/blog/wp-content/uploaded/2010/04/itunes-kickass.png" alt="" width="115" height="96" /> A few minutes ago I clicked on an iTunes store link on a website and had to again completely <em>lose it</em> because of the iTunes app popping up without me asking it to. This is a common annoyance that people have found a bunch of different ways to combat, ranging from messing with the system&#8217;s (or the browser&#8217;s) mapping of URL protocol handlers to rewriting parts of web pages via a browser plugin (e.g. GreaseMonkey) or a localhost web proxy (e.g. GlimmerBlocker).
</p>
<p><span id="more-441"></span></p>
<div class="note">
<strong>Note (Aug &#8217;10):</strong> Now that Safari 5 has support for extensions, installing the <a href="http://einserver.de/nomoreitunes">NoMoreiTunes extension</a> is probably a better way to do this.
</div>
<p>
I read somewhere that Safari (or the OS? or iTunes?) sometimes decides to &#8220;fix&#8221; the mappings of iTunes URL protocol handlers, forcing you to &#8220;play cat and mouse&#8221; if you decide to prevent iTunes from automagically opening up by removing it as the itms: protocol handler, so I decided that it would be best to try and fix this problem by messing with the iTunes website source via GlimmerBlocker, which I already was using for ad blocking.
</p>
<p>
I couldn&#8217;t find any straightforward directions on how to do this with GlimmerBlocker so I decided to post it here myself once I figured out how to do it. So this is how I prevented iTunes from automatically opening up whenever I open up a store link in my browser:
</p>
<ul>
<li>Open the GlimmerBlocker &#8220;filters&#8221; tab and <strong>add a new filter</strong>, as well as <strong>a new rule</strong> for this filter.</li>
<li>Select <strong>Whitelist URL, optionally modifying content</strong> as the action</li>
<li>For the <em>Host</em> section, select <strong>is</strong> as the predicate and type in <strong>itunes.apple.com</strong></li>
<li>Select <strong>ignored</strong> for both <em>Path</em> and <em>Query</em></li>
<li>Switch to the <strong>transform</strong> tab and type in the following:</li>
<div class="codecolorer-container javascript mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/detectAndOpenItunes\(\);/g</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;&lt;!-- detectAndOpenItunes() zapped --&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<li>Make sure the <em>Only for content-type</em> selection in the bottom-right corner of the dialog sheet is <strong>html</strong></li>
<li>Save</li>
</ul>
<p>
This seems to correctly prevent the iTunes app from opening up whenever a store website is opened, but it still allows for opening the viewed product in the stand-alone app via the <em>&#8220;View in iTunes&#8221;</em> link on the page.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/441/prevent-itunes-websites-from-opening-the-itunes-app-using-glimmerblocker/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Trash files from the OS X command line</title>
		<link>http://hasseg.org/blog/post/406/trash-files-from-the-os-x-command-line/</link>
		<comments>http://hasseg.org/blog/post/406/trash-files-from-the-os-x-command-line/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 01:02:10 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=406</guid>
		<description><![CDATA[I spend a lot of time in the Terminal on my computer &#8212; a lot of things are just better done with a command-line interface than in the GUI. When removing files via the command-line people usually just, well, remove them (with the rm command), but this means that they&#8217;ll be eschewing the Trash, one [...]]]></description>
			<content:encoded><![CDATA[<p>
<img src="/trash/appIcon.png" alt="trash picture" align="right" width="96" height="88" /> I spend a lot of time in the Terminal on my computer &#8212; a lot of things are just better done with a command-line interface than in the GUI. When removing files via the command-line people usually just, well, <em>remove</em> them (with the <a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/rm.1.html">rm</a> command), but this means that they&#8217;ll be eschewing the <a href="http://en.wikipedia.org/wiki/Trash_(computing)">Trash</a>, one of the user-friendliest things (even relatively) modern operating systems have had to offer for a long time.
</p>
<p><span id="more-406"></span></p>
<p>
It&#8217;s obvious we need a <span style="font-family:monospace;">trash</span> command that we can use instead of <span style="font-family:monospace;">rm</span> when we&#8217;re not 101% sure we need to <em>actually remove these files, like, right now</em>. Here are a couple of existing solutions I&#8217;ve found, my impressions of them, and then my version at the bottom:
</p>
<h3><a href="http://www.sveinbjorn.org/osxutils_docs">osxutils&#8217; trash</a> by Sveinbjörn Þórðarson</h3>
<p>
This is what I&#8217;ve used up until now. It&#8217;s a small Perl script that simply manually moves the specified files into the trash folder under the current user&#8217;s home directory:
</p>
<div class="codecolorer-container perl mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># relevant code snippet:</span><br />
<span style="color: #339933;">...</span><br />
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">-</span>e <span style="color: #ff0000;">&quot;$ENV{HOME}/.Trash/$path_segs[$#path_segs]&quot;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">$path_segs</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$#path_segs</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.=</span> <span style="color: #ff0000;">&quot; copy $cnt&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000066;">system</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;mv '$ARGV[$argnum]' '$ENV{HOME}/.Trash/$path_segs[$#path_segs]'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #339933;">...</span></div></div>
<p>
The biggest problem with this is that it moves all trashed files onto the <strong>same volume</strong> instead of using each volume&#8217;s own trash folders (this is not a good idea). It also deals with <strong>filename collisions</strong> manually, which is a bit volatile. The good thing about this is that it <strong>doesn&#8217;t follow &#8220;leaf&#8221; symbolic links</strong>, which is in my opinion the expected behaviour (what if I want to trash the link instead of its target?).
</p>
<h3><a href="http://www.dribin.org/dave/osx-trash/">osx-trash</a> by Dave Dribin</h3>
<p>
This one is a lot better. It&#8217;s a Ruby script that uses the <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ScriptingBridgeConcepts/Introduction/Introduction.html">Scripting Bridge</a> to ask Finder to perform all the actual &#8220;heavy lifting&#8221; (e.g. moving the files to the trash) which means that <strong>each volume&#8217;s own trash folders are utilized properly and filename collisions are handled in a standard way</strong>:
</p>
<div class="codecolorer-container ruby mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># relevant code snippets:</span><br />
...<br />
<span style="color:#9900CC;">finder</span> = SBApplication.<span style="color:#9900CC;">applicationWithBundleIdentifier</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;com.apple.Finder&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
...<br />
<span style="color:#9900CC;">path</span> = <span style="color:#CC00FF; font-weight:bold;">Pathname</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span><br />
url = NSURL.<span style="color:#9900CC;">fileURLWithPath</span><span style="color:#006600; font-weight:bold;">&#40;</span>path.<span style="color:#9900CC;">realpath</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
item = finder.<span style="color:#9900CC;">items</span>.<span style="color:#9900CC;">objectAtLocation</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span><br />
item.<span style="color:#9900CC;">delete</span><br />
...</div></div>
<p>
It also allows you to list all the files that are currently in the trash and empty it (normally or securely). The few minor negative things are the fact that it <strong>follows leaf symbolic links</strong> and the fact that when you try to trash multiple files you don&#8217;t have access rights for, Finder will pop up an <strong>authentication dialog separately for each file</strong>.
</p>
<h3><a href="/trash">my trash</a></h3>
<p>
Due to the few things that I wanted the <span style="font-family:monospace;">trash</span> command to do differently, I wrote my own. In order to make sure that filename collisions are handled in the standard manner and that each volume&#8217;s trash folders are properly used (just like with Dave Dribin&#8217;s script) this one first tries to use the <strong>standard system API</strong> for trashing files, and if that fails due to the user not having the correct access rights, then asks Finder to trash those files (Finder can authenticate the current user as an administrator and move the files into that user&#8217;s trash &#8212; if you simply run this program as root, the files will be moved to root&#8217;s trash, which is not what we want):
</p>
<div class="codecolorer-container objc mac-classic codecolorer-customstyle" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">// relevant code snippets:</span><br />
...<br />
<span style="color: #11740a; font-style: italic;">// first try the standard API function (this should be</span><br />
<span style="color: #11740a; font-style: italic;">// the fastest way, and we get a nice status value</span><br />
<span style="color: #11740a; font-style: italic;">// as well):</span><br />
<span style="color: #11740a; font-style: italic;">// </span><br />
FSRef fsRef;<br />
FSPathMakeRefWithOptions<span style="color: #002200;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> UInt8 <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>filePath fileSystemRepresentation<span style="color: #002200;">&#93;</span>,<br />
&nbsp; &nbsp; kFSPathMakeRefDoNotFollowLeafSymlink,<br />
&nbsp; &nbsp; <span style="color: #002200;">&amp;</span>fsRef,<br />
&nbsp; &nbsp; <span style="color: #a61390;">NULL</span> <span style="color: #11740a; font-style: italic;">// Boolean *isDirectory</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#41;</span>;<br />
OSStatus ret <span style="color: #002200;">=</span> FSMoveObjectToTrashSync<span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>fsRef, <span style="color: #a61390;">NULL</span>, kFSFileOperationDefaultOptions<span style="color: #002200;">&#41;</span>;<br />
...<br />
<span style="color: #11740a; font-style: italic;">// if no access rights, construct Apple event describing</span><br />
<span style="color: #11740a; font-style: italic;">// a &quot;delete all items in this list&quot; action and send it to Finder:</span><br />
<span style="color: #11740a; font-style: italic;">// </span><br />
<span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>descr <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span><br />
&nbsp; &nbsp; descriptorWithDescriptorType<span style="color: #002200;">:</span><span style="color: #bf1d1a;">'furl'</span><br />
&nbsp; &nbsp; data<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>url absoluteString<span style="color: #002200;">&#93;</span> dataUsingEncoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#91;</span>urlListDescr insertDescriptor<span style="color: #002200;">:</span>descr atIndex<span style="color: #002200;">:</span>i<span style="color: #002200;">++</span><span style="color: #002200;">&#93;</span>;<br />
...<br />
ProcessSerialNumber finderPSN <span style="color: #002200;">=</span> getFinderPSN<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>targetDesc <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span><br />
&nbsp; &nbsp; descriptorWithDescriptorType<span style="color: #002200;">:</span><span style="color: #bf1d1a;">'psn '</span><br />
&nbsp; &nbsp; bytes<span style="color: #002200;">:&amp;</span>finderPSN<br />
&nbsp; &nbsp; length<span style="color: #002200;">:</span><span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>finderPSN<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;<br />
<span style="color: #400080;">NSAppleEventDescriptor</span> <span style="color: #002200;">*</span>descriptor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSAppleEventDescriptor</span><br />
&nbsp; &nbsp; appleEventWithEventClass<span style="color: #002200;">:</span><span style="color: #bf1d1a;">'core'</span><br />
&nbsp; &nbsp; eventID<span style="color: #002200;">:</span><span style="color: #bf1d1a;">'delo'</span><br />
&nbsp; &nbsp; targetDescriptor<span style="color: #002200;">:</span>targetDesc<br />
&nbsp; &nbsp; returnID<span style="color: #002200;">:</span>kAutoGenerateReturnID<br />
&nbsp; &nbsp; transactionID<span style="color: #002200;">:</span>kAnyTransactionID<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#91;</span>descriptor setDescriptor<span style="color: #002200;">:</span>urlListDescr forKeyword<span style="color: #002200;">:</span><span style="color: #bf1d1a;">'----'</span><span style="color: #002200;">&#93;</span>;<br />
...<br />
AESendMessage<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>descriptor aeDesc<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&amp;</span>reply, kAEWaitReply, kAEDefaultTimeout<span style="color: #002200;">&#41;</span>;<br />
...</div></div>
<p>
The difference is that this one <strong>doesn&#8217;t follow leaf symlinks</strong>, and when deleting multiple files that you don&#8217;t have access rights for, Finder will only show <strong>one authentication dialog</strong> (I had to implement this kind of &#8220;manually&#8221; because I couldn&#8217;t find any way to accomplish it with the Scripting Bridge). I also copied the idea and implementation of emptying the trash and listing its contents via the Scripting Bridge from Dave&#8217;s script. This <span style="font-family:monospace;">trash</span> is written in (Objective-)C, <span class="info" title="yeah, I actually only used Objective-C and C because it was at first the only way I knew how to accomplish what I wanted, even though I now know this could've been done adequately with Ruby or Python as well">for all those extra milliseconds that are so goddamn important</span> when waiting for files to be trashed.
</p>
<p>
You can <a href="/trash">go through my trash here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/406/trash-files-from-the-os-x-command-line/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Print AppleScript files with color-coding in the Terminal</title>
		<link>http://hasseg.org/blog/post/392/print-applescript-files-with-color-coding-in-the-terminal/</link>
		<comments>http://hasseg.org/blog/post/392/print-applescript-files-with-color-coding-in-the-terminal/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 17:37:53 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=392</guid>
		<description><![CDATA[Even though I curse and hate its syntax, I have to admit that AppleScript certainly provides one of the nicest things OS X has to offer in comparison to other operating systems: almost-ubiquitous scripting of GUI applications (one could argue that this is not due to the AppleScript language itself, but the Open Scripting Architecture [...]]]></description>
			<content:encoded><![CDATA[<p>
<img align="right" src="/asprint/appIcon.png" alt="asprint image" width="128" height="106" style="margin-left: 5px;" /> Even though I <em>curse and hate</em> its syntax, I have to admit that AppleScript certainly provides one of the nicest things OS X has to offer in comparison to other operating systems: almost-ubiquitous scripting of GUI applications (one could argue that this is not due to the AppleScript language itself, but the <a href="http://developer.apple.com/mac/library/documentation/AppleScript/Conceptual/AppleScriptX/Concepts/osa.html">Open Scripting Architecture</a> which AppleScript is simply a language for, but that&#8217;s just semantics). Recently I&#8217;ve had to work with AppleScript files a bit more than usual while implementing <a href="/tagger">Tagger</a>&#8216;s <em>front app scripts</em> feature, and I noticed that I often wanted to <strong>print out the contents of (compiled) AppleScript files</strong> in the Terminal. The built-in command <a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/osadecompile.1.html"><span style="font-family:monospace;">osadecompile</span></a> does just that: it reads in the AppleScript file, decompiles it, formats the code and nicely prints it out. I&#8217;m used to seeing my code with <strong>syntax highlighting</strong>, though, so I decided to write a small program that works similarly to <span style="font-family:monospace;">osadecompile</span> but uses ANSI escape sequences to format the output.
</p>
<p><span id="more-392"></span></p>
<p>
The <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSAppleScript_AppKitAdditions/Reference/Reference.html#//apple_ref/occ/instm/NSAppleScript/richTextSource">Application Kit additions to the <span style="font-family:monospace;">NSAppleScript</span> class</a> provide an implementation of the syntax highlighting (which would be the hardest part in implementing something like this) and I already have the <a href="/ansiEscapeHelper"><span style="font-family:monospace;">ANSIEscapeHelper</span> class</a> that provides the translation of an <span style="font-family:monospace;">NSAttributedString</span> to an ANSI-escaped <span style="font-family:monospace;">NSString</span> (which would be the second-hardest part in implementing something like this) so writing a command-line program around these two parts was quite simple in the end. The program is called <strong><span style="font-family:monospace;">asprint</span></strong> and it has <a href="/asprint">its own page</a> on this site where you can download it.
</p>
<p>
This is what using <span style="font-family:monospace;">asprint</span> looks like:
</p>
<div align="center">
<img src="http://hasseg.org/blog/wp-content/uploaded/2010/03/asprint-screenshot.png" alt="asprint screenshot" width="445" height="592" />
</div></p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/392/print-applescript-files-with-color-coding-in-the-terminal/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My Custom GeekTool 2 Build with Support for ANSI Colors, UTF-8 and Different Writing Directions</title>
		<link>http://hasseg.org/blog/post/350/my-custom-geektool-2-build-with-support-for-ansi-colors-utf-8-and-different-writing-directions/</link>
		<comments>http://hasseg.org/blog/post/350/my-custom-geektool-2-build-with-support-for-ansi-colors-utf-8-and-different-writing-directions/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 22:23:40 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=350</guid>
		<description><![CDATA[A year ago I released version 1.0.8 of my icalBuddy command-line application that I initially wrote as a way to get nicely formatted lists of my events and tasks from the OS X calendar store on top of my desktop background picture using GeekTool. This particular version was notable in my mind because it introduced [...]]]></description>
			<content:encoded><![CDATA[<p>
<img align="right" src="http://hasseg.org/blog/wp-content/uploaded/2009/07/GeekTool-hasseg-logos.png" alt="GeekTool-hasseg-logos" width="77" height="77" /> A year ago I released <a href="http://hasseg.org/icalBuddy/#1.0.8">version 1.0.8</a> of my <strong><a href="http://hasseg.org/icalBuddy">icalBuddy</a></strong> command-line application that I initially wrote as a way to get nicely formatted lists of my events and tasks from the OS X calendar store on top of my desktop background picture using <strong><a href="http://projects.tynsoe.org/en/geektool/">GeekTool</a></strong>. This particular version was notable in my mind because it introduced initial support for <strong>formatting the output via <a href="http://en.wikipedia.org/wiki/ANSI_escape_code">ANSI escape sequences</a></strong>. The initial formatting was static (that is, you couldn&#8217;t change it) and very simple (it only made the titles bold), but since then I&#8217;ve implemented all kinds of different customization options that can be used to specify how the output should be colored and otherwise formatted. The only problem was that <strong>GeekTool didn&#8217;t support ANSI escape sequences</strong>, which meant that instead of the nicely formatted output I wanted GeekTool would display a bunch of gibberish if I used the <span style="font-family:monospace;">-f</span> icalBuddy argument.
</p>
<p><div style="padding:4px;background:#eee;border:1px solid #ddd;">
<em><strong>Update (Sep 6, 09):</strong> Recompiled the preference pane as 32/64-bit binary with support for garbage collection so that it would not force System Preferences to restart on Snow Leopard.</em>
</div>
</p>
<p><span id="more-350"></span></p>
<p>
There was nothing on the horizon about any further additions to GeekTool (or any similar programs) that would provide the features I wanted (although <a href="http://thememymac.com/2009/geektool/geektool-three/">version 3 of GeekTool</a> seems to be in the making, and there&#8217;s also the GPL&#8217;d <a href="http://github.com/balthamos/geektool-3/">NerdTool</a> project which aims to implement a clone of v2 with some changes and fixes), but luckily Yann Bizeul, the author of GeekTool, had released the source code to it, which enabled me to put this feature (and a few others) in. As you can see from the screenshot below, I also took the liberty to rearrange the GUI a bit:
</p>
<p align="center">
<img src="http://hasseg.org/blog/wp-content/uploaded/2009/07/geektool-hasseg.org-build.png" alt="geektool-hasseg.org-build" width="450" height="326" />
</p>
<p>
I&#8217;ve been running this custom build for a few months now without any problems so I feel reasonably confident about releasing it. No open-source license has been specified for GeekTool 2.1.2 so I unfortunately won&#8217;t be releasing the source code for the changes I made. Sorry :(
</p>
<h2>Download link</h2>
<p>
First the most important part &mdash; here&#8217;s the download link:
</p>
<p><strong><a href="/stuff/geektool/GeekTool-2.2.1-unofficial-hasseg.org-build.zip">GeekTool-2.2.1-unofficial-hasseg.org-build.zip</a> (Latest version. Requires Leopard (Mac OS 10.5+))</strong> <em>(Sep 6, 2009: Recompiled the preference pane as 32/64-bit binary with support for garbage collection so that it would not force System Preferences to restart on Snow Leopard.)</em></p>
<p>
<a href="/stuff/geektool/GeekTool-2.2.0-unofficial-hasseg.org-build.zip">GeekTool-2.2.0-unofficial-hasseg.org-build.zip</a> <em>(Requires Leopard. Based on source code from version 2.1.2)</em>
</p>
<p><span style="color:#FF0000;">Disclaimer: I will most probably *not* fix bugs in this version or develop it further in any way. This is simply a temporary solution until the next official version of GeekTool comes around (if it includes these features, which I don&#8217;t know if it does), or someone else releases something similar.</span></p>
<p>
In order to install it, do the following:
</p>
<ol>
<li>Extract the files from the zip archive by double-clicking on it in Finder</li>
<li>Double-click on the <span style="font-family:monospace;">GeekTool.prefPane</span> file icon in Finder to install it</li>
<li>If you already had GeekTool installed, System Preferences will ask if you want to replace it. Select <em>&#8220;Replace&#8221;</em>, quit and restart System Preferences and open the GeekTool preference pane, verifying that the version label now says <em>&#8220;unofficial hasseg.org build.&#8221;</em></li>
<li>Unselect the <em>&#8220;Enable GeekTool&#8221;</em> checkbox in order to kill the old version&#8217;s background process, and then select it again in order to run the updated one.</li>
</ol>
<h2>Added Features</h2>
<h3>ANSI Escape Sequence Support</h3>
<p>
As said, this version includes support for ANSI escape sequences, including all the supported <span style="color:green;">foreground</span> and <span style="background-color:rgb(200,255,200);">background</span> colors (each of which you can change yourself on an entry-by-entry basis in GeekTool&#8217;s preferences), <strong>intensity</strong> (bolding) and <u>underlining</u> (both <u>single</u> and <u style="border-bottom:1px solid;">double</u>). Here&#8217;s an example of how my (customized) icalBuddy output looks in my GeekTool setup:
</p>
<p align="center">
<img src="http://hasseg.org/blog/wp-content/uploaded/2009/07/geektool-hasseg.org-build-desktop-example.png" alt="geektool-hasseg.org-build-desktop-example" width="450" height="377" />
</p>
<p>
In order to learn how to customize icalBuddy&#8217;s ANSI-formatted output, please refer to the <a href="http://hasseg.org/icalBuddy/config-man.html">icalBuddyConfig man page</a>. Also remember that you need to use the <span style="font-family:monospace;">-f</span> (or <span style="font-family:monospace;">&#8211;formatOutput</span>) argument to get formatted output in the first place.
</p>
<p>
Here&#8217;s what the new little preferences window that you can use to customize the <em>actual</em> colors used for displaying ANSI escape colors looks like:
</p>
<p><div align="center">
<img src="http://hasseg.org/blog/wp-content/uploaded/2009/07/geektool-hasseg.org-build-ansicolors.png" alt="geektool-hasseg.org-build-ansicolors" width="450" height="326" />
</div>
</p>
<p>
You can specify different colors for each GeekTool entry you have.
</p>
<h3>UTF-8 Support</h3>
<p>This version now supports UTF-8, which means that unicode characters (umlauts, arabic, hebrew etc.) will display correctly (version 2 only supported ASCII).</p>
<h3>Text Writing Direction Setting</h3>
<p>
I had received word from one particular user of icalBuddy from a country where the language is written from right to left (arabic, to be precise,) who had issues with the bullet point sometimes shifting to the right side of the row instead of staying at the left. This was due to the OS X text layout algorithm trying to figure out if it should print characters in a string onto the screen from right to left or from left to right and sometimes failing due to mixtures of latin and arabic characters being on the same line. Now problems such as this can be fixed by explicitly specifying the text layout direction:
</p>
<p align="center">
<img src="http://hasseg.org/blog/wp-content/uploaded/2009/07/geektool-hasseg.org-build-textdirection.png" alt="geektool-hasseg.org-build-textdirection" width="450" height="326" /></p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/350/my-custom-geektool-2-build-with-support-for-ansi-colors-utf-8-and-different-writing-directions/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

