chris carter's web log

Home |  Contact |  Admin
 

How to Make Things Complicated

Posted on June 7, 2008

I have some classes that work together to make writing html easier.  One class is Element and one Attribute that represent their obvious pieces of html.  One feature implemented is the ability to add attributes as a string like this: border=0;height=100%; .  As a feature, that string is parsed into two attributes, one representing border with a value of 0 and the other representing height with a value of 100%.  Simple, right? Totally. 

Here's the code i was using to parse that string into attributes, the first thing is to split on the semi-colons:

public virtual Element AddAttribute(string nameValuePairsSeparatedByAnEqualsSign)
{
	string[] nameValuePairs = nameValuePairsSeparatedByAnEqualsSign.Split(';');
	foreach (string nameValuePair in nameValuePairs)
	{

		if (String.IsNullOrEmpty(nameValuePair))
			continue;

		this.AddAttribute(new Attribute(nameValuePair));
	}
	return this;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

 And here's the contstructor for an Attribute:

public Attribute(string nameValuePairsSeparatedByAnEqualsSign)
{
	if (String.IsNullOrEmpty(nameValuePairsSeparatedByAnEqualsSign))
		throw new ArgumentException("nameValuePairSeparatedByEqualsSign is null or empty.", "nameValuePairsSeparatedByAnEqualsSign");

	string[] nameValues = nameValuePairsSeparatedByAnEqualsSign.Split('=');
	_name = nameValues[0];
	if (nameValues.Length > 1)
		_value = nameValues[1];
}
1
2
3
4
5
6
7
8
9
10

This was all working perfectly until I started a new project, one of the tasks of the project is to create a .csproj file.  One element of a csproj looks like this:

<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
1

That's perfectly legit xml, but that attribute busted my code, the double equals.  So I set out to fix it.  Here's something I came up with that worked, but man, soooooo stoopid complicated:

public static List<Pair<string,string>> Parse1(string attlist)
	{
		List<Pair<string,string>> attributes = new List<Pair<string,string>>();
		List<char> buffer = new List<char>();

		Pair<string,string> attribute = null;
		for (int i = 0; i < attlist.Length; i++)
		{
			char c = attlist[i];

			if (c == '=')
			{
				if (attlist[i + 1] == '=')
				{
					buffer.Add(c);
					buffer.Add('=');
					i++;
				}
				else
				{
					if (attribute == null)
					{
						attribute = new Pair<string,string>();
						attribute.First = new String(buffer.ToArray());
					}
					else
					{
						attribute.Second = new String(buffer.ToArray());
						attributes.Add(attribute);
						attribute = null;
					}
					buffer.Clear();
				}
			}
			else if (c == ';')
			{
				attribute.Second = new String(buffer.ToArray());
				attributes.Add(attribute);
				attribute = null;
				buffer.Clear();
			}
			else
				buffer.Add(c);
		}
		if (attribute != null)
		{
			attribute.Second = new String(buffer.ToArray());
			attributes.Add(attribute);
		}
		return attributes;
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

I asked Levon Hackmeister how he'd do the same thing, and had a wicked simple solution, replace the double equals with something else like deq, do the original split on equals, then replace deq with the original ==.  Blam, done.  Here's the modified code, just needed to change the constructor on Attribute. Note the Replace("==", "&deq;") before the split on equals, and the Replace("&deq;", "==") when assigning the value.

public Attribute(string nameValuePairsSeparatedByAnEqualsSign)
{
	if (String.IsNullOrEmpty(nameValuePairsSeparatedByAnEqualsSign))
		throw new ArgumentException("nameValuePairSeparatedByEqualsSign is null or empty.", "nameValuePairsSeparatedByAnEqualsSign");

	string[] nameValues = nameValuePairsSeparatedByAnEqualsSign.Replace("==", "&deq;").Split('=');
	_name = nameValues[0];
	if (nameValues.Length > 1)
		_value = nameValues[1].Replace("&deq;", "==");
}
1
2
3
4
5
6
7
8
9
10

Sometimes it's easy to skip over an easy solution and jump right into a pile of crap. 

Regular Expressions

I thought about using regex. That's as far as I got though :)

Why I Require Email When Posting Comments On My Blog

Posted on June 7, 2008

2 reasons, one of them is not necessary, and is merely for commenter bling, the other helps me by eliminating 99.999 percent of spam comments.

Avatar

Wikipedia describes an avatar as ...a computer user's representation of himself or herself.... Here's my avatar, those who know me will see the obvious resemblance(note the glistening pecs):

When I post comment on a site that knows how to grab an avatar by email, my avatar appears next to my comment. 

Email Spam

Comment spam sucks.  When I was using just a CAPTCHA image, i was getting thousands of spam comments a day, totally sucked.  Except for a few randoms, and by "a few" i'm talking like less than 20, akismet has filtered all of the spam.  It's free for personal use like this blog, all you have to do is sign up for a wordpress blog. Once you get that set up you get a api key sent to you and you're set to go.  Go where? Exactly.  I used the Akismet Api from codeplex to use the akismet service, super simple.  Right before a comment gets to me it's filtered through akismet, if it gets a thumbs down from akismet as being legitimate, the comment is ignored and not passed on to me for moderation.