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

<channel>
	<title>John Sheehan : Blog &#187; C#</title>
	<atom:link href="http://john-sheehan.com/blog/index.php/category/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://john-sheehan.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 30 Aug 2010 22:13:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Using Web Service APIs in Your Apps (Twin Cities .NET User Group Talk Video)</title>
		<link>http://john-sheehan.com/blog/using-web-service-apis-in-your-apps-video/</link>
		<comments>http://john-sheehan.com/blog/using-web-service-apis-in-your-apps-video/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 23:44:33 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[RestSharp]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/?p=213</guid>
		<description><![CDATA[On November 5th I gave a talk at the Twin Cities .NET User Group entitled &#8216;Using web service APIs in your applications&#8217;. I started out with a very brief overview of how REST APIs work and then talked about the current state of using REST APIs in .NET. I followed that up with a demonstration [...]]]></description>
			<content:encoded><![CDATA[<p>On November 5th I gave a talk at the <a href="http://www.tcdnug.com" target="_blank">Twin Cities .NET User Group</a> entitled &#8216;Using web service APIs in your applications&#8217;. I started out with a <em>very </em>brief overview of how REST APIs work and then talked about the current state of using REST APIs in .NET. I followed that up with a demonstration of a new OSS project I&#8217;m working on for making accessing REST APIs much easier. The project is called <a href="http://twitter.com/RestSharp" target="_blank">RestSharp</a> but in the talk I refer to it as Stillwater as that was my working name for it prior to coming up with the final name.</p>
<p>Next I put <a href="http://restsharp.org" target="_blank">RestSharp</a> to use by writing a Twitter search bot that runs as an Azure worker role searching for mentions of a search term and then creating <a href="http://www.fogbugz.com" target="_blank">FogBugz</a> tasks from the results. Then I demonstrated using <a href="http://twilio.com" target="_blank">Twilio</a> to receive phone calls (utilizing ASP.NET MVC) and create FogBugz cases from those incoming phone calls. And lastly I demonstrated how to use RestSharp with Twilio&#8217;s REST API to initiate an outgoing phone call from a .NET app.</p>
<p>This was my first formal technical presentation (I gave one at jQuery Conference, but that was much more informal) and you can tell early on in the video. Stick with it however, things smooth out as they go along. Also, the audio is a little tinny with some minor background noise, but it&#8217;s not unbearable.</p>
<p>I&#8217;ll be posting more about RestSharp/Stillwater soon as I get closer to launching it. You can follow <a href="http://twitter.com/RestSharp" target="_blank">@RestSharp on Twitter</a>, <a href="http://github.com/johnsheehan/RestSharp" target="_blank">follow the project on GitHub</a> or <a href="http://restsharp.org" target="_blank">visit the official site</a> (nothing there yet though).</p>
<p><strong><a href="http://johnsheehan-screencasts.s3.amazonaws.com/tcdnug/tcdnug.html" target="_blank">Watch the Video (49:25)</a></strong>     <br />Download (right click, save as): <a href="http://johnsheehan-screencasts.s3.amazonaws.com/tcdnug/tcdnug.mp4" target="_blank">MP4 (103MB)</a> | <a href="http://johnsheehan-screencasts.s3.amazonaws.com/tcdnug/tcdnug.wmv" target="_blank">WMV (135MB)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/using-web-service-apis-in-your-apps-video/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://johnsheehan-screencasts.s3.amazonaws.com/tcdnug/tcdnug.wmv" length="142283319" type="video/x-ms-wmv" />
<enclosure url="http://johnsheehan-screencasts.s3.amazonaws.com/tcdnug/tcdnug.mp4" length="108718281" type="video/mp4" />
		</item>
		<item>
		<title>How would you refactor this boolean parameter?</title>
		<link>http://john-sheehan.com/blog/how-would-you-refactor-this-boolean-parameter/</link>
		<comments>http://john-sheehan.com/blog/how-would-you-refactor-this-boolean-parameter/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 18:18:49 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/how-would-you-refactor-this-boolean-parameter/</guid>
		<description><![CDATA[I’ve got this piece of code and I’d like to get rid of the boolean parameter. How would you do it? I have some ideas, but I’m looking for some alternate perspectives.]]></description>
			<content:encoded><![CDATA[<p>I’ve got this piece of code and I’d like to get rid of the boolean parameter. How would you do it? I have some ideas, but I’m looking for some alternate perspectives.</p>
<p> <script src="http://gist.github.com/136025.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/how-would-you-refactor-this-boolean-parameter/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Building a mostly real-time web-based Twitter client with ASP.NET MVC, jQuery and TweetSharp, Part 1</title>
		<link>http://john-sheehan.com/blog/building-a-mostly-real-time-web-based-twitter-client-with-aspnet-mvc-jquery-and-tweetsharp-part-1/</link>
		<comments>http://john-sheehan.com/blog/building-a-mostly-real-time-web-based-twitter-client-with-aspnet-mvc-jquery-and-tweetsharp-part-1/#comments</comments>
		<pubDate>Tue, 26 May 2009 00:51:17 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Managed Assembly]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SubSonic]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/building-a-mostly-real-time-web-based-twitter-client-with-aspnet-mvc-jquery-and-tweetsharp-part-1/</guid>
		<description><![CDATA[Back when I launched ManagedAssembly.com around MIX I put together a page to show real-time Twitter search results for ‘MIX09’. On the heels of the dvplrs.com launch this week and the lack of .NET representation, I decided to update my live Twitter page to show live updates of notable people in the .NET community. This [...]]]></description>
			<content:encoded><![CDATA[<p>Back when I launched <a href="http://managedassembly.com/" target="_blank">ManagedAssembly.com</a> around MIX I put together a page to show real-time Twitter search results for ‘MIX09’. On the heels of the dvplrs.com launch this week and the lack of .NET representation, I decided to update my live Twitter page to show live updates of notable people in the .NET community. This is how I built it. You can see the finished product over at <a href="http://managedassembly.com/twitter" target="_blank">ManagedAssembly.com/Twitter</a>.</p>
<p>Since I decided to use the standard Twitter API instead of the Search API, I had to build a server-side cache of updates so that I wasn’t hitting the API on every view of the page which would quickly exhaust the API rate limits. Using a database was overkill so I decided to use ASP.NET’s built-in cache mechanism to store new updates. When the client makes a request for the latest updates, the items will be served out of the cache. The cache is updated every so often with new items.</p>
<p>The workflow when the client makes a request for updates (via jQuery) is like so:</p>
<ul>
<li>Grab the date of the last cache update from the cache. If the value doesn’t exist or it’s older than the cache expiration threshold, it’s time to get more statuses from Twitter. </li>
<li>When new updates are pulled from Twitter, store the highest ID in the cache as well so that for future requests we can get only the new tweets. </li>
<li>Pull the currently cached items and add the new items from the Twitter API call to it. </li>
<li>When updates are sent to the browser, the client-side code stores the latest ID. For future requests this ID is passed back to the server which returns items from the cached list that are greater than the locally-stored ID. </li>
</ul>
<p>What this gives us is the ability to only call Twitter once a minute no matter how many times the site is hit. It also allows for each visitor to only get back tweets that are new to them (which is different for every visitor depending on when the first hit the page) whenever they make a request. Since the tweets are being pulled from memory on almost every request there’s no delay while the API call is being made. If the application restarts and we lose the cache it won’t really matter because we just grab all the updates it will send and repopulate the cache. It also means that the amount of data being sent to the client via JSON is the bare minimum needed. That makes updating the UI simple (just append the new ones without having to process the full list) and keeps the bandwidth requirements low.</p>
<p>That was a lot of words, so time for some code. We start by determining if we need to get new items from Twitter and if so, grabbing them. This uses the <a href="http://john-sheehan.com/blog/pluggable-aspnet-cachemanager/" target="_blank">CacheManager from a previous post</a>.</p>
<div style="font-family: consolas, courier new; background: black; color: white; font-size: 9pt; overflow: auto">
<pre style="margin: 0px"><span style="color: #ffc66d; font-weight: bold">CacheManager</span> cache = <span style="color: #cc7832; font-weight: bold">new</span> <span style="color: #ffc66d; font-weight: bold">CacheManager</span>(<span style="color: #cc7832; font-weight: bold">new</span> <span style="color: #ffc66d; font-weight: bold">ShortTermProvider</span>());</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #6897bb">IEnumerable</span>&lt;<span style="color: #ffc66d; font-weight: bold">TwitterStatus</span>&gt; statuses = <span style="color: #cc7832; font-weight: bold">new</span> <span style="color: #ffc66d; font-weight: bold">List</span>&lt;<span style="color: #ffc66d; font-weight: bold">TwitterStatus</span>&gt;();</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">long</span> maxId = <span style="color: #0080c0; font-weight: bold">0</span>;</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #6897bb">DateTime</span> lastFetch = cache.Get&lt;<span style="color: #6897bb">DateTime</span>&gt;(<span style="color: #a5c25c; font-weight: bold">&quot;last_fetch&quot;</span>);</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">if</span> (lastFetch &lt; <span style="color: #6897bb">DateTime</span>.Now.AddMinutes(-<span style="color: #0080c0; font-weight: bold">1</span>)) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">long</span> lastCacheId = cache.Get&lt;<span style="color: #cc7832; font-weight: bold">long</span>&gt;(<span style="color: #a5c25c; font-weight: bold">&quot;last_id&quot;</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">if</span> (lastCacheId == <span style="color: #0080c0; font-weight: bold">0</span>)</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; lastCacheId = <span style="color: #0080c0; font-weight: bold">1</span>; <span style="color: gray; font-weight: bold">// TweetSharp/twitter returns null if you use Since(0)</span></pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">var</span> request = <span style="color: #ffc66d; font-weight: bold">FluentTwitter</span>.CreateRequest().AuthenticateAs(<span style="color: #a5c25c; font-weight: bold">&quot;UserGoesHere&quot;</span>, <span style="color: #a5c25c; font-weight: bold">&quot;passwordgoeshere&quot;</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160; request.Configuration.UseGzipCompression();</pre>
<pre style="margin: 0px">&#160;&#160;&#160; request.Statuses().OnFriendsTimeline().Since(lastCacheId).AsJson();</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; statuses = request.Request().AsStatuses();</pre>
<pre style="margin: 0px">}</pre>
</div>
<p>The first time this is hit <em>lastFetch</em> doesn’t exist in cache and the cache manager returns the default for DateTime (DateTime.MinValue) which I’m pretty sure is always more than a minute ago. We’ll update the fetch time in cache later. Once we’ve determined that the cache is empty or expired, we grab the <em>last_id</em> value from cache (which is 0 if it doesn’t exist). We then use <a href="http://tweetsharp.com" target="_blank">TweetSharp</a> to get the latest updates and store them in a list.</p>
<p>We also make sure that <em>statuses</em> isn’t null because if you’ve exceed the Twitter API rate limit, TweetSharp returns a null collection. Once we have the updates we have to process them since the text doesn’t include links for @mentions, #hashtags or links. When deciding how to approach this part I contacted <a href="http://twitter.com/jongalloway" target="_blank">Jon Galloway</a> and he pointed me to the code in <a href="http://code.google.com/p/wittytwitter/" target="_blank">Witty</a> which handles creating links, which I borrowed heavily from (thanks Jon!). MA also uses SubSonic 2.2 for the DAL and I used one of the methods provided in that library for determining if a word is a URL.</p>
<div style="font-family: consolas, courier new; background: black; color: white; font-size: 9pt; overflow: auto">
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">if</span> (statuses != <span style="color: #cc7832; font-weight: bold">null</span>) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">foreach</span> (<span style="color: #cc7832; font-weight: bold">var</span> status <span style="color: #cc7832; font-weight: bold">in</span> statuses) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">string</span> raw = status.Text;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">string</span>[] words = <span style="color: #ffc66d; font-weight: bold">Regex</span>.Split(raw, <span style="color: #a31515">@&quot;([ \(\)\{\}\[\]])&quot;</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #ffc66d; font-weight: bold">StringBuilder</span> output = <span style="color: #cc7832; font-weight: bold">new</span> <span style="color: #ffc66d; font-weight: bold">StringBuilder</span>();</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">foreach</span> (<span style="color: #cc7832; font-weight: bold">string</span> word <span style="color: #cc7832; font-weight: bold">in</span> words) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">if</span> (word.StartsWith(<span style="color: #a5c25c; font-weight: bold">&quot;#&quot;</span>)) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">string</span> hashtag = <span style="color: #ffc66d; font-weight: bold">String</span>.Empty;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #ffc66d; font-weight: bold">Match</span> foundHashtag = <span style="color: #ffc66d; font-weight: bold">Regex</span>.Match(word, <span style="color: #a31515">@&quot;#(\w+)(?&lt;suffix&gt;.*)&quot;</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">if</span> (foundHashtag.Success) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; hashtag = foundHashtag.Groups[<span style="color: #0080c0; font-weight: bold">1</span>].Captures[<span style="color: #0080c0; font-weight: bold">0</span>].Value;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.Append(<span style="color: #cc7832; font-weight: bold">string</span>.Format(<span style="color: #a31515">@&quot;#&lt;a href=&quot;&quot;http://search.twitter.com/search?q=%23{0}&quot;&quot; target=&quot;&quot;_blank&quot;&quot;&gt;{0}&lt;/a&gt;&quot;</span>, hashtag));</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">else</span> <span style="color: #cc7832; font-weight: bold">if</span> (word.StartsWith(<span style="color: #a5c25c; font-weight: bold">&quot;@&quot;</span>)) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">string</span> userName = <span style="color: #ffc66d; font-weight: bold">String</span>.Empty;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #ffc66d; font-weight: bold">Match</span> foundUserName = <span style="color: #ffc66d; font-weight: bold">Regex</span>.Match(word, <span style="color: #a31515">@&quot;@(\w+)(?&lt;suffix&gt;.*)&quot;</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">if</span> (foundUserName.Success) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; userName = foundUserName.Groups[<span style="color: #0080c0; font-weight: bold">1</span>].Captures[<span style="color: #0080c0; font-weight: bold">0</span>].Value;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.Append(<span style="color: #cc7832; font-weight: bold">string</span>.Format(<span style="color: #a31515">@&quot;@&lt;a href=&quot;&quot;http://twitter.com/{0}&quot;&quot; target=&quot;&quot;_blank&quot;&quot;&gt;{0}&lt;/a&gt;&quot;</span>, userName));</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">else</span> <span style="color: #cc7832; font-weight: bold">if</span> (SubSonic.Sugar.<span style="color: #ffc66d; font-weight: bold">Validation</span>.IsURL(word)) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.Append(<span style="color: #cc7832; font-weight: bold">string</span>.Format(<span style="color: #a31515">@&quot;&lt;a href=&quot;&quot;{0}&quot;&quot; target=&quot;&quot;_blank&quot;&quot;&gt;{0}&lt;/a&gt;&quot;</span>, word));</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">else</span> {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output.Append(word);</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; status.Text = output.ToString();</pre>
<pre style="margin: 0px">&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; cache.Store(<span style="color: #a5c25c; font-weight: bold">&quot;last_fetch&quot;</span>, <span style="color: #6897bb">DateTime</span>.Now);</pre>
<pre style="margin: 0px">}</pre>
</div>
<p>OK now that we’ve got the latest updates from the API and added the links, it’s time to store them in the cache.</p>
<div style="font-family: consolas, courier new; background: black; color: white; font-size: 9pt; overflow: auto">
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">var</span> cachedStatuses = cache.Get&lt;<span style="color: #ffc66d; font-weight: bold">List</span>&lt;<span style="color: #ffc66d; font-weight: bold">TwitterStatus</span>&gt;&gt;(<span style="color: #a5c25c; font-weight: bold">&quot;cachedStatuses&quot;</span>);</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">if</span> (cachedStatuses == <span style="color: #cc7832; font-weight: bold">null</span>) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; cachedStatuses = <span style="color: #cc7832; font-weight: bold">new</span> <span style="color: #ffc66d; font-weight: bold">List</span>&lt;<span style="color: #ffc66d; font-weight: bold">TwitterStatus</span>&gt;();</pre>
<pre style="margin: 0px">}</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">if</span> (statuses != <span style="color: #cc7832; font-weight: bold">null</span>) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; cachedStatuses.AddRange(statuses);</pre>
<pre style="margin: 0px">}</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">if</span> (cachedStatuses.Count &gt; <span style="color: #0080c0; font-weight: bold">0</span>) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; maxId = cachedStatuses.Max(s =&gt; s.Id);</pre>
<pre style="margin: 0px">&#160;&#160;&#160; cache.Store(<span style="color: #a5c25c; font-weight: bold">&quot;last_id&quot;</span>, maxId);</pre>
<pre style="margin: 0px">}</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">cache.Store(<span style="color: #a5c25c; font-weight: bold">&quot;cachedStatuses&quot;</span>, cachedStatuses);</pre>
</div>
<p>Last but not least we build a JSON return value for all the tweets in the cache with an ID higher than the one sent by the client (lid is a parameter passed from the client).</p>
<div style="font-family: consolas, courier new; background: black; color: white; font-size: 9pt; overflow: auto">
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">long</span> lastClientId = lid ?? <span style="color: #0080c0; font-weight: bold">1</span>;</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">var</span> data = <span style="color: #cc7832; font-weight: bold">from</span> s <span style="color: #cc7832; font-weight: bold">in</span> cachedStatuses</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">where</span> s.Id &gt; lastClientId</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">orderby</span> s.Id <span style="color: #cc7832; font-weight: bold">descending</span></pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832; font-weight: bold">select</span> <span style="color: #cc7832; font-weight: bold">new</span> {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Id = s.Id,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ProfileImageUrl = s.User.ProfileImageUrl,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Text = s.Text,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Source = s.Source,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UserName = s.User.ScreenName,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RelativeTime = s.CreatedDate.ToRelativeTime(<span style="color: #cc7832; font-weight: bold">false</span>),</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ClientLink = s.Source,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IsReply = s.InReplyToStatusId != <span style="color: #0080c0; font-weight: bold">0</span>,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InReplyToId = s.InReplyToStatusId,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InReplyToUser = s.InReplyToScreenName</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px"><span style="color: #cc7832; font-weight: bold">return</span> Json(<span style="color: #cc7832; font-weight: bold">new</span> { results = data.Take(<span style="color: #0080c0; font-weight: bold">100</span>), max_id = maxId });</pre>
</div>
<p>In <a href="http://john-sheehan.com/blog/building-a-mostly-real-time-web-based-twitter-client-with-aspnet-mvc-jquery-and-tweetsharp-part-2/">Part 2</a> I’ll cover building the UI.</p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/building-a-mostly-real-time-web-based-twitter-client-with-aspnet-mvc-jquery-and-tweetsharp-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Updated .NET Cheat Sheet for Visual Studio Built-in C# Code Snippets</title>
		<link>http://john-sheehan.com/blog/updated-net-cheat-sheet-for-visual-studio-built-in-c-code-snippets/</link>
		<comments>http://john-sheehan.com/blog/updated-net-cheat-sheet-for-visual-studio-built-in-c-code-snippets/#comments</comments>
		<pubDate>Thu, 21 May 2009 03:42:22 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/updated-net-cheat-sheet-for-visual-studio-built-in-c-code-snippets/</guid>
		<description><![CDATA[I figured since Visual Studio 2010 was just around the corner that it was about time to update my Visual Studio Built-in Code Snippets Cheat Sheet for 2008. You can find the updated cheat sheet with the others.]]></description>
			<content:encoded><![CDATA[<p>I figured since Visual Studio 2010 was just around the corner that it was about time to update my Visual Studio Built-in Code Snippets Cheat Sheet for 2008. You can find the <a href="/blog/net-cheat-sheets/">updated cheat sheet with the others</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/updated-net-cheat-sheet-for-visual-studio-built-in-c-code-snippets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Argotic Syndication Framework with ASP.NET MVC</title>
		<link>http://john-sheehan.com/blog/using-argotic-syndication-framework-with-aspnet-mvc/</link>
		<comments>http://john-sheehan.com/blog/using-argotic-syndication-framework-with-aspnet-mvc/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 18:12:15 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/using-argotic-syndication-framework-with-aspnet-mvc/</guid>
		<description><![CDATA[One of my favorite open source projects is the Argotic Syndication Framework. Argotic makes it really easy to generate RSS (and Atom and others) feeds with .NET. The library has a really clean API and has great extensibility support for RSS extensions like Media RSS. I’ve been working almost exclusively with ASP.NET MVC the past [...]]]></description>
			<content:encoded><![CDATA[<p>One of my favorite open source projects is the <a href="http://www.codeplex.com/Argotic" target="_blank">Argotic Syndication Framework</a>. Argotic makes it really easy to generate RSS (and Atom and others) feeds with .NET. The library has a really clean API and has great extensibility support for RSS extensions like Media RSS.</p>
<p>I’ve been working almost exclusively with ASP.NET MVC the past five or six months and also been doing a lot of RSS feed generation. To make it easier to return RSS feeds from a controller action, I’ve created a new class that derives from ActionResult called RssResult. RssResult takes in a feed generated with Argotic and spits out the appropriate content type and content from the feed. Here’s what RssResult looks like:</p>
<div style="font-size: 9pt; background: black; color: white; font-family: consolas, courier new">
<pre style="margin: 0px"><span style="font-weight: bold; color: #cc7832">public</span> <span style="font-weight: bold; color: #cc7832">class</span> <span style="font-weight: bold; color: #ffc66d">RssResult</span> : <span style="font-weight: bold; color: #ffc66d">ActionResult</span></pre>
<pre style="margin: 0px">{</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">public</span> <span style="font-weight: bold; color: #ffc66d">RssFeed</span> RssFeed { <span style="font-weight: bold; color: #cc7832">get</span>; <span style="font-weight: bold; color: #cc7832">set</span>; }</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">public</span> RssResult(<span style="font-weight: bold; color: #ffc66d">RssFeed</span> feed) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; RssFeed = feed;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">public</span> <span style="font-weight: bold; color: #cc7832">override</span> <span style="font-weight: bold; color: #cc7832">void</span> ExecuteResult(<span style="font-weight: bold; color: #ffc66d">ControllerContext</span> context) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; context.HttpContext.Response.ContentType = <span style="font-weight: bold; color: #a5c25c">&quot;application/rss+xml&quot;</span>;</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="font-weight: bold; color: #ffc66d">SyndicationResourceSaveSettings</span> settings = <span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">SyndicationResourceSaveSettings</span>();</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; settings.CharacterEncoding = <span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">UTF8Encoding</span>(<span style="font-weight: bold; color: #cc7832">false</span>);</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; RssFeed.Save(context.HttpContext.Response.OutputStream, settings);</pre>
<pre style="margin: 0px">&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">}</pre>
</div>
<p>And here’s a sample controller action:</p>
<div style="font-size: 9pt; background: black; color: white; font-family: consolas, courier new">
<pre style="margin: 0px"><span style="font-weight: bold; color: #cc7832">public</span> <span style="font-weight: bold; color: #ffc66d">ActionResult</span> Index() {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #ffc66d">PostCollection</span> posts = <span style="font-weight: bold; color: #ffc66d">PostService</span>.ListPopular(<span style="font-weight: bold; color: #0080c0">1</span>, <span style="font-weight: bold; color: #0080c0">30</span>);</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #ffc66d">RssFeed</span> feed = <span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">RssFeed</span>();</pre>
<pre style="margin: 0px">&#160;&#160;&#160; feed.Channel.Title = <span style="font-weight: bold; color: #a5c25c">&quot;Managed Assembly : Popular&quot;</span>;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; feed.Channel.LastBuildDate = <span style="color: #6897bb">DateTime</span>.Now;</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">foreach</span> (<span style="font-weight: bold; color: #cc7832">var</span> post <span style="font-weight: bold; color: #cc7832">in</span> posts) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; feed.Channel.AddItem(<span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">RssItem</span> {</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Author = post.User.DisplayName,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Description = post.FeedContents,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; PublicationDate = post.CreateDate,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Title = post.FeedTitle,</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Link = <span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">Uri</span>(post.FeedLink)</pre>
<pre style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; });</pre>
<pre style="margin: 0px">&#160;&#160;&#160; }</pre>
<pre style="margin: 0px">&#160;</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">return</span> Feed(feed);</pre>
<pre style="margin: 0px">}</pre>
</div>
<p>My controller base class has the ‘Feed’ method like so:</p>
<div style="font-size: 9pt; background: black; color: white; font-family: consolas, courier new">
<pre style="margin: 0px"><span style="font-weight: bold; color: #cc7832">public</span> <span style="font-weight: bold; color: #ffc66d">RssResult</span> Feed(<span style="font-weight: bold; color: #ffc66d">RssFeed</span> feed) {</pre>
<pre style="margin: 0px">&#160;&#160;&#160; <span style="font-weight: bold; color: #cc7832">return</span> <span style="font-weight: bold; color: #cc7832">new</span> <span style="font-weight: bold; color: #ffc66d">RssResult</span>(feed);</pre>
<pre style="margin: 0px">}</pre>
</div>
<p>In this example, the feed would be built up on every request. In some cases, I’ve added caching (using my <a href="http://john-sheehan.com/blog/pluggable-aspnet-cachemanager/" target="_blank">CacheManager</a>) so that the feed is only generated every 15 or 30 minutes.</p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/using-argotic-syndication-framework-with-aspnet-mvc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Code Review: A simple markup processor</title>
		<link>http://john-sheehan.com/blog/code-review-a-simple-markup-processor/</link>
		<comments>http://john-sheehan.com/blog/code-review-a-simple-markup-processor/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 06:43:54 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Code Review]]></category>

		<guid isPermaLink="false">http://john-sheehan.com/blog/?p=103</guid>
		<description><![CDATA[The purpose of this post is to find a better way to write the code shown below. The examples below are not meant to be best practices or examples I would expect to be used in any system. I came up with this and am posting it to get a code review from anyone who [...]]]></description>
			<content:encoded><![CDATA[<p>The purpose of this post is to find a better way to write the code shown below. The examples below are not meant to be best practices or examples I would expect to be used in any system. I came up with this and am posting it to get a code review from anyone who stumbles upon it. I would love to find a better way to accomplish this, so if you have ideas or suggestions, please post them in the comments.</p>
<p>I have a side project I’m working on which requires users to be able to enter in comments. I wanted to support a very limited set of formatting so things like TinyMCE, FCKEditor, Markdown and the like are out. I have some basic requirements:</p>
<ol>
<li>Convert *italics* to &lt;em&gt;italics&lt;/em&gt; and likewise for _bold_ to &lt;strong&gt;bold&lt;/strong&gt;, but not in code blocks. </li>
<li>For code blocks, convert lines starting with at least four spaces to be wrapped in &lt;pre&gt;&lt;/pre&gt; tags. Consecutive lines should be grouped together. </li>
<li>Encode any HTML. </li>
<li>Convert line breaks to HTML line breaks outside of code blocks. </li>
</ol>
<p>I’ve created a <a target="_blank" href="http://john-sheehan.com/blog/wp-content/uploads/sampleparserinput.txt">text file you can look at</a> that has some sample input.</p>
<p>For the first requirement, I’ve created a method to take a string input, a delimiter and an HTML tag to replace the delimiters with. I’ve also created a list of special characters used in regular expressions so I can assemble a proper regex if the delimiter is one of those characters.</p>
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: black; color: white; font-size: 9pt; font-weight: bold; padding-top: 5px">
<p style="margin: 0px"><span style="color: #cc7832">private</span> <span style="color: #cc7832">static</span> <span style="color: #ffc66d">List</span><span style="font-weight: normal">&lt;</span><span style="color: #cc7832">string</span><span style="font-weight: normal">&gt; SpecialRegexChars =</span></p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">new</span> <span style="color: #ffc66d">List</span><span style="font-weight: normal">&lt;</span><span style="color: #cc7832">string</span><span style="font-weight: normal">&gt; { </span><span style="color: #a5c25c">&quot;$&quot;</span>, <span style="color: #a5c25c">&quot;^&quot;</span>, <span style="color: #a5c25c">&quot;{&quot;</span>, <span style="color: #a5c25c">&quot;[&quot;</span>, <span style="color: #a5c25c">&quot;(&quot;</span>, <span style="color: #a5c25c">&quot;|&quot;</span>, <span style="color: #a5c25c">&quot;)&quot;</span>, <span style="color: #a5c25c">&quot;]&quot;</span>, <span style="color: #a5c25c">&quot;}&quot;</span>, <span style="color: #a5c25c">&quot;*&quot;</span>, <span style="color: #a5c25c">&quot;+&quot;</span>, <span style="color: #a5c25c">&quot;?&quot;</span>, <span style="color: #a31515; font-weight: normal">@&quot;\&quot;</span> };</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px"><span style="color: #cc7832">private</span> <span style="color: #cc7832">static</span> <span style="color: #cc7832">string</span> ReplaceWithHtml(<span style="color: #cc7832">string</span> input, <span style="color: #cc7832">string</span> delimiter, <span style="color: #cc7832">string</span> tag)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">if</span> (SpecialRegexChars.Contains(delimiter))</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; delimiter = <span style="color: #a31515; font-weight: normal">@&quot;\&quot;</span> + delimiter;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">string</span> regex = delimiter + <span style="color: #a5c25c">&quot;(.+)&quot;</span> + delimiter;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">string</span> output = input;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #ffc66d">Regex</span> r = <span style="color: #cc7832">new</span> <span style="color: #ffc66d">Regex</span>(regex);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">foreach</span> (<span style="color: #ffc66d">Match</span> match <span style="color: #cc7832">in</span> r.Matches(input))</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">if</span> (match.Groups.Count &gt; <span style="color: #6897bb">1</span>)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; output = output.Replace(match.Groups[<span style="color: #6897bb">0</span>].Value, <span style="color: #cc7832">string</span><span style="font-weight: normal">.Format(</span><span style="color: #a5c25c">&quot;&lt;{1}&gt;{0}&lt;/{1}&gt;&quot;</span>, match.Groups[<span style="color: #6897bb">1</span>].Value, tag));</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">return</span> output;</p>
<p style="margin: 0px">}</p>
</div>
<p>Originally I ran this method using the entire sample input and it worked great, except for that if you had text surrounded by * or _ in a code block, it was replaced with a tag. So I set this aside and moved on to detecting code blocks so I could know where to avoid performing the replacement.</p>
<p>A code block for this scenario is any single or consecutive group a lines of text that start with four or more spaces. The beginning of every block needs to be prepended with a &lt;pre&gt; tag and appended with a &lt;/pre&gt; closing tag. I considered using regex to handle this, but I couldn’t (and honestly didn’t want to) get my head around it. If there is a simple, easily-readable regex (there’s an oxymoron) that accomplishes what I’m about to demonstrate, please share it in the comments.</p>
<p>Short of an elegant regex, the next option I decided to try is splitting the input into an array of lines and looping through each line and determining whether or not it is a code block along with the lines before and after it. The vast majority of input will be relatively short so while a loop isn’t perfect, it actually works pretty well in this case. It also allows me to process the tag replacement on a per-line basis depending on whether or not that line is code.</p>
<p>Not too long after starting on my Codify method I had a morass of complicated and nearly unreadable ‘if’ statements. But, it worked! I was getting exactly the desired output. But I knew I could never come back and read the code later if the requirements changed. I worked at cleaning it up as much as possible focusing on improving readability, and this is the result:</p>
<div style="padding-bottom: 5px; padding-left: 5px; padding-right: 5px; font-family: consolas; background: black; color: white; font-size: 9pt; font-weight: bold; padding-top: 5px">
<p style="margin: 0px"><span style="color: #cc7832">private</span> <span style="color: #cc7832">static</span> <span style="color: #cc7832">string</span> Codify(<span style="color: #cc7832">string</span> input)</p>
<p style="margin: 0px">{</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">bool</span> isInCodeBlock = <span style="color: #cc7832">false</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">string</span>[] lines = input.Split(<span style="color: #cc7832">new</span>[] { <span style="color: #ffc66d">Environment</span><span style="font-weight: normal">.NewLine }, </span><span style="color: #2b91af; font-weight: normal">StringSplitOptions</span><span style="font-weight: normal">.None);</span></p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">for</span> (<span style="color: #cc7832">int</span> i = <span style="color: #6897bb">0</span>; i &lt; lines.Length; i++)</p>
<p style="margin: 0px">&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> isFirst = i == <span style="color: #6897bb">0</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> isLast = i == lines.Length &#8211; <span style="color: #6897bb">1</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> isNotFirst = i &gt; <span style="color: #6897bb">0</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> isNotLast = i &lt; lines.Length &#8211; <span style="color: #6897bb">1</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">string</span> nextLine = (isNotLast ? lines[i + <span style="color: #6897bb">1</span>] : <span style="color: #a5c25c">&quot;&quot;</span>).TrimEnd();</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">string</span> prevLine = (isNotFirst ? lines[i - <span style="color: #6897bb">1</span>] : <span style="color: #a5c25c">&quot;&quot;</span>).TrimEnd();</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> nextLineIsCode = isLast ? <span style="color: #cc7832">false</span> : nextLine.StartsWith(<span style="color: #a5c25c">&quot;&#160;&#160;&#160; &quot;</span>);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> prevLineIsCode = prevLine.StartsWith(<span style="color: #a5c25c">&quot;&#160;&#160;&#160; &quot;</span>);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">string</span> prefix = <span style="color: #a5c25c">&quot;&quot;</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">string</span> suffix = <span style="color: #a5c25c">&quot;&quot;</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">string</span> contents = <span style="color: #ffc66d">HttpUtility</span><span style="font-weight: normal">.HtmlEncode(lines[i].TrimEnd());</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">bool</span> thisLineIsCode = contents.StartsWith(<span style="color: #a5c25c">&quot;&#160;&#160;&#160; &quot;</span>);</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">if</span> (((isFirst) || (isNotFirst &amp;&amp; !isInCodeBlock)) &amp;&amp; thisLineIsCode)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; prefix = <span style="color: #a5c25c">&quot;&lt;pre&gt;&quot;</span> + <span style="color: #ffc66d">Environment</span><span style="font-weight: normal">.NewLine;</span></p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isInCodeBlock = <span style="color: #cc7832">true</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">if</span> (!isInCodeBlock)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contents = ReplaceWithHtml(contents, <span style="color: #a5c25c">&quot;*&quot;</span>, <span style="color: #a5c25c">&quot;em&quot;</span>);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; contents = ReplaceWithHtml(contents, <span style="color: #a5c25c">&quot;_&quot;</span>, <span style="color: #a5c25c">&quot;strong&quot;</span>);</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">if</span> (isInCodeBlock &amp;&amp; !nextLineIsCode)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; suffix = <span style="color: #ffc66d">Environment</span><span style="font-weight: normal">.NewLine + </span><span style="color: #a5c25c">&quot;&lt;/pre&gt;&quot;</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; isInCodeBlock = <span style="color: #cc7832">false</span>;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #cc7832">if</span> (!thisLineIsCode &amp;&amp; !nextLineIsCode &amp;&amp; !prevLineIsCode)</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; suffix = <span style="color: #a5c25c">&quot;&lt;br /&gt;&quot;</span>;</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160;&#160;&#160;&#160;&#160; lines[i] = <span style="color: #cc7832">string</span><span style="font-weight: normal">.Concat(prefix, contents, suffix);</span></p>
<p style="margin: 0px">&#160;&#160;&#160; }</p>
<p style="margin: 0px">&#160;</p>
<p style="margin: 0px">&#160;&#160;&#160; <span style="color: #cc7832">return</span> <span style="color: #cc7832">string</span><span style="font-weight: normal">.Join(</span><span style="color: #ffc66d">Environment</span><span style="font-weight: normal">.NewLine, lines);</span></p>
<p style="margin: 0px">}</p>
</div>
<p>While this isn’t the prettiest 45 lines of code I&#8217;ve ever written, it <em>does</em> work.</p>
<p>If you see something, anything, wrong with this code, tell me about it in the comments! Don’t hold back, I want to know everything you think is wrong with this code. I’m trying to work on not being attached to code I write so this will be good practice.</p>
]]></content:encoded>
			<wfw:commentRss>http://john-sheehan.com/blog/code-review-a-simple-markup-processor/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
