Warren Falk

readers are plentiful, thinkers are rare

Archive for May, 2006

Development in Variable Width (follow up)

Tuesday, May 30th, 2006

I am still using variable width for my development. I still have not noticed any more annoyances besides those I had already noted in my first post (space character too thin, developers that try to line stuff up too often etc.). I have corrected the space-too-thin problem by editing the font. I took the liberty of merging the monospace versions of the parentheses, angle brackets, and curly braces (I used Bitstream Vera Mono for that) into my favorite proportional font so far (Verdana – like Tahoma, but with wider spacing between letters).

I also fixed some other annoyances, such as the tiny margin on either side of single and double quotes. This made it very hard to read, and made things such as a single quote, wrapped in double quotes, a very hard thing to decipher. So I increased that margin significantly.

Then I did a couple more things. I made the parentheses (that I copied in from the monospace font) to be more concave. I like that much better. I also made their footprints wider to compensate. Then I added a dot in the middle of the zero, and even put a very thin line through the seven, just because.

I even adjusted the kerning between certain characters to make operators easier to read. I made >>, => and -> spaced closer together, but when I tested them out, I found that my development environment does not seem to take advantage of kerning. If it had, I might have also added some more operator kerning.

So for anyone who is interested, here is the font: WF-Programmer Postscript Font file

DOM Builder Shortcut Function

Tuesday, May 16th, 2006

I’ve created a library to aid in the creation of DOM trees from within Javascript using a json-like syntax. If you’ve ever createElemented or appendChilded your way to a DOM tree, you know why this might be handy.

I like having a standardized DOM, but the language is so incredibly verbose that to build even the most rudimentary DOM tree in javascript takes long line after long line of code. Take the following HTML excerpt for example:

<div class="player">
	<img class="icon" src="img/p1.gif"/>
	<p class="playername">
		<span class="name">Warren</span> (next to move)
	</p>
	<p class="actions">
		[ <a href="lastmove.php">last move</a> ]
	</p>
	<br class="clear"/>
</div>

Now if we want to do this in raw standard DOM javascript code, it will look like this:

var div_player = document.createElement('div');
div_player.className = 'player';
var img_icon = div_player.appendChild(document.createElement('img'));
img_icon.className = 'icon';
img_icon.setAttribute('src', 'img/p1.gif');
var p_playername = div_player.appendChild(document.createElement('p'));
p_playername.className = 'playername';
var span_name = p_playername.appendChild(document.createElement('span'));
span_name.className = 'name';
span_name.appendChild(document.createTextNode('Warren'));
p_playername.appendChild(document.createTextNode(' (next to move)'));
var p_actions = div_player.appendChild(document.createElement('p'));
p_actions.className = 'actions';
p_actions.appendChild(document.createTextNode('[ '));
var a_lastmove = p_actions.appendChild(document.createElement('a'));
a_lastmove.setAttribute('href', 'lastmove.php');
a_lastmove.appendChild(document.createTextNode('last move'));
p_actions.appendChild(document.createTextNode(' ]'));
br_clear = div_player.appendChild(document.createElement('br'));
br_clear.className = 'clear';

And to be fair, I even took advantage of the .className property available for HTML instead of the DOM’s more verbose setAttribute method. The resulting code is much harder to read or debug and is horribly bulky in an environment where code is actually transmitted to the client over a network.

To solve the problem, I created a function called jcreate(). The function takes a single parameter and returns a single node. But the range of parameters it can take is its power. If you pass a string, it will return a DOMTextNode containing that string. If you pass in an array, the first element of the array becomes the “tag descriptor,” and the following elements become the child nodes (becoming parameters, themselves to recursive calls to jcreate()). The descriptor format is simply “tagname.classname#idname” and so it works like this:

