Adding Line Numbers to Code Fragments


The layout of this article and it's code has been broken a bit by my site redesign, but the concepts are still valid. In fact, I actually am using this within my own syntax highlighting utility which is one of the reasons that the layout is broken.

I started putting together a tutorial tonight, and it struck me that it would be very convenient to add line numbers to my code fragments. I searched around for a solution using CSS or Javascript and I came up empty. It was painful enough to manually add the numbers that I decided to build my own solution. I'm sure other solutions are out there, but I couldn't find any.

Of course, I'm using the prototype.js and behaviour.js libraries as a base, although if you thought about it for any length of time, you could alleviate those requirements.

The end solution is very simple, simply add some javascript headers to your page, and identify any code fragments you want numbered with the class 'ncode'. On page load, the javascript will place line numbers in the code, surrounded by span tags and space entities for alignment. The span class is "linenumber", so for my purposes, I just styled that class to have a yellow background and a 1 pixel right border.

Here's what you need in your header...

<script src="/js/prototype.js" type="text/javascript"></script>
<script src="/js/numbering.js" type="text/javascript"></script>

and here's the code, numbered by itself:


function line_spacing(len,curline){
	ln = '';
	lens = len + '';
	curlines = curline + '';
	if(lens.length > curlines.length){
		k = lens.length - curlines.length;
		ln = "";
		for(l=0;l<k;l++){
			ln = " "+ln;
		}
	}
	ln +=curlines; 
	return ln;
}
function numbers(elem){
 myarray = elem.innerHTML.split("\n");
 numbered = "";
 //alert(myarray.length + "\n" + myarray[1]);
 for(i=0;i<myarray.length;i++){
 	if(i==0){
 		numbered += myarray[i];
 	} else{
 	  line = line_spacing(myarray.length,(i-1));
// 	  i <= 10 ? line=" "+(i-1):line=(i-1);
 	  numbered += ''+line+"" + myarray[i]+"\n";
 	}
 } 
 elem.innerHTML = numbered;
} 

Behaviour.addLoadEvent(codenumbering);  

function codenumbering(){
	ne = document.getElementsByClassName('ncode');
	
	if(!(ne.length)) return;
	mynum = ne.length;
	for(j=0;j<mynum;j++){
		//alert(i + " " + mynum);
		numbers(ne[j]); 
		//alert("should loop" +j + " " + mynum);
	}
} 

Ideally, I'd like to actually make it so that when you selected and copied the text insice <code> blocks, it didn't actually grab the line numbers, but that's for another day. A quick and easy solution for now.

Unfortunately, in line number 8 above (see how nice it is to have line numbers!), Moveable Type is parsing the &nbsp; - so don't actually copy/paste it. You can download the line number free source here.

Talk About Adding Line Numbers to Code Fragments