Coffee Space


Listen:

Code Highlight

NOTE: Depreciated code.

Below is the source for the syntax highlighting for this site, which I wrote in a night as a lightweight system for highlighting bits of code. It's by no means complete, but I've designed it in such a way that it should be complete enough.

Highlights

Code

// Code-Highlight.js
//
// This javascript adds simple syntax highlighting, boasting a small file size,
// simple therefore compatible, backwards compatible for systems not running
// javascript and clean formatting. Code also offers the ability to print in a
// clean and printer friendly fashion.
//
// Version 1.0.1
// Written By B[]Array
//
// License:
//   No warranty, free to use. It would be kind if you said that you have used
//   this code. Use commercially if you wish, after all with any luck this will
//   help make the internet a cleaner place.

function codehighlight(){
  var outerright = '</pre>';
  var fontstart = '<b><font color="';
  var fontend = '</font></b>';
  
  var red = "red";
  var maroon = "maroon";
  var olive = "olive";
  var teal = "teal";
  var grey = "darkslategray";
  
  var symbolpairs = [
    ["[", '">['],
    ["]", '">]'],
    ["{", '">{'],
    ["}", '">}'],
    ["(", '">('],
    [")", '">)']
  ];
  
  var symbolmath = [
    ["+", '">+'],
    ["-", '">-'],
    ["*", '">*'],
    ["^", '">^'],
    ["//", '">//']
  ];
  
  var symbolother = [
    [".", '">.'],
    [",", '">,'],
    ["?", '">?'],
    ["!", '">!'],
    ["£", '">£'],
    ["$", '">$'],
    ["%", '">%'],
    ["@", '">@'],
    ["~", '">~'],
    ["|", '">|'],
    ["#", '">#'],
    [":", '">:']
  ];
  
  var number = [
    ["0", '">0'],
    ["1", '">1'],
    ["2", '">2'],
    ["3", '">3'],
    ["4", '">4'],
    ["5", '">5'],
    ["6", '">6'],
    ["7", '">7'],
    ["8", '">8'],
    ["9", '">9']
  ];
  
  var codeblocks = document.getElementsByClassName("code");
  for(var i = 0; i < codeblocks.length; i++){
    var id = 'code' + i;
    var outerleft = '<input id="printcode" type="button" value="Print Code" onclick="printcode(\'' + id + '\');" /><pre class="code" id="' + id + '">';
    
    var newblock = document.createElement("p");
    newblock.innerHTML = codeblocks[i].innerHTML;
    
    for(var z = 0; z < symbolpairs.length; z++)
      newblock.innerHTML = newblock.innerHTML.split(symbolpairs[z][0]).join(fontstart + teal + symbolpairs[z][1] + fontend);
    
    for(var z = 0; z < symbolmath.length; z++)
      newblock.innerHTML = newblock.innerHTML.split(symbolmath[z][0]).join(fontstart + maroon + symbolmath[z][1] + fontend);
    
    for(var z = 0; z < symbolother.length; z++)
      newblock.innerHTML = newblock.innerHTML.split(symbolother[z][0]).join(fontstart + red + symbolother[z][1] + fontend);
    
    for(var z = 0; z < number.length; z++)
      newblock.innerHTML = newblock.innerHTML.split(number[z][0]).join(fontstart + olive + number[z][1] + fontend);
    
    newblock.innerHTML = outerleft + newblock.innerHTML + outerright;
    codeblocks[i].parentNode.replaceChild(newblock, codeblocks[i]);
  }
}

function printcode(id){
  var win = window.open('', '_blank');
  win.document.write('<html><head></head><body>');
  win.document.write('<h1>' + document.title + '</h1>');
  win.document.write('<h2>' + document.getElementsByTagName("h1")[0].innerHTML + '</h2>');
  
  var codeblock = document.getElementById(id);
  win.document.write('<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">' + codeblock.innerHTML + '</pre>');
  
  win.document.write('</body></html>');
  
  // Special code for IE >= 10
  win.document.close();
  win.focus();
  
  win.print();
  win.close();
}

Use in Page

First things first, you will need to include the javascript file by placing the following into your code:

<script type="text/javascript" src="code-highlight.js"></script>

Next, you must allow the code to run by calling it's constructor codehighlight();.

NOTE: I do know that it can be run from the onload in the body tag, but I wish to leave it open for future scripts to be added as part of a larger modular system.

...
<head>
  ...
  <script type="text/javascript">
    function main(){
      codehighlight();
    }
  </script>
</head>
<body onload="main();">
...
</body>
...

Now the code will parse the html on the page, next to add you code sections:

<pre class="code">
  <!-- Your code here -->
</pre>

Further Experimentation

Further experimenting revealed that it's much more efficient to use the what appears to be much more bloated multiple passes algorithm on the code than doing a character by character search once. I suspect that this is because the browser actually uses a much lighter search and replace algorithm than in the emulated environment of javascript. It's probably the difference between C++ search and replace and a much higher level language. The effects on this page were anything up to 20 seconds page lockup compared to the almost instant viewing of this page with the current code.

If anybody has any advice on how to speed up or simplify the current passes without loosing too much if anything of the syntax I would be happy to listen. I find it somewhat annoying that it isn't faster, but still, it isn't bad for a browser based language and currently the speed is good on most devices, even old ones.