|
/* |
|
data-line-number |
|
only attribute or number. |
|
if number is specified, then line number start its value. |
|
|
|
data-marker-line |
|
comma separated value. |
|
|
|
data-not-escape-html |
|
if specified, then not escape html |
|
|
|
*/ |
|
window.addEventListener("DOMContentLoaded", function() { |
|
hljs.configure({ |
|
tabReplace: ' ', // 4 spaces |
|
}); |
|
|
|
var unescape_repl_map = { |
|
'<' : '<', |
|
'>' : '>', |
|
'&' : '&' |
|
}; |
|
|
|
function create_escaped_textnode(ele) { |
|
// http://stackoverflow.com/questions/6234773/can-i-escape-html-special-chars-in-javascript |
|
return document.createTextNode( |
|
ele.innerHTML |
|
// single "<" already escaped in innerHTML |
|
.replace(/&(lt|gt|amp);/g, function(m) { |
|
return unescape_repl_map[ m ]; |
|
}) |
|
); |
|
} |
|
function chomp(e) { |
|
// function remove_newline(node, ofs) { |
|
// if (node.nodeType == 3 && node.data.length > 0) { // 3 : Text |
|
// if (ofs < 0) { |
|
// ofs = node.data.length - 1; |
|
// } |
|
// if (node.data[ofs] == "\n") { |
|
// node.deleteData(ofs, 1); |
|
// } |
|
// } |
|
// } |
|
// remove_newline(e.firstChild, 0); |
|
// remove_newline(e.lastChild, -1); |
|
var c = e.firstChild; |
|
if (c.nodeType == 3 && c.data.length > 0 && c.data[0] == "\n") { |
|
c.deleteData(0, 1); |
|
} |
|
c = e.lastChild; |
|
if (c.nodeType == 3 && c.data.length > 0 && c.data[c.data.length - 1] == "\n") { |
|
c.deleteData(c.data.length - 1, 1); |
|
} |
|
} |
|
function hljs_escape_html(e) { |
|
if (! e.hasAttribute("data-not-escape-html")) { |
|
var text = create_escaped_textnode(e); |
|
e.innerHTML = ""; |
|
e.appendChild(text); |
|
} |
|
chomp(e); |
|
// e.innerHTML = e.innerHTML |
|
// .replace(/^[\r\n]+|[\r\n]$/g, "") |
|
// .replace(/&/g, "&") |
|
// .replace(/</g, "<") |
|
// .replace(/>/g, ">") |
|
// .replace(/"/g, """) |
|
// .replace(/'/g, "'"); |
|
return e; |
|
} |
|
function hljs_migrate_syntaxhighlighter(e) { // pre[class*="brush:"] |
|
var text = create_escaped_textnode(e); |
|
e.innerHTML = ""; |
|
var code = document.createElement("code"); |
|
code.appendChild(text); |
|
e.appendChild(code); |
|
chomp(code); |
|
// code.parentNode.classList.add("hljs"); |
|
var m = /brush:\s*(\w+)/.exec(e.className); |
|
if (m) { |
|
code.classList.add(m[1]); |
|
} |
|
m = /highlight:\s*\[([^\]]+)\]/.exec(e.className); |
|
if (m) { |
|
code.dataset.markerLine = m[1]; |
|
} |
|
/* TODO: |
|
gutter |
|
first-line |
|
*/ |
|
return code; |
|
} |
|
function hljs_modify_line_number(code, start, marker) { |
|
|
|
var lines = code.textContent.split(/\r\n|\r|\n/).length; |
|
if (lines > 1) { |
|
if (marker && marker.length > 0) { |
|
var markers = new Array(lines); |
|
markers.fill(" "); |
|
var ofs = start > 0 ? start : 1; |
|
marker.forEach(function(line) { |
|
var i = line - ofs; |
|
if (0 <= i && i < lines) { |
|
markers[i] = '<span class="marker"> </span> '; |
|
} |
|
}); |
|
var marker_area = document.createElement("code"); |
|
marker_area.className = "hljs hljs-markers"; |
|
marker_area.innerHTML = markers.join("\n"); |
|
code.parentNode.insertBefore(marker_area, code); |
|
// code.parentNode.style.position = 'relative'; |
|
code.style.position = "relative"; |
|
code.style.backgroundColor = 'transparent'; |
|
} |
|
if (start > 0) { |
|
var nums = new Array(lines); |
|
nums.fill(start); |
|
nums.forEach(function(v, i, a) { |
|
a[i] = (v + i) + '.'; |
|
}); |
|
var lineno = document.createElement("code"); |
|
lineno.className = "hljs hljs-line-numbers"; |
|
lineno.innerHTML = nums.join("\n"); |
|
code.parentNode.insertBefore(lineno, code); |
|
if (marker && marker.length > 0) { // has marker ? |
|
lineno.style.backgroundColor = 'transparent'; |
|
} |
|
} |
|
} |
|
} |
|
|
|
Array.prototype.forEach.call(document.querySelectorAll("pre > code"), function(code) { |
|
code = hljs_escape_html(code); |
|
code.parentNode.classList.add("hljs-container"); |
|
hljs.highlightBlock(code); |
|
}); |
|
// migration for SyntaxHighlighter |
|
Array.prototype.forEach.call(document.querySelectorAll('pre[class*="brush:"]'), function(code) { |
|
code = hljs_migrate_syntaxhighlighter(code); |
|
code.parentNode.classList.add("hljs-container"); |
|
hljs.highlightBlock(code); |
|
}); |
|
|
|
// line number |
|
function extract_attr(code, attr) { |
|
if (code.hasAttribute("data-line-number")) { |
|
attr.start_line = code.dataset.lineNumber === "" ? 1 : parseInt(code.dataset.lineNumber, 10); |
|
} |
|
if (code.hasAttribute("data-marker-line")) { |
|
attr.marker_line = code.dataset.markerLine.split(/[,\s]+/).reduce(function(a, i) { |
|
if (/^\d+$/.test(i)) { |
|
a.push(parseInt(i,10)); |
|
} |
|
return a; |
|
}, []); |
|
console.log(attr.marker_line); |
|
} |
|
return attr; |
|
/* TODO: |
|
check parent node (PRE) ? |
|
*/ |
|
} |
|
Array.prototype.forEach.call(document.querySelectorAll("pre > code"), function(code) { |
|
// hljs_modify_line_number(code, 10, [12,14,16]); |
|
// hljs_modify_line_number(code, null, [3,6,9]); |
|
var attr = extract_attr(code, {}); |
|
hljs_modify_line_number(code, attr.start_line, attr.marker_line); |
|
}); |
|
/* TODO: |
|
copy code to clipboard |
|
*/ |
|
}); |
|
|
|
|