Wednesday, September 19, 2007
Recently, a reader inquired as to how I format the source code samples on my blog. After writing up the set of steps that I normally run through, I decided that I should post them here so that 1) interested readers might benefit, and 2) I won't forget my own process.

First of all, I should point out that there are several tools available to help format source code for the web, and Brig Lamoreaux has a good review of several here. My personal tool of choice is CopySourceAsHtml. It does a great job of getting code out of Visual Studio with accurate syntax highlighting. With a few tweaks to the HTML, it can produce exactly what I need.

Here is the exact process that I go through to create code samples that look equally good on the web and in RSS feeds.

Step 1: Write Your Code

Step 1: Write Your Code

Some important tips:

  • The code should be concise and well formatted. Most readers skim code, so it should be clear enough to get the general idea from a brief overview.
  • Make sure the code compiles! It can be quite embarrassing to be contacted by a reader who, after copying and pasting the code, found that it didn't compile.

Step 2: Copy As HTML

Step 2: Copy As HTML

Select the code sample in Visual Studio, and decrease the indent (Shift+Tab) until the code is aligned at column 1. Next, select "Copy As HTML..." from the editor's context menu. At this point, you'll be presented with the "Copy As HTML" dialog.

The first time that the dialog is displayed, some options need to be set. Fortunately, the dialog remembers your settings so that you don't need to change them next time. On the "General" tab, uncheck everything except for "Embed styles."

Step 2a: Copy As HTML (General tab)

Next, switch to the "File Style" tab to add additional CSS styles to the <div> tag that will surround the HTML-formatted code sample. Here are the styles that I use for my blog:

border: 1px dotted rgb(221, 221, 221);
margin: 4px;
padding: 4px;
font-family: Consolas,'Courier New',Courier,monospace;
font-size: small;
color: rgb(0, 0, 0);
background-color: rgb(255, 255, 255);

Step 2b: Copy As HTML (File Style tab)

Finally, click the OK button to copy the code to the clipboard.

Step 3: Massage the HTML

Once pasted in the HTML source editor of your choice, the code sample will render like this:

Sub Main()
  Dim publicationdate = Date.Today
  Dim isbn = 42
  Dim price = 0.99D
  Dim firstName = "Dustin"
  Dim lastName = "Campbell"
 
  Dim book = <book publicationdate=<%= publicationdate %> ISBN=<%= isbn %>>
               <title>F#: For The Excessively Nerdy</title>
               <price><%= price %></price>
               <author>
                 <first-name><%= firstName %></first-name>
                 <last-name><%= lastName %></last-name>
               </author>
             </book>
End Sub

Unfortunately, CopySourceAsHtml wraps every line in the code sample with <pre style="margin: 0px;"></pre> tags. These tags override some of the CSS styles that we specified for the <div> tag. Thankfully, this is easily corrected with two replace operations:

  1. Replace all instances of <pre margin="0px"> with blank text.
  2. Replace all instances of </pre> with <br /> to preserve the line breaks.

The syntax coloring is achieved by using <span> tags. Occasionally, a space will appear between two uses of a <span> tag. For example, in the code sample above, "End Sub" is actually represented like this:

<span style="color: blue;">End</span> <span style="color: blue;">Sub</span>

Some RSS readers make the mistake of removing the space in between these <span> tags, causing the words to run together. To fix this potential problem, just replace all instances of "</span> <span" with "</span>&nbsp;<span".

When finished, the code sample should render like this:

Sub Main()
  Dim publicationdate = Date.Today
  Dim isbn = 42
  Dim price = 0.99D
  Dim firstName = "Dustin"
  Dim lastName = "Campbell"
 
  Dim book = <book publicationdate=<%= publicationdate %> ISBN=<%= isbn %>>
               <title>F#: For The Excessively Nerdy</title>
               <price><%= price %></price>
               <author>
                 <first-name><%= firstName %></first-name>
                 <last-name><%= lastName %></last-name>
               </author>
             </book>
End Sub

Really, it's not that much effort. Once the CopySourceAsHtml options are set to your liking, it is a simple matter to copy, paste and make a few modifications to get the desired result. Most of the work is in writing the code sample.

posted on Wednesday, September 19, 2007 4:39:54 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]