jcreate('Warren'); // creates a text node
jcreate(['div']); // creates a div element
jcreate(['div.test#name']); // creates a div element with attributes class="test" and id="name"
jcreate(['div.test#name', 'Warren']); // identical div, but with a child text node
jcreate(['div.test#name, ['p.text', 'Warren'], ['p.subtext', 'super genius']]); // here the div contains two paragraphs
// now let's format that with indents
jcreate(
	['div.test#name,
		['p.text', 'Warren'],
		['p.subtext', 'super genius'],
		]);

In addition to the CSS-like descriptor above, you can also have an attribute descriptor of the format “@attrname.” An attribute is coded then as ['@href', '#help'] and so a link is coded as ['a', ['@href', '#help'], 'click for help'].

You can also use DOM nodes in the json-syntax instead of the json-like alternative. Why would you? Because it can give you a reference variable to that node that you can use later in your code to change the contents. It looks like this:

jcreate(
	['div.test#name,
		x = jcreate(['p.text', 'Warren']),
		['p.subtext', 'super genius'],
		]);
	.
	.
	.
	x.className = 'text highlight';

The HTML code at the beginning of this article can be then built dynamically using the following code:

x = jcreate(
['div.player',
	['img.icon', ['@src', 'img/p1.gif']],
	['p.playername', ['span.name', 'Warren'], ' (next to move)'],
	['p.actions',
		'[ ',
		['a', ['@href', 'lastmove.php'], 'last move'],
		' ]',
		]
	['br.clear']]);

The overhead for all this convenience is a few functions:

function create(n,c,i) { var e = document.createElement(n); if(c) e.className = c; if(i) e.id = i; return e; }
function attr(n,v) { var a = document.createAttribute(n); a.value = v; return a; }
function nodecreate(n) { return create(n.tagName, n.className, n.id); }
function text(s) { return document.createTextNode(s); }

function jid(s)
{
	a = s.split('#');
	b = a[0].split('.');
	return {tagName: b[0], className: b[1], id: a[1]};
}
function jcreate(j)
{
	if (j.nodeType) return j;
	if (typeof(j) == 'string') return text(j);
	if (j[0])
	{
		var id = j[0];
		if (id.substring(0,1) == '@') return attr(id.substring(1), j[1]);
		var e = nodecreate(jid(id));
		for (var i = 1; i < j.length; i++)
		{
			c = jcreate(j[i]);
			c && ((c.nodeType == 2) ? e.setAttributeNode(c) : e.appendChild(c));
		}
		return e;
	}
	return null;
}

In the future, I might extend this to allow javascript objects more complex than arrays (more like json syntax). But so far, I haven't really found a good reason to.

I've tested this, so far, in IE, Mozilla, Opera, and Konqueror. I am confident it works in Safari also but if someone could verify that and comment here, I'd be grateful.

Development in Variable Width

Wednesday, May 10th, 2006

The traditional font family for use in writing computer code is monospace. Partly this is because monospace was all that was available when computer programming began and remained largely the only choice until relatively recently. Mostly, though, monospace is used because coders use spacing to line up their code to make it more readable.

I visited a website which listed some favorite programming fonts and described the properties of each font which made it suitable for programming. All the fonts were monospace as one would assume. However a commentor on the site said that he began using a variable width font a few years previously and never looked back.

So I’ve decided to give it a try, and so far, I like it. Variable width fonts are just easier on the eyes after a while. Still, you need a decent programming font. I would like one where the parentheses (and brackets) have wider than average spacing, and similar characters such as zero and the letter ‘O’ are distinguishable. Interestingly, I’ve found that when I don’t intentionally line my code up, I actually don’t want it to line up. I have found that it is actually easier to read the code when all the characters in the line below do not line up directly under characters in the line above. My left margin is always clean because the spaces and tabs are always the same size. For the most part, I don’t see spacing as a problem. In my particular font, I wish the space character was bigger, though. Another “pro” is that I can fit a whole lot more on one line without using a small font or a harder to read, narrow font.

There are some “cons” though. That narrow font means that people who wrap their comments to more than one line seem to wrap them way too soon. And using a variable width font means I will, likewise, tend to wrap mine later than would be readable for a monospace-font developer. My left margin is always clean, but every once in a great while, I find that code that was intended to line up does not. However, this hasn’t been a problem for me. Coders, I think, often over-format their code, even reducing readability to some degree.

What I would like to see is an editor that can mitigate the downsides of variable width fonts by manipulating the whitespace and recognizing the language syntax. For instance, the editor should be able to detect when a monospace-font developer adds superfluous whitespace for the purpose of lining up code and then expand the variable width whitespace as necessary to make sure the code is lined up. Though this can’t ever be perfect, it can be perfected to a reasonable degree. Also, comment blocks that are obviously wrapped intentionally could be “unwrapped” then “rewrapped.” There are email applications that do this with email text wrapped to the standard 80-or-so lines.  The editor can then automatically wrap comments back to monospace width when saving.

I am currently using KDevelop, KDE’s development environment, for my C++ development.  I might just try to find out where the editor code is and see if I can implement something like this.  In the mean time, though, I think I’ll keep experimenting with different variable width fonts anyway.

.
Entries (RSS) and Comments (RSS).