This doc is outdated as there is a new version of the script. Please see LIPT: Inyección de listas a gogó (Spanish) while I prepare the English translation.
As suggested by Ingo Chao in a problem with the impression of the tag pre, I developed a Javascript function to convert any <pre class="code"> element into an ordered list. Now, for something completely different, a new version.
<pre class="code"> anymore. Instead, we search the first code element inside every pre element (Why? Because that's the output I get from Markdown).
function foo() { // Just a demo
//doSomething();
doNothing();
}
Download the Javascript source, put it somewhere in your server and point to it from an script tag in your HTML doc. Now you can define the CSS rules. The ordered list has a class name of code, every line has a class name of tab# (tab0, tab1, tab2, etc.) where the actual code lives inside a code element. Comments are marked as spans with class name cmt.
Anyone that you like. It'd be nice if you send me a note telling you are using this script or pay a beer for me ;)
Look at Ingo Chao's List Injection PRE Tags to find my inspiration source and alternative implementations. And please, send any comment about this code to choan@alice.0z0ne.com.
Have a nice day,
Choan C. Gálvez
function lipt() {
/* change to FALSE if you don't want to proccess comments (boogie buggy) */
var PROCCESS_COMMENTS = true;
if (!document.getElementsByTagName) {
return;
}
// look for pre tags in the doc
var pres = document.getElementsByTagName('pre');
if (0 == pres.length) {
return; // no pre tags, nothing to do
}
for (var i = 0; i < pres.length; i++) {
var pre = pres[i];
// search ONE code tab inside the pre
var code = pre.getElementsByTagName('code')[0];
if (null == code) {
continue; // no one here, try with the next pre tag
}
// go for the job
var inMultiLineComment = false;
var content = getText(code);
// normalize new lines
if (!window.opera) { /* Opera seems to have a nice bug with global replacements */
content = content.replace(/\n|\r|\r\n/g, '\n');
} else {
content = content.replace(/\n|\r|\r\n/, '\n');
}
content = content.replace(/^\n*/, ''); /* trim empty lines at start */
content = content.replace(/\n*$/, ''); /* trim empty lines at the end */
var lines = content.split('\n');
var ol = document.createElement('ol');
ol.className = 'code';
for (var j = 0; j < lines.length; j++) {
var line = lines[j];
line = line.replace(/\t/g, ' '); // replace tab with four spaces
var cname = 'tab' + (Math.floor(countSpaces(line) / 4) - 1); // className for this line
var restSpaces = countSpaces(line) % 4;
line = line.replace(/^ +/, '');
if (restSpaces) {
for (var k = 0; k < restSpaces; k++) {
line = '\u00A0' + line;
}
}
var parts = new Array();
if (inMultiLineComment) {
parts = ['', line];
} else {
parts = [line];
}
if (PROCCESS_COMMENTS) {
var slashSlashPos = line.indexOf('//');
var starSlashPos = line.indexOf('/*');
var slashStarPos = line.indexOf('*/');
if (slashSlashPos != -1) {
parts = line.split('//');
parts[1] = '//' + parts[1];
} else if (starSlashPos != -1) {
if (inMultiLineComment) {
parts = ['', line];
} else {
parts = line.split('/*');
parts[1] = '/*' + parts[1];
}
inMultiLineComment = true;
}
if (slashStarPos != -1) {
inMultiLineComment = false;
}
}
var li = document.createElement('li');
li.className = cname; // tab0, tab1, etc.
var span = document.createElement('code');
var code = document.createTextNode(parts[0]);
span.appendChild(code);
if (parts[1]) {
var cmt = document.createElement('span');
cmt.appendChild(document.createTextNode(parts[1]));
cmt.className = 'cmt';
span.appendChild(cmt);
}
span.appendChild(document.createTextNode('\u00A0')); /* Unicode non-breaking space fix for Firefox */
li.appendChild(span);
ol.appendChild(li);
};
pre.parentNode.replaceChild(ol, pre);
i--; // if we replace the pre, now there are n - 1 pre elements in the collection we are traversing
};
function countSpaces(s) {
var spaceCount = 0;
for (var i = 0; i < s.length; i++) {
if (' ' == s.substr(i,1)) {
spaceCount++;
} else {
break;
}
};
return spaceCount;
}
function getText(node) {
/* from JavaScript The Definitive Guide */
var s = '';
var children = node.childNodes;
for (var i=0; i < children.length; i++) {
var child = children[i];
if (child.nodeType == 3 /* Text node */) {
s += child.data;
} else {
s += getText(child);
}
}
return s;
}
}
// add the handler to the onload event
var oldOnload = window.onload;
if (typeof oldOnload == 'function') {
window.onload = function() {
oldOnload();
lipt();
}
} else {
window.onload = lipt;
}
Created 2005/06/25.