<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>I Prefer Jim</title>
	
	<link>http://www.ipreferjim.com</link>
	<description>Developer James Schubert shares his code and his thoughts.</description>
	<lastBuildDate>Mon, 10 Jun 2013 05:03:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ipreferjim" /><feedburner:info uri="ipreferjim" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nd/3.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-nd/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/ipreferjim" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fipreferjim" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>Android Studio and Library Projects</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/56dX4tM_6RU/</link>
		<comments>http://www.ipreferjim.com/2013/06/android-studio-and-library-projects/#comments</comments>
		<pubDate>Mon, 10 Jun 2013 05:03:17 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Advanced]]></category>
		<category><![CDATA[Errors]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[Tricks]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1069</guid>
		<description><![CDATA[This is basically a quick brain-dump post. I have previously attempted to get into Android application development, but with only 8-10 hours of "free" time per month, it was difficult to get traction with an app before the goog machine overhauled everything. This happened repeatedly. I had some great ideas for a mobile app over [...]]]></description>
				<content:encoded><![CDATA[<p>This is basically a quick brain-dump post. I have previously attempted to get into Android application development, but with only 8-10 hours of "free" time per month, it was difficult to get traction with an app before the goog machine overhauled everything. This happened repeatedly.  I had some great ideas for a mobile app over the weekend, and thought I'd give it another go and guess what? Everything is overhauled: Android Studio is the next big thing, ant builds are out and gradle builds are in.  I decided to force myself to overcome my annoyances and try out Android Studio.</p>
<p>Android Studio is beautiful and operationally stable, although very buggy. I've found four bugs in less than two days.  The biggest bug and usability issue, however, is in creating an Android Library project and adding a reference to it in another project.</p>
<p>Here are the steps I took to reference another project.  These steps <em>may not be accurate</em>, but I don't care. I figured they may help save someone some time.</p>
<ol>
<li>
Create an Android library project using Android Studio.</p>
<p>There’s a bug in Android Studio 0.1.3 which apparently does not mark android library projects as library projects, so navigate to <strong>MyLibProject/MyLib</strong> and change the android plugin reference to:</p>
<pre class="brush: plain; title: ; notranslate">apply plugin: 'android-library'</pre>
</li>
<li>Create a main application project, in my case <strong>MyApplication2</strong></li>
<li>Add library as git submodule or nested directory under <strong>MyApplication2</strong></li>
<li>Edit <strong>settings.gradle</strong> in the main project to:
<pre class="brush: plain; title: ; notranslate">include ':MyLibProject:MyLib’, ':MyApplication2'</pre>
</li>
<li>Edit <strong>MyApplication2/build.gradle</strong> to compile the lib project in the dependencies task:
<pre class="brush: plain; title: ; notranslate">compile project(':MyLibProject:MyLib’)</pre>
</li>
<li>Navigate to your library subdirectory and execute:
<pre class="brush: bash; title: ; notranslate">gradle clean &amp;&amp; gradle assemble</pre>
</li>
<li>Press <em>CTRL+ALT+SHIFT+S</em> to open the Project Structure dialog</li>
<li>Create a new module, change module name and point content root to MyLibProject</li>
<li>Change Package name to the package name of your lib and press Finish</li>
<li>Click <strong>MyApplication2</strong> (not MyApplication2Project) in the Project Structure dialog and select the <em>Dependencies</em> tab.</li>
<li> Click the green plus icon and select <em>Library|Java</em></li>
<li>Select <strong>MyLibProject/MyLib/build/bundle/release</strong> folder, choose Project Library, and hit ok</li>
<li>Save. The library should now be usable.</li>
</ol>
<p>These instructions may seem a bit hurried, but it should get the job done. I've run through numerous attempts at different options, and these are the only ones that seem to have stuck.</p>
<p>I might also mention, I've created an ANDROID_HOME environment variable to load in my shell which points to the sdk directory under the android-studio installation.  I've also downloaded gradle-1.6 to ~/bin, and symlinked gradle to ~/bin/gradle which adds gradle to my path.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1069&amp;md5=cafb017722072446474c39811abef0f8" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/56dX4tM_6RU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/06/android-studio-and-library-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F06%2Fandroid-studio-and-library-projects%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Android+Studio+and+Library+Projects&amp;description=This+is+basically+a+quick+brain-dump+post.+I+have+previously+attempted+to+get+into+Android+application+development%2C+but+with+only+8-10+hours+of+%22free%22+time+per+month%2C+it+was+difficult...&amp;tags=Advanced%2CErrors%2Crant%2CTricks%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/06/android-studio-and-library-projects/</feedburner:origLink></item>
		<item>
		<title>Computer Science Programming Basics In Ruby</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/nI6tdIFGD2I/</link>
		<comments>http://www.ipreferjim.com/2013/06/computer-science-programming-basics-in-ruby/#comments</comments>
		<pubDate>Sat, 08 Jun 2013 18:10:13 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Review]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1055</guid>
		<description><![CDATA[Computer Science Programming Basics In Ruby Originally submitted at O'Reilly Product: Computer Science Programming Basics in Ruby by oreilly Submitted at: O'Reilly Great intro to basics! by JimSchubert from Seattle WA on 6/7/2013 Pros: Accurate, Well-written, Helpful examples, Easy to understand, Concise Best Uses: Student, Novice Describe Yourself: Developer I read this book as part of the O'Reilly blogger program. I have been a [...]]]></description>
				<content:encoded><![CDATA[<p>Computer Science Programming Basics In Ruby<br />
<a title="Click to view product page" href="http://shop.oreilly.com/product/0636920028192.do" target="_blank">Originally submitted at O'Reilly</a><br />
<iframe src="http://cdn.oreillystatic.com/widgets/public/205.html" height="140" width="550" frameborder="0" scrolling="no"></iframe></p>
<div><strong>Product:</strong> Computer Science Programming Basics in Ruby by <i>oreilly</i></div>
<div><strong>Submitted at:</strong> O'Reilly</div>
<h3>Great intro to basics!</h3>
<p>by <strong>JimSchubert</strong> from <strong>Seattle WA</strong> on <strong>6/7/2013</strong></p>
<p><strong>Pros:</strong> <em>Accurate, Well-written, Helpful examples, Easy to understand, Concise</em><br />
<strong>Best Uses:</strong> <em>Student, Novice</em><br />
<strong>Describe Yourself:</strong> <em>Developer</em></p>
<p>I read this book as part of the O'Reilly blogger program. I have been a professional software engineer since 2008, and I thought that I wouldn't gain much from this book from a technical perspective and just provide some creative feedback for future readers. I also regularly enjoy teaching others about technology and different aspects of development. I was very impressed with the authors' presentation of material.</p>
<p>If you have a degree in computer science, this book is most likely not for you. The actual material discusses things like what an array is and how to use one. It also provides examples of how to use branching conditional structures, objects, files, etc; like the title says, these are the basics.</p>
<p>What impressed me the most was the use of diagrams throughout the book. As engineers we regularly try to cut corners by going light on documentation, which is a practice that plagues the field and turns our science into more of an art. What is even more difficult than writing documentation or learning materials for other engineers? Writing for non-engineers. This book does an excellent job of explaining concepts that most authors take for granted. For example, I think you would have difficulty finding an introductory level book that doesn't explain arrays with a picture of adjacent boxes to represent indexes; as engineers we assume that new engineers may have issues with data structures, but we regularly take control flow for granted. I think we assume that control flow can be really explained by requesting it to directions, but this simplification may not work for everyone. This book presents control flow by providing an application example, then displaying the logic of the example in a flowchart. I love that. I think this aspect alone would easily reduce some of the intimidation a new student to the computer science field may have.</p>
<p>I would recommend this book to students or anyone considering a career move into software or web development. I would also personally be interested on reading more by this team of authors on advanced topics.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1055&amp;md5=270574e9fbc03e95909ae7c1d853f69f" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/nI6tdIFGD2I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/06/computer-science-programming-basics-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F06%2Fcomputer-science-programming-basics-in-ruby%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Computer+Science+Programming+Basics+In+Ruby&amp;description=Computer+Science+Programming+Basics+In+Ruby+Originally+submitted+at+O%27Reilly+Product%3A%C2%A0Computer+Science+Programming+Basics+in+Ruby%C2%A0by%C2%A0oreilly+Submitted+at%3A%C2%A0O%27Reilly+Great+intro+to+basics%21+by%C2%A0JimSchubert%C2%A0from%C2%A0Seattle+WA%C2%A0on%C2%A06%2F7%2F2013+Pros%3A+Accurate%2C+Well-written%2C+Helpful+examples%2C+Easy...&amp;tags=Review%2CReviews%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/06/computer-science-programming-basics-in-ruby/</feedburner:origLink></item>
		<item>
		<title>git prepare-commit-msg with node.js</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/wn6TRpXQdbk/</link>
		<comments>http://www.ipreferjim.com/2013/04/git-prepare-commit-msg-with-node-js/#comments</comments>
		<pubDate>Sun, 07 Apr 2013 20:55:56 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1049</guid>
		<description><![CDATA[I think people often overlook using node.js as a scripting tool like ruby or python. If you search the web for examples of customized git hooks, you'll probably have visited git-scm.com, where most of the examples are in ruby. I wanted to show a pretty simple prepare-commit-msg hook written in node.js. This hook will append [...]]]></description>
				<content:encoded><![CDATA[<p>I think people often overlook using node.js as a scripting tool like ruby or python. If you search the web for examples of customized git hooks, you'll probably have visited <a href="http://git-scm.com/" alt="http://git-scm.com/">git-scm.com</a>, where most of the examples are in ruby.</p>
<p>I wanted to show a pretty simple prepare-commit-msg hook written in node.js. This hook will append the name and description of whatever working branch you commit from. I use this technique to create a working branch for a JIRA ticket number, so all my commits to this ticket automatically include that ticket number. Then, JIRA can be configured to display github commits directly in the ticket details when that commit references the ticket in the commit message.</p>
<p>The script:</p>
<pre class="brush: jscript; title: ; notranslate">
#!/usr/bin/env node
var exec = require('child_process').exec,
    util = require('util'),
    fs = require('fs'),
    contents = null,
    branch, desc;

console.log(process.argv);

// expect .git/COMMIT_EDITMSG
if(/COMMIT_EDITMSG/g.test(process.argv[2])){
    // look for current branch name
    branch = exec(&quot;git branch | grep '*'&quot;,
      function (err, stdout, stderr) {
        if(err){
			// git branch will fail if initial commit has not been done,
			// so we can safely skip this hook
			process.exit(0); 
		}

		// opens .git/COMMIT_EDITMSG
        contents = fs.readFileSync(process.argv[2]);
		
		// trims extra characters from start/end of line
        var name = stdout.replace('* ','').replace('\n','');
		
		// If the branch has a description, pull that
        desc = exec('git config branch.'+ name +'.description',
            function(err, stdout, stderr){
				// don't handle errors (because we write out branch anyway)
                
				// we found a description, add to 'name'
				if(stdout){ name = util.format('%s (%s)', name, stdout.replace(/\n/g,'')); }

				// '(no branch)' indicates we are in a rebase or other non-HEAD scenario
                if(name !== '(no branch)'){
				
					// Append branch name to original contents.
                    contents = util.format('%s\n\n:%s\n', contents, name);
					
					// write contents back out to .git/COMMIT_EDITMSG
                    fs.writeFileSync(process.argv[2], contents);
                    process.exit(0);
                } else {
                    process.exit(0);
                }
        });
    });
}
</pre>
<p>The above script is pretty well-commented. If you decide to use it, you may want to comment out the first console.log which dumps all arguments sent to the script.</p>
<p>Here's an example of its usage.</p>
<p>Create and initialize a new local git repository.</p>
<pre class="brush: bash; title: ; notranslate">
$ mkdir example
$ cd example
$ git init
</pre>
<p>Then, copy the above example script into the git hooks directory under .git/hooks/prepare-commit-msg</p>
<p>Now, in the example directory, create and commit a file into the repository:</p>
<pre class="brush: bash; title: ; notranslate">
$ touch first
$ git add .
$ git commit -m 'Initial commit'
</pre>
<p>You'll see the array of arguments passed through the custom git hook, but if you issue a git log, you'll only see the commit message 'Initial commit'. That's because this custom hook expects a git branch, but there is no git branch until your initial commit is complete. To verify the script is working:</p>
<pre class="brush: bash; title: ; notranslate">
$ touch second
$ git add .
$ git commit -m 'Second commit'
</pre>
<p>A git log will now show you a tweaked message:</p>
<pre class="brush: plain; title: ; notranslate">
    Second commit
    
    :master
</pre>
<p>Now, you can create a branch named 'ABC-123' and do another commit:</p>
<pre class="brush: bash; title: ; notranslate">
$ git checkout -b ABC-123
$ touch third
$ git add .
$ git commit -m 'Third commit'
</pre>
<p>The commit message:</p>
<pre class="brush: plain; title: ; notranslate">
    Third commit
    
    :ABC-123
</pre>
<p>This hook also allows you to print out the branch description.  To test, invoke the branch description editor:</p>
<pre class="brush: bash; title: ; notranslate">
$ git branch --edit-description ABC-123
</pre>
<p>I've added the text 'Supporting branch for ABC-234 and ABC-567'. Save this buffer according to your editor (<strong>:wq</strong> if you're using vim).</p>
<p>Add a fourth file as we have before, then verify with git log:</p>
<pre class="brush: plain; title: ; notranslate">
    Fourth commit
    
    :ABC-123 (Supporting branch for ABC-234 and ABC-567)
</pre>
<p>Because this script strips newlines from the branch description, you'd need to keep it short. Usually, that's not a problem.</p>
<p>This shows how to append text to your commit message, but it can easily be modified to replace commonly misspelled words (teh -> the).</p>
<p>This prepare-commit-msg hook is available in my <a href="https://github.com/jimschubert/blogs" title="jimschubert/blogs" target="_blank">blogs repo on github</a>.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1049&amp;md5=c62906ab006fcdd9471d2ec6a0d8a5ba" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/wn6TRpXQdbk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/04/git-prepare-commit-msg-with-node-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F04%2Fgit-prepare-commit-msg-with-node-js%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=git+prepare-commit-msg+with+node.js&amp;description=I+think+people+often+overlook+using+node.js+as+a+scripting+tool+like+ruby+or+python.+If+you+search+the+web+for+examples+of+customized+git+hooks%2C+you%27ll+probably+have+visited...&amp;tags=github%2Cnodejs%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/04/git-prepare-commit-msg-with-node-js/</feedburner:origLink></item>
		<item>
		<title>Why I don’t recommend the Step module [node.js, npm]</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/z9sAxnLM97k/</link>
		<comments>http://www.ipreferjim.com/2013/03/why-i-dont-recommend-the-step-module/#comments</comments>
		<pubDate>Sun, 17 Mar 2013 07:27:50 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1042</guid>
		<description><![CDATA[I prefer asyc to step. The async module has a cleaner interface, more options, and utilities. It's a little beefier in size, but those things are beside the point. Here's why I don't really like step. Tell me what you'd expect from this function: Did you guess: If you're not familiar with Step, you'll probably [...]]]></description>
				<content:encoded><![CDATA[<p>I prefer asyc to step. The async module has a cleaner interface, more options, and utilities. It's a little beefier in size, but those things are beside the point.</p>
<p>Here's why I don't really like step.  Tell me what you'd expect from this function:</p>
<pre class="brush: jscript; title: ; notranslate">
var Step = require('step');

Step(
	function first(){
		console.log('first');
		
		this();
	},
	
	function second(){
		var x;
		console.log('second');
		if(!x){
			// do something that should set x
		}
		return x;
	},
	
	function third(){
		console.log('third');
	}
)
</pre>
<p>Did you guess:</p>
<pre class="brush: plain; title: ; notranslate">
$ node step-example.js 
first
second
</pre>
<p>If you're not familiar with Step, you'll probably look at that first function and wonder what <code>this();</code> actually does. Well, it is actually shorthand for <code>next();</code> (I'm simplifying a little here).</p>
<p>Assuming you're at least somewhat familiar with asynchronous control flow, you could assume <code>this();</code> calls the next function. But, what about the second function? It's returning a value. Does that return from <em>second</em>, or from <em>Step</em>, or from some other function? It returns from <em>second()</em>, but... it passes the value to <em>third</em>. Or, it should. Unless <em>x</em> is undefined, in which case it will be considered an unchained function. Now, I don't think your variables should regularly be 'undefined' at the point of return, but what if you use or someone on your team uses the popular convention of calling a callback as <code>return callback(x);</code>. If the Step module's convention of tweaking <em>this</em> semantics is ignored, another developer may look at it as a typo, "You can't call the context like that..." Right?  Also, what if someone doesn't understand the return value can't be <em>undefined</em> and comments out the middle of that function? You may have cleanup logic that isn't getting checked in <code>third()</code>.<br />
We've all seen that happen before.</p>
<p>In the above example, if <em>x</em> was not <em>undefined</em>, it would be passed as a parameter to <code>third()</code>.</p>
<p>It's this inconsistency which makes me feel like Step is an accident waiting to happen in a regular development team. The source code is pretty well written and concise. I think the author has done a great job, but the usage is unintuitive and I wouldn't recommend using the module.</p>
<p>On the other hand, async is beautifully intuitive.</p>
<p>Consider this example:</p>
<pre class="brush: jscript; title: ; notranslate">
var async = require('async');

async.series([
	function first(done){
		console.log('first');
		done(null, 'first');
	},
	function second(done){
		var x;
		console.log('second');
		if(!x){
			// do something that should set x
		}
		done(null, x);
	},
	function third(done){
		console.log('third');
		
		done(null, 'third');
	}
], function(err, results){
	console.log(results);
})
</pre>
<p>async.series allows us to run a series of tasks (functions defined within the array), which pass a value to the callback (that last function you see).</p>
<p>If you forget to pass a value, the results will contain <em>undefined</em> at the index of the array. Your third function won't be skipped unless you forget to invoke the callback. To me, this is a pretty obvious error and one that is easy to spot and correct.  Here's is the output of the above call:</p>
<pre class="brush: plain; title: ; notranslate">
first
second
first
third
[ 'first', undefined, 'third' ]
</pre>
<p>To be fair, the example of Step acts more like a waterfall function. Here's what that would look like in async.</p>
<pre class="brush: jscript; title: ; notranslate">
async.waterfall([
	function first(done){
		console.log('first');
		done(null, 'first');
	},
	function second(val, done){
		var x;
		console.log('second has val: %j', val);
		if(!x){
			// do something that should set x
		}
		done(null, x);
	},
	function(val, done){
		console.log('third has val: %j', val);
		
		done(null, 'third');
	}
], function(err, val){
	console.log('callback has val: %j', val)
});
</pre>
<p>The above code is available on github: <a href="https://github.com/jimschubert/blogs" title="jimschubert/blogs on GitHub" target="_blank">https://github.com/jimschubert/blogs</a></p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1042&amp;md5=0b038cba68cdb4f2d59f35aa002b73c0" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/z9sAxnLM97k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/03/why-i-dont-recommend-the-step-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F03%2Fwhy-i-dont-recommend-the-step-module%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Why+I+don%26%238217%3Bt+recommend+the+Step+module+%5Bnode.js%2C+npm%5D&amp;description=I+prefer+asyc+to+step.+The+async+module+has+a+cleaner+interface%2C+more+options%2C+and+utilities.+It%27s+a+little+beefier+in+size%2C+but+those+things+are+beside+the+point.+Here%27s...&amp;tags=Javascript%2Cnodejs%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/03/why-i-dont-recommend-the-step-module/</feedburner:origLink></item>
		<item>
		<title>CommonJS Modules, node’s require() and private members</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/0T9bPLZ_EGA/</link>
		<comments>http://www.ipreferjim.com/2013/03/commonjs-modules-nodes-require-and-private-members/#comments</comments>
		<pubDate>Sat, 02 Mar 2013 23:47:07 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Advanced]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1038</guid>
		<description><![CDATA[CommonJS Modules, node's require() and private members Interestingly, node.js module documentation doesn't even mention CommonJS or the specification proposal it implements. I won't go over CommonJS Modules 1.0 in-depth in this post, but I suggest you read both of these links if you plan to explore node.js development. An important take-away from this blog post [...]]]></description>
				<content:encoded><![CDATA[<h1>CommonJS Modules, node's require() and private members</h1>
<p>Interestingly, node.js <a href="http://nodejs.org/docs/latest/api/modules.html" alt="node.js modules">module documentation</a> doesn't even mention CommonJS or the specification proposal it implements.  I won't go over CommonJS <a href="http://wiki.commonjs.org/wiki/Modules/1.0" alt="CommonJS Modules 1.0">Modules 1.0</a> in-depth in this post, but I suggest you read both of these links if you plan to explore node.js development.</p>
<p>An important take-away from this blog post (so important that I state it first) is that node.js caches modules. A module's exports are nothing more than an object. When you set a function or property to be exported, you're setting it on an object.</p>
<p>Conceptually, this:</p>
<pre class="brush: jscript; title: ; notranslate">
var someFunction = function(){ /* implement */ };
module.exports.someFunction = exports.someFunction = someFunction;
</pre>
<p>...is the same as doing this outside of CommonJS modules...</p>
<pre class="brush: jscript; title: ; notranslate">
var someFunction = function(){ /* implement */ };
var exports = {};
exports.someFunction = someFuntion;
</pre>
<p>I know, that seems like it should be common sense.  When node.js caches the exports object at the application level, I think understanding this can become hairy -- especially if you come from a compiled language background.</p>
<p>For example, consider the following module.</p>
<pre class="brush: jscript; title: ; notranslate">
var count = 0;

var doSomethingShared = function(){
	count += 1;
	console.log(&quot;Shared call count: %d&quot;, count);
};

var doSomethingNotShared = function(){
	console.log(&quot;Other modules don't know about me!&quot;);
};

module.exports.shared = exports.shared =  doSomethingShared;
module.exports.unshared = exports.unshared =  doSomethingNotShared;
</pre>
<p>We can require this module easily and play around with it in node REPL:</p>
<pre class="brush: plain; title: ; notranslate">
$ node
&gt; var example = require('./example.js');
undefined
&gt; example.shared()
Shared call count: 1
undefined
&gt; example.shared()
Shared call count: 2
undefined
&gt; example.shared()
Shared call count: 3
undefined
&gt; example.shared()
Shared call count: 4
undefined
&gt; example.unshared()
Other modules don't know about me!
undefined
</pre>
<p>In the same REPL instance, you can re-require the module and see that 'count' is indeed shared:</p>
<pre class="brush: plain; title: ; notranslate">
&gt; var example2 = require('./example.js');
undefined
&gt; example2.shared()
Shared call count: 5
undefined
&gt; example2.shared()
Shared call count: 6
undefined
</pre>
<p>You can even require the shared function directly:</p>
<pre class="brush: jscript; title: ; notranslate">
&gt; var shared = require('./example.js').shared;
undefined
&gt; shared()
Shared call count: 7
undefined
&gt; shared()
Shared call count: 8
undefined
</pre>
<p>I think you get the point; private variables which aren't exported are shared. In this example, 'count' is a private static property of the module.</p>
<h2>Why this matters</h2>
<p>This is very important, because when working in the asynchronous environment of node.js you have to be aware about *what* is being cached privately at the module level.  In addition to this, if you plan to cache functions for whatever reason, you have to be incredibly sure you know what you're doing.  I recommend to <strong>NEVER CACHE CALLBACK FUNCTIONS</strong>. </p>
<p>As an example of this statement, I've created a sample file processor script in the github repo as fs-example.js.  That script reads this blog's directory in the repo, then loops over the files and executes 'processor', which is a custom broken module displaying the above problem.  fs-example.js does an inline require, which as you've seen above doesn't make a difference.</p>
<p>The problem I'll display here exists because async calls are likely to take different lengths of time to execute.  My example is using the linux commands 'head -1' and 'tail -1' on each file to get the first and last lines, respectively. These commands are nearly instantaneous, so I'm using a random setTimeout to display the problem with caching functions.  You could easily modify these scripts to 'head' and 'tail' different web sites. But, whatever.  Because head.js and tail.js are simple spawn wrappers, I'll focus on processor.js, which is where the potential bugginess exists.</p>
<pre class="brush: jscript; title: ; notranslate">
// begin processor.js
var head = require('./head'),
	tail = require('./tail');
	
// don't do this IRL
var callback = null;

var processor = function(file, cb){
	if('function' === typeof cb){
		callback = cb;
	}
	
	// these fail
	head(file, function(d){
		callback(d)
	});
	tail(file, function(d){
		callback(d)
	});
	
	// these succeed
	// head(file, callback);
	// tail(file, callback);
};

module.exports = exports = processor;
</pre>
<p>This is a simple file for having such a subtle bug. The file includes the customized head and tail scripts. Then, it creates a function that tags a file, caches the callback function, and calls head and tail to execute the callback.  You'll notice the commented-out lines at the end that claim 'these succeed'.  Here's why...</p>
<p>When a callback is passed directly to a function as is done with <code>head(file, callback)</code>, the function itself is passed as a reference. Meaning, when the head module executes that callback, it will always execute the referenced callback.  Now, what if another developer wants to add logging or other processing of the data?  You'll likely get something like the example, where a function is created and callback is called directly (rather than the cb passed into the function originally).  Because 'callback' is cached at the module level and shared across calls to processor, the scope created by the processor function is shared with the anonymous function callback and points to whatever is the most recent callback function rather than what one might expect to be the intended function.</p>
<p>We could avoid the problem in the above non-commented code by referencing the 'cb' parameter rather than the cached 'callback' variable. This is because processor creates a closure over 'callback', but 'cb' would always be within the current execution context.</p>
<p>You can play around with the code from this post, which is available on <a href="https://github.com/jimschubert/blogs" alt="jimschubert github">github</a>.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1038&amp;md5=7bdd305376480f66c500e6c34c384809" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/0T9bPLZ_EGA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/03/commonjs-modules-nodes-require-and-private-members/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F03%2Fcommonjs-modules-nodes-require-and-private-members%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=CommonJS+Modules%2C+node%26%238217%3Bs+require%28%29+and+private+members&amp;description=CommonJS+Modules%2C+node%27s+require%28%29+and+private+members+Interestingly%2C+node.js+module+documentation+doesn%27t+even+mention+CommonJS+or+the+specification+proposal+it+implements.+I+won%27t+go+over+CommonJS+Modules+1.0+in-depth+in...&amp;tags=Advanced%2CJavascript%2Cnodejs%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/03/commonjs-modules-nodes-require-and-private-members/</feedburner:origLink></item>
		<item>
		<title>“Unable to update the dependencies of the project”</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/FewXgLlk0lY/</link>
		<comments>http://www.ipreferjim.com/2013/01/unable-to-update-the-dependencies-of-the-project/#comments</comments>
		<pubDate>Fri, 04 Jan 2013 16:40:43 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Errors]]></category>
		<category><![CDATA[fix]]></category>
		<category><![CDATA[wix]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1035</guid>
		<description><![CDATA[I've recently had to switch from Visual Studio 2012 back to Visual Studio 2010 to do maintenance on another project. This project is currently stuck in Visual Studio 2010 until I have time to convert the old setup projects to WiX. I often receive the following error message during Release builds: Closing Visual Studio 2010 [...]]]></description>
				<content:encoded><![CDATA[<p>I've recently had to switch from Visual Studio 2012 back to Visual Studio 2010 to do maintenance on another project.  This project is currently stuck in Visual Studio 2010 until I have time to convert the old setup projects to WiX.  I often receive the following error message during Release builds:</p>
<pre class="brush: plain; title: ; notranslate">
&quot;Unable to update the dependencies of the project&quot;
</pre>
<p>Closing Visual Studio 2010 and reopening seemed to have fixed the problem up until about a week ago.  I've found that installing <a href="http://support.microsoft.com/kb/2286556" title="FIX: Error message when you build a Visual Studio 2010 setup project: 'Unable to update the dependencies of the project'" target="_blank">this hotfix</a> seems to resolve the issue.  The only problem is that I've had to install the hotfix multiple times.</p>
<p>The 'cause' on the hotfix page says the issue is a result of how Visual Studio 2010 refreshes dependencies.  I wonder if this is handled by Windows Updates updating the .NET Framework?  Whatever it is, it's pretty annoying to have to apply this patch regularly.  I guess it's just another reason for developers to move setup projects to WiX.</p>
<p><a href="http://support.microsoft.com/kb/2286556" title="http://support.microsoft.com/kb/2286556" target="_blank">http://support.microsoft.com/kb/2286556</a></p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1035&amp;md5=8c1505768ad21f9c4847c369f367a6f5" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/FewXgLlk0lY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2013/01/unable-to-update-the-dependencies-of-the-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2013%2F01%2Funable-to-update-the-dependencies-of-the-project%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=%26%238220%3BUnable+to+update+the+dependencies+of+the+project%26%238221%3B&amp;description=I%27ve+recently+had+to+switch+from+Visual+Studio+2012+back+to+Visual+Studio+2010+to+do+maintenance+on+another+project.+This+project+is+currently+stuck+in+Visual+Studio+2010+until...&amp;tags=Errors%2Cfix%2Cwix%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2013/01/unable-to-update-the-dependencies-of-the-project/</feedburner:origLink></item>
		<item>
		<title>My Review of Values, Units, and Colors</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/G83G9444FRE/</link>
		<comments>http://www.ipreferjim.com/2012/11/my-review-of-values-units-and-colors/#comments</comments>
		<pubDate>Sun, 25 Nov 2012 19:55:06 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=1016</guid>
		<description><![CDATA[Originally submitted at O'Reilly Foundational CSS3 Components Values, Units, and Colors Excellent intro or review By Jim Schubert from Richmond, VA on 11/25/2012 &#160; 5out of 5 Pros: Easy to understand, Helpful examples, Well-written, Concise, Accurate Best Uses: Expert, Intermediate, Novice, Student Describe Yourself: Developer I am reviewing "Values, Units, and Colors" as part of [...]]]></description>
				<content:encoded><![CDATA[<div class="hreview">
<div class="item">
<p><a href="http://shop.oreilly.com/product/0636920027621.do">Originally submitted at O'Reilly</a></p>
<div><img src="http://images.powerreviews.com/images_products/02/43/19478221_100.jpg" class="photo" align="left" style="margin: 0 0.5em 0 0">
<p style="margin-top:0">Foundational CSS3 Components</p>
</div>
<p><a href="http://shop.oreilly.com/product/0636920027621.do" style="display: none;" class="url fn"><span class="fn">Values, Units, and Colors</span></a></div>
<p><br clear="left">
<p><strong class="summary">Excellent intro or review</strong></p>
<div>By <strong>Jim Schubert</strong> from <strong>Richmond, VA</strong> on <strong><abbr title="20121125T1200-0800" class="dtreviewed" style="border: none; text-decoration: none;">11/25/2012</abbr></strong></div>
<p>
<div style="margin: 0.5em 0; height: 15px; width: 83px; background-image: url(http://images.powerreviews.com/images/stars_small.gif); background-position: 0px -180px;" class="prStars prStarsSmall">&nbsp;</div>
</p>
<div style="display: none"><span class="rating">5</span>out of 5</div>
<p><strong>Pros: </strong>Easy to understand, Helpful examples, Well-written, Concise, Accurate</p>
<p><strong>Best Uses: </strong>Expert, Intermediate, Novice, Student</p>
<p><strong>Describe Yourself: </strong>Developer</p>
<p style="margin-top:1em" class="description">I am reviewing "Values, Units, and Colors" as part of the O'Reilly Blogger Review program. I have had about a 6 month hiatus from full-time web development, so I thought I'd be able to offer a somewhat fresh perspective of this book's content.<br xmlns:pr="xalan://com.pufferfish.core.beans.xmlbuilders.xsl.Functions"><br />It's a short, quick read. It's also well-worth the price.  There were quite a few things I didn't know (or hadn't considered), such as some odd behavior in older versions of Internet Explorer and certain times a value may mean something different depending on the order of values and keywords.</p>
<p>I especially loved the explanation of HSL versus RGB. I had always avoided HSL and HSLa, because RGB and RGBa seem more intuitive to me. This book explains the two very well, in a way I think someone more familiar with HSL than RGB would gain an equally better understanding as I have.</p>
<p>The book also covers some relative length units which I've never used or seen used (ex, rem, ch).</p>
<p>Usually, I'm not very impressed with short books of this nature. I think it's fairly difficult to get *enough* information in so few pages. I think the subject matter in this book is focused enough to cover it quickly and concisely in less than 50 pages. I'll admit, I didn't expect to say aloud while reading this, "Huh, now that makes sense."</p>
<p>I'd definitely recommend this book to fellow web developers, or anyone interested in tweaking the styles of their own website. I will definitely reread this book in the future.</p>
<p style="margin-top:0.5em">(<a href="http://www.powerreviews.com/legal/terms_of_use.html" rel="license">legalese</a>)</p>
</div>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=1016&amp;md5=941d4cfd03128475ce4ce68e04b377c3" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/G83G9444FRE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/11/my-review-of-values-units-and-colors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F11%2Fmy-review-of-values-units-and-colors%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=My+Review+of+Values%2C+Units%2C+and+Colors&amp;description=Originally+submitted+at+O%27Reilly+Foundational+CSS3+Components+Values%2C+Units%2C+and+Colors+Excellent+intro+or+review+By+Jim+Schubert+from+Richmond%2C+VA+on+11%2F25%2F2012+%26nbsp%3B+5out+of+5+Pros%3A+Easy+to...&amp;tags=Reviews%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/11/my-review-of-values-units-and-colors/</feedburner:origLink></item>
		<item>
		<title>[Android] on{X} – automate your life</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/Tw3uMT6K9JA/</link>
		<comments>http://www.ipreferjim.com/2012/10/android-onx-automate-your-life/#comments</comments>
		<pubDate>Mon, 22 Oct 2012 22:59:07 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Microsoft]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=998</guid>
		<description><![CDATA[Lately, I've been obsessing over Microsoft. A couple of months ago, I would have told you that Windows 8 was a terrible move on Microsoft's part. I had installed the Windows 8 preview in a virtual machine and found it difficult to use. After discussing Windows 8 quite a bit with my friend, Travis, I [...]]]></description>
				<content:encoded><![CDATA[<p>Lately, I've been obsessing over Microsoft.  A couple of months ago, I would have told you that Windows 8 was a terrible move on Microsoft's part. I had installed the Windows 8 preview in a virtual machine and found it difficult to use. After discussing Windows 8 quite a bit with my friend, Travis, I came to the conclusion that the VM made things difficult. My VM manager is VirtualBox and, unlike VMware, the 'Windows Key' is not intercepted by the Guest machine.</p>
<p>This month's edition of MSDN Magazine is focused entirely on Windows 8. After reading about the WindowsMetadata architecture, I was hooked. I have been a .NET developer for almost 5 years now, and I think C# is one of the few languages to 'get it right'. One of the things I've always loved about .NET is the Common Language Runtime (CLR), which allows developers to write in their language of choice while actually compiling down into a bytecode call IL (this is the heart of .NET). </p>
<p>WinRT takes it a little further. Instead of compiling into IL bytecode, WinRT exposes a native API, and the metadata acts as an adapter between the underlying native types and the types of the WinRT language being used. I was pretty stoked about this, so I decided to give Windows 8 a true evaluation.</p>
<p>After installing Windows 8 to physical media, I was pretty impressed with the operating system. Learning a few hotkeys like <em>WINDOWS</em> key, <em>WINDOWS+X</em>, <em>WINDOWS+I</em>, and <em>WINDOWS+J</em> makes things a lot easier, and I was missing out on these in the VM.</p>
<p>You're probably wondering what that has to do with Microsoft' <a href="https://www.onx.ms/" title="on{X} application for Android" target="_blank">on{X} application for Android</a>?  Well, it appears Microsoft has spent a great deal of time in unifying different languages and architectures recently. WinRT is one example. An Android application called on{X} is another.  on{X} exposes underlying Android APIs to a scriptable (JavaScript) interface. I was intrigued by the idea, so I wanted to test a pretty simple recipe.</p>
<p>I've been bothered by the lack of customizable volume controls in Android for some time. I have a Samsung Galaxy with Android 4.1 running on it, and I *still* have no way to automatically reduce media and notification volume to nearly nothing between 11pm and 7am while still allowing phone calls.</p>
<p>The on{X} team has <a href="https://www.onx.ms/#!recipeEditPage?scriptId=textOnMissedCallWhenNoisy" title="Text reply in a noisy place" target="_blank">created a script</a> which replies to missed calls with a specific message when you're in a noisy place.  Using this script as a guide, I created a script called <strong>Between 11:00 PM and 7:00 AM, 50% ringer  for known contacts and 5% other audio</strong>:</p>
<p>(<a href="https://gist.github.com/4001499" title="View the gist on Github" target="_blank">https://gist.github.com/4001499</a>)<br />
<script src="https://gist.github.com/4001499.js?file=script.js"></script></p>
<p>After you enter this script into your dashboard on onx.ms, you can push it to your phone.  The on{X} application scheduler will automatically load the script based on the timer definitions.</p>
<p><del datetime="2012-11-02T13:46:36+00:00">I plan to tweak this script a bit to store the previous ringer state in localStorage and to adjust the stored and current ringer states if the ringer volume is adjusted at any time during the bedtime period.  It might also be nice to increase the volume only for phone numbers from contacts in a specific group like 'Family', 'Important People', or 'Favorites.</del></p>
<p><em>Updated 2012-11-02: The above script now adjusts volume for incoming calls only if the calling party's number exists as a contact</em></p>
<p>So, here's the tie-in. It seems Microsoft is trying to unify a lot of things. With Windows 8, they're trying to unify the mobile and desktop experience (Yes, it will probably take you a week to get used to it, but it's worth it). With WinRT, they're trying to unify the applicability and usability of all code; you can expose C# code to JavaScript in WinRT. With on{X}, they're unifying API automation on the Android platform using a very popular dynamic language.  For a company that historical has had a reputation for not 'playing along', Microsoft sure is making the game easier for developers in a lot of ways.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=998&amp;md5=38a5b015315bd8ab9ee33dc15022b958" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/Tw3uMT6K9JA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/10/android-onx-automate-your-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F10%2Fandroid-onx-automate-your-life%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=%5BAndroid%5D+on%7BX%7D+%26%238211%3B+automate+your+life&amp;description=Lately%2C+I%27ve+been+obsessing+over+Microsoft.+A+couple+of+months+ago%2C+I+would+have+told+you+that+Windows+8+was+a+terrible+move+on+Microsoft%27s+part.+I+had+installed+the...&amp;tags=Javascript%2CMicrosoft%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/10/android-onx-automate-your-life/</feedburner:origLink></item>
		<item>
		<title>Generating sprites with HTML5 canvas (node-canvas)</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/QSNiOfwDSQw/</link>
		<comments>http://www.ipreferjim.com/2012/10/generating-sprites-with-html5-canvas-node-canvas/#comments</comments>
		<pubDate>Sun, 14 Oct 2012 22:31:01 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Advanced]]></category>
		<category><![CDATA[Examples]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=981</guid>
		<description><![CDATA[About a week ago, I posted about drawing simple shapes in HTML5. HTML5's Canvas isn't only useful on the client side. About a year ago, I rewrote my Quaketracker mashup which pulls rss content from USGS and displays markers on a Google Map. For part of this rewrite, I wanted to use custom markers to [...]]]></description>
				<content:encoded><![CDATA[<p>About a week ago, I posted about <a href="http://www.ipreferjim.com/2012/10/drawing-a-custom-html5-shape/" title="Drawing a custom HTML5 shape" target="_blank">drawing simple shapes in HTML5</a>. HTML5's Canvas isn't only useful on the client side.</p>
<p>About a year ago, I <a href="https://github.com/jimschubert/quaketracker" title="Quaketracker code on Github" target="_blank">rewrote</a> my <a href="http://ipreferjim.com/maps/" title="Quaketracker" target="_blank">Quaketracker</a> mashup which pulls rss content from USGS and displays markers on a Google Map. For part of this rewrite, I wanted to use custom markers to indicate the magnitude of the earthquake, both numerically and colorfully. That task was more involved than I realized it would be. There doesn't seem to be any easy way to generate such a sprite in The Gimp or other graphics software, so I set out to generate a sprite of magnitudes 0.0 through 9.9 with a color range from yellow to orange using node-canvas.  This actually made the task very simple.</p>
<div id="attachment_982" class="wp-caption alignright" style="width: 45px"><a href="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/base.png?9d7bd4"><img src="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/base.png?9d7bd4" alt="base.png" title="base.png" width="35" height="35" class="size-full wp-image-982" /></a><p class="wp-caption-text">marker</p></div>
<p>Before writing the script, I had to decide on an image.  I created a pretty simple quote-bubble-like marker with a white background and a black outline. The image is 35x35 square with some transparency padding the actual marker image. This allows me to calculate the layout pretty easily.  The white background on black outline gives me a very specific color to replace with the desired color of intensity.</p>
<p><a href="github.com/learnboost/node-canvas" title="node-canvas on github" target="_blank">node-canvas</a> is a custom implementation of Canvas for node.js. When I originally wrote this script, I had a few issues compiling node-canvas.  When I tweaked the script today, I had no issues.  However, it seems like some things are not well-documented or incomplete (PixelArray).</p>
<h2>Scripting it in node.js</h2>
<p>A lot of times, if your script writes out to files, it's best to check for dependencies and cause your script to exit if they're not met.  For example, I know this script is completely useless without node-canvas, so I can probe for the availability of that module and provide directions for installation. I'd do this before attempting to load any other functions from the canvas module.  You could also check for versions at this point.  If someone runs this script with node-canvas 0.6.0 it will still work, but this may not be the case with other modules.  Here's how I start off the script.</p>
<pre class="brush: jscript; title: ; notranslate">
var p = require('util').puts;

try {
    var probe = require('canvas');
} catch(e) {
    p(&quot;Cannot find node-canvas module.&quot;);
    p(&quot;Did you install dependencies:\n&quot;);
    p(&quot;\tnpm install -d&quot;);
    process.exit();
}

var fs = require('fs');
var Canvas = require('canvas');
var Image = Canvas.Image;

var canvas, ctx, baseImage, outImage, img;
</pre>
<p>I don't usually use 'global' variables like those in the last line of the above snippet for applications or client-side scripting. For a script like this, you could have everything as a global variable as long as the names don't clash with your imported modules.</p>
<p>To initialize shared variables, I like to define an <em>init()</em> function and call that function at the end of the script. This is pretty common in other languages like Ruby and Python, so why node server-side JavaScript?</p>
<pre class="brush: jscript; title: ; notranslate">
var init = function() {
	// our working image is 35x35, we want 10x10 sheet of sprites
	canvas = new Canvas(35*10,35*10);
	ctx = canvas.getContext('2d');
	baseImage = __dirname + '/base.png';
	outImage = __dirname + '/markers.png';

	// pre-load the image
	img = new Image;
	img.onload = function() {
		processImage(fileProcessingComplete);
	};
	
	img.src = baseImage;
};
</pre>
<p>The cool thing about node-canvas is that the usage is very similar to the Canvas API implemented in browsers supporting the HTML5 Canvas.  In fact, aside from the <em>__dirname</em> special property of node.js, you should be able to drop this init function into a browser with no problems.  For this script, I want 100 different magnitudes to be generated from 0.0 through 9.9 (00-99 is 100) so the canvas is initialized to 10 rows and 10 columns of 35x35 squares. Just like a client-side Image object, we want to bind any post-processing of the image via the <em>onload()</em> function.</p>
<p>I'm going to Memento you a bit, and for that I'm sorry but the end is the easier concept. When all the processing is complete, we want to pull image data from the Canvas element and write it out to a file.</p>
<pre class="brush: jscript; title: ; notranslate">
var fileProcessingComplete = function() {
	var out = fs.createWriteStream(outImage),
            stream = canvas.createPNGStream();

	stream.on('data', function(chunk){
	  out.write(chunk);
	});

	// when PNG stream is done, drain WriteStream
	stream.on('end', function(){
	  p('saved ' + outImage);
	  out.destroySoon();
	});
};
</pre>
<p>Accessing streams in node.js is usually done asynchronously. We can take chunks of data from the ReadStream of <em>createPNGStream()</em> and pump that to the WriteStream of the output file. When the data from the PNG is done streaming, we tell the output stream to finish writing its buffered data and destroy itself. It sounds intense, but it's pretty straightforward.</p>
<p>Processing the colors and marker images is the fun part. To match the function call in the <em>init</em> function, we just create a function with a callback in the standard way.</p>
<pre class="brush: jscript; title: ; notranslate">
var processImage = function(cb) {
        // other code removed
	if(typeof cb === &quot;function&quot;) {
		cb.call(this);
	}
}
</pre>
<p>If there's a callback function passed as a parameter, when <em>processImage</em> is finished, it will call that function passing the current scope as the execution scope and no parameters.</p>
<p>To draw out the custom marker, we'll want to define how we want to display the text and at what color we want to have the 0.0 marker start.</p>
<pre class="brush: jscript; title: ; notranslate">
ctx.font = 'normal 12px Impact';
ctx.textAlign = 'center';
var color = [255, 255, 0, 235];
</pre>
<p>The color array represents red, green, blue, and alpha channel (opacity). This may look odd if you're used to specifying alpha channels in css as "rgba(255,255,0,0.92)", but that value of 235 will give roughly 92% opacity.</p>
<p>We can make the script run pretty quickly by using a second canvas 2d context for the recolor phases (which modifies every white pixel).</p>
<pre class="brush: jscript; title: ; notranslate">
// use a temp Canvas and Context of 35x35 size.
var tempCanvas = new Canvas(35,35);
var tempCtx = tempCanvas.getContext('2d');
</pre>
<p>This is an optimization I made today when tweaking the original script. In the original version of this script, I would write the base image to the output canvas then iterate over 'NxN' pixels on the output canvas to change the color of one pixel.  Using a temporary canvas context, we only have to iterate over 35 pixels wide by 35 pixels high for every new marker.  This not only speeds up the process, but it could be a difference of having a script that won't run on slower machines.</p>
<p>For each of the desired 100 magnitudes, we'll want to find the x and y values (top-left pixel) to which we'll write the updated marker. For every 1/2 magnitude, the Green color value decrements by 13 points.</p>
<pre class="brush: jscript; title: ; notranslate">
for(var magnitude = 0; magnitude &lt;= 100; magnitude++) {
	var y = 35 * Math.floor(magnitude/10),
		x = ( 35*(magnitude % 10) );

	// This increments the color slightly
	if(magnitude % 5 == 0){
		color[1] = color[1] - 13;
	}

        // some code removed

	ctx.fillText(&quot;&quot; + parseFloat(magnitude / 10, 1), x + (35/2), y + (35/2), 35);
}
</pre>
<p>The last line of the above snippet fills the magnitude text on the output canvas. This could be moved to the next part of the script for a further optimization: instead of just modifying each white pixel's color, we could recolor and apply the text.</p>
<p>The part of the script which changes the color according to the magnitude looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
tempCtx.drawImage(img, 0, 0, 35,35);
var imgData = tempCtx.getImageData(0, 0, 35, 35);
var data = imgData &amp;&amp; imgData.data;
if(data) {
	try {
		for(var pixel=0;pixel&lt;data.length;pixel=pixel+4) {
			var red = data[pixel]
			var green = data[pixel+1];
			var blue = data[pixel+2];
			var alpha = data[pixel+3];

			if(red == 255 &amp;&amp; green == 255 &amp;&amp; blue == 255) {
				data[pixel] = color[0];
				data[pixel+1] = color[1];
				data[pixel+2] = color[2];
				data[pixel+3] = color[3];
			}
		}
	} catch (err) { console.error(err.message); }

	// Write our temp image data to the final canvas context
	/* imageData, dx, dy, sx, sy, sw, sh */
	ctx.putImageData(imgData,x,y,0,0, 35, 35);
}
</pre>
<p>Writing to the temporary canvas's 2d context gives us access to a data buffer which represents a 35x35 image where each pixel is represented by 4 bytes (rgba). Iterating this buffer by 4's, we can check that the given pixel (excluding alpha because that doesn't matter in this case) is white or rgba(255,255,255). If the pixel is white, we replace those 4 indexes with the values in our color array.  When we're done iterating the buffer representing the 35x35 image, we can call <em>putImageData</em> on the output canvas. With that, the sprite is complete and our callback handles writing the file.</p>
<h2>A note about putImageData</h2>
<p><em>putImageData</em> can be a strange beast. Notice the comment <strong>imageData, dx, dy, sx, sy, sw, sh</strong>... these are the parameters accepted by the function. Even the <a href="http://dev.w3.org/html5/2dcontext/#dom-context-2d-putimagedata" title="HTML5 2d Context specs for putImageData" target="_blank">HTML5 Specs</a> might make you go, "Uhm... what?"  The idea is pretty simple once you understand it. You want to write a buffer (imgData) where the top-left pixel is at dx,dy. sx and sy (or dirtyX and dirtyY) represent a dirty rectangle of size sw x sh (or dirtyWidth by dirtyHeight).</p>
<p>If the imageData passed to the function is the same height and width as the target canvas context, you wouldn't want to overwrite <em>every single pixel</em> would you?  You'd only want to overwrite pixels that have changed. Suppose in this script, I had an imageData object of 350x350 to complement the output canvas. When putting the modified imageData, I would have to calculate the current 35x35 box offset and write out the imageData to 0,0. As an example, if I wanted to overwrite the 35x35 box for the 9.9 magnitude marker with an imageData buffer of 350x350, I might write:</p>
<pre class="brush: jscript; title: ; notranslate">
ctx.putImageData(imgData, 0, 0, 315, 315, 35, 35);
</pre>
<p>This would tell the context that although my buffer is 350x350, I've only changed a 35x35 rectangle starting at 315x15.  Canvas is smart enough to only update those pixels rather than every pixel in the canvas.</p>
<p>On the other hand, in the script I've written, I only have an imageData object which represents a 35x35 buffer.  So, I can tell <em>putImageData</em> to start at the point defined by (x,y) and write the buffer into a 35x35 rectangle. I like this method a little more, but it may not always be the case that you're writing a smaller buffer to the context.</p>
<h2>The code</h2>
<p>As always, the code for this blog post is available on github at <a href="https://github.com/jimschubert/blogs/tree/master/2012-10-14" title="jimschubert/blogs on github" target="_blank">jimschubert/blogs</a>.</p>
<h2>The sprite</h2>
<p>Here's what the generated sprite looks like.<br />
<div id="attachment_993" class="wp-caption aligncenter" style="width: 360px"><a href="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/markers.png?9d7bd4"><img src="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/markers.png?9d7bd4" alt="" title="Quaketracker markers" width="350" height="350" class="size-full wp-image-993" /></a><p class="wp-caption-text">Markers generated for Quaketracker</p></div></p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=981&amp;md5=e1004610ecaa996a0cc8927c9501cb0b" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/QSNiOfwDSQw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/10/generating-sprites-with-html5-canvas-node-canvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F10%2Fgenerating-sprites-with-html5-canvas-node-canvas%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Generating+sprites+with+HTML5+canvas+%28node-canvas%29&amp;description=About+a+week+ago%2C+I+posted+about+drawing+simple+shapes+in+HTML5.+HTML5%27s+Canvas+isn%27t+only+useful+on+the+client+side.+About+a+year+ago%2C+I+rewrote+my+Quaketracker+mashup...&amp;tags=Advanced%2CExamples%2Chtml5%2Cnodejs%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/10/generating-sprites-with-html5-canvas-node-canvas/</feedburner:origLink></item>
		<item>
		<title>Getting started with jQuery plugins</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/1lXMc0WKxHA/</link>
		<comments>http://www.ipreferjim.com/2012/10/getting-started-with-jquery-plugins/#comments</comments>
		<pubDate>Sun, 14 Oct 2012 01:57:52 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Examples]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=973</guid>
		<description><![CDATA[jQuery plugins aren't that difficult to write, but some folks seem to have a hard time understanding how to get started, so I thought I would write a quick blog post about that. I'll show how to make a pretty simple keyword highlighter which also wraps your pre/code elements in a div with a header [...]]]></description>
				<content:encoded><![CDATA[<p>jQuery plugins aren't that difficult to write, but some folks seem to have a hard time understanding how to get started, so I thought I would write a quick blog post about that. I'll show how to make a pretty simple keyword highlighter which also wraps your pre/code elements in a div with a header span element.</p>
<p>I've written a few jQuery plugins before.  One of my favorites is <a href="https://github.com/jimschubert/jquery.empuzzle" title="jimschubert/jquery.empuzzle" target="_blank">jquery.empuzzle</a>. This is a favorite not only because it's <a href="http://jimschubert.github.com/jquery.empuzzle/" title="Try out jquery.empuzzle" target="_blank">incredibly fun</a>, but because it covers a few areas of jquery plugin development:</p>
<ol>
<li>default options</li>
<li>merge options</li>
<li>custom selectors</li>
<li>plugin structure</li>
</ol>
<p>It also covers a particular gotcha when your plugin interacts with images (i.e. images may load after document ready is fired). It's definitely worth checking it out, but I'd like to show a much simpler plugin here.</p>
<h2>The structure</h2>
<p>jQuery plugins are commonly written as an *immediate function*. This is creates a closure which executes immediate on the jQuery object itself:</p>
<pre class="brush: jscript; title: ; notranslate">
;(function($) {
    // your plugin goes here.
})(jQuery);
</pre>
<p>I often wrap a jQuery plugin in semicolons as you see above to prevent any <a href="http://bonsaiden.github.com/JavaScript-Garden/#core.semicolon" title="Semicolon insertion explained at JavaScript Garden" target="_blank">automatic semicolon insertion errors</a>.  This is something I would consider a 'best practice' and I suggest you do the same.</p>
<p>Within this structure, you'll want to extend jQuery to include your plugin's code.</p>
<p>$.fn is a pointer to the jQuery prototype object. When you execute a jQuery call like this:</p>
<pre class="brush: jscript; title: ; notranslate">
var examples = $('.test-elements');
</pre>
<p>.. you will receive a jQuery object. This object represents an array of results matching the selector passed to the jQuery function.  You can use <em>console.log()</em> from within your plugin function to see how you might interact with this object.</p>
<pre class="brush: jscript; title: ; notranslate">
;(function($) {
    $.fn.example = function(arg) {
        console.log(this);
    };
})(jQuery);
</pre>
<p>You now have the start to a plugin called 'example'.  You can execute this 'plugin' in the normal way.</p>
<pre class="brush: jscript; title: ; notranslate">
var examples = $('.test-elements');
examples.example();

// same as: $('.test-elements').example();
</pre>
<p>Now, you'll want to iterate over each object found by the query selector and perform whatever functionality your plugin will provide. Let's define some functionality so we can have a (somewhat) useful plugin.  We'll keep with the 'example' theme and write a plugin which stylizes a &lt;code&gt; tag and adds a small box in the top-left corner which says 'Example'. (I got this idea from Twitter's Bootstrap framework, <a href="http://twitter.github.com/bootstrap/base-css.html" title="Twitter Bootstrap on Github" target="_blank">see here</a>).  We'll also 'highlight' a few keywords within our example.</p>
<p>Here's what we want our final product to look like (after some hideous styling, of course):</p>
<p><a href="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/Selection_011.png?9d7bd4"><img src="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/Selection_011.png?9d7bd4" alt="" title="Selection_011" width="430" height="114" class="aligncenter size-full wp-image-974" /></a></p>
<p>For the goal screenshot, I've used <a href="http://code.google.com/p/google-code-prettify/" title="Google Code prettify" target="_blank">Google's prettify</a> plugin, which is licensed under <a href="http://www.apache.org/licenses/LICENSE-2.0" title="Apache 2.0 License" target="_blank">Apache 2.0</a>.  I don't use this in the final product.</p>
<p>There will be a few things we'll need to do in this plugin:</p>
<ol>
<li>Merge settings specified by the user with our default settings</li>
<li>Wrap the code block in a styled 'example' box</li>
<li>"parse" the contents for a select set of keywords</li>
<li>Wrap any found keywords with a style span</li>
</ol>
<p>For the parsing bit, I'll just use a global RegEx replace on the contents of the code element.</p>
<h2>Providing defaults</h2>
<p>Providing defaults in a jQuery plugin and allowing a user to pass options to merge isn't difficult. Your plugin function will accept a parameter I like to call 'opts' and return a `this.each` function.  Within the `.each` function, you'll extend the defaults object with those options passed into your plugin function and store the merged options into a new object called 'options'. A very simple example which writes out to console.log might look like this:</p>
<pre class="brush: jscript; title: ; notranslate">
;(function($) {
    var defaults = {
        arr: [1,2,3,4,5,6],
        sample: &quot;sample&quot;,
        style: &quot;style&quot;
    };

    var example = function(opts) {
        return this.each(function() {
            // merge opts with defaults into new object
            // so changes don't change defaults
            var options = $.extend({}, defaults, opts);
            console.log({ 
                elem: this.innerText,
                options: options
            });
        });
    };

    $.fn.example = example;
})(jQuery);
</pre>
<p>Here are some options we might want to allow for the example plugin:</p>
<ol>
<li>A class name for the box and a class name for the label</li>
<li>An object mapping keywords to class names.</li>
<li>A parse error callback</li>
<li>A data attribute to specify a different 'Example' box text (so each element can define its own label)</li>
</ol>
<p>Our <em>defaults</em> object will look like this (more or less):</p>
<pre class="brush: jscript; title: ; notranslate">
    var defaults = {
        boxCss: &quot;example-box&quot;,
	labelCss: &quot;example-label&quot;,
        keywords: { &quot;function&quot;:&quot;blue&quot;, &quot;this&quot;:&quot;blue&quot;, &quot;jQuery&quot;:&quot;red&quot; },
        onError: function() { },
        exampleAttr: &quot;&quot;
    };
</pre>
<h2>Wrapping our targets</h2>
<p>To make our lives simple, we'll first wrap the target element with a div for our example box.  Then, we'll add a span just before the code block.  We can improve performance by creating the wrapper div's HTML outside of the '.each' function.  Because we're allowing the option of pulling the labeling span's text from the code element itself, we'll have to build that HTML within the '.each' function.</p>
<p>Here's what we have so far.</p>
<pre class="brush: jscript; title: ; notranslate">
;(function($) {
    var defaults = {
        boxCss: &quot;example-box&quot;,
        labelCss: &quot;example-label&quot;,
        keywords: { &quot;function&quot;:&quot;blue&quot;, &quot;this&quot;:&quot;blue&quot;, &quot;jQuery&quot;:&quot;red&quot; },
        onError: function() { },
        exampleAttr: &quot;&quot;
    };

    var example = function(opts) {
        var options = $.extend({}, defaults, opts);
        
        var wrapperHtml = [
            '&lt;div class=&quot;',
            options.boxCss,
            '&quot;&gt;&lt;/div&gt;'
        ].join('');

        var labelArr = [
            '&lt;span class=&quot;',
            options.labelCss,
            '&quot;&gt;',
            &quot;Example&quot;,
            '&lt;/span&gt;'
        ];

        return this.each(function() {
            var labelText = &quot;Example&quot;;
            if(options.exampleAttr) {
                labelText = $(this).attr(options.exampleAttr);
            }

            var labelHtml = [
                '&lt;span class=&quot;',
                options.labelCss,
                '&quot;&gt;',
                labelText,
                '&lt;/span&gt;'
            ].join('');

            $(this).wrap(wrapperHtml);
            $(this).before(labelHtml);
        });
    };

    $.fn.example = example;
})(jQuery);
</pre>
<h2>onError function</h2>
<p>The onError function we allow in the options object does nothing more than provide a message if we don't have a code element to update with keyword highlights.  We will supply a message to the callback function and return from the current iteration of '.each'.  This goes at the beginning of the 'this.each' function.</p>
<pre class="brush: jscript; title: ; notranslate">
// Find node for replacing text.
var replacementNode = $(this).children('code').andSelf().filter('code');

if(replacementNode.length == 0) {
    if(typeof options.onError === &quot;function&quot;){
        options.onError(&quot;No code nodes found&quot;);
    }
    
    return;
}
</pre>
<p>With the combination of children/andSelf/filter in the above code, we allow the plugin to operate on both 'pre' and 'code' elements.</p>
<p>When allowing users to pass functions as callbacks or to provide added functionality to a plugin, *always* check that it is a function.</p>
<h2>"Parsing" contents</h2>
<p>In the interest of saving some time, I'm going to use a regular expression to replace text within the code block. This isn't necessarily the most efficient way to achieve a budget syntax highlighter, but it will work.</p>
<p>To do this, we'll need to grab the text from our code node in which we'll replace keywords.  Then, for every keyword in the hash of keywords-to-classes, we'll create a span to represent the highlighted keyword. Then, we'll do a search and replace using a global regular expression object, substituting each found keyword with the keyword wrapped in a span element.  This goes at the end of the 'this.each' function.</p>
<pre class="brush: jscript; title: ; notranslate">
    var originalText = replacementNode.text();
            
    Object.keys(options.keywords).forEach(function(key,idx){
        var replacement = [
            '&lt;span class=&quot;',
            options.keywords[key],
            '&quot;&gt;',
            key,
            '&lt;/span&gt;'
        ].join('');
        
        var re = new RegExp(key,&quot;g&quot;);
        originalText = originalText.replace(re, replacement);
    });
</pre>
<p>The only thing left to do is to add styles to your document and you're all set with a customized syntax highlighter!</p>
<p>There are a few issues with this simple implementation.  First, keywords don't get merged (I'll leave that as an exercise for you).  Second, this only highlights keywords. It doesn't provide regex matching for full-text highlights. In other words, this won't highlight comments.</p>
<p>If you're unfamiliar with jQuery plugins, or you're planning to begin writing a keyword highlighter plugin, this should at least get you started!</p>
<h2>Try it out!</h2>
<p>Check out the <a href="http://jsfiddle.net/jimschubert/ScvZW/" title="An example on jsfiddle" target="_blank">jsfiddle</a>.<br />
<iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/jimschubert/ScvZW/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<h2>Get the code</h2>
<p>The code for this blog post is <a href="https://github.com/jimschubert/blogs/tree/master/2012-10-13" title="Code for this post is available on Github" target="_blank">available on Github</a>.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=973&amp;md5=bec2e3f54e46f38205c021a438715569" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/1lXMc0WKxHA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/10/getting-started-with-jquery-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F10%2Fgetting-started-with-jquery-plugins%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Getting+started+with+jQuery+plugins&amp;description=jQuery+plugins+aren%27t+that+difficult+to+write%2C+but+some+folks+seem+to+have+a+hard+time+understanding+how+to+get+started%2C+so+I+thought+I+would+write+a+quick+blog...&amp;tags=Examples%2CJavascript%2CjQuery%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/10/getting-started-with-jquery-plugins/</feedburner:origLink></item>
		<item>
		<title>Drawing a custom HTML5 shape</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/5i4sPtRDhFE/</link>
		<comments>http://www.ipreferjim.com/2012/10/drawing-a-custom-html5-shape/#comments</comments>
		<pubDate>Thu, 04 Oct 2012 16:48:28 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=961</guid>
		<description><![CDATA[HTML5 is fun. I've meant to post about it more than I have in the past (which is 0 posts). I recently got the urge, so I want to show how to draw a heart and a star on HTML5 canvas. Some background A few days ago, I heard about typescript, which is a typed [...]]]></description>
				<content:encoded><![CDATA[<p>HTML5 is fun. I've meant to post about it more than I have in the past (which is 0 posts).  I recently got the urge, so I want to show how to draw a heart and a star on HTML5 canvas.</p>
<h2>Some background</h2>
<p>A few days ago, I heard about <a href="http://www.typescriptlang.org/" title="typescript" target="_blank">typescript</a>, which is a typed superset of JavaScript. It's similar to coffeescript, dart, and others in that it defines a language which compiles down to plain JavaScript. It's different than most because it gives JavaScript the concept of types and compile-time type checking. The compiler is available cross-platform, but the IDE tools are only available for Visual Studio 2012 or in-browser on the website.</p>
<p>Anyway, I wanted to play around with typescript so I decided to see how easily I could convert <a href="https://github.com/jimschubert/brushes.js" title="brushes.js on github" target="_blank">brushes.js</a> to use some of the typed semantics of typescript.  It wasn't too difficult and the code actually looks way cleaner in typescript. The only issue I've found is that types are not inferred 100% accurately at times.  For instance, <a href="https://developer.mozilla.org/en-US/docs/DOM/document.getElementsByTagName" title="getElementsByTagName on Mozilla Developer Network" target="_blank">document.getElementsByTagName</a> returns a NodeList. Indexed elements are considered Node elements and <em>not</em> a more specific type.  An example, you would expect the following snippet to compile properly:</p>
<pre class="brush: jscript; title: ; notranslate">
if($tag) {
	var canvas = $tag('canvas') ? $tag('canvas')[0] : null;
	if(canvas &amp;&amp; canvas.getContext) {
		this.context = canvas.getContext(&quot;2d&quot;);
	}
}
</pre>
<p>Unfortunately, you're presented with a message that says <em>getContext</em> doesn't exist on Node.<br />
<a href="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/Selection_010.png?9d7bd4"><img src="http://www.ipreferjim.com/site/wp-content/uploads/2012/10/Selection_010.png?9d7bd4" alt="typescript Node select message" title="typescript Node select message" width="612" height="128" class="aligncenter size-full wp-image-965" /></a></p>
<p>To remove this message, you need to do something I personally don't like doing (although it's completely legal in JavaScript)-- access the function by key.</p>
<pre class="brush: jscript; title: ; notranslate">
if($tag) {
	var canvas = $tag('canvas') ? $tag('canvas')[0] : null;
	if(canvas &amp;&amp; canvas[&quot;getContext&quot;] &amp;&amp; typeof canvas[&quot;getContext&quot;] === &quot;function&quot;) {
		this.context = canvas[&quot;getContext&quot;](&quot;2d&quot;);
	}
}
</pre>
<p>Aside from this little problem, I found the coding experience to be beneficial and fun.  In fact, while modifying some of the code for the brushes (hearts and stars), I was motivated to write a blog post showing how to create some basic custom shapes in HTML5...</p>
<h2>HTML5</h2>
<p>The awesome thing about HTML5 is that you now have a drawing area natively embedded directly into HTML.  That's pretty awesome because it opens up the browser to do some really awesome stuff. There are some pretty phenomenal examples of the power of HTML5 (sometimes mixed with WebGL) at <a href="www.chromeexperiments.com" title="www.chromeexperiments.com" target="_blank">chromeexperiments.com</a>. In fact, I had the urge to start working on brushes.js after playing with an experiment called Harmony by MrDoob.  MrDoob has since moved onto creating the hugely-popular <a href="http://mrdoob.github.com/three.js/" title="three.js" target="_blank">three.js</a>.  With those two links, I think you can get lost for hours in the power of the browser. If you're just getting started with some of the new HTML5 APIs, you may want to check out <a href="http://html5demos.com/" title="html5demos.com" target="_blank">remy's HTML5 demos</a>.</p>
<h2>Drawing</h2>
<div class="wp-caption aligncenter" style="width: 713px"><a href="http://xkcd.com/1029/"><img alt="How to draw a star on xkcd.com" src="http://imgs.xkcd.com/comics/drawing_stars.png" title="How to draw a star on xkcd.com" width="703" height="208" /></a><p class="wp-caption-text">Image courtesy of xkcd.com</p></div>
<p>Drawing is nothing new in programming.  You can easily find algorithms for drawing specific shapes on game dev sites.  In fact, I believe I found the algorithm for the star in a C++ game programming book I purchased but haven't gotten around to reading fully.</p>
<p>The HTML5 canvas is a grid in which (0,0) is in the top-let corner of the grid. It is easiest to draw shapes starting at the origin, then move them into place when you're done.  The canvas API makes this easy using the <a href="https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Transformations#A_translate_example" title="translate on MDN" target="_blank">translate</a> function.  Suppose you want to draw an image at (100,100). Using <em>context.translate(100,100)</em> (where <em>context</em> is the 2d drawing context of your canvas element) will cause the drawing context to temporarily set the origin at (100,100), allowing you to draw easily without the headache of calculating offsets.</p>
<p>The steps necessary to draw a simple shape are as follows:</p>
<ol>
<li>Query the dom for the canvas element</li>
<li>Call <em>context.getContext("2d")</em> on canvas element</li>
<li>Save the context</li>
<li>Translate context origin to desired location</li>
<li>Set additional properties on the context</li>
<li>Call <em>context.beginPath()</em></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Drawing_shapes" title="Canvas - Drawing Shapes on MDN" target="_blank">Draw your shapes</a></li>
<li>Stroke or fill your shape</li>
<li>Call <em>context.closePath()</em> to indicate drawing has completed</li>
<li>Call <em>context.restore()</em> to restore the previously saved context</li>
</ol>
<p>This may seem like quite a bit. For an example, I've created a <a href="http://jsfiddle.net/jimschubert/cBu9a/1/" title="HTML5 shapes" target="_blank">jsfiddle</a> so you can play around and see the above steps in action.</p>
<h3>Try it</h3>
<p><iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/jimschubert/cBu9a/1/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<h3>Code</h3>
<p>The code for this blog post is available on github at <a href="https://github.com/jimschubert/blogs/tree/master/2012-10-04" title="gh:jimschubert/blogs">jimschubert/blogs</a></p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=961&amp;md5=4c1bd8427b78603f2a6225aac7fced09" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/5i4sPtRDhFE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/10/drawing-a-custom-html5-shape/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F10%2Fdrawing-a-custom-html5-shape%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Drawing+a+custom+HTML5+shape&amp;description=HTML5+is+fun.+I%27ve+meant+to+post+about+it+more+than+I+have+in+the+past+%28which+is+0+posts%29.+I+recently+got+the+urge%2C+so+I+want+to+show...&amp;tags=html5%2CJavascript%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/10/drawing-a-custom-html5-shape/</feedburner:origLink></item>
		<item>
		<title>My Review of Hilary Mason: Advanced Machine Learning</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/zXTnnvxDDU0/</link>
		<comments>http://www.ipreferjim.com/2012/09/my-review-of-hilary-mason-advanced-machine-learning/#comments</comments>
		<pubDate>Sat, 22 Sep 2012 19:49:34 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Review]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=951</guid>
		<description><![CDATA[Originally submitted at O'Reilly Hilary Mason: Advanced Machine Learning Hilary Mason: Advanced Machine Learning More "Intro to Machine Learning part 2" By Jim Schubert from Richmond, VA on 9/22/2012 &#160; 4out of 5 Pros: Helpful examples, Easy to understand Cons: Too basic, Not comprehensive enough Best Uses: Novice, Student Describe Yourself: Developer I watched this [...]]]></description>
				<content:encoded><![CDATA[<div class="hreview">
<div class="item">
<p><a href="http://shop.oreilly.com/product/0636920025610.do">Originally submitted at O'Reilly</a></p>
<div><img src="http://images.powerreviews.com/images_products/06/58/18430068_100.jpg" class="photo" align="left" style="margin: 0 0.5em 0 0">
<p style="margin-top:0">Hilary Mason: Advanced Machine Learning</p>
</div>
<p><a href="http://shop.oreilly.com/product/0636920025610.do" style="display: none;" class="url fn"><span class="fn">Hilary Mason: Advanced Machine Learning</span></a></div>
<p><br clear="left">
<p><strong class="summary">More "Intro to Machine Learning part 2"</strong></p>
<div>By <strong>Jim Schubert</strong> from <strong>Richmond, VA</strong> on <strong><abbr title="2012922T1200-0800" class="dtreviewed" style="border: none; text-decoration: none;">9/22/2012</abbr></strong></div>
<p>
<div style="margin: 0.5em 0; height: 15px; width: 83px; background-image: url(http://images.powerreviews.com/images/stars_small.gif); background-position: 0px -144px;" class="prStars prStarsSmall">&nbsp;</div>
</p>
<div style="display: none"><span class="rating">4</span>out of 5</div>
<p><strong>Pros: </strong>Helpful examples, Easy to understand</p>
<p><strong>Cons: </strong>Too basic, Not comprehensive enough</p>
<p><strong>Best Uses: </strong>Novice, Student</p>
<p><strong>Describe Yourself: </strong>Developer</p>
<p style="margin-top:1em" class="description">I watched this video as part of O'Reilly Media's blogger program. I haven't worked with machine learning topics in the past, and I was interested to learn a bit from this video. It turns out that I use many of the machine learning concepts in the linux terminal almost daily, but on much smaller data (personal computer logs). I've even parsed Apache logs in almost the same way as presented in this video's "Learning from your data" segment.<br xmlns:pr="xalan://com.pufferfish.core.beans.xmlbuilders.xsl.Functions"><br />At first, I was little confused why this video is called "Advanced Machine Learning" because I didn't feel like any of the topics were all too advanced. Each segment seems to only skim the surface of a very general topic. In fact, it seems to me that this video is more of a continuation of Ms. Mason's other Machine Learning video on O'Reilly-- "An Introduction to Machine Learning with Web Data." It may be more appropriately named "An introduction to data analysis", and that's not a bad thing! Don't be turned away by a misleading title. Fair warning: I've rated the video based on the content with my proposed title.</p>
<p>If you're looking for an in-depth discussion of machine learning algorithms, this isn't the video for you. If you're looking for an introduction in getting things done with data, you should check out this video. Although the amount of information is pretty light, it is still a good way to get your start conceptually. If you look at the scripts and sample data provided in the code repository, you'll be off to a good start to learn more about your data.</p>
<p>For instance, Hillary makes it a point to break things down into a few simple steps:</p>
<p>1) What is your data?<br />2) What do you want to learn from your data?<br />3) How to extract that information.</p>
<p>Again, I wouldn't recommend this video if you're  software engineer with a desire to learn in-depth machine learning algorithms. I do recommend this video if you're interested in understanding some fundamentals of machine learning and how they're applied in some advanced production scenarios (especially at bit.ly).</p>
<p>I also recommend checking out the code examples and learning the basics of the python modules used in the scripts. They will help you analyze your data in a meaningful way.</p>
<p style="margin-top:0.5em">(<a href="http://www.powerreviews.com/legal/terms_of_use.html" rel="license">legalese</a>)</p>
</div>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=951&amp;md5=45753b5c4f87dcf7a14c2c414dd5ede0" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/zXTnnvxDDU0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/09/my-review-of-hilary-mason-advanced-machine-learning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F09%2Fmy-review-of-hilary-mason-advanced-machine-learning%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=My+Review+of+Hilary+Mason%3A+Advanced+Machine+Learning&amp;description=Originally+submitted+at+O%27Reilly+Hilary+Mason%3A+Advanced+Machine+Learning+Hilary+Mason%3A+Advanced+Machine+Learning+More+%22Intro+to+Machine+Learning+part+2%22+By+Jim+Schubert+from+Richmond%2C+VA+on+9%2F22%2F2012+%26nbsp%3B...&amp;tags=Review%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/09/my-review-of-hilary-mason-advanced-machine-learning/</feedburner:origLink></item>
		<item>
		<title>bash function: md.view</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/zd8fDHRn_BY/</link>
		<comments>http://www.ipreferjim.com/2012/09/bash-function-md-view/#comments</comments>
		<pubDate>Sat, 15 Sep 2012 17:00:23 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Tricks]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=945</guid>
		<description><![CDATA[One of my favorite bash functions is md.view, which is available in my dotfiles repository. There's not really anything particularly cool about this function. It checks for markdown and reminds me to install it if I haven't yet. It doesn't do this for Google Chrome because that's the first application I install on new machines. [...]]]></description>
				<content:encoded><![CDATA[<p>One of my favorite bash functions is <strong>md.view</strong>, which is available in my <a href="https://github.com/jimschubert/dotfiles/blob/master/.bash/functions" title="dotfiles" target="_blank">dotfiles</a> repository.</p>
<pre class="brush: bash; title: ; notranslate">
# test markdown files, probably a better way to test for programs.
function md.view {
    local i=true
    type -p markdown &amp;&gt; /dev/null || i=false
    if $i ; then 
        local output=&quot;/tmp/md.view-$(date +%F).html&quot;;
        markdown $1 &gt; &quot;$output&quot;;
        google-chrome &quot;$output&quot;; # xdg-open would open default browser after next line executes
        rm &quot;$output&quot;;
    else
        echo &quot;markdown is not installed&quot;
    fi
}
</pre>
<p>There's not really anything particularly cool about this function.  It checks for markdown  and reminds me to install it if I haven't yet.  It doesn't do this for Google Chrome because that's the first application I install on new machines. Usually, you'd use <code>xdg-open</code> to choose a browser, but this can cause problems with the remove command at the end of the function (depending on how the browser creates its process).</p>
<p>Anyway, this is really useful when I'm creating README files using markdown for my github repositories.  For instance, I was just updating a README to refer to *_32.png images.  The problem is that <code>*</code> and <code>_</code> are special tokens in markdown. I'd never attempted to escape one after the other, which is often broken in parsers.  With this function in my extended .bash\functions, I can quickly check output with:</p>
<pre class="brush: bash; title: ; notranslate">
$ md.view README.md
</pre>
<p>I know, it's such a simple thing to have as a favorite. Sometimes really simple things have a huge impact, especially if you type out README files regularly </p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=945&amp;md5=010bda899351344a237fb843c3c969ce" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/zd8fDHRn_BY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/09/bash-function-md-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F09%2Fbash-function-md-view%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=bash+function%3A+md.view&amp;description=One+of+my+favorite+bash+functions+is+md.view%2C+which+is+available+in+my+dotfiles+repository.+There%27s+not+really+anything+particularly+cool+about+this+function.+It+checks+for+markdown+and+reminds...&amp;tags=linux%2CTricks%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/09/bash-function-md-view/</feedburner:origLink></item>
		<item>
		<title>Internal Server Error in .NET 4, “Calling LoadLibraryEx on ISAPI filter”</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/4Nb2lzLi6ik/</link>
		<comments>http://www.ipreferjim.com/2012/08/internal-server-error-in-net-4-calling-loadlibraryex-on-isapi-filter/#comments</comments>
		<pubDate>Thu, 16 Aug 2012 00:30:04 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=940</guid>
		<description><![CDATA[I encountered an odd issue today. I received an Internal Server Error for a .NET 4 application: I looked around for a quick solution and found a few articles which suggested running aspnet_regiis -r from the Framework64 directory. This didn't work. Then, I noticed the path separator is doubled in the message. Removing this extra [...]]]></description>
				<content:encoded><![CDATA[<p>I encountered an odd issue today.</p>
<p>I received an Internal Server Error for a .NET 4 application:</p>
<pre class="brush: plain; title: ; notranslate">
Calling LoadLibraryEx on ISAPI filter &quot;C:\Windows\Microsoft.NET\Framework\v4.0.30319\\aspnet_filter.dll&quot; failed
</pre>
<p>I looked around for a quick solution and found a few articles which <a href="http://blog.clicdata.com/2010/09/05/calling-loadlibraryex-on-isapi-filter-cwindowsmicrosoft-netframeworkv4-0-30319aspnet_filter-dll-failed/" title="An article with aspnet_regiis solution" target="_blank">suggested </a>running <strong>aspnet_regiis -r</strong> from the Framework64 directory.  This didn't work.</p>
<p>Then, I noticed the path separator is doubled in the message.  Removing this extra backslash fixes the issue.</p>
<p>To Fix in IIS 7:</p>
<ol>
<li>Hit WINDOWS KEY + R, and run <strong>inetmgr</strong></li>
<li>Highlight either your machine or site node in the left panel</li>
<li>Choose <strong>ISAPI Filters</strong> from the middle panel</li>
<li>Expand the 'Executable' column in the ISAPI Filters view</li>
<li>Double-click the offending filter (in my case, <em>ASP.NET_4.0.30319.0</em>)</li>
<li>Remove the duplicate '\' and click 'OK'</li>
<li>Restart the service and everything should be good</li>
</ol>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=940&amp;md5=524a69cff54eaf8c3272ded2fef8133f" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/4Nb2lzLi6ik" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/08/internal-server-error-in-net-4-calling-loadlibraryex-on-isapi-filter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F08%2Finternal-server-error-in-net-4-calling-loadlibraryex-on-isapi-filter%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=Internal+Server+Error+in+.NET+4%2C+%26%238220%3BCalling+LoadLibraryEx+on+ISAPI+filter%26%238221%3B&amp;description=I+encountered+an+odd+issue+today.+I+received+an+Internal+Server+Error+for+a+.NET+4+application%3A+I+looked+around+for+a+quick+solution+and+found+a+few+articles+which...&amp;tags=blog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/08/internal-server-error-in-net-4-calling-loadlibraryex-on-isapi-filter/</feedburner:origLink></item>
		<item>
		<title>ServiceStack’s Markdown Razor Engine. Wow.</title>
		<link>http://feedproxy.google.com/~r/ipreferjim/~3/oxQCe_ObHL0/</link>
		<comments>http://www.ipreferjim.com/2012/07/servicestacks-markdown-razor-engine-wow/#comments</comments>
		<pubDate>Sun, 15 Jul 2012 16:08:38 +0000</pubDate>
		<dc:creator>jimschubert</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Examples]]></category>

		<guid isPermaLink="false">http://www.ipreferjim.com/?p=931</guid>
		<description><![CDATA[ServiceStack is a pretty sweet-looking alternative to WCF. It provides strongly-typed, well-designed, REST/RCP+SOAP services for .NET and Mono. Check out the README in the repository to see how ridiculously easy it is to setup a service. Unfortunately, I haven't yet had a chance to use the stack. I was looking through the code today and [...]]]></description>
				<content:encoded><![CDATA[<p><a href="https://github.com/ServiceStack/ServiceStack" title="ServiceStack/ServiceStack on github" target="_blank">ServiceStack</a> is a pretty sweet-looking alternative to WCF. It provides strongly-typed, well-designed, REST/RCP+SOAP services for .NET and Mono.  Check out the README in the repository to see how ridiculously easy it is to setup a service.  Unfortunately, I haven't yet had a chance to use the stack. I was looking through the code today and saw a Markdown-Razor Engine.</p>
<p>I was like, <strong>"Wha....?</strong></p>
<p>Yes, they offer an alternative view engine which blends <a href="http://daringfireball.net/projects/markdown/" title="Click for more info on markdown" target="_blank">Markdown</a> and Razor.  These are my two favorite syntaxes, so I had to see how well it compiles.</p>
<p>I compiled the ServiceStack.RazorEngine from source (in Ubuntu 12.04/Mono, no less!) to test a simple markdown file.</p>
<p>I created this markdown file, <strong>example.md</strong>, to throw at the framework.</p>
<pre class="brush: plain; title: ; notranslate">
# Example ServiceStack.Markdown

## Showing @examples.Count items

@foreach (var item in examples) {
  - @item.Name: @item.Number 
}


**Note: The template requires a space after the item.Number value**

For more information, check out 
[the docs](http://www.servicestack.net/docs/markdown/markdown-razor).

Also, *don't forget* to check out the code at 
[gh:ServiceStack/ServiceStack](https://github.com/ServiceStack/ServiceStack)

Here are some _other_ attempts to **break** 
the markdown **generation_of_html**. **escaped\_underscore\_in\_tags**

A space after double-asterisk (&amp;lt;strong&amp;gt; tags) will ** break **
</pre>
<p>Now, when I say <em>simple</em>, I mean it has most elements of markdown that I use regularly.  It also uses the markdown-razor <strong>foreach</strong> syntax which iterates over a collection of <strong>Example</strong> objects.  This view is not strongly-typed, so this is equivalent to a dynamic Razor view.</p>
<p>The code to compile this view is really simple. You create the template engine, and provide a markdown page object which takes a full path (.e.g <em>/fakepath/Debug</em>) and the template contents (e.g. the above markdown snippet). </p>
<pre class="brush: csharp; title: ; notranslate">
// Create the markdown-razor template compiler
MarkdownFormat format = new MarkdownFormat();
string contents = File.ReadAllText(template);
var page = new MarkdownPage(format, path, &quot;example&quot;, contents );
format.AddPage(page);
</pre>
<p>Then, you create your view object (ViewBag?).</p>
<pre class="brush: csharp; title: ; notranslate">
// Create our view container (ViewBag)
var view = new Dictionary&lt;string, object&gt;() 
{
	{ &quot;examples&quot;, examples }
};
</pre>
<p>All that's left is to pass in the view object and compile it to html!</p>
<pre class="brush: csharp; title: ; notranslate">
// Compile and output. 
// This can be redirected to html file 
// e.g. RazorExample.exe &gt; output.html
var html = format.RenderDynamicPageHtml(&quot;example&quot;, view);
Console.WriteLine(html);
</pre>
<h2>The Code</h2>
<p>As always, the code for this post is <a href="https://github.com/jimschubert/blogs/tree/master/2012-07-15" title="The code for this post is available on github" target="_blank">available on github</a>.  More examples on the Markdown Razor syntax available in ServiceStack are available in the test project in ServiceStack's repository.</p>
 <p><a href="http://www.ipreferjim.com/site/?flattrss_redirect&amp;id=931&amp;md5=3ea64710c442be8ff384e8242e3778f0" title="Flattr" target="_blank"><img src="http://www.ipreferjim.com/site/wp-content/plugins/flattr/img/flattr-badge-large.png?9d7bd4" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/ipreferjim/~4/oxQCe_ObHL0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.ipreferjim.com/2012/07/servicestacks-markdown-razor-engine-wow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=jimschubert&amp;popout=1&amp;url=http%3A%2F%2Fwww.ipreferjim.com%2F2012%2F07%2Fservicestacks-markdown-razor-engine-wow%2F&amp;hidden=1&amp;language=en_GB&amp;category=text&amp;title=ServiceStack%26%238217%3Bs+Markdown+Razor+Engine.+Wow.&amp;description=ServiceStack+is+a+pretty+sweet-looking+alternative+to+WCF.+It+provides+strongly-typed%2C+well-designed%2C+REST%2FRCP%2BSOAP+services+for+.NET+and+Mono.+Check+out+the+README+in+the+repository+to+see+how+ridiculously+easy...&amp;tags=C%23%2CExamples%2Cblog" type="text/html" />
	<feedburner:origLink>http://www.ipreferjim.com/2012/07/servicestacks-markdown-razor-engine-wow/</feedburner:origLink></item>
	</channel>
</rss><!-- Served from: www.ipreferjim.com @ 2013-06-10 06:06:46 by W3 Total Cache -->