kick it on DotNetKicks.com
There's been some interest recently in the new XML literal feature coming to Visual Basic 9. If you're not familiar with this feature, the idea is that you can embed XML directly into VB code like this:
Sub Main()
  Dim publicationdate = Date.Today
  Dim isbn = 42
  Dim price = 0.99D
  Dim firstName = "Dustin"
  Dim lastName = "Campbell"

  Dim book = <book publicationdate=<%= publicationdate %> ISBN=<%= isbn %>>
               <title>F#: For The Excessively Nerdy</title>
               <price><%= price %></price>
               <author>
                 <first-name><%= firstName %></first-name>
                 <last-name><%= lastName %></last-name>
               </author>
             </book>
End Sub

That compiles to something similar to this:

Public Sub Main()
  Dim publicationdate As Date = Date.Today
  Dim isbn As Integer = 42
  Dim price As Decimal = 0.99
  Dim firstName As String = "Dustin"
  Dim lastName As String = "Campbell"
 
  Dim book = New XElement("book", _
                          New XAttribute("publicationdate", publicationdate), _
                          New XAttribute("ISBN", isbn), _
                          New XElement("title", "F#: For The Excessively Nerdy"), _
                          New XElement("price", price), _
                          New XElement("author", _
                                       New XElement("first-name", firstName), _
                                       New XElement("last-name", lastName)))
End Sub

To me, this is a great example of what syntactic sugar should be all about: making tasks easier for developers. The VB team has gone to great pains to expose the new APIs in System.Xml.Linq in the most intuitive way possible. As a C# guy, I'm shamefully filled with deep feelings of VB envy.

Since I spend most of my time working on a wholly remarkable refactoring tool, you might be wondering what sort of refactoring support we have in store for these snazzy new XML literals. How about Extract Method?

Here's the preview hint that is displayed for Extract Method when the XML literal is selected:

Extract Method on XML Literal

And here's the successfully refactored code after applying Extract Method:

Private Function GetBook(ByVal publicationdate As Date, ByVal isbn As Integer, _
                         ByVal price As Decimal, ByVal firstName As String, _
                         ByVal lastName As String) As XElement
 
  Return <book publicationdate=<%= publicationdate %> ISBN=<%= isbn %>>
           <title>F#: For The Excessively Nerdy</title>
           <price><%= price %></price>
           <author>
             <first-name><%= firstName %></first-name>
             <last-name><%= lastName %></last-name>
           </author>
         </book>
End Function
 
Sub Main()
  Dim publicationdate = Date.Today
  Dim isbn = 42
  Dim price = 0.99D
  Dim firstName = "Dustin"
  Dim lastName = "Campbell"
 
  Dim book = GetBook(publicationdate, isbn, price, firstName, lastName)
End Sub

Notice the pieces that Refactor! must have to be in place to get this right:

  • The refactoring must be smart enough to understand how the XML literal is transformed into XElements, XAttributes and XNames under the hood.
  • The refactoring must identify any dependant variables that are referenced within the embedded expressions of the XML literal.
  • The refactoring must infer the types of the dependant variables in order to declare the parameters of the new method.

We still have some work to do before Visual Studio 2008 reaches the RTM stage, but it looks like things are shaping up nicely.

posted on Wednesday, September 19, 2007 9:21:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Thursday, September 06, 2007
Last night, I managed to catch the Counting Crows just as their summer tour was wrapping up. It was a fantastic show, full of energy and nostalgia. They played a few bits from their new album (due out in November), and performed several songs from the past. I was pleased that their set list was made up of songs they really seemed to enjoy playing (e.g. "Perfect Blue Buildings") rather than just laboriously running through their hits. For me, it was definitely a musical walk down memory lane. For a couple of hours, I was taken back to the post-grunge era of the mid-nineties when guys like Dave Matthews ruled the college rock world.

posted on Thursday, September 06, 2007 6:29:55 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]

kick it on DotNetKicks.com
 Thursday, August 30, 2007
Debates about the fonts and colors that programmers use tend to get out of control very quickly. While studies on the readability and eye fatigue of various font and color schemes exist, it very much remains a matter of personal preference. However, one detail that many programmers seem to agree on is that the default scheme presented by Visual Studio is less than ideal. Standard 10 point Courier New is simply difficult for most people (at least most people that care about this sort of thing—except Rick Strahl) to look at all day.

VS 2005 Default with ClearType

A common solution—especially for high-resolution displays—is to increase the font size in the editor. Personally, I'm a big fan Microsoft's Consolas font, and as Scott Hanselman points out, I really feel that it looks best at 15 point.

VS 2005 with Consolas and ClearType

