/**
* Super simple syntax highlighting plugin for CSSS code snippets * Usage: <code lang="javascript"> * @author Lea Verou */
(function(){
if(!document.body.insertAdjacentHTML) {
return;
}
var self = window.Highlight = {
languages: { javascript: { 'comment': /(\/\*.*?\*\/)|\/\/.*?(\r?\n|$)/g, // TODO multiline support 'string': /(('|").*?(\2))/g, // used to be: /'.*?'|".*?"/g, 'keyword': /\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof)\b/g, 'boolean': /\b(true|false)\b/g, 'number': /\b-?(0x)?\d*\.?\d+\b/g, 'regex': /\/.+?\/[gim]{0,3}/g } }, isInited: function(code) { return code.hasAttribute('data-highlighted'); }, init: function(code) { if(!code || self.isInited(code)) { return; // or should I rehighlight? } var lang = self.languages[code.getAttribute('lang')]; if(!lang) { return; } code.normalize(); for(var token in lang) { // Assumption: If there are other tags in the code, they don't cut a token in half var textNodes = getTextNodes(code, function(node) { var parent = node.parentNode; return !(/span/i.test(parent.nodeName) && /^token\s/.test(parent.className)); }); for(var i=0; i<textNodes.length; i++) { var oldNode = textNodes[i], text = oldNode.nodeValue .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>'); var newText = text.replace(lang[token], function($0) { return '<span class="token ' + token + '">' + $0 + '</span>' }); if(newText !== text) { replaceNodeWithHTML(oldNode, newText); } } } code.setAttribute('data-highlighted', 'true'); }, container: function(container) { if(!container) { return; } var codes = container.querySelectorAll('code[lang]'); for(var i=0; i<codes.length; i++) { Highlight.init(codes[i]); } }
}
function getTextNodes(root, filter) {
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, filter? {acceptNode: filter} : null, false), node, textNodes = []; while(node = walker.nextNode()) { textNodes.push(node); } return textNodes;
}
function replaceNodeWithHTML(node, html) {
// Replace text node with element var temp = document.createElement('div'); node.parentNode.replaceChild(temp, node); // Use insertAdjacentHTML to insert the new markup temp.insertAdjacentHTML('beforeBegin', html); // Remove the element temp.parentNode.removeChild(temp);
}
// Highlight current slide function highlightSlide() {
self.container(document.getElementById(location.hash.slice(1)));
}
addEventListener('hashchange', highlightSlide, false); addEventListener('DOMContentLoaded', highlightSlide, false);
})();