<?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"
	>

<channel>
	<title>matthew ephraim's blog</title>
	<atom:link href="http://www.mattephraim.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mattephraim.com</link>
	<description></description>
	<pubDate>Thu, 22 Jul 2010 05:36:22 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Introducing Candid Canvas</title>
		<link>http://www.mattephraim.com/blog/2010/07/21/introducing-candid-canvas/</link>
		<comments>http://www.mattephraim.com/blog/2010/07/21/introducing-candid-canvas/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 05:36:22 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=97</guid>
		<description><![CDATA[
The Canvas Tag

  If you&#8217;re a web developer (or even mildly interested in the world of web development)
  you&#8217;ve probably heard of HTML5&#8217;s new Canvas tag.
  You&#8217;re probably also aware that the Canvas tag allows web developers to create some
  really
  great
  animations right in the browser.
  No [...]]]></description>
			<content:encoded><![CDATA[
<h3>The Canvas Tag</h3>
<p>
  If you&#8217;re a web developer (or even mildly interested in the world of web development)
  you&#8217;ve probably heard of HTML5&#8217;s new <a href="http://en.wikipedia.org/wiki/Canvas_element">Canvas tag</a>.
  You&#8217;re probably also aware that the Canvas tag allows web developers to create some
  <a href="http://www.chromeexperiments.com/detail/plasmatree/">really</a>
  <a href="http://www.chromeexperiments.com/detail/plasmatree/">great</a>
  <a href="http://www.chromeexperiments.com/detail/canopy/">animations</a> right in the browser.
  No plugins needed (well, depending on your browser, maybe one <a href="http://code.google.com/chrome/chromeframe/">plugin</a>).
</p>
<p>
  As soon as I saw what was possible with the Canvas tag, I wanted to start using it myself. So, I looked at
  some of the <a href="https://developer.mozilla.org/en/canvas_tutorial">Canvas tutorials</a> available online
  and figured out how to create some simple drawings. It was fun, and simple, and I was happy.
</p>
<p>
  And then I decided to try my hand at creating some Canvas animations.
</p>

<h3>The Problem</h3>
<p>
  Now, I&#8217;m not a Canvas expert, so my analysis could be way off base, but I quickly came to the conclusion that creating a
  Canvas animation could be quite difficult. It&#8217;s fairly easy to do if your animation only has a few elements. And it&#8217;s manageable if you don&#8217;t
  mind having a lot of extra code for handling the animation&#8217;s timing and state variables. But, as time went on, I found that even simple
  animations became difficult to manage very quickly. My hat&#8217;s off to the developers that have created some of the more complex Canvas
  animations out there. I don&#8217;t know how you do it.
</p>
<p>
  My first instinct when I began to run into problems with the Canvas animations I was trying to create was to look for a Canvas animation
  library that might help me out. It turns out that there are a few out there. Unfortunately, I didn&#8217;t find one that I felt fit well with the
  kinds of animations I wanted to create.
</p>
<p>
  And so, with a stack of problems I intended to solve, I set out to create a Canvas animation library that would solve each and every one of them.
</p>

<h3>Candid Canvas</h3>
<p>
  What I came up with was a new Canvas animation library that I call <a href="http://github.com/mephraim/candid_canvas">Candid Canvas</a>.
</p>
<ul>
  <li>
    Unlike several of the other Canvas animation libraries out there, Candid Canvas doesn&#8217;t provide you with any special drawing tools. You&#8217;re still
    on your own when it comes to drawing your animation.
  </li>
  <li>
    Candid Canvas also doesn&#8217;t keep track of the elements that have been drawn to the Canvas tag. You&#8217;re on your own for that too.
  </li>
  <li>
    Candid Canvas is intended to help you manage the parts of creating a Canvas animation related to, well&#8230;animating it.
  </li>
  <li>
    Candid Canvas helps you break down your animation into separate scenes.
  </li>
  <li>
    And it helps you break your scenes down into individual elements responsible for drawing different
    pieces of the scene.
  </li>
  <li>
    Candid Canvas also helps you play, pause and reset your animation.
  </li>
</ul>
<p>
  Candid Canvas is not a library for everyone. But if you&#8217;re looking for a little extra help when creating Canvas animation, I hope that Candid Canvas
  will work for you!
</p>
<p>
  Download, contribute and submit bugs and feature requests at the Candid Canvas <a href="http://github.com/mephraim/candid_canvas">Github project</a>.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2010/07/21/introducing-candid-canvas/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Usability, Browsability and&#8230;Sniffability?</title>
		<link>http://www.mattephraim.com/blog/2010/05/03/usability-browsability-andsniffability/</link>
		<comments>http://www.mattephraim.com/blog/2010/05/03/usability-browsability-andsniffability/#comments</comments>
		<pubDate>Mon, 03 May 2010 06:56:00 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=93</guid>
		<description><![CDATA[
  As any cat owner (or roommate of a cat owner) knows, there are times
  when a scented candle becomes a crucial component of maintaining one&#8217;s
  own sanity. Recently, when posed with a situation in which I found myself
  lacking the proper oder masking equipment, I took a stroll over to [...]]]></description>
			<content:encoded><![CDATA[<p>
  As any cat owner (or roommate of a cat owner) knows, there are times
  when a scented candle becomes a crucial component of maintaining one&#8217;s
  own sanity. Recently, when posed with a situation in which I found myself
  lacking the proper oder masking equipment, I took a stroll over to my local
  big box retailer and made my way to the home and garden section. There I began
  my search for perfect flame activated cat stink deterrent. 
</p>
<p>
  Now, anyone who&#8217;s ever tried to choose a winner among a wide variety of
  competing scents knows that there&#8217;s really only one way to figure how a 
  particular candle matches up with your own scent preferences. You pick it up.
  And you smell it. Unfotunately (as you will see below), with many candles this obvious scent comparision
  technique is difficult, if not impossible. Clearly, the companies who make the candles
  that are most difficult to smell are indifferent to or ignorant of how their target
  audience actually browses their products. 
</p>
<p>
  Perhaps it seems a little silly to analyze the <em>usability</em> (and sniffability) 
  of scented candles. After all, candles come cheap. If you buy the wrong one, you can
  just buy another one next time. However, I would argue that a few simple packaging 
  changes can make all the difference in the world when it comes to making a candle easy
  to smell.
</p>
<p>
  And with that, I&#8217;d like to show you a few examples of what I found during my candle adventures.
</p>

<h3>First, the Good</h3>
<p>
  The companies that make these first 3 candles clearly <em>get it</em>. The packaging is easy 
  to open without breaking and one candle brand even includes holes to allow sniffing without
  opening the packaging. This is how candle packaging <em>should</em> be designed.
</p>
<p>
  <img src="/images/blog/candles/soy_candle.jpg" title="A good candle" alt="A good candle" />
  <img src="/images/blog/candles/lume_candle.jpg" title="A good candle" alt="A good candle" />
  <img src="/images/blog/candles/tea_candle.jpg" title="A good candle" alt="A good candle" />
</p>

<h3>Now, the Bad</h3>
<p>
  I&#8217;m not a candle expert, so I can&#8217;t tell you why so many candles come in glass jars. What I can 
  tell you is that glass jars that aren&#8217;t easy to open make for a bad candle browsing experience.
  Not the worst candle browsing experience, mind you. That experience is reserved for the candles
  below.
</p>
<p>
  <img src="/images/blog/candles/glass_candles.jpg" title="Some bad candles" alt="Some bad candles" />
</p>

<h3>And finally, the Ugly</h3>
<p>
  Two types of candles, and two types of impossible to preview packaging.
  Let&#8217;s hope the description on the package is vivid enough to evoke an accurate scent in the 
  consumer&#8217;s mind. Otherwise, you&#8217;re really rolling the dice when you choose to buy a candle that you
  can&#8217;t actually smell.
</p>
<p>
  <img src="/images/blog/candles/oil.jpg" title="An ugly candle" alt="An ugly candle" />
  <img src="/images/blog/candles/sticks.jpg" title="Some ugly candles" alt="Some ugly candles" />
</p>

<p>
  User experience is a hot topic in the world of web design right now. And usability certainly is 
  key to making a good website. However, a good user experience is vital everywhere. Even when it 
  comes to things as trivial as candle shopping. I&#8217;d like to think that the candle makers who took the 
  time to truly consider how their customers would seek out their products will be rewarded with success. 
</p>
<p>
  And yes, I bought one of the easier to sniff candles.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2010/05/03/usability-browsability-andsniffability/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My Naive Apple Tablet Predictions</title>
		<link>http://www.mattephraim.com/blog/2010/01/27/my-naive-apple-tablet-predictions/</link>
		<comments>http://www.mattephraim.com/blog/2010/01/27/my-naive-apple-tablet-predictions/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 07:14:55 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[apple]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=90</guid>
		<description><![CDATA[
  Being somewhat of an Apple fanboy, I thought it might be fun
  come up with a list of Apple announcement predictions before
  the official tablet(?) announcement later today.

   
  I haven&#8217;t been following any of the rumor sites lately, so my 
  predictions come from complete ignorance. [...]]]></description>
			<content:encoded><![CDATA[<p>
  Being somewhat of an Apple fanboy, I thought it might be fun
  come up with a list of Apple announcement predictions before
  the official tablet(?) announcement later today.
</p>
<p>   
  I haven&#8217;t been following any of the rumor sites lately, so my 
  predictions come from complete ignorance. Nevertheless, what 
  follows are my completely baseless guesses and crazy dreams about 
  what Steve Jobs will introduce today. 
</p>

<h3>Naive Apple Tablet Predictions</h3>
<ul class="list">
  <li>
    Apple will introduce not just a tablet computer or also-ran
    ebook reader, but a completely new class of device, or rather, 
    line of devices. Steve Jobs will give a rundown of past innovations
    like the printing press, the personal computer, the Internet and 
    finally the new Apple device. He will be dismissive of the terms
    &#8220;tablet&#8221; and &#8220;ebook reader&#8221; because of their limited scope and demonstrate
    how the Apple device goes forward into uncharted territory.
  </li>
  <li>
    The device will be thinner than any ebook reader or tablet currently on the market.
    It will be made of metal, probably aluminum and will feel very solid.
    It will also have a full color touch screen that covers almost the entire
    front side of the device, with practically no frame around the edges. It won&#8217;t look 
    like a larger version of the iPhone. It will be much more visually stunning and 
    innovative.
  </li>
  <li>
    The new line of devices won&#8217;t follow the &#8220;i&#8221; naming convention. So, no iTab or iSlab or 
    anything along those lines. Rather, the new devices will have names 
    like &#8220;Slate&#8221; and &#8220;Slate Pro&#8221;, with a small model targeted at consumers and 
    a bigger model targeted at pro users. The iPhone will also be updated to support 
    some of the features that the new devices offer.
  </li>
  <li>
    It doesn&#8217;t seem likely that the new device will use e-paper, as it will probably
    still need to function somewhat like a traditional computer. However, I could see
    the new device featuring a technology like OLED, which would allow for a high contrast screen
    that is also low power.  
  </li>
  <li>
    The touch screen on the device will be amazing. The responsiveness, multi touch
    and included software will raise the bar for touch screens and tablets to the 
    next level, similar to what the iPhone did for smartphones. 
  </li>
  <li>
    The device will use solid state for storage and will have an impressive amount
    of storage space for a device so thin. 
  </li>
  <li>
    Battery life will be amazing. Something like 10 to 15 hours on a charge and even longer
    when in a lower power mode. 
  </li>
  <li>
    Apple will announce a list of partnerships with magazines like Time and newspapers like the 
    New York Times for a new type of subscription that allows users to subscribe to a newspaper
    or magazine through the device and receive the latest copy wirelessly. The Media Store (maybe?) version 
    of a magazine like Time will look nearly identical to the print version, but will also 
    contain interactive ads, supplemental videos and links to related content online. Subscription
    fees will be in the area of $10 for most media offered.
  </li>
  <li>
    The new Media Store will also offer enhanced versions of books. The books will function similar
    to the way they do on most e-readers, but the Apple device will offer a new level of interactivity
    with the books. It will likely also include video and links to online content within books, just like the 
    the other types of media.
  </li>
  <li>
    Finally, Apple will overhaul iTunes. The name &#8220;iTunes&#8221; is no longer relevant and hasn&#8217;t been for a long time.
    The existing iTunes software will be reworked into a new application that manages the different types of 
    content that can be downloaded to the Apple device as well as the content on regular Apple computers and iPhones. 
  </li>
</ul>

<p>These are my pipe dreams. In reality, I expect something a lot closer to a big fat iPhone</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2010/01/27/my-naive-apple-tablet-predictions/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Draggability for the Raphaël Library</title>
		<link>http://www.mattephraim.com/blog/2009/10/31/draggability-for-the-raphael-library/</link>
		<comments>http://www.mattephraim.com/blog/2009/10/31/draggability-for-the-raphael-library/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 07:05:39 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=86</guid>
		<description><![CDATA[
	I&#8217;ve been using the Raphaël JavaScript library a lot lately
	for a JavaScript SVG project I&#8217;ve been working on. It&#8217;s easy to use and eases a lot of the pain of using 
	JavaScript with SVG. However, I eventually came to a point where I needed to have
	SVG elements that could be dragged around on the Raphael [...]]]></description>
			<content:encoded><![CDATA[<p>
	I&#8217;ve been using the <a href="http://raphaeljs.com/">Raphaël</a> JavaScript library a lot lately
	for a JavaScript SVG project I&#8217;ve been working on. It&#8217;s easy to use and eases a lot of the pain of using 
	JavaScript with SVG. However, I eventually came to a point where I needed to have
	SVG elements that could be dragged around on the Raphael canvas. After looking around for a 
	good plugin that would allow me to do what I wanted, I decided that I needed to write my own.
	The result is the <a href="http://github.com/mephraim/raphael.draggable">raphael.draggable</a>
	plugin.
</p>
<p>
	raphael.draggable is fairly straightforward to use. You simply need to call the 
	<strong>draggable.enable()</strong> on the raphael object you would like to enable the plugin
	for. raphael.draggable works for all raphael elements and for raphael sets as well. Sets that have
	raphael.draggable enabled will drag all elements in the set whenever any element in the set is
	dragged.
</p>
<h3>Using the raphael.draggable plugin</h3>
<div class="code_block">
<span class="code_label"></span>
<pre class="prettyprint"><code> // Creating a canvas and enabling draggable for it
var paper = Raphael(0,0, 800, 600);
paper.draggable.enable();

// Creating a rectangle element and enabling draggable for it
var rect = paper.rect(0, 0, 100, 100);
rect.attr({ 'fill': 'white' });
rect.draggable.enable();

// Creating a set and enabling draggable for it
var set = paper.set();
set.draggable.enable();
set.push(rect);

</code></pre>
</div>
<p>
    Currently, raphael.draggable has only been tested for Firefox and Safari. Those are the only two
    browsers I needed to test it for. Source code and documentation are available on 
    <a href="http://github.com/mephraim/raphael.draggable">github</a>. Constructive criticism, 
    and especially constructive contributions to the code are welcome!
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/10/31/draggability-for-the-raphael-library/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An Old Friend</title>
		<link>http://www.mattephraim.com/blog/2009/10/28/an-old-friend/</link>
		<comments>http://www.mattephraim.com/blog/2009/10/28/an-old-friend/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 03:24:43 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[photography]]></category>

		<category><![CDATA[urban exploring]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=83</guid>
		<description><![CDATA[
    Last week, the city of Chicago announced 
    that demolition of the Michael Reese Hospital campus would begin. And, unlike so many delayed city projects, the demolition 
    of the campus has indeed started.


    When I first explored the Michael Reese campus, [...]]]></description>
			<content:encoded><![CDATA[<p>
    Last week, the city of Chicago <a href="http://abclocal.go.com/wls/story?section=news/local&#038;id=7076465">announced</a> 
    that demolition of the Michael Reese Hospital campus would begin. And, unlike so many delayed city projects, the demolition 
    of the campus has indeed started.
</p>
<p>
    When I first explored the Michael Reese campus, one of the buildings that stood out to me was the 
    Friend Pavilion. At first glance, it looked like a simple, concrete structure. Small and nestled
    in a grove of trees and gardens, I didn&#8217;t immediately pay much attention to it among the other large, modern structures.
    However, when I got closer, I was drawn in by Friend&#8217;s expansive windows and simple interior.
</p>
<p>
    Friend was built as a place where patients could rest and be rehabilitated. When I was finally able to explore
    the building from the inside, I struck by how truly peaceful the interior was. Despite being a hospital in the 
    middle of a bustling metropolis, the world inside of the Friend Pavilion was surprisingly tranquil and relaxing. 
    The simple, open rooms and picturesque landscape outside made for a very appealing place to rest. 
    Pictures of the building don&#8217;t do it justice.
</p>
<p>
    Not so long ago, not even that much more than a year ago, patients were still being served by the Friend Pavilion.
    When I first became interested in the hospital campus in early 2008, I visited the Friend pavilion several times and noted that it 
    certainly wasn&#8217;t in pristine condition. But, at the same time, the building wasn&#8217;t in the dilapidated condition that the city of Chicago
    pretends that it was in. It was only through purposeful negligence by the city that Friend (like many of the other 
    buildings on the campus) was allowed to deteriorate.
</p>
<p>
    As sad as it makes me to say it, the building never will be restored or recognized for the sanctuary that it was and could have been.
    This week, the Friend Pavilion was 
    <a href="http://featuresblogs.chicagotribune.com/theskyline/2009/10/chicago-lets-its-savage-side-show-first-gropius-building-demolished-at-michael-reese-.html">
    destroyed</a> with little fanfare.
</p>
<h3>The Friend Pavilion</h3>
<p>
    <a href="http://www.flickr.com/photos/brownfields/3605775617/" title="Yes, they'll all come to see me... by Matt Ephraim, on Flickr">
        <img src="http://farm4.static.flickr.com/3555/3605775617_06a31e49cf.jpg" width="500" height="375" alt="Yes, they'll all come to see me..." />
    </a>
</p>
<p>
    <a href="http://www.flickr.com/photos/brownfields/3605771737/" title="At my window sad &amp; lonely by Matt Ephraim, on Flickr">
        <img src="http://farm4.static.flickr.com/3659/3605771737_8d90aafc41.jpg" width="500" height="375" alt="At my window sad &amp; lonely" />
    </a>
</p>
<p>
    <a href="http://www.flickr.com/photos/brownfields/3606591800/" title="Well I was thinking... by Matt Ephraim, on Flickr">
        <img src="http://farm4.static.flickr.com/3376/3606591800_94303848a1.jpg" width="500" height="374" alt="Well I was thinking..." />
    </a>
<p>
   <a href="http://www.flickr.com/photos/brownfields/sets/72157619419217442/">More Michael Reese Photos</a> 
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/10/28/an-old-friend/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The End of Michael Reese Hospital</title>
		<link>http://www.mattephraim.com/blog/2009/10/23/the-end-of-michael-reese-hospital/</link>
		<comments>http://www.mattephraim.com/blog/2009/10/23/the-end-of-michael-reese-hospital/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 22:09:57 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[photography]]></category>

		<category><![CDATA[urban exploring]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=81</guid>
		<description><![CDATA[
  The Michael Reese Hospital campus saga is one that I&#8217;ve been following ever since I stumbled on the campus
  a little over a year ago. I&#8217;ve been following the efforts that preservationists have 
  been making to save the historically significant Walter Gropius buildings on the site. I handed out literature [...]]]></description>
			<content:encoded><![CDATA[<p>
  The Michael Reese Hospital campus <a href="http://www.savemrh.com/">saga</a> is one that I&#8217;ve been following ever since I stumbled on the campus
  <a href="/blog/2008/05/04/spring-exploring-time/">a little over a year ago</a>. I&#8217;ve been following the efforts that preservationists have 
  been making to save the historically significant Walter Gropius buildings on the site. I handed out literature and attended 
  <a href="http://www.webitects.com/blog/posts/2">community meetings</a>, hoping that some of the buildings would be saved. In the end, it 
  looks like most of the campus will still be lost.
</p>
<p>
  This week, despite Chicago losing its bid for the 2016 Olympics, demolition of the campus begins. There is 
  <a href="http://www.chicagobreakingnews.com/2009/10/city-might-spare-a-2nd-michael-reese-building.html">hope</a> that at least one of the
  buildings, the Singer Pavilion, might be saved. But, alas, the rest of the campus may be lost. 
</p>
<h3>The Singer Pavilion</h3>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3605776979/" title="Singer Pavilion by Matt Ephraim, on Flickr">
    <img src="http://farm4.static.flickr.com/3308/3605776979_b5d95b0710.jpg" width="500" height="375" alt="Singer Pavilion" />
  </a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3606596174/" title="Singer Pavilion by Matt Ephraim, on Flickr">
    <img src="http://farm3.static.flickr.com/2438/3606596174_817b11616e.jpg" width="382" height="500" alt="Singer Pavilion" />
  </a>
</p>
<p>
  Thanks to the <a href="http://www.savemrh.com/">Gropius in Chicago Coalition</a> and the rest of the architectural preservation
  community for all of your efforts in trying to save these buildings.
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/10/23/the-end-of-michael-reese-hospital/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Introducing GhostscriptSharp</title>
		<link>http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/</link>
		<comments>http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 05:46:22 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ghostscript]]></category>

		<category><![CDATA[GhostscriptSharp]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=75</guid>
		<description><![CDATA[
A few months ago, I posted some code that I had used to generate thumbnail images from PDF files. Before writing the code, I had searched high and low for some simple code that would allow me to take a PDF file and generate a thumbnail from the first page of that PDF file. Unfortunately, [...]]]></description>
			<content:encoded><![CDATA[<p>
A few months ago, <a href="http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/">I posted some code</a> that I had used to generate thumbnail images from PDF files. Before writing the code, I had searched high and low for some simple code that would allow me to take a PDF file and generate a thumbnail from the first page of that PDF file. Unfortunately, I didn&#8217;t find many C# solutions. The best I could find was the Ghostscript library and some references to using it from C#. 
</p>
<p>
In my previous post, I talked about some of the issues I had with using Ghostscript from the command line. It wasn&#8217;t difficult, but it wasn&#8217;t something that I wanted to do. Finally, I ended up writing a C# wrapper that would talk to the Ghostscript library and generate the PDF thumbnail files that I wanted. I figured it was a common enough issue that at least someone else would find it useful.
</p>
<p>
Almost immediately, that post became the most popular post on my site. I still get 10 or so Google hits from it every day. So, I figured I&#8217;d clean up the code a little bit (which involved some helpful changes that people suggested in the comments of my post) and release it to the world.
</p>
<p> 
I decided to call the library GhostscriptSharp and you can find it on <a href="http://github.com/mephraim/ghostscriptsharp/tree/master">Github</a>. There are probably a lot of things that could be added or cleaned up, so if you&#8217;d like to contribute, feel free to create your own fork and let me know if you have changes I could pull in.
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Portland Pictures</title>
		<link>http://www.mattephraim.com/blog/2009/03/30/portland-pictures/</link>
		<comments>http://www.mattephraim.com/blog/2009/03/30/portland-pictures/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 20:51:03 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=73</guid>
		<description><![CDATA[
  


  


  


  Seattle/Portland
]]></description>
			<content:encoded><![CDATA[<p>
  <a href="http://www.flickr.com/photos/brownfields/3394700276/" title="Little Boxes by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3434/3394700276_eaafcf632a.jpg" width="500" height="333" alt="Little Boxes" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3393894987/" title="Seaweed by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3649/3393894987_35609351a4.jpg" width="333" height="500" alt="Seaweed" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3394705066/" title="Geometry by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3640/3394705066_c0117c07b0.jpg" width="333" height="500" alt="Geometry" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/sets/72157615972383627/">Seattle/Portland</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/03/30/portland-pictures/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Seattle Pictures</title>
		<link>http://www.mattephraim.com/blog/2009/03/29/seattle-pictures/</link>
		<comments>http://www.mattephraim.com/blog/2009/03/29/seattle-pictures/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 20:36:01 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[photography]]></category>

		<category><![CDATA[Seattle]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=70</guid>
		<description><![CDATA[
  


  


  


  Seattle/Portland
]]></description>
			<content:encoded><![CDATA[<p>
  <a href="http://www.flickr.com/photos/brownfields/3393887537/" title="Flying over Seattle by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3626/3393887537_b3b9e06809.jpg" width="500" height="333" alt="Flying over Seattle" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3393888939/" title="Moss Handle by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3597/3393888939_e89858c983.jpg" width="500" height="329" alt="Moss Handle" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/3394696386/" title="Windows XP by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3589/3394696386_6f25bac4c0.jpg" width="333" height="500" alt="Windows XP" /></a>
</p>
<p>
  <a href="http://www.flickr.com/photos/brownfields/sets/72157615972383627/">Seattle/Portland</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/03/29/seattle-pictures/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Dynamic Rake Tasks</title>
		<link>http://www.mattephraim.com/blog/2009/02/05/dynamic-rake-tasks/</link>
		<comments>http://www.mattephraim.com/blog/2009/02/05/dynamic-rake-tasks/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 00:58:25 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=64</guid>
		<description><![CDATA[
	This is a quick little Ruby trick that I thought was pretty neat. 
	If you have a Rake file and you have a bunch of similar tasks that 
	you don&#8217;t want to have to write by hand, you can dynamically 
	generate the Rake tasks by using a little bit of Ruby code.



	For example, maybe I [...]]]></description>
			<content:encoded><![CDATA[<p>
	This is a quick little Ruby trick that I thought was pretty neat. 
	If you have a Rake file and you have a bunch of similar tasks that 
	you don&#8217;t want to have to write by hand, you can dynamically 
	generate the Rake tasks by using a little bit of Ruby code.
</p>

<p>
	For example, maybe I want to change the contents of a 
	few different directories on my file system. And say that
	I want to have a different rake task for each directory,
	so that I can type something like this:
</p>

<div class="code_block">
	<span class="code_label">Command line</span>
	<pre class="prettyprint"><code>rake modify:songs</code></pre>
</div>

<p>
	Or like this:
</p>

<div class="code_block">
	<span class="code_label">Command line</span>
	<pre class="prettyprint"><code>rake modify:documents</code></pre>
</div>

<p>
	With a small number of directories, it wouldn&#8217;t be a big deal
	to write a task for each directory. But, if I have 100 directories,
	that might get to be a little bit tedious. So, instead of writing the
	tasks manually, I&#8217;ll have Ruby do it: 
</p>

<div class="code_block">
	<span class="code_label">rakefile.rb</span>
	<pre class="prettyprint"><code>namespace :modify do
	[:music, :documents, :application, :home].each do |directory|
		task directory do
			change_contents(directory)
		end
	end
end</code></pre>
</div>

<p>
	In the code above I&#8217;m taking an array of 4 directories and using that array to call the Rake <strong>task</strong>
	function to create a new task for each directory. I&#8217;m also passing the name of the directory on to a function
	that changes the contents of the specific directory.
</p>

<p>
	It&#8217;s a pretty simple trick, but it&#8217;s definitely come in handy for me.
</p>
	]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/02/05/dynamic-rake-tasks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Syntax Highlighting is Fun</title>
		<link>http://www.mattephraim.com/blog/2009/02/03/syntax-highlighting-is-fun/</link>
		<comments>http://www.mattephraim.com/blog/2009/02/03/syntax-highlighting-is-fun/#comments</comments>
		<pubDate>Tue, 03 Feb 2009 22:58:52 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[general programming]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=62</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<a href="http://www.flickr.com/photos/brownfields/3251868894/" title="JavaScript by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3434/3251868894_c44d919bd5.jpg" width="500" height="419" alt="JavaScript" /></a>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/02/03/syntax-highlighting-is-fun/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Simple C# Wrapper for Ghostscript</title>
		<link>http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/</link>
		<comments>http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 02:54:10 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<category><![CDATA[Ghostscript]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=47</guid>
		<description><![CDATA[Update:

This post has become somewhat popular (relative to my other posts anyway), so I decided to take the code and release it as an open source library. More information here


PDF thumbnails with Ghostscript

	I&#8217;ve been looking for a while now for a simple solution for generating thumbnail images from PDF files. 
	I wanted something that would [...]]]></description>
			<content:encoded><![CDATA[<strong>Update:</strong>
<p>
This post has become somewhat popular (relative to my other posts anyway), so I decided to take the code and release it as an open source library. <a href="http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/">More information here</a>
</p>

<h3>PDF thumbnails with Ghostscript</h3>
<p>
	I&#8217;ve been looking for a while now for a simple solution for generating thumbnail images from PDF files. 
	I wanted something that would let me programmatically load in a PDF file, choose a page, and generate a
	thumbnail from that page. As far as I can tell, there are only a few open source options and of those options
	I haven&#8217;t been able to find one that I could get working with C#.
</p>

<p> 
	After seeing it recommended a few times, I decided take a look at <a href="http://pages.cs.wisc.edu/~ghost/">Ghostscript</a>. 
	Ghostscript is an open source interpreter for Postscript and PDF files. Among other things, Ghostscript allows you generate
	images from PDF pages. Which is exactly what I needed.
</p>

<p>
	Ghostscript is a tool that can be used from the command line, which is how most of the examples I&#8217;ve found online have used it.
	Unfortunately, this is what a call to Ghostscript looks like:
</p>

<div class="code_block">
<span class="code_label"></span>
<pre class="prettyprint"><code>gs -q -dQUIET -dPARANOIDSAFER  -dBATCH -dNOPAUSE \          
-dNOPROMPT -dMaxBitmap=500000000 -dFirstPage=1 \
-dAlignToPixels=0 -dGridFitTT=0 -sDEVICE=jpeg \
-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r100x100 \
-sOutputFile=output.jpg input.pdf
</code></pre>
</div>

<p>
	Not pretty. Luckily, I needed to automate the task of creating the thumbnails, so I wouldn&#8217;t need to manually generate the parameters
	to be passed to the command line tool. However, I still felt like there might be a better way to hook into Ghostscript&#8217;s functionality.
	So, I decided to take advantage of the <a href="http://pages.cs.wisc.edu/~ghost/doc/svn/API.htm">API</a> provided by Ghostscript by 
	writing a simple C# wrapper for the API to use in my current ASP.Net project.
</p>

<h3>A simple Ghostscript wrapper</h3>
<p>
	The first thing I needed was the Windows version of the Ghostscript DLL, which can be obtained <a href="http://pages.cs.wisc.edu/~ghost/doc/GPL/gpl863.htm">here</a>.
	Once I included the DLL in my project, I needed to expose the unmanaged API functions to my C# wrapper function.
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>[DllImport("gsdll32.dll", EntryPoint = "gsapi_new_instance")]
private static extern int CreateAPIInstance(out IntPtr pinstance, 
                                        IntPtr caller_handle);

[DllImport("gsdll32.dll", EntryPoint = "gsapi_init_with_args")]
private static extern int InitAPI(IntPtr instance, int argc, IntPtr argv);

[DllImport("gsdll32.dll", EntryPoint = "gsapi_exit")]
private static extern int ExitAPI(IntPtr instance);

[DllImport("gsdll32.dll", EntryPoint = "gsapi_delete_instance")]
private static extern void DeleteAPIInstance(IntPtr instance);</code></pre>
</div>

<p>
	Above, I complained about the long list of parameters that need to be passed to the Ghostscript command line tool. 
	Those same parameters need to be passed to the API, so the next thing I did was create a function that wrapped up
	the functionality for building the list of parameters. For simplicity, I left in a lot of default parameters, but
	the function could be expanded later on to allow more specific parameters. 
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>
private string[] GetArgs(string inputPath, string outputPath, 
                         int firstPage, int lastPage, int width, int height)
{
    return new[]
    {
        // Keep gs from writing information to standard output
        "-q",                     
        "-dQUIET",
       
        "-dPARANOIDSAFER", // Run this command in safe mode
        "-dBATCH", // Keep gs from going into interactive mode
        "-dNOPAUSE", // Do not prompt and pause for each page
        "-dNOPROMPT", // Disable prompts for user interaction           
        "-dMaxBitmap=500000000", // Set high for better performance
        
        // Set the starting and ending pages
        String.Format("-dFirstPage={0}", firstPage),
        String.Format("-dLastPage={0}", lastPage),   
        
        // Configure the output anti-aliasing, resolution, etc
        "-dAlignToPixels=0",
        "-dGridFitTT=0",
        "-sDEVICE=jpeg",
        "-dTextAlphaBits=4",
        "-dGraphicsAlphaBits=4",
        String.Format("-r{0}x{1}", width, height),

        // Set the input and output files
        String.Format("-sOutputFile={0}", outputPath),
        inputPath
    };
}</code></pre></div>

<p>
	Once I had a way of creating a list of parameters, I could start using the Ghostscript API functions. I created a function called <strong>CallAPI</strong> that would
	accept an array of parameters and use them to call the Ghostcript API. 
</p>
<p>
	The function I created for building a list of arguments returned an array
	of strings, but to use the API I needed to convert each of those parameters into a ANSI null terminated byte array (I added the code I used to do this to the bottom of this post). Then I needed to allocate some space
	in memory for each of those arguments and get pointers to each one of them. 
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>var argStrHandles = new GCHandle[args.Length];
var argPtrs = new IntPtr[args.Length];

// Create a handle for each of the arguments after 
// they've been converted to an ANSI null terminated
// string. Then store the pointers for each of the handles
for (int i = 0; i < args.Length; i++)
{
    argStrHandles[i] = GCHandle.Alloc(StringToAnsi(args[i]), GCHandleType.Pinned);
    argPtrs[i] = argStrHandles[i].AddrOfPinnedObject();
}

// Get a new handle for the array of argument pointers
var argPtrsHandle = GCHandle.Alloc(argPtrs, GCHandleType.Pinned);</code></pre></div>

<p>
	Then, to use the newly converted parameters, I needed to create an instance of the Ghostscript API and pass them into the initialization function.
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>// Get a pointer to an instance of the GhostScript API 
// and run the API with the current arguments
IntPtr gsInstancePtr;
CreateAPIInstance(out gsInstancePtr, IntPtr.Zero);
InitAPI(gsInstancePtr, args.Length, argPtrsHandle.AddrOfPinnedObject());</code></pre></div>

<p>
	The call to <strong>InitAPI</strong> runs Ghostscript and generates any requested files at the output path. 
</p>
<p> 
	Now the only remaining thing I needed to do was clean up the memory that was allocated for the API. 
	To handle this, I wrote a cleanup function that takes in the items that need to be cleaned up.
	The API provides some cleanup functions, so I called those in the cleanup function as well.
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>private void Cleanup(GCHandle[] argStrHandles, GCHandle argPtrsHandle, 
                                       IntPtr gsInstancePtr)
{
    for (int i = 0; i < argStrHandles.Length; i++)
        argStrHandles[i].Free();

    argPtrsHandle.Free();

    ExitAPI(gsInstancePtr);
    DeleteAPIInstance(gsInstancePtr);
}</code></pre></div>

<p>
	One last thing I added to the wrapper was a simple function for generating thumbnails from a source PDF file. Technically, I could have just used the 
	CallAPI function to do that, but I wanted to hide the details of working with the API from code outside of the wrapper class.
</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>
public void GeneratePageThumbs(string inputPath, string outputPath, 
                              int firstPage, int lastPage, int width, int height)
{
    CallAPI(GetArgs(inputPath, outputPath, firstPage, lastPage, width, height));
}</code></pre></div>

<p>
	The <strong>GeneratePageThumbs</strong> doesn&#8217;t do anything other than calling the CallAPI function. However, in the future, I&#8217;d like to 
	provide other functions that use the Ghostscript API as well. If anyone has any ideas for improving the code, drop me line. 
</p>	

<p><strong>Update:</strong> Here is the code I used to convert the arguments to null terminated byte arrays. There might be a better way to do this in .Net, this is just the quick solution I&#8217;m using.</p>

<div class="code_block">
<span class="code_label">C#</span>
<pre class="prettyprint"><code>public static byte[] StringToAnsi(string original)
{
       var strBytes = new byte[original.Length + 1];
       for (int i = 0; i < original.Length; i++)
            strBytes[i] = (byte)original[i];
        
        strBytes[original.Length] = 0;
        return strBytes;
}</code></pre>
</div>

<p>
<strong>Update:</strong> This code has been <a href="http://www.mattephraim.com/blog/2009/07/08/introducing-ghostscriptsharp/">open sourced</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/01/06/a-simple-c-wrapper-for-ghostscript/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Treating C# Like A Scripting Language</title>
		<link>http://www.mattephraim.com/blog/2009/01/02/treating-c-like-a-scripting-language/</link>
		<comments>http://www.mattephraim.com/blog/2009/01/02/treating-c-like-a-scripting-language/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 02:12:29 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=45</guid>
		<description><![CDATA[Creating code on the fly

	One thing that I like about scripting languages is their ability to dynamically 
	modify code during runtime. Ruby and JavaScript, for example, both give you the ability
	to load in code directly from a string and execute it as part of your program. 
	While that sort of thing can be dangerous, it [...]]]></description>
			<content:encoded><![CDATA[<h3>Creating code on the fly</h3>
<p>
	One thing that I like about scripting languages is their ability to dynamically 
	modify code during runtime. Ruby and JavaScript, for example, both give you the ability
	to load in code directly from a string and execute it as part of your program. 
	While that sort of thing can be dangerous, it also gives you access to some really fun
	metaprogramming techniques. 
</p>
<p>
	While working on a simple DSL for one my ASP.NET sites, I started to wonder if C# had 
	some similar functionality that I could take advantage of. In particular, I wanted to load
	in C# code from a file and execute the code inside of it. What I found was that C# does
	indeed have the ability to accomplish this task, albeit in sort of an ugly way. 
</p>

<h3>Using C# to compile C#</h3>
<p>
	Most scripting languages give you a function that allows you directly evaluate a block or raw
	string of code as soon as it&#8217;s encountered. Because C# is a compiled language, it&#8217;s a little bit
	more complicated. The C# code needs to be compiled into an assembly before it can be used. And then
	classes from the compiled code can be instantiated directly from the assembly. 
</p>
<p>
	C# code can be compiled on the fly with an instance of the
	<strong><a href="http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx">CSharpCodeProvider</a></strong>
	class (there&#8217;s a <a href="http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.vbcodeprovider.aspx">similar class</a> 
	for VB.Net as well). Additionally, you can create an instance of the
	<strong><a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.aspx">CompilerParameters</a></strong> class, which contains a collection of parameters that
	will be used when compiling your code. In the example below, I&#8217;m creating a new C# compiler and a set of parameters
	that will tell it not to create an assembly file, but to instead compile the new assembly in memory. I also tell 
	the compiler to include System.dll as a reference assembly.
</p>

<div class="code_block">
	<span class="code_label">C#</span>
	<pre class="prettyprint"><code>// Create a new instance of the C# compiler
var compiler = new CSharpCodeProvider();

// Create some parameters for the compiler
var parms    = new System.CodeDom.Compiler.CompilerParameters
{
    GenerateExecutable      = false,
    GenerateInMemory        = true
};
parms.ReferencedAssemblies.Add("System.dll");</code></pre>
</div>

<p>
	Once a C# compiler has been created, you can use it to compile raw source into an assembly. 
	CSharpCodeProvider allows you to compile code from a variety of sources. In the example below, 
	I&#8217;m using the <strong>CompileAssemblyFromSource</strong> method to compile my code directly from an array of strings. 
	CompileAssemblyFromSource will look at the code provided and return an instance of the 
	<strong><a href="http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerresults.aspx">CompilerResults</a></strong> 
	class.
</p>

<div class="code_block">
	<span class="code_label">C#</span>
	<pre class="prettyprint"><code>// Try to compile the string into an assembly
var results = compiler.CompileAssemblyFromSource(parms, new string[]
{@" using System;

    class MyClass
    {
        public void Message(string message)
        {
            Console.Write(message);
        }               
    }"});</code></pre>
</div>

<p>
	One thing to note is that the compilation method will complete regardless of whether or not the code has compiled successfully.
	To make sure you code has compiled, you need to check the <strong>Errors</strong> collection that is part 
	of the CompilerResults instance returned by CompileAssemblyFromSource. If there were no errors, the code
	was compiled successfully and you can begin using the assembly.
</p>

<h3>Using the compiled code</h3>
<p>
	Once your code is compiled into an assembly, you can use that assembly to create instances of classes from your source code
	and use reflection to invoke methods and get and set properties of those classes. In the example below, I&#8217;m creating 
	an instance of <strong>MyClass</strong> and storing it as an object. I&#8217;m then using reflection to invoke the
	<strong>Message</strong> method on the class. 
</p>

<div class="code_block">
	<span class="code_label">C#</span>
	<pre class="prettyprint"><code>// If there weren't any errors get an instance of "MyClass" and invoke
// the "Message" method on it
if (results.Errors.Count == 0)
{
    var myClass = results.CompiledAssembly.CreateInstance("MyClass");
    myClass.GetType().
            GetMethod("Message").
            Invoke(myClass, new []{ "Hello World!" });
}</code></pre>
</div>

<p>
	It&#8217;s not exactly pretty, but it gets the job done. Scripting languages make it much easier to accomplish this sort of task,
	but it&#8217;s still nice to see that it can be done in C#. 
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2009/01/02/treating-c-like-a-scripting-language/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Quick Little Extension to the Spreadsheet Gem</title>
		<link>http://www.mattephraim.com/blog/2008/12/31/a-quick-little-extension-to-the-spreadsheet-gem/</link>
		<comments>http://www.mattephraim.com/blog/2008/12/31/a-quick-little-extension-to-the-spreadsheet-gem/#comments</comments>
		<pubDate>Thu, 01 Jan 2009 00:58:13 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=40</guid>
		<description><![CDATA[The problem

	One of the most tedious tasks I have to complete at work is importing excel spreadsheets into a database. Often, a client will give me 
	a spreadsheet of data that needs to be imported into an existing database. And, if I&#8217;m really lucky, the data needs to be reformatted
	before it can be imported.  [...]]]></description>
			<content:encoded><![CDATA[<h3>The problem</h3>
<p>
	One of the most tedious tasks I have to complete at work is importing excel spreadsheets into a database. Often, a client will give me 
	a spreadsheet of data that needs to be imported into an existing database. And, if I&#8217;m really lucky, the data needs to be reformatted
	before it can be imported.  I tried a few different methods of accomplishing this task before I settled on using the Ruby 
	<a href="http://rubyforge.org/projects/spreadsheet/">Spreadsheet</a> gem to import and format the spreadsheet data. I then use the 
	Ruby <a href="http://ruby-dbi.rubyforge.org/">DBI</a> library to import the data into a database. 
</p>
<p>
	Spreadsheet works great for reading data from a spreadsheet file, but one thing that always annoyed me was that I needed to know the index
	of a column before I could get the value from it. So, for example, if a spreadsheet stored the value for <strong>First Name</strong> in 
	the 3rd column, I would need to know that the 3rd slot in each row array represented the the first name value. I thought it would be really 
	nice if I could access that value for a row by saying something like <strong>row[:first_name]</strong>. I had a little bit of extra time over 
	the holidays, so I decided to see if it would be possible to make this functionality happen.
</p>
<h3>My solution</h3>
<p>
	The first thing I did was create my own row class for the Spreadsheet library. I decided that I would create a new class called <strong>HashRow</strong>
	that would allow you to access the values of each row by using symbols that represented each column header or by using the original method of accessing
	row values with an index number. For simplicity, I assumed that the first row of the spreadsheet was the header row. I also simplified values for each
	column header by stripping out any characters that couldn&#8217;t be represented by a symbol. So, a header value of <strong>First Name</strong> becomes 
	<strong>:first_name</strong>.
</p>
<p>
	I also added a few convenience methods to HashRow. The <strong>header?</strong> method returns true if the row is a header row and the
	<strong>empty?</strong> method returns true if the row is completely empty.
</p>
<div class="code_block">
	<span class="code_label">Ruby</span>
	<pre class="prettyprint"><code># Wraps Spreadsheet::Excel::Row row array with extra functionality
class Spreadsheet::HashRow < Spreadsheet::Excel::Row
	attr_reader :index
	
	# Keeps the original row value array 
	# and also creates a hash of values 
	def initialize(row, col_hash, index)
		@val_array = row
		@val_hash  = get_val_hash(col_hash)
		@index 	   = index
	end
	
	# Is this row the first row in the spreadsheet?
	def header?
		@index === 0
	end
	
	# Checks if every cell in the row is set to nil
	def empty?
		@val_array.compact.length === 0
	end
			
	# Returns the value in the row based on the index 
	# or key passed in. Integer values returns the row value 
	# by index in the array and symbols return the value 
	# for the symbol or string
	def [](value)
		if value.is_a? Integer
			@val_array[value]
		else
			@val_hash[value.to_s.downcase]
		end
	end
	
	private 
	
	# Uses a hash columns to build another hash for the 
	# values in the array with keys for the column heads
	def get_val_hash(col_hash)
		col_hash.keys.inject({}) do |acc, key|
			acc.merge(key => @val_array[col_hash[key]])
		end
	end
end</code></pre>
</div>
<p>
	Once I had my HashRow class, I needed to open the <strong>Spreadsheet::Excel::Worksheet</strong> class so that I could replace the 
	<strong>row</strong> method with a new method that returned an instance of the HashRow class. I aliased the old row method and 
	used it inside my new row method to pass in a reference to the original row array. 
	I also added a private method to help determine the index of each of column and a private method to format the column names. 
</p>
<div class="code_block">
	<span class="code_label">Ruby</span>
	<pre class="prettyprint"><code># Extends Spreadsheet::Excel::Worksheet so that the Rows become HashRows
class Spreadsheet::Excel::Worksheet		
	# Override the original row method with a new method 
	# that returns the custom HashRow class instead of an array
	alias_method :old_row, :row
	def row(value)
	    Spreadsheet::HashRow.new(old_row(value), get_col_indexes, value)
	end
		
	private
		
	# Returns a hash that contains key/value pairs for the column 
	# headers and the the index of each header
	def get_col_indexes
	    @col_indexes ||= old_row(0).inject({}) do |hash, cell|
	        hash.merge(get_col_key(cell.to_s) => hash.length)
	    end
	end
			
	# Converts the name of a column header to a 
        # specially formatted string
	def get_col_key(col)
	    col.gsub(/[\(\)]+/, "").
	         gsub(/\s/, "_").
	         downcase
	end
end</code></pre>
</div>
<p>
	Once I included my new spreadsheet extension file I could use the Spreadsheet library similar to the way I had used it 
	before, only now I had access to the row values by the row and index and by the column header name.
</p>
<div class="code_block">
	<span class="code_label">Ruby</span>
	<pre class="prettyprint"><code>Spreadsheet.open(FILE).worksheet(0).each do |row|
	unless row.empty? || row.header?
		puts row[:first_name]
		puts row[:last_name]
	end
end</code></pre>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/12/31/a-quick-little-extension-to-the-spreadsheet-gem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Screwing Around With Screw.Unit</title>
		<link>http://www.mattephraim.com/blog/2008/11/26/trying-out-screwunit/</link>
		<comments>http://www.mattephraim.com/blog/2008/11/26/trying-out-screwunit/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:24:34 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<category><![CDATA[screw.unit]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=35</guid>
		<description><![CDATA[I just started using the delightfully named Screw.Unit for JavaScript testing, and I have to say that, so far, I&#8217;m pretty pleased with it. Screw.Unit is a JavaScript testing framework that allows you to easily create and run unit tests for your JavaScript code. For example, here is a really simple hello world type test [...]]]></description>
			<content:encoded><![CDATA[<p>I just started using the delightfully named <a href="http://github.com/nkallen/screw-unit/tree/master">Screw.Unit</a> for JavaScript testing, and I have to say that, so far, I&#8217;m pretty pleased with it. Screw.Unit is a JavaScript testing framework that allows you to easily create and run unit tests for your JavaScript code. For example, here is a really simple hello world type test written with Screw.Unit:</p>

<div class="code_block">
   <span class="code_label">JavaScript/Screw.Unit</span>
<pre class="prettyprint"><code>describe("A simple hello world test", function()
{
    it("is a test for truth example", function()
    {
        expect(true).to(equal, true);
    };
};</code></pre>
</div>
<p>If I were to run the test on a page that had the framework loaded in, I&#8217;d get a nice pretty rundown of my tests, showing that the hello world test had indeed passed (true does, in fact, equal true).</p>
<p>One thing that I immediately wondered about was how the keywords in the framework worked. At first, I assumed they were global variables and was a little put off by that idea. Would functionality like &#8220;describe&#8221;, &#8220;expect&#8221; and &#8220;it&#8221; interfere with other code that happened to use those same function names or variables? Fortunately, I was surprised to find this code in the framework: 

<div class="code_block">
   <span class="code_label">JavaScript/Screw.Unit</span>
<pre class="prettyprint"><code>var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
var fn = new Function("matchers", "specifications",
  "with (specifications) { with (matchers) { " + contents + " } }"
);

fn.call(this, Screw.Matchers, Screw.Specifications);</code></pre>
</div>
<p>Located in the initialization portion of Screw.Unit, this cryptic looking piece of code is actually doing something very clever. It&#8217;s using the Function.toString() method to extract the content of the function wrapper around all of your tests. It&#8217;s then taking the contents of that function and creating a new function that is using the &#8220;with&#8221; keyword to execute your code in the context of the framework&#8217;s keywords and functions.</p>

<p>In other words, it&#8217;s taking your tests and tricking JavaScript into thinking that your test functions have access to the properties and methods stored in Screw.Matchers and Screw.Specifications. This gives you access to the framework functionality without leaking any variables into the global namespace.</p>

<p>That sort of cleverness gives me hope that JavaScript has a bright future ahead.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/11/26/trying-out-screwunit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Historic Night</title>
		<link>http://www.mattephraim.com/blog/2008/11/10/a-historic-night/</link>
		<comments>http://www.mattephraim.com/blog/2008/11/10/a-historic-night/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 05:03:49 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[photography]]></category>

		<category><![CDATA[Obama]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/?p=32</guid>
		<description><![CDATA[
On November 4th, 2008, I was given an amazing opportunity to witness history in Chicago&#8217;s Grant Park. I stood 50 feet away as Barack Obama gave his first speech as the president elect of the United States of America








]]></description>
			<content:encoded><![CDATA[<p>
On November 4th, 2008, I was given an amazing opportunity to witness history in Chicago&#8217;s Grant Park. I stood 50 feet away as Barack Obama gave his first speech as the president elect of the United States of America
</p>

<p><a href="http://www.flickr.com/photos/brownfields/3018780291/" title="A Light by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3160/3018780291_469719015d.jpg" width="500" height="333" alt="A Light" /></a></p>

<p><a href="http://www.flickr.com/photos/brownfields/3018779641/" title="First Family by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3230/3018779641_ac6f311c4d.jpg" width="500" height="333" alt="First Family" /></a></p>

<p><a href="http://www.flickr.com/photos/brownfields/3018775505/" title="Front Row by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3025/3018775505_e8ba0ed063.jpg" width="500" height="333" alt="Front Row" /></a></p>

<p><a href="http://www.flickr.com/photos/brownfields/3019618546/" title="Hope by Matt Ephraim, on Flickr"><img src="http://farm4.static.flickr.com/3289/3019618546_408d174e3c.jpg" width="500" height="333" alt="Hope" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/11/10/a-historic-night/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Speaking of Browser Bugs&#8230;</title>
		<link>http://www.mattephraim.com/blog/2008/10/02/speaking-of-browser-bugs/</link>
		<comments>http://www.mattephraim.com/blog/2008/10/02/speaking-of-browser-bugs/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 18:49:29 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[internet]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/blog/2008/10/02/speaking-of-browser-bugs/</guid>
		<description><![CDATA[I keep breaking Google Chrome. Without even trying.
]]></description>
			<content:encoded><![CDATA[<p>I keep breaking Google Chrome. Without even trying.</p>
<img src="http://farm4.static.flickr.com/3168/2908074440_2aef4e1569_o.jpg" />]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/10/02/speaking-of-browser-bugs/feed/</wfw:commentRss>
		</item>
		<item>
		<title>It&#8217;s a (Firefox) bug!</title>
		<link>http://www.mattephraim.com/blog/2008/09/30/its-a-firefox-bug/</link>
		<comments>http://www.mattephraim.com/blog/2008/09/30/its-a-firefox-bug/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 01:24:18 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/blog/2008/09/30/its-a-firefox-bug/</guid>
		<description><![CDATA[
Sometimes it&#8217;s a relief when you find that a bug you&#8217;re trying to fix in your own code is actually related to someone else&#8217;s code. I&#8217;ve been trying to figure out why large text blocks inside of an xml file keep getting truncated when I read the file in with JavaScript. Turns out it&#8217;s Firefox [...]]]></description>
			<content:encoded><![CDATA[<p>
Sometimes it&#8217;s a relief when you find that a bug you&#8217;re trying to fix in your own code is actually related to someone else&#8217;s code. I&#8217;ve been trying to figure out why large text blocks inside of an xml file keep getting truncated when I read the file in with JavaScript. Turns out it&#8217;s <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=452675">Firefox Bug 452675</a>.
</p>

<div class="code_block">
<span class="code_label">Bug</span>
<pre><code>FF 3 creates multiple #text nodes for elements with well under 
4096 characters of text data</code></pre>
</div>


<p>Good to know I&#8217;m not crazy&#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/09/30/its-a-firefox-bug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Keep tinyMCEPopup From Loading the Popup CSS File</title>
		<link>http://www.mattephraim.com/blog/2008/07/12/keep-tinymcepopup-from-loading-the-popup-css-file/</link>
		<comments>http://www.mattephraim.com/blog/2008/07/12/keep-tinymcepopup-from-loading-the-popup-css-file/#comments</comments>
		<pubDate>Sat, 12 Jul 2008 07:03:59 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[javascript]]></category>

		<category><![CDATA[TinyMCE]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/blog/2008/07/12/keep-tinymcepopup-from-loading-the-popup-css-file/</guid>
		<description><![CDATA[The tinyMCEPopup helper class for TinyMCE automatically includes a theme stylesheet file. I figured out a workaround that keeps this from happening.]]></description>
			<content:encoded><![CDATA[<p>
This week I have been developing my first TinyMCE plugin. One of the first steps was designing the popup dialog box that would be associated with the plugin. Initially, everything was going smoothly. I had the XHTML and CSS just the way I wanted it and I was ready to move on to the next step of developing the JavaScript that would power the functionality of the plugin. 
</p>
<p>
One of the utility files that TinyMCE allows you to include is a file called <strong>tiny_mce_popup.js</strong>. Including this file gives you access to a class called <strong><a href="http://wiki.moxiecode.com/index.php/TinyMCE:API/tinyMCEPopup">tinyMCEPopup</a></strong>. This class provides you with some helper functions that come in handy when developing the dialog box for a TinyMCE plugin. Unfortunately, including the helper file also has a side effect: the helper class will automatically include the current theme&#8217;s css file. In the case of my plugin, the css file for the current theme completely changed the way my plugin&#8217;s XHTML was styled. And not in a good way. 
</p>
<p>
One solution would have been to modify my stylesheet or alter my XHTML so that the stylesheet didn&#8217;t interfere with the way I wanted the page to look. I tried to do this initially, but what I really wanted was for the theme stylesheet not to be included at all. As far as I can tell there&#8217;s no built in way to do force the tinyMCEPopup class to not include the stylesheet. So, I developed a workaround that seems to keep the stylesheet from loading without causing any side effects.
</p>
<p>
The first thing I needed to do was to unset the property that defined the theme stylesheet for popup dialogs. That way when the tinyMCEPopup class tried to include the file, it wouldn&#8217;t find anything to include. The location of the popup stylesheet is stored in the settings for the editor instance under <strong>editor.settings.popup_css</strong>. I figured out that the property could be unset at the beginning of the command that was executed when the button for my plugin was clicked. 
</p>
<div class="code_block">
	<span class="code_label">JavaScript</span>
	<pre class="prettyprint"><code>editor.addCommand('mceMyPluginCommand', function() 
{		
	// Set the popup css to null while page loads 
	// because my plugin uses its own css
	editor.settings.popup_css = null; 
	...
});</code></pre>
</div>
<p>
This worked fine, but setting the popup_css property to null caused the stylesheet for any other plugin&#8217;s popup dialog to not load correctly. To get around this problem I needed to restore the original popup_css property once my plugin&#8217;s dialog box was finished loading. To do this, I simply added a command to the editor that would restore the original popup_css property.
</p>
<div class="code_block">
	<span class="code_label">JavaScript</span>
	<pre class="prettyprint"><code>// Registers an event that will 
// Add command to restore the original css file
ed.onInit.add(function() 
{ 
	var origCss = editor.settings.popup_css;
	editor.addCommand("mceMyPlugin_restoreCss", 
                       function() { editor.settings.popup_css = origCss; });
});</code></pre>
</div>
<p>
The previous two pieces of code could be run during the initialization of my plugin. Finally, I needed to use the tinyMCEPopup class inside of my popup dialog to call the function that restored the css.
</p>
<div class="code_block">
	<span class="code_label">JavaScript</span>
	<pre class="prettyprint"><code>// Restore the popup css to the original theme css
tinyMCEPopup.execCommand("mceMyPlugin_restoreCss");</code></pre>
</div>
<p>
It&#8217;s not the most elegant solution to the problem, but so far it&#8217;s the only way I&#8217;ve been able to figure out how to force the tinyMCEPopup class not to load the theme css file.
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/07/12/keep-tinymcepopup-from-loading-the-popup-css-file/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Miracle Fruit Experiment Part 3: Fail</title>
		<link>http://www.mattephraim.com/blog/2008/07/01/miracle-fruit-experiment-part-3-fail/</link>
		<comments>http://www.mattephraim.com/blog/2008/07/01/miracle-fruit-experiment-part-3-fail/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 04:27:55 +0000</pubDate>
		<dc:creator>Matthew Ephraim</dc:creator>
		
		<category><![CDATA[miracle fruit]]></category>

		<guid isPermaLink="false">http://www.mattephraim.com/blog/2008/07/01/miracle-fruit-experiment-part-3-fail/</guid>
		<description><![CDATA[
Miracle Fruit needs warmth and humidity to grow (so I&#8217;m told). My apartment is sunny, but when I started trying to grow Miracle Fruit I didn&#8217;t think it would be warm enough to get the seeds started. So, I decided that it might be a good idea to set the seeds out on the windowsill, [...]]]></description>
			<content:encoded><![CDATA[<p>
Miracle Fruit needs warmth and humidity to grow (so I&#8217;m told). My apartment is sunny, but when I started trying to grow Miracle Fruit I didn&#8217;t think it would be warm enough to get the seeds started. So, I decided that it might be a good idea to set the seeds out on the windowsill, where it was nice and sunny and warm. I had been doing that for about 2 weeks now, without any trouble.
</p>
<p>
Unfortunately, it was too good to last. When I came home tonight my roommate told me, with a look of sadness, that something had happened to my seeds. Somehow, my mini green houses had fallen off the windowsill and onto the deck, spilling the seeds and the soil all over the place. By the time I came home my roommate and cleaned up the mess. A lot of the soil was gone and it appeared that the seeds had blown into a hole where no one can escape.
</p>
<p>
<h3>
Miracle Fail
</h3>
<img src="http://farm4.static.flickr.com/3178/2629509247_5215a1c779.jpg?v=0" />
</p>
<p>
To be continued&#8230;?
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattephraim.com/blog/2008/07/01/miracle-fruit-experiment-part-3-fail/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
