|
/*jslint browser: true, maxlen: 79 */ |
|
/*globals hljs, window*/ |
|
var RJW = (function (document, window, hljs) { |
|
'use strict'; |
|
var getKids, |
|
addNumbers, |
|
formatCode; |
|
|
|
getKids = function (parentTag, childTag) { |
|
var parents = document.getElementsByTagName(parentTag), |
|
children = []; |
|
|
|
childTag = childTag.toUpperCase(); |
|
|
|
[].slice.call(parents).forEach(function (parent) { |
|
if (parent.firstChild.tagName === childTag) { |
|
children.push(parent.firstChild); |
|
} |
|
}); |
|
|
|
return children; |
|
}; |
|
|
|
addNumbers = function (lineArray, firstLine) { |
|
var currentLine = firstLine, |
|
endLine = firstLine + lineArray.length - 1, |
|
lineWidth = endLine.toString().length, |
|
numberedLines = [], |
|
|
|
padOut = function (string, targetWidth) { |
|
while (string.length < targetWidth) { |
|
string = ' ' + string; |
|
} |
|
return string; |
|
}; |
|
|
|
lineArray.forEach(function (line) { |
|
numberedLines.push('<span class="line-number">' + |
|
padOut(currentLine.toString(), lineWidth) + |
|
' {2}</span>' + line); |
|
currentLine += 1; |
|
}); |
|
|
|
return numberedLines; |
|
}; |
|
|
|
formatCode = function () { |
|
var codeBlocks = getKids('pre', 'code'), |
|
languages = Object.keys(hljs.LANGUAGES), |
|
// This will need changing when I upgrade to the new hljs API |
|
langRegex = new RegExp('^(' + languages.join('|') + '):\\n'); |
|
|
|
codeBlocks.forEach(function (el) { |
|
var oldContent = el.innerHTML, |
|
newContent, |
|
lang = oldContent.match(langRegex), |
|
line; |
|
|
|
// Language line found, so strip it and set class |
|
if (lang) { |
|
lang = lang[1]; |
|
el.setAttribute('class', 'language-' + lang); |
|
oldContent = oldContent.split('\n').slice(1).join('\n'); |
|
} |
|
|
|
// Detect line numbers |
|
line = oldContent.match(/^\ *(\d+):\ {2}/); |
|
if (line) { |
|
// Get numbering start point |
|
line = parseInt(line[1], 10); |
|
// Remove line numbers |
|
oldContent = oldContent.replace(/^\ *\d+:\ {2}/mg, ''); |
|
} |
|
|
|
// Strip empty lines |
|
oldContent = oldContent.replace(/\n+$/, ''); |
|
|
|
// Returned cleaned-up code to element |
|
el.innerHTML = oldContent; |
|
|
|
// Highlight code if language was given |
|
if (lang) { |
|
hljs.highlightBlock(el); |
|
} |
|
|
|
// Add line numbers to highlighted code, add plain link |
|
if (line) { |
|
newContent = el.innerHTML.split('\n'); |
|
newContent = addNumbers(newContent, line); |
|
newContent.push('\n<a href="#" class="code-link">' + |
|
'Show without line numbers</a>'); |
|
el.innerHTML = newContent.join('\n'); |
|
|
|
el.lastChild.addEventListener('click', function (e) { |
|
var w = window.open(), |
|
d = w.document, |
|
codePage = '<html><head><title>Code</title></head>' + |
|
'<body><pre><code>' + oldContent + |
|
'</code></pre></body></html>'; |
|
|
|
// Cancel triggering event |
|
if (e.preventDefault) { |
|
e.preventDefault(); |
|
} |
|
|
|
d.open(); |
|
d.write(codePage); |
|
d.close(); |
|
}, false); |
|
} |
|
}); // End of .forEach |
|
}; // End of formatCode |
|
|
|
window.addEventListener('load', formatCode, false); |
|
return true; |
|
|
|
}(document, window, hljs)); |