comments edit

Tentative logo Ken Robertson points out some minor inaccuracies (none intentional) in my announcement about Subtext concerning Community Server.

I went ahead and made some corrections in the announcement, though I defended my point about targeting different markets which I will repeat here.

As for the target market, I see your point that I may be slightly off. My point is that by commercializing Community Server, you’ve created an incentive to target the needs of larger paying corporations. You’re a business and you need the cash inflow. Nothing wrong with that.

I also go on to mention in my update to the announcement

Starting this project is not an attack of Telligent or Community Server by any means. I do wish them well. I just think there’s still room for a tightly focused Open Source blogging engine targeted to individuals with no restrictions. It’s very likely that Community Server 1.1 or 1.2 will blow our socks off and have us questioning whether Subtext is worth the time. But until then, I think Subtext will ride the wave of backlash at the perceived hastiness in which CS 1.0 was released and hopefully turn into a compelling product in its own right. We’re carving out a niche here.

Only time will tell if I’m proven wrong or not. In the mean time, we have a team of people really amped about this project. It will be a fun experiment whatever happens.

Get involved!\ If you’re interested in helping out, please feel free to check out the project site, make or comment on feature requests, or if you’re really bold, load up CVS and take a look at the source code.

Also, if anyone out there is a WiX expert, I could certainly use some help!

P.S. That logo up there is a tentative logo made by Robb. Who knew that dude was an artist?

[Listening to: Need You Tonight - INXS - The Greatest Hits (3:01)]

comments edit

I’m looking for a Windows Forms control or dialog used to both parse and build connection strings by walking the user though selecting a server, database, etc…

If you know of such a control, please provide a comment. I’ve been able to build OLEDB connection strings using the Microsoft OLE DB type library, but it only produces OLEDB connection string. I want a dialog or control that can walk a user into building a valid connection string like:



comments edit

This quote from Sharp as a Marble just cracks me up.

Then, on the way into work, a car passed me with a bumper sticker on the window that said These colors dont run and a picture of the American flag. Cept the sticker had not weathered the rain very well and the ink had ran. Irony, eh?

[Via Sharp as a Marble]

code comments edit

I’m posting this in the hopes that it helps someone out there with the same problem because I just KNOW how often you’re adding files using CVS. It’s the little spark that gets your juices flowing while sitting at work daydreaming about how much you can’t wait to use CVS again.

Anyways, I was creating a new CVS module and adding the contents of some source code to the repository when I heard the sound of breaking glass that TortoiseCVS uses to indicate a problem (it’s a rather lovely sound).

It seems I had some sort of network issue while adding files. No problem, I thought, I’ll just add the files that haven’t been added and then commit all the files.

Unfortunately, every time I tried commiting files I heard that dreaded breaking glass. My error message was something like:

