Code Offer

Code Is Poetry!

Simple Javascript code formatter

Description

This simple Javascript function attempts to format lines within a <pre> tag. I needed a means of making blocks of code more readable when publishing snippets on this site and had seen that many other sites do the same.

At the moment my utility is very simple but without too much more work could be extended to format different languages.

Below, I’m using the code formatter to highlight the code of itself, so no separate demo is needed! Although, if you wish to use the code you should download it from here rather than try and copy if from below as I did have to modify the code to appear correctly. This was necessary due to HTML elements being output within the code that is then being displayed within a HTML page. The code formatter isn’t that smart, yet.

 

How it works

The code considers all <pre> tags within the page and checks to see if a ‘lang’ (language) parameter is specified. If it is then the contents of this tag are passed across to the formatCode function for formatting.

The contents are split into individual lines and any line break characters removed. These are no longer needed as the final output will comprise a pair of spans for each line: one to hold a sequential line number and a second to hold the formatted content.

Some general replacements covering HTML elements and quoted strings are processed followed by language-specific items. At the moment this is simply a list of language keywords for Java-style languages, comments and HTML tags.

The formatted line number and content spans are accumulated and once all lines are processed, written directly back to the original container tag.

A function called colourKeywords does exactly as its name suggests, matching a line of code with a list of keywords and styling as needed by encapsulating the keyword within a span tag.

 

Code

  1   //Colour constants
  2    var fc_cmt="#888";
  3    var fc_html="#11a";
  4    var fc_quot="#a24";
  5    var fc_kwds="#008";
  6	
  7    //Language keywords
  8    var fc_java_kwds="public|int|float|double|private|new|
  9		void|synchronized|if|for|byte|break|else";
 10	
 11    var pres=document.getElementsByTagName("pre");
 12    for (var a=0; a<pres.length; a++) {
 13        var elem=pres[a];
 14        if (elem.className.toLowerCase()=='code') formatCode(elem);
 15    }
 16	
 17    function formatCode(precode) {
 18        var lang=precode.lang.toLowerCase();
 19        var textlines=precode.innerHTML.split(/\r|\n/);
 20        var linecount=1;
 21        var newcode="";
 22	  
 23        //Process each line of text
 24        for (var b=0; b<textlines.length; b++) {
 25            var code=textlines[b];
 26            //Remove line/form feed characters
 27            code=code.replace(/\f|\n/g,"");
 28            //Decode special HTML elements:- ampersand, less than, greater than
 29            if (lang=="html") code=code.replace(/&/g,'&amp;')
 30				.replace(/</g,'&lt;').replace(/>/g,'&gt;');
 31            //Double quoted string
 32            code=code.replace(/(".+")/g,"&lt;span
 33				style=\"color: "+fc_quot+";\">$1&lt;/span>");
 34            //Single quoted string
 35            code=code.replace(/('.+')/g,"&lt;span
 36				style=\"color: "+fc_quot+";\">$1&lt;/span>");
 37		  
 38            //HTML
 39            if (lang=="html") {
 40                //tags
 41                code=code.replace(/&lt;(\S.*?)&gt;/g,"&lt;span 
 42			style=\"color: "+fc_html+";\">&lt;$1&gt;&lt;/span>");
 43                //comments
 44                code=code.replace(/&lt;!--/g,"&lt;span 
 45			style=\"color: "+fc_cmt+";\">&lt;!--");
 46                code=code.replace(/--&gt;/g,"--&gt;&lt;/span>");
 47            }
 48		  
 49            //Java
 50            if (lang=="java") {
 51                //comments
 52                code=code.replace(/(\/\/.*)/,"&lt;span
 53			style=\"color: "+fc_cmt+";\">$1&lt;/span>");
 54                //keywords
 55                code=colourKeywords(fc_java_kwds,code);
 56            }
 57		  
 58            //Accumulate line numbers and reformatted text
 59            var formatline=("   "+linecount).slice(-3);
 60            newcode+="&lt;span style=\"background: #bbb; color: #000;
 61				border-right: solid 2px #2b2; padding-right: 7px;\">"+
 62				formatline+"&lt;/span>"+code+"&lt;br />";
 63            linecount++;
 64        }	  
 65	  
 66        //Assign formatted text back to PRE element
 67        //The outerHTML is used for IE so that
 68        //whitespace is retained.
 69        if ("outerHTML" in elem) {
 70            elem.outerHTML="&lt;pre class='code'>"+newcode+"&lt;/pre>";
 71        } else {
 72            elem.innerHTML=newcode;
 73        }
 74    }
 75	
 76    function colourKeywords(keywords,codeline) {
 77        var wordre=new RegExp("("+keywords+") ","gi");
 78        return codeline.replace(wordre,"&lt;span
 79		style=\"color: "+fc_kwds+";\">$1 &lt;/span>");
 80    }

 

Future Improvements

Hopefully you can see how support for additional languages could easily be added. Also, it would be useful if it catered for mixed/multiple languages, e.g. embedded HTML code within Javascript quoted strings.

Leave a comment

Information

This entry was posted on July 21, 2012 by .