<?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 &#187; Programming</title>
	<atom:link href="http://hasseg.org/blog/post/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://hasseg.org/blog</link>
	<description></description>
	<lastBuildDate>Sun, 29 Apr 2012 09:35:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Use Unicode Emoji as Icons in Native iOS Apps</title>
		<link>http://hasseg.org/blog/post/692/use-unicode-emoji-as-icons-in-native-ios-apps/</link>
		<comments>http://hasseg.org/blog/post/692/use-unicode-emoji-as-icons-in-native-ios-apps/#comments</comments>
		<pubDate>Sun, 29 Apr 2012 09:21:37 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=692</guid>
		<description><![CDATA[A while back, I wrote about using unicode emoji characters as icons in web apps. The big caveat with that was that these characters were only available on iOS devices, which made the trick much less useful in a web app, which of course are generally meant to be more or less cross-platform. If you&#8217;re [...]]]></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" /> A while back, I wrote about <a href="/blog/post/546/use-unicode-emoji-as-image-free-icons-in-ios-web-apps/">using unicode emoji characters as icons in web apps</a>. The big caveat with that was that these characters were <strong>only available on iOS devices</strong>, which made the trick much less useful in a web app, which of course are generally meant to be more or less cross-platform. If you&#8217;re developing a <strong>native iOS app</strong>, though, using these standard colorful bitmap emoji characters as icons is a much more realistic proposition, because you can be sure that all the devices your app runs on will have them available. In this post I will show how to easily do this.
</p>
<p><span id="more-692"></span></p>
<p>
The easiest way to display emoji icons in your app&#8217;s UI is to simply <strong>use a control that renders text</strong>, like a <span style="font-family:monospace;">UILabel</span> or a <span style="font-family:monospace;">UIButton</span>. Sometimes, though, you will want to <strong>render one of these characters into a <span style="font-family:monospace;">UIImage</span></strong> so that you can manipulate the pixels somehow or simply to be able to show them in certain positions in certain controls that expect an image object.
</p>
<p>
In <a href="/speed-dialer-factory">Speed Dialer Factory</a>, I used emoji icons to make some options in table view cells a bit more recognizable:
</p>
<p style="text-align:center;">
<img src="http://hasseg.org/blog/wp-content/uploaded/2012/04/sdf-emoji.png" alt="" title="" width="400" height="336" />
</p>
<p>
In this particular case, I needed the emoji characters to be rendered into <span style="font-family:monospace;">UIImages</span> so that I could make them <strong>monochrome</strong> when the cells were disabled. In addition, using the image section of the table view cells allowed me to ensure that the labels of all of the cells were <strong>horizontally aligned</strong>.
</p>
<p>
Below you can find the source code for a <span style="font-family:monospace;">UIImage</span> category that I use for this. Here is <strong>an example</strong> how how I might use a method in this category to apply one of the above images into a table view cell:
</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">tableViewCell.imageView.image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage hg_imageFromString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;<span style="color: #2400d9;">\u</span>E001&quot;</span><span style="color: #002200;">&#93;</span>;</div></div>
<p>
And here is <strong>the source code</strong>:
</p>
<p><span style="font-family:monospace;">UIImage+HGViewRendering.h</span>:</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: #6e371a;">#import &lt;UIKit/UIKit.h&gt;</span><br />
<br />
<span style="color: #a61390;">@interface</span> UIImage <span style="color: #002200;">&#40;</span>HGViewRendering<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_imageFromView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>view;<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_imageFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>str;<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_cachedImageFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>str;<br />
<br />
<span style="color: #a61390;">@end</span></div></div>
<p><span style="font-family:monospace;">UIImage+HGViewRendering.m</span>:</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: #6e371a;">#import &quot;UIImage+HGViewRendering.h&quot;</span><br />
<span style="color: #6e371a;">#import &lt;QuartzCore/QuartzCore.h&gt;</span><br />
<br />
<span style="color: #a61390;">@implementation</span> UIImage<span style="color: #002200;">&#40;</span>HGViewRendering<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_imageFromView<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>view<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; UIGraphicsBeginImageContextWithOptions<span style="color: #002200;">&#40;</span>view.bounds.size, view.opaque, <span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>view.layer renderInContext<span style="color: #002200;">:</span>UIGraphicsGetCurrentContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; UIImage <span style="color: #002200;">*</span>img <span style="color: #002200;">=</span> UIGraphicsGetImageFromCurrentImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; UIGraphicsEndImageContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> img;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_imageFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>str<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; UILabel <span style="color: #002200;">*</span>label <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UILabel alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; label.text <span style="color: #002200;">=</span> str;<br />
&nbsp; &nbsp; label.opaque <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;<br />
&nbsp; &nbsp; label.backgroundColor <span style="color: #002200;">=</span> UIColor.clearColor;<br />
&nbsp; &nbsp; CGSize measuredSize <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>str sizeWithFont<span style="color: #002200;">:</span>label.font<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; label.frame <span style="color: #002200;">=</span> CGRectMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span>, <span style="color: #2400d9;">0</span>, measuredSize.width, measuredSize.height<span style="color: #002200;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>UIImage hg_imageFromView<span style="color: #002200;">:</span>label<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> hg_cachedImageFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>str<br />
<span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #a61390;">static</span> <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>cache <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>cache <span style="color: #002200;">==</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cache <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableDictionary</span> dictionary<span style="color: #002200;">&#93;</span> retain<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; UIImage <span style="color: #002200;">*</span>image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>cache objectForKey<span style="color: #002200;">:</span>str<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>image <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #a61390;">return</span> image;<br />
&nbsp; &nbsp; image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UIImage hg_imageFromString<span style="color: #002200;">:</span>str<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>cache setObject<span style="color: #002200;">:</span>image forKey<span style="color: #002200;">:</span>str<span style="color: #002200;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> image;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@end</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/692/use-unicode-emoji-as-icons-in-native-ios-apps/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<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>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>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>Quick Look Plugin/Generator for Image Folders</title>
		<link>http://hasseg.org/blog/post/292/quick-look-plugingenerator-for-image-folders/</link>
		<comments>http://hasseg.org/blog/post/292/quick-look-plugingenerator-for-image-folders/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 16:23:20 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=292</guid>
		<description><![CDATA[One of the things that I&#8217;ve always thought Windows XP did better than OS X is how it displays the thumbnails of contained images on the icons of folders that have image files inside them. I always felt this to be quite useful, but couldn&#8217;t think of any reasonable way to implement it on the [...]]]></description>
			<content:encoded><![CDATA[<p>
<img align="right" src="http://hasseg.org/blog/wp-content/uploaded/2009/03/plugin.jpg" alt="plugin" title="plugin" width="65" height="65" /> One of the things that I&#8217;ve always thought Windows XP did better than OS X is how it displays the thumbnails of contained images on the icons of folders that have image files inside them. I always felt this to be quite useful, but couldn&#8217;t think of any reasonable way to implement it on the Mac before OS X Leopard came along with its Quick Look plug-in architecture.
</p>
<p><span id="more-292"></span></p>
<p>
So I wrote a Quick Look plugin for just that. I call it <a href="/imageFolderQLGenerator/">ImageFolderQLGenerator</a> and its results, when viewed within Finder, look like this:
</p>
<div align="center">
	<img src="/imageFolderQLGenerator/example-thumbnails.png" width="457" height="186" />
</div>
<div align="center" style="margin-bottom:20px;">
	<img src="/imageFolderQLGenerator/example-preview.png" width="336" height="258" />
</div>
<p>
Implementing the plugin itself wasn&#8217;t very difficult, even for someone as inexperienced in C as me, but the biggest headache has been something that I&#8217;ve yet to find a solution to: as you can see, Finder automatically wraps folder thumbnails into these &#8220;icon decors&#8221; with their page curls and drop shadows and whatnot &#8212; I haven&#8217;t found any way to prevent this from happening. As far as I know, Finder decides if it wants to do that based on the type of the content (in this case, folders) and there&#8217;s nothing you can do to influence its choice. If someone knows a cure for this, please let me know!
</p>
<p>
You can <a href="/imageFolderQLGenerator/">download ImageFolderQLGenerator here</a>. I&#8217;ve released it under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License version 2.0</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/292/quick-look-plugingenerator-for-image-folders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>fcshctl: the Flex Compiler Shell Controller</title>
		<link>http://hasseg.org/blog/post/194/fcshctl-the-flex-compiler-shell-controller/</link>
		<comments>http://hasseg.org/blog/post/194/fcshctl-the-flex-compiler-shell-controller/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 17:32:35 +0000</pubDate>
		<dc:creator>Ali Rantakari</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[jEdit]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://hasseg.org/blog/?p=194</guid>
		<description><![CDATA[Introduction Like I&#8217;ve mentioned before in this blog, I develop Flex applications using the Flex SDK and jEdit instead of Adobe&#8217;s Flex Builder IDE. This setup has worked very well for me but one annoying issue I&#8217;ve had to deal with because of this is the slow compilation speed: every time I make a small [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>
Like I&#8217;ve mentioned before in this blog, I develop Flex applications using the Flex SDK and jEdit instead of Adobe&#8217;s Flex Builder IDE. This setup has worked very well for me but one annoying issue I&#8217;ve had to deal with because of this is <strong>the slow compilation speed</strong>: every time I make a small change into one of my projects and recompile it, the mxmlc compiler (that my build scripts are calling) has to load the JVM into memory and recompile my whole project from scratch, which obviously takes a while. Compiling things in Flex Builder is a lot faster, and the reason for that is <em><a href="http://labs.adobe.com/wiki/index.php/Flex_Compiler_Shell">the Flex Compiler Shell</a></em>, which it uses for compilation instead of mxmlc.
</p>
<div style="padding:4px;background:#eee;border:1px solid #ddd;">
<em><strong>Update (Version 0.5.1, Mar 17, 09):</strong></p>
<ul>
<li>Display a &#8220;compiling&#8230;&#8221; message before sending fcsh a compilation command in order to let the user know that something is going on and that they should wait instead of just killing the process.</li>
<li>If the log file exists when fcshctl runs, check if there are any other fcshctl instances running, and if not, assume that the log file has been orphaned, delete it and continue.</li>
<li>Exit with status code 0 (&#8220;ok&#8221;) if fcsh output ends in the <em>&#8220;Nothing has changed since the last compile&#8221;</em> message.</li>
</ul>
<p></em>
</div>
<p><span id="more-194"></span></p>
<div style="padding:4px;background:#eee;border:1px solid #ddd;">
<em><br />
<strong>Update (Version 0.5, Dec 10, 08):</strong></p>
<ul>
<li>Made it possible to specify a filename as the argument to the &#8220;clear&#8221; command &#8212; fcshctl will then try to find the first compile target id matching the specified filename and clear the corresponding id (example: &#8220;fcshctl clear MyApp.mxml&#8221;)</li>
<li>Made fcshctl find compile target ids corresponding to specific filenames or paths by asking fcsh directly via the &#8220;info&#8221; command instead of retaining them on its own in a temporary file (this is in order to avoid problems that could arise if this temp file and fcsh&#8217;s own list of retained compile target ids would get out of sync.)</li>
<li>Added command &#8220;id&#8221; which can be used to find the first compile target id matching a specified string (example: &#8220;fcshctl id MyApp.mxml&#8221;)</li>
</ul>
<p><strong>Update (Version 0.4, Nov 4, 08):</strong></p>
<ul>
<li>Made the script use only one logfile (i.e. one with a static path) and check its existence (and if it does exist, wait for it to be deleted) before continuing, so as to make sure no two fcshctl instances can try to send commands to fcsh at the same time, or before an already running command has finished executing and returned control to the prompt.</li>
</ul>
<p></em>
</div>
<p></p>
<p>
The basic idea behind the Flex Compiler Shell is that it would stay in memory between compilations (thus avoiding the cost of loading up the JVM every time you want to compile something) and use a technique called <strong>incremental compilation</strong> that, as the name suggests, is based on the idea of only compiling the parts of your project that have changed since the last compilation (thus making the process a lot faster). When you run the Flex Compiler Shell executable (called <em>fcsh</em>), you&#8217;re thrown into an interactive shell where you can run commands in order to compile your projects and control the operation of fcsh itself.
</p>
<h2>The Problem</h2>
<p>
When I found out about fcsh, tried it out and saw how much faster it was than mxmlc, of course I wanted to immediately start using it instead in my build scripts. The biggest problem with doing this, though, is the fact that <strong>the basic operation of these two programs is fundamentally different</strong>: when you run mxmlc, it compiles the project, prints some messages to standard output and then exits (with the exit status 0 if the compilation was successful or 1 if it wasn&#8217;t), which is perfect for integrating it into build scripts. Fcsh, on the other hand, throws you into a shell of its own and expects you to essentially operate it from within itself (instead of simply calling it with some arguments and then having it return with some standard output and an exit status like mxmlc).
</p>
<p>
The other issue that makes fcsh more difficult to use in general is that in order to use the incremental compilation feature, you have to first compile your project like you normally would (using the &#8220;mxmlc&#8221; command), then make note of the <em>&#8220;compile target id&#8221;</em> number that fcsh then assigns to this project and specifies in its output, and for future compilations use the &#8220;compile N&#8221; (where N is the compile target id) command.
</p>
<h2>The Solution</h2>
<p>
I tried to search for a solution to this problem that somebody else might have come up with but didn&#8217;t find an adequate one (a list of the ones that I could find is further down), so I decided to give it a shot myself. My approach, called <strong>fcshctl</strong> (short for &#8220;fcsh controller&#8221;), is basically a simple bash script that:</p>
<ol>
<li>starts the fcsh process if it isn&#8217;t already running</li>
<li>forwards its arguments to fcsh as commands</li>
<li>reads the output of that command from the fcsh interactive shell and prints it to the standard output</li>
<li>exits with status 0 (success) or >0 (failure)</li>
</ol>
<p>
In addition to this, I also made the script <strong>automatically and transparently invoke the incremental compilation feature</strong> whenever applicable so that I wouldn&#8217;t have to worry about keeping track of the compile target ids and using a different command for the compilation whenever one had already been assigned.
</p>
<p>
Below is a summarization of the pros and cons of this solution:
</p>
<h3>Pros:</h3>
<ul>
<li>It&#8217;s quite simple &#8212; just one shell script (a few others are included in the .zip that are only for convenience and not required)</li>
<li>It runs the fcsh instance in a <a href="http://www.gnu.org/software/screen/">GNU screen</a> session, which means that:</li>
<ul>
<li>The running fcsh instance is accessible to all user processes (i.e. not just within a single shell session, for example)</li>
<li>It is possible for the user to enter the running fcsh interactive shell at any time (by attaching to the screen session via the command <span style="font-family:monospace;">screen -r -S fcsh</span>) and manually interact with it</li>
</ul>
<li>It automatically checks whether you&#8217;ve compiled a specific file before and keeps track of the compile target ids that fcsh assigns so that it can automatically and transparently invoke the incremental compilation feature and let you access the speed gains that are fcsh&#8217;s main offering without any additional work. This feature can also be turned off by setting an environment variable.</li>
<li>A proxy script (called <span style="font-family:monospace;">fcshctl-mxmlc</span>) that can be used in place of mxmlc is provided. It simply calls fcshctl with <span style="font-family:monospace;">&#8220;mxmlc&#8221;</span> as the first argument, followed by all the other arguments you specify, so that you can simply use this script as a stand-in for mxmlc in any build scripts that you may be using without having to modify them any further.</li>
</ul>
<h3>Cons:</h3>
<ul>
<li>It uses the GNU screen logging mechanism and polling for changes in the log file in order to catch the output of commands sent to fcsh, which is not very elegant and causes a slowdown of maybe about a couple hundred milliseconds before the output is printed to stdout.</li>
<li>The output of the executed fcsh command is not printed to the standard output as it comes, but instead all at once when the command finishes (this is not a problem for me personally, but others might want to fix this).</li>
<li>It&#8217;s implemented as a bash script, which means that it&#8217;s not the fastest monster out there (we&#8217;re talking about milliseconds here, though, so it doesn&#8217;t bother me at all).</li>
</ul>
<h2>Download</h2>
<p>
You can download fcshctl here:</p>
<ul>
<li><strong><a href="/stuff/fcshctl/fcshctl-v0.5.1.zip">fcshctl-v0.5.1.zip</a> (latest)</strong></li>
<li><a href="/stuff/fcshctl/fcshctl-v0.5.zip">fcshctl-v0.5.zip</a></li>
<li><a href="/stuff/fcshctl/fcshctl-v0.4.zip">fcshctl-v0.4.zip</a></li>
<li><a href="/stuff/fcshctl/fcshctl-v0.3.zip">fcshctl-v0.3.zip</a></li>
</ul>
<p>
fcshctl has been tested with fcsh versions <em>3.0.0 build 477</em> and <em>3.1.0 build 2710</em> on Mac OS 10.5.5. It is licensed under <a href="http://hasseg.org/stuff/license/MIT_License.txt">the MIT License</a>.
</p>
<p>
The script requires the following to be in your <span style="font-family:monospace;">$PATH</span>: rm, mv, cat, ps, sleep, tail, head, grep, awk, screen, xargs and basename. <strong>You also need to have the <span style="font-family:monospace;">FLEX_HOME</span> environment variable set to point to the Flex SDK root path.</strong>
</p>
<h2>Example of use</h2>
<p><pre>
fcshctl $ export FLEX_HOME=/Users/username/code/SDKs/flex_sdk_3.1
fcshctl $
fcshctl $ ./fcshctl
<span style="color:blue;">
Usage: fcshctl &lt;commands&gt;

&nbsp;&nbsp;Substitute &lt;commands&gt; with any commands you
&nbsp;&nbsp;would like to send fcsh, just like you would
&nbsp;&nbsp;enter them in the interactive fcsh shell
&nbsp;&nbsp;session.

&nbsp;&nbsp;To get a list of the available commands, run:

&nbsp;&nbsp;&nbsp;&nbsp;fcshctl help
</span>
fcshctl $
fcshctl $ ./fcshctl help
<span style="color:blue;">List of fcsh commands:
mxmlc arg1 arg2 ...      full compilation and optimization; return a target id
compc arg1 arg2 ...      full SWC compilation
compile id               incremental compilation
clear [id]               clear target(s)
info [id]                display compile target info
quit                     quit</span>
fcshctl $
fcshctl $ ./fcshctl mxmlc ~/code/Flex/projects/testbed/testbed.mxml
<span style="color:blue;">Loading configuration file /Users/username/code/SDKs/flex_sdk_3.1/frameworks/flex-config.xml
Recompile: /Users/username/code/Flex/projects/testbed/testbed.mxml
Reason: The source file wasn't fully compiled.
Files changed: 0 Files affected: 1
/Users/username/code/Flex/projects/testbed/testbed.mxml(28):  Error: Incorrect number of arguments.  Expected 2.

&nbsp;&nbsp;&nbsp;&nbsp;func1("toka");
</span>
fcshctl $ echo $?
1
fcshctl $
fcshctl $
</pre>
</p>
<h2>Other similar solutions</h2>
<p>
Below is a list of other approaches to the problem of integrating fcsh to non-standard (i.e. non-Flex Builder) workflows (roughly in order from most promising to least promising), and short lists of reasons why I personally didn&#8217;t want to use them. If my solution doesn&#8217;t seem good to you, you should maybe check some of these out.
</p>
<p>
<a href="http://www.vim.org/scripts/script.php?script_id=1793">fcsh tools</a> by <em>Mike Rowe</em></p>
<ul>
<li>Runs fcsh in a daemonized process, which means you won&#8217;t be able to enter the interactive shell of a running fcsh process and manually interact with it</li>
<li>You can only specify the filename to compile; has no support for additional mxmlc arguments</li>
<li>For GNU/Linux (but seems to work just fine on OS X as well)</li>
</ul>
<p><a href="http://code.google.com/p/flex-compiler-shell-daemon/">flex-compiler-shell-daemon</a> by <em>Leonardo Soto Muños</em> (also see <a href="http://blog.leosoto.com/2008/10/flex-compiler-shell-daemon.html">his blog post about it</a>)</p>
<ul>
<li>I couldn&#8217;t get it to work out of the box on OS X</li>
<li>Runs fcsh in a daemonized process, which means you won&#8217;t be able to enter the interactive shell of a running fcsh process and manually interact with it</li>
</ul>
<p><a href="http://fcshwrapper.blogspot.com/">FCSH Wrapper</a> by <em>Mihai Vasilache</em></p>
<ul>
<li>For Windows</li>
<li>Designed to be used with Ant</li>
<li><a href="http://mihai.vasilache.googlepages.com/classDiagram.jpg">A bit complicated</a></li>
</ul>
<p><a href="http://code.google.com/p/fsch/">http://code.google.com/p/fsch/</a> by <em>nimrod97</em></p>
<ul>
<li>For Windows</li>
</ul>
<p><a href="http://zarkov.bigsource.de/front_content.php">BigSource Zarkov</a> by <em>BigSource GbR</em></p>
<ul>
<li>For Eclipse &#038; Ant</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://hasseg.org/blog/post/194/fcshctl-the-flex-compiler-shell-controller/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