cvs commit: failed to create lock directory for `/cvsroot/MyProject/SomeDirectory’\ (/cvsroot/MyProject/SomeDirectory/#cvs.lock):\ No such file or directory\ cvs commit: lock failed - giving up\ cvs [commit aborted]: lock failed - giving up

Well that’s strange, the error message is having trouble creating a lock for the directory “SomeDirectory” because it doesn’t exist. But when I use Tortoise CVS to add contents, it shows that everything has been added.

What I discovered is that CVS stores information about the state of the repository in local hidden folders named, you guessed it, “CVS”. If something very bad happens, it’s quite possible that the local information will get out of synch with the information on the server. That’s exactly what I ran into.

To fix it, I copied my source tree to a new directory, deleted the old source tree, and ran a Checkout command to get the latest version that actually made it into the repository. Then I copied that set aside source tree over the one I had just checked out so that all the new files made it into the tree. That then showed that I still needed to add some files and directories to the CVS repository, which I did. Finally, a commit of the source tree worked flawlessly.

By the way, I’m a relative CVS rookie, though I’ve used it quite a bit. So if there was a better way to do this, let me know.

For a great tutorial on source control, check out Eric Sink’s series Source Control HOWTO.

[Listening to: Chinese Burn (Forbidden City Remix) - Paul Van Dyk - Perspective CD2 (10:36)]

subtext comments edit

This document describes the goals for future versions of Subtext as well as a plan for achieving them. The goals for this roadmap are the following:

  • Communicate to end users what features are planned for future releases
  • Elicit feedback from users about upcoming releases
  • Provides a prioritization of features

This document is a work in progress and feedback is welcome.

Administrative Road Map

  1. Documenting existing source code and features. (priority: high)
  2. Fill specific project roles (patch manager, forum manager, etc…) (priority: high)
  3. Set up a website and Wiki for Subtext (unfortunately is taken). (priority: med)
  4. Set up an automated build process (NAnt) (priority: low)

Upcoming Releases

As we flesh out the roadmap, we’ll divide it into sections based on planned future individual releases. For now, this document will simply list goals and features planned for the near and far future.

Gotta Have It Features Immediately (priority 1)

These features will directly support the principles of the Subtext project. UPDATE: We are rethinking the single vs multiple blog support. More details later. One important “feature” that must be discussed is the dropping of the “multiple blogs on one installation” feature. In order to maintain Subtext’s goals of simplicity and it’s focus on the hobbyist and individual blogger, it makes sense to focus on the scenario where users are using Subtext to create a single blog. This will distinguish Subtext from Community Server which is geared towards corporations and groups that wish to host multiple blogs. Please provide feedback on this decision.

  • Installer for local setup: We’ve started an installer using the WiX toolkit. Initially, this will be an MSI package that will install both a website and the database when run locally. Eventually, it will have to be able to upgrade an existing installation.
  • Simplified configuration (single blog): By removing the multiple blogs feature, configuration can be simplified immensely.
  • Configuration utility: Upon first installing Subtext, the configuration utility will be an easy to use WinForms app used to set the connection string (and certain other settings if any) within the web.config file. This utility can be run at any time to tweak web.config settings without having to muck around the XML by hand.
  • Kick ass documentation: Can’t stress this enough. We’ll use NDoc to generate code and API documentation. As for user documentation, we’ll have both a project site and a wiki.
  • Comments Automatically Expire: This is currently hard-coded into Subtext and needs to be made configurable. Allow the user to have comments turned off after a configurable number of days. Existing comments will still be displayed, but no new comments will be allowed.

Gotta Have It, But Just not yet (priority 1.5)

  • Friendly Urls: Currently, Subtext creates permalinks that look like In a future version, we want the permalink to have a more human readable URL. For example, this might be converted to
  • Improved Usability: One of my pet peeves about .TEXT is how hard it is to edit a really old post. You have to page through the data grid of posts till you find it. Instead, a simple option is to create a new admin token that skin creators can place in their skin where a post is rendered. When a user is logged in as an admin, the token is displayed as an icon with a link that the admin can click to edit that post. Thus, to edit an old post, simply make sure you’re logged in as an admin and leverage Google to find the post, and then click on the admin token.
  • Replace/Upgrade FreeTextBox.dll: Hopefully with something that won’t mangle HTML.
  • Comment Moderation: This is merely one tool in the constant battle to fight comment spam. Allows users to turn on and off comment moderation.
  • Simple Comment Filtering Rules Currently, uses a simple trigger that filters out comments with a certain number of links. This exceedingly simple filter does remarkably well. To fight comment spam, we should start with a few simple (and configurable) rules for filtering comment spam. We can add more complex rules later.

Important, But Maybe Next Release Features (priority 2)

  • Membership Provider Model implementation: This will be a very simple system that allows a blog owner to create accounts with certain roles (reader, author, admin). Thus a blog can have multiple authors for a single blog.
  • New CSS based Templates: These will be templates that can be “skinned” purely via CSS (ala CSS Zen Garden). We’ll provide a tool for a blog owner to edit and switch CSS for this particular template.
  • XHTML compliance: Both transitional and strict.
  • Comment Filtering Rules Engine: This will be similar to the Junk Mail rules engine in Outlook. We’ll provide a web based interface for creating filtering rule used to combat comment spam.

Features to dream about (priority we’re dreaming)

  • A Spell Checker: For all those bad spelers out there.
  • Migration utility: We’re not so arrogant as to believe you’ll never use another blogging engine again. If you do, we want to help you migrate your permalinks and posts to it.
  • MySql Provider: because not everyone wants to pay for SQL Server hosting and some people want to honor their license agreement for MSDN Universal. ;)
  • Mono support: This may be way down the road, but supporting Mono would be a nice way to introduce the Linux crowd to the beauty of ASP.NET and Subtext. Besides, we’ll finally get props from the Slashdot crowd for our 1337 sk1llz.
  • Intelligent comment filtering: Whether it be via Bayes filtering or some other means, but a more autonomous method of spam filtering is called for.

Tags: Subtext

subtext, open source comments edit

sub text\ Function: noun\

  1. The implicit or metaphorical meaning (as of a literary text)\
  2. A story within the story.

What is .TEXT?

.TEXT is a popular (among .NET loving geeks), scalable, and feature rich blogging engine started by Scott Watermasysk and released as an open source project under a BSD license. Scott did a wonderful job with .TEXT as evidenced by its widespread use among bloggers and being the blogging engine for among others.

Sounds great. So why fork it?

There are several reasons I think a fork is waranted.

.TEXT is dead as an open source product.

.TEXT is dead as a BSD licensed open source project. Out of its ashes has risen Community Server which integrates a new version of the .TEXT source code with Forums and Photo Galleries. Community Server is now a product being sold by Telligent Systems. There is a non-commercial license available, but it requires displaying the telligent logo and restricts usage to non-commercial purposes. I’d prefer to use a blogging engine with an OSI approved license, in particular the BSD license works well for me.

As an aside, if you’re wondering how they can take an open source project and turn it into a commercial product, it’s quite easy actually. Here’s the story of another commercially acquired open source project.

Community Server Targets A Different Market

Another reason is that Community Server has become sort of the Team System of blogging engines. By virtue of it going commercial, it’s being targetted to a different market than your average hobbyist and blogger. While I’m sure many are looking forward to the tight integration with forums and photo gallery, that’s just not something I personally need. This integration project was quite ambitious, but it resulted, in my opinion, a rushed 1.0 release as evidenced by this list of bugs. Bugs are fine, but many of these are regressions of RSS functionality that worked fine in .TEXT. I’ve helped Jayson with fixing some of these bugs in CS. As a developer on the RSS Bandit team, you can guess that proper RSS support is very near and dear to me. Starting this project will enable me to have a hand in both ends of the blogging spectrum.

Ok, So Who Does Subtext Target?

Subtext is the name I’ve chosen for this fork of .TEXT. Subtext targets the blogging enthusiast who wants a usable and tightly focused blogging engine. If you’ve ever caught yourself throwing your hands in the air and declaring that you’re going to write your own blogging engine from scratch, Subtext is going to be for you. My first and primary task is to streamline the installation and configuration process (hence my recent fascination with WiX).

What are the Subtext Guiding Principles

There are several principles that will serve to guide development on Subtext.

  • Usability
  • Badass Quality
  • Documentation
  • Focused
  • Easy to install and configure

One of the difficulties of many open source projects is their typical lack of documentation. Working with Dare and Torsten, I helped improve their already impressive documentation of RSS Bandit. I’d like to do the same for Subtext.

Likewise, I want to make setting up Subtext a pleasure, not a royal headache. That’s my first task and highest priority at this point.

Where’s Subtext At Now?

Currently I’m in the planning stage for Subtext. I’ve uploaded the code to the Subtext SourceForge project and am currently recruiting a few core members to help out. I’ve started with the .TEXT 0.95 code base, so if you have patches to submit, by all means please do. I’ve already added some small changes to make it more XHTML compliant. In the beginning, I plan to recruit a small core team of developers with write access to help me review and apply code patches, as well as do some of the development. Over time I hope the team will grow as we find developers who are making meaningful contributions.

In the meanwhile, I’ll be drawing up some project guidelines and a roadmap so stay tuned.

UPDATE: Ken Robertson points out some inaccuracies with this announcement in his blog. I went ahead and made some corrections.

One thing he mentions is that I’m slightly off when I say that the target market for CS is larger institutions. I agree that CS may work well for small fries like me, but I defended my assertion with a comment in his blog.

As for the target market, I see your point that I may be slightly off. My point is that by commercializing Community Server, you’ve created an incentive to target the needs of larger paying corporations. You’re a business and you need the cash inflow. Nothing wrong with that.

Starting this project is not an attack of Telligent or Community Server by any means. I do wish them well. I just think there’s still room for a tightly focused Open Source blogging engine targeted to individuals with no restrictions. It’s very likely that Community Server 1.1 or 1.2 will blow our socks off and have us questioning whether Subtext is worth the time. But until then, I think Subtext will ride the wave of backlash at the perceived hastiness in which CS 1.0 was released and hopefully turn into a compelling product in its own right. We’re carving out a niche here.

Tags: Subtext

comments edit

UPDATE Wow, check out the privacy policy for Google Web Accelerator… On second thought maybe I’ll hold off on installing that.

When you use Google Web Accelerator, Google servers receive and log your page requests. Page requests and data sent in encrypted form using an HTTPS connection will not go through Google. It is possible that some personally identifiable information could be sent to Google, if the information is sent without using an encrypted (HTTPS) connection.

To enhance Google Web Accelerator’s performance, Google temporarily caches cookies from third party sites that are used in your Web requests. For more information, please see our FAQ.

To accelerate delivery of content, Google Web Accelerator retrieves and caches webpages before you request them. Therefore, your Google Web Accelerator cache may include copies of webpages you have not visited. You can clear the cache following instructions in the FAQ.

Google Web Accelerator Google announced on its blog that they’ve release a beta version of their new web accelerator designed for broadband use. I’ll give it a shot and see how well it works.

Man, these guys are pushing out a lot of interesting products. My screen is starting to look like a Google sponsored desktop.

comments edit

I started off planning to write a quick installer for a little something I’m working on. Unhappy with the limited abilities of Visual Studio’s Setup and Deployment project, I finally started playing with WiX.

After a good deal of time reading through the documentation, I have a pretty good handle on it. However, it’s difficult to apply the WiX philosophy (build your setup project as you go along) to an existing project that already has several hundred files.

Along comes Tallow to the rescue (part of the WiX toolkit) which can generate a fragment containing components themselves containing references to your files. Sweet! But now you have to reference all the generated components within your Feature element.

So that drags me further into the hole where I’m performing minor surgery on the Tallow source code. I soon discover a list of other feature requests (auto-generate Guids, etc…) and I soon catch myself. Hey, I’m just here to build a setup project, not rewrite the whole damn setup toolkit.

So I now have a customized version of Tallow.exe that will generate Guids for components. It will also generate a commented section of ComponentRef statements like so.

<!–\ <ComponentRef Id=’component0’ /<\ <ComponentRef Id=’component1’ />\ <ComponentRef Id=’component2’ />\ –>

You can manually (eww!) cut and paste that section into your main .wxs file in order to reference all the components in the generated fragment.

Now back to my initial task…

[Listening to: Daydream - Privilege - A Trip In Trance (CD 2) (3:45)]

comments edit

You’ve heard CSS purists beat it into you over and over again that “Tables are bad, umkaaay?”. But man, what a pain when you’re trying to do something as simple as a web form and you want the labels to align to the right and the controls to align to the left.

So Dimitri here rides in to the rescue with TILT (Table Injection for Layout Technique). He showed this to me a few weeks ago and has finally polished it to the point that he’s ready to tell the world.

Essentially, this technique allows you to mark up your code semantically like the CSS purist you are, but then with some crafty usage of Javascript, modify the DOM and inject a TABLE (with all the benefits therein). Genius.

comments edit

The Corporation I know I’m late to the game, but since I rely on Netflix, I’m always watching movies long after the general population has seen them. However, we just finished watching the documentary “The Corporation” and I couldn’t recommend it more if you haven’t seen it already.

Even if you’re a tried and true Capitalist (like I am), it’s worth watching as it does a pretty good job of raising questions about how we define wealth and corporate responsibility among other things.

It certainly provides insight into the question of whether corporations should act purely on self interest. Corporations should definitely be responsible to their shareholders, but perhaps also to their stake holders. If a corporation is owned by people in the U.S., but pollutes the air in Chile, it’s being responsible to its share holders, but what about the stake holders?

In the end, I think the big take away from the documentary is that for corporations to be truly responsible to shareholders, they must redefine what it means to provide “value” to shareholders. Value is more than immediate cash profit. Value is also provided via sustainability. Clean air is valuable. Clean water is value.

A second take away is that when our news agencies are in the pockets of big corporations, how will people get the truth so they can make more rational decisions about policy regarding the environment and corporations? That’s a real disheartening topic.

Well not one to underestimate human nature, it leaves me with the big question of how do you make it profitable for companies to be sustainable? That’s certainly one way to enact change. But it has to be done in such a way that it is inherently profitable to be sustainable. Enacting policies might just make corporations leave U.S. soil. One approach is to wait till the environment has been plundered so much that there’s no other way. I’d prefer we not wait so long.

comments edit

A while ago Patrick Cauldwell highlighted a wonderful technique of using embedded resources for unit testing with external files.

Fully on board with Pat, I’ve applied that technique to client script blocks when building web controls and ASP.NET pages.

How often have you written (or had to deal with) crap like this.

string script = "<script language=\"javascript\">"
  + "function SomeFunction(someParam)" + Environment.NewLine
  + "{" + Environment.NewLine
  + "    alert(’Man, this sucks!’);" + Environment.NewLine
  + "}" + Environment.NewLine
  + "</script>";

A preferred approach is to have your client script code in a separate file. For web controls, I generally have a folder named Resources that contains a folder named Scripts. I’ll add my client script files there as embedded resources. In figure 1 below, you can see that I have two script files in my project.

Embedded Scripts\ Figure 1 Script files.

To make sure these files are compiled as embedded resources, I select the files and set the build action to embedded resource in the Properties window as in figure 2.

Embedded Resource \ Figure 2 Build Action = Embedded Resource.

Now when I need to display these scripts in a page, I can use the following code which makes use of my handy dandy ScriptHelper class.

  string script = ScriptHelper.UnpackScript("PairedDropDown.js");
  Page.RegisterClientScriptBlock("PairedDropDownHandler", script);

The contents of my embedded script files do not contain the <script> tags. I leave that responsibility to my ScriptHelper class so that these script files can be used as stand alone script files as well. The code for my script helper class is below.

/// <summary>
/// Utility class for extracting embedded scripts.
/// </summary>
/// <remarks>
/// Uses a naming convention. All scripts should be placed 
/// in the Resources\Scripts folder. The scriptName is just 
/// the filename of the script.
/// </remarks>
public static class ScriptHelper
  /// <summary>
  /// Returns the contents of the embedded script as
  /// a stringwrapped with the start / end script tags.
  /// </summary>
  /// <param name="scriptName">FileName of the script.</param>
  /// <returns>Contents of the script.</returns>
  public static string UnpackScript(string scriptName)
    string language = "javascript";
    string extension = Path.GetExtension(scriptName);
    if(0 == string.Compare(extension, ".vbs", true
      , CultureInfo.InvariantCulture))
      language = "vbscript";
    return UnpackScript(scriptName, language);

  public static string UnpackScript(string scriptName, string scriptLanguage)
    return "<script language=\"Javascript\">"
      + Environment.NewLine
      + UnpackEmbeddedResourceToString("Resources.Scripts." + scriptName)
      + Environment.NewLine
      + "</script>";
  // Unpacks the embedded resource to string.
  static string UnpackEmbeddedResourceToString(string resourceName)
    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    Stream resourceStream = executingAssembly
      .GetManifestResourceStream(typeof(ScriptHelper), resourceName);
    using(StreamReader reader = new StreamReader(resourceStream, Encoding.ASCII))
      return reader.ReadToEnd();

You’ll be seeing this ScriptHelper class again when I highlight some controls you might find useful. If you’re already using ASP.NET 2.0 (aka Whidbey), there’s an even better way to handle client files.

UPDATE: I just realized I was using code from a StringHelper class I wrote. I updated that bit to inline the simple functionality.

comments edit

Well I didn’t get much of an on topic response to my question of whether readers would be bothered by ads in an RSS feed, but I did get into a nice chat about hosting at home verse with a service. Apparently Robb Allen has enough computers at home to supply a third-world country. Think about it Robb? They can really use it. ;)

But it appears that a general backlash is brewing against the idea. It’s the battle between the Utopian view of RSS and market pressures. Personally, if a feed is interesting enough to me, I’d be happy to tolerate ads as long as the ads weren’t too distracting or garish. For small fries like me, it’s a nice way to supplement the income, especially as one who has recently made the jump to be independent.

Having said that, it’s almost always a bad move to alienate readers (unless your taking a principled stance on an important issue you believe in). The best choice (for me at least) is to offer a choice (paper or plastic?). I’ll probably keep my main feed ad free, but add a separate (but equal) rss feed that would contain an occasional ad. At that point I’ll cajole, grovel, and beg subscribers to switch to the feed with ads to help a brotha out.

comments edit

Orange Chicken In my comments, Barrywinces at the relevance of some Ad Sense ads he sees.

For the most part, I’ve been quite impressed by AdSense relevancy. For a while now, I’ve had nice colorful Family Guy ads on my home page. When I wrote about my Orange Chicken incident, a commenter pointed out that I hilariously had ads for Orange Chicken on my blog.

But ad-sense can backfire as well. I had one post where I was critical of the Republican party and I noticed that Google was showing ads seeking fund raisers for the GOP. I laughed out loud and figured, hey, that’s a good way to keep my blog balanced. Everytime I criticize the Republican party, my ads will balance that by advertising for them. I’ll criticize the ineffective Democrats as well so that this post gets ads for Libertarians or the Green party.

UPDATE: Looks like Rory’s noticing how eerily relevant AdSense can be.

comments edit

This past weekend Akumi and I headed over to the downtown flower mart to purchase some plants. We came home with a couple money trees and some bamboo for my office.


There’s something about Bamboo that is very soothing for me. Sometimes if I look at it long enough, I can swear that the leaves are moving gracefully, twisting upwards.

[Listening to: Undo - Björk - Vespertine (5:38)]

comments edit

As you’ve probably heard, Google is testing AdSense within RSS on a single site.

I love the idea of being able to include a Google AdSense ad within my RSS feed and watching the money roll in. At least in theory. Once ads proliferate in RSS feeds, ad-blockers within RSS aggregators will proliferate. Just look at this prototyped ad-blocker for RSS Bandit that Torsten developed.

Another issue that comes to mind is that the audience for web ads is not the same audience for rss feeds. I have a theory that those who find my site via a Google search are more likely to click on an ad than someone who is subscribed to my RSS feed?

Why is that? It boils down to the fact that a subscriber via RSS isn’t likely to be in the middle of a search for a particular piece of information while reading my blog as would a Google user. Rather, I suspect that he or she is a friend or a geek wondering if I’ll finally be inspired someday to write something worthwhile because I once wrote something interesting enough some time ago that encouraged this person to add me to his or her aggregator and now only inertia keeps this person from unsubscribing. But I digress.

Unfortunately, I don’t have any hard (or even soft) numbers to back this claim up because I don’t have ads in my RSS feed. Recently I was linked to on Scoble’s link blog which jumped up the number of aggregator views, while my web views remained constant. Likewise, my tiny advertising revenue for that day stayed constant as would be expected because those who read my blog via an aggregator aren’t likely to take their time to look at the actual site and click on an ad. I’d love to know what the effect would have been had my feed included an ad.

When I post something that users find via Google, my web views jump as does my advertising revenue, which makes perfect sense. I’ll be watching with interest to see how Google’s experiment with Longhorn blogs does and if they end up rolling it out to everyone. I’ll certainly experiment with it to see if my conjecture is correct unless I get a backlash from commenters saying they’d rather not see it in personal blogs. Thoughts?

As for my advertising revenue in case you were wondering, I’m strictly a small fry, though I do make more than enough to pay for hosting.

[Listening to: 3-2-1 Fire! - Fat Boy Slim - Fatboy Slim: Live On Brighton Beach (4:34)]

company culture comments edit

I saw this post on Don Park’s blog…

My perspective on this latest hot topic is that I think companies should act only in interest of itself, the Microsoft shareholders in this case, and not anyone else, including its employees. So I think the discussion should have been about whether leaders of Microsoft made the right decision in the interest of its shareholders.

I don’t understand this mode of thinking. Should people in general act purely on self interest and not for the common good? Why should corporations be any different? After all, they are made up of people, both shareholders and employees. It seems not all companies agree as Boeing, Nike, Coors, HP, and others supported the bill.

I suppose Microsoft would have continued to support the bill if it was rewritten to state that gays are not protected under anti-discrimination laws to own stocks in major corporations. Oh then you’d see some major rallying around gay rights.

I understand that having a corporation get behind a political cause is a touchy situation. Whose values do you support? Your employees? Your shareholders? America at large? But it’s clear that this bill supports values Microsoft already holds dear. Microsoft has in the past supported this bill and has shown itself to be progressive in its own policies.

And Ballmer’s worry of discriminating against anti-gay bigots is a real piece of work. Here’s a snippet.

What message does the company taking a position send to its employees who have strongly-held beliefs on the opposite side of the issue?

As Shelley eloquently points out, this bill doesn’t deny rights to others. And the message would have already been sent by the fact that Microsoft’s own policies are reflected in this bill. So if you’re worried about the bigots feelings Mr. Ballmer, are you going to change your policies to reflect that as well?

We’ve all seen what acting purely on corporate self-interest produces. Oh, Enron springs to mind, sweat shops, destruction of the environment, and countless other examples. Corporations have all the rights of a person without many of the implicit responsibilities. Corporations are members of the community. It’s time they start acting like it.

comments edit

UPDATE: Mea culpa! Maurice pointed out that (except for the casing) my original expression WAS correct. I only needed the RegexOptions.SingleLine option. I didn’t need to add the (\s|\n) everywhere. Here’s a corrected post. Thanks Maurice!

Last time I talked about matching HTML with regular expressions, I published a regular expression with a couple small bugs. The first bug was not my fault, but rather the fault of the rich text editor that comes with .TEXT. It was being overly “helpful” when I tried to edit the post and uppercased some of the code. As you know, “\S” is much different than “\s” to a regular expression.

The second bug is entirely my fault and I write this as a confession and to provide a fix. You see, I assumed (and you know what happens when we assume) that complete tags tend to be on a single line. Well that’s not the always the case. You might encounter something ugly like this:

<div     id = "blah" alt=" man    this is ugly html "     >     fire this guy... </div> 

The expression I had posted wouldn’t have matched the div tag sitting in plain sight there so I went in there and corrected that sucker all by itself. It requires using the RegexOptions.SingleLine option so that the . character matches \n. Here’s the expression reprinted (with correct casing) for your reference.

</?\w+((\s+\w+(\s*=\s*(?:”.*?” ’.*?’ [\^’”>\s]+))?)+\s* \s*)/?>

The main difference is now I’m including \n anywhere I’m matching whitespace (via \s). In order for this to work, you need to use the RegexOption SingleLine. Here’s a code snippet that uses this expression to match the above html.

string html = “<div\n\tid=\“blah\” alt=\” man\n”

    + “\tthis is ugly html \”\n”

    + “\t>”

    + “fire this guy…\n”

    + “</div>”;


Regex regex = new Regex(@”</?\w+((\s+\w+(\s*=\s*(?:””.*?””|’.*?’|[\^’””>\s]+))?)+\s*|\s*)/?>”, RegexOptions.Singleline);


MatchCollection matches = regex.Matches(html);

Console.WriteLine(“…..Original Html……”);

Console.WriteLine(html + Environment.NewLine);

Console.WriteLine(“…..Each Tag……”);

foreach(Match match in matches)


    Console.WriteLine(“TAG: “ + match.Value.Replace(“\n”, “ “));


This produces the output:

.....Original Html......<div    id="blah" alt=" man   this is ugly html "   >fire this guy...</div>.....Each Tag......TAG: <div     id="blah" alt=" man     this is ugly html "     >TAG: </div>

So sorry about that. Hope this one treats you better.

tech comments edit

I’m chatting with my buddy Micah who will ask me a question and then annoyingly answer it himself immediately after. For example, he asked me how FireFox picks up an icon from web pages. I replied that there’s a favicon protocol but that I didn’t know the details. He then proceeded to explain how to format the link tag properly.

Apparently the latest version of Trillian will highlight words with links to their definition in Wikipedia. So as you chat with your friends, you become a living breathing dictionary. That’s a rather nice feature for IM conversations.