This is well-covered territory in the blogosphere, but I want to discuss a point that frequently is overlooked. While many of us strive for the perfect font and color scheme in the text editor, we neglect the opportunities for improvement in other windows. For example, I may feel good about using 15-point Consolas to decrease my eye strain, but I haven't done anything to improve my experience with IntelliSense.

VS 2005 Intellisense

(Public speakers are often the biggest culprits of this. Helpful presenters will increase the size of their editor font, but few will adjust other areas such as IntelliSense, debugging windows, etc.)

Fortunately, Visual Studio 2005 makes changing the fonts and colors of much of the IDE easy. The "Show settings for" combo box on the Fonts and Colors page of Visual Studio's Options dialog provides the ability to customize many areas of the IDE, in addition to the text editor. For example, the default font setting for the statement completion window is definitely too small when compared to the 15-point font size that I use in the text editor.

Statement Completion options

One simple trick to improve the readability of the statement completion window is to use exactly the same font and point size as the text editor. Logically, if I'm searching for a class or method name in IntelliSense, it might be easier to find if it looks exactly like it will when inserted into the text editor.

IntelliSense with Consolas

A similar effect can be achieved by adjusting the font of the editor tooltips. Compare the default setting...

Editor Tooltips

...to the adjusted one.

Editor Tooltips with Consolas

Other good candidates for similar adjustment are:

  • DataTips – These are the cool expandable tooltips that appear when identifiers are moused-over in debug mode. Making these easier to read is a must.
  • [All Text Tool Windows] – This is actually a font and color group that controls several settings. When selected, any adjustment made affects the Command, Disassembly, Find Results, Immediate, Memory, Output and Registers windows.
  • [Watch, Locals, and Autos Tool Windows] – As the name suggests, this group handles adjustments for the Watch, Locals and Autos windows.

Remember: when your goal is to improve readability and reduce eye fatigue, adjusting the font in the text editor isn't enough. Pay attention to the font in all areas of Visual Studio.

posted on Thursday, August 30, 2007 1:15:54 PM (Eastern Standard Time, UTC-05:00)  #    Comments [6]

kick it on DotNetKicks.com
 Wednesday, August 22, 2007
Last night, I had the pleasure of attending Jason Follas' "Exploit the XML Capabilities of SQL Server 2005" talk at the Northwest Ohio .NET Users Group (NWNUG). I have a good understanding of XML and the System.Xml namespace, but I have to admit that I'm a bit of a noob when it comes to SQL Server. It just isn't something that I encounter in my day-to-day work. However, Jason really connected some dots for me. If you have an opportunity to attend this talk, I recommend it.

posted on Wednesday, August 22, 2007 9:02:11 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]

kick it on DotNetKicks.com
 Monday, August 20, 2007
..for the Day of .NET is coming.

Day of .NET is a FREE .NET-only conference that is held annually in the Spring. This year's "Nerdo de Mayo" was such a big success that a decision was made to hold the conference bi-annually. Another Day of .NET is scheduled for October 20th in Ann Arbor, Michigan. If you live in Northwest Ohio, Northeast Indiana, Southern Michigan, or Hattiesburg, Mississippi, you should plan on attending. The content is always of the highest quality.

If you are planning on being there, help spread the word in the blogosphere with a delightfully EV-IL badge.

Day of .Net October 20, 2007 - See You there!

posted on Monday, August 20, 2007 9:28:58 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Friday, August 17, 2007
Several weeks ago, I posted this bit of code that shows how we might use a C# 3.0 query expression to calculate the sum of the squares of an array of integers.
static void Main()
{
  var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

  var
sum = (from n in numbers
             where (n % 2) == 0
             select n * n).Sum();

  Console
.WriteLine("Sum: {0}", sum);
}

Translating this sample into Visual Basic 9.0 produces almost identical code.

Sub Main()
  Dim numbers() = New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

  Dim
total = (From n In numbers _
               Where (n Mod 2) = 0 _
               Select n * n).Sum()

  Console.WriteLine("Sum: {0}", total)
End Sub

However, this translation is a bit naive because Visual Basic 9.0 actually provides syntax for more of the standard query operators than C# 3.0 does. While we have to call the "Sum" query operator explicitly in C#, Visual Basic allows us to use it directly in the query.

Sub Main()
  Dim numbers() = New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

  Dim
total = Aggregate n In numbers _
              Where (n Mod 2) = 0 _
              Select n * n _
              Into Sum()

  Console.WriteLine("Sum: {0}", total)
End Sub

In fact, Visual Basic even allows us to create our own aggregate functions and use them directly in query expressions.

<Extension()> _
Function Product(ByVal source As IEnumerable(Of Integer)) As Integer
  Dim
result = 1
  For Each n In source
    result *= n
  Next
  Return
result
End Function

Sub
Main()
  Dim numbers() = New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

  Dim total = Aggregate n In numbers _
              Where (n Mod 2) = 0 _
              Select n _
              Into Product()

  Console.WriteLine("Sum: {0}", total)
End Sub

Here we get the product of the even numbers in the array. (I removed the expression to square each even number because it produced an OverflowException.)

I should point out that there is a behavioral difference that the Visual Basic "Aggregate" keyword introduces. A standard "From" query expression is delay evaluated. That is, the results aren't actually evaluated until they are accessed through, say, a "For Each" loop. However, an "Aggregate" query expression forces the results to be evaluated immediately. In contrast, C# 3.0 query expressions always produce results that are delay evaluated.1

1A bold statement that will be completely recanted if any reader can find an example that proves otherwise.2
2Please, prove me wrong. Seriously. I'm interested in this stuff.3
3This footnote motif is clearly ripped off from Raymond Chen.

posted on Friday, August 17, 2007 10:46:31 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]

kick it on DotNetKicks.com
 Thursday, August 16, 2007
After writing up this post, I found similar instructions elsewhere. Oh well... you can't always be first.

CopySourceAsHtml on the context menu of Visual Studio's editorCopySourceAsHtml is an extremely useful Visual Studio add-in that places a new menu item on the context menu of the editor. This is especially helpful for bloggers looking for an easy way to get rich source code highlighting into their blogs.

In general, I usually find it necessary to massage the HTML results a bit to get code to look good in RSS feeds, but it is far easier than, say, manual highlighting.

Yesterday, while working on my Art of Currying article, I found it necessary to highlight some C# 3.0 code and was disappointed to find that the trusty "Copy As HTML..." menu item wasn't available. Fortunately, it's very easy to install the add-in into Visual Studio 2008 beta 2.

The CopySourceAsHtml installer drops four files in the "My Documents\Visual Studio 2005\Addins" directory:

  • CopySourceAsHtml.AddIn -- an XML file that describes the add-in and is used for registration with Visual Studio.
  • CopySourceAsHtml.dll -- the add-in itself.
  • CopySourceAsHtml.dll.config -- a configuration file that contains various user settings.
  • CopySourceAsHtml.pdb -- debugging symbols for the add-in. This really isn't needed but it doesn't hurt anything either.

Simply copy these files to the "My Documents\Visual Studio 2008\Addins" directory. If the "Addins" subdirectory doesn't exist, just create it. If you are using Windows Vista, substitute "Users\CURRENTUSER\Documents" for "My Documents".

Next, in a text editor, open the CopySourceAsHtml.AddIn file that you just copied and change the two <Version> tags from 8.0 to 9.0. When you're finished, it should look like this:

<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<
Extensibility xmlns="http://schemas.microsoft.com/AutomationExtensibility">
  <
HostApplication>
    <
Name>Microsoft Visual Studio Macros</Name>
    <Version>9.0</Version>
  </
HostApplication>
  <
HostApplication>
    <
Name>Microsoft Visual Studio</Name>
    <
Version>9.0</Version>
  </
HostApplication>
  <
Addin>
    <
FriendlyName>CopySourceAsHtml</FriendlyName>
    <
Description>Adds support to Microsoft Visual Studio 2005 for copying source code, syntax highlighting, and line numbers as HTML.</Description>
    <
Assembly>CopySourceAsHtml.dll</Assembly>
    <
FullClassName>JTLeigh.Tools.CopySourceAsHtml.Connect</FullClassName>
    <
LoadBehavior>1</LoadBehavior>
    <
CommandPreload>0</CommandPreload>
    <
CommandLineSafe>0</CommandLineSafe>
  </
Addin>
</
Extensibility>

Save the file and... your're done! Start up Visual Studio 2008 beta 2, and that handy context menu item is now available and works great.

posted on Thursday, August 16, 2007 11:03:44 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]

kick it on DotNetKicks.com
 Wednesday, August 15, 2007
It's time to get back to functional programming with C# 2.0. This time, I look at how the technique of "currying" fits into the picture.
posted on Wednesday, August 15, 2007 2:35:46 PM (Eastern Standard Time, UTC-05:00)  #    Comments [7]

kick it on DotNetKicks.com