303 lines
724 KiB
JavaScript
303 lines
724 KiB
JavaScript
|
/*! highlight.js v9.18.0 | BSD3 License | git.io/hljslicense */
|
||
|
!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"==typeof exports||exports.nodeType?n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs})):e(exports)}(function(a){var f=[],o=Object.keys,_={},g={},C=!0,n=/^(no-?highlight|plain|text)$/i,E=/\blang(?:uage)?-([\w-]+)\b/i,t=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},m="</span>",O="Could not find the language '{}', did you forget to load/include a language module?",B={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},c="of and for in not or if then".split(" ");function x(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function d(e){return e.nodeName.toLowerCase()}function R(e){return n.test(e)}function i(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function p(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),d(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function v(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){a+="<"+d(e)+f.map.call(e.attributes,function(e){return" "+e.nodeName+'="'+x(e.value).replace(/"/g,""")+'"'}).join("")+">"}function l(e){a+="</"+d(e)+">"}function u(e){("start"===e.event?c:l)(e.node)}for(;e.length||n.length;){var s=o();if(a+=x(t.substring(r,s[0].offset)),r=s[0].offset,s===e){for(i.reverse().forEach(l);u(s.splice(0,1)[0]),(s=o())===e&&s.length&&s[0].offset===r;);i.reverse().forEach(c)}else"start"===s[0].event?i.push(s[0].node):i.pop(),u(s.splice(0,1)[0])}return a+x(t.substr(r))}function l(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return i(n,{v:null},e)})),n.cached_variants?n.cached_variants:function e(n){return!!n&&(n.eW||e(n.starts))}(n)?[i(n,{starts:n.starts?i(n.starts):null})]:Object.isFrozen(n)?[i(n)]:[n]}function u(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(u)}}function M(n,t){var i={};return"string"==typeof n?r("keyword",n):o(n).forEach(function(e){r(e,n[e])}),i;function r(a,e){t&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n,t,r=e.split("|");i[r[0]]=[a,(n=r[0],(t=r[1])?Number(t):function(e){return-1!=c.indexOf(e.toLowerCase())}(n)?0:1)]})}}function S(r){function s(e){return e&&e.source||e}function f(e,n){return new RegExp(s(e),"m"+(r.cI?"i":"")+(n?"g":""))}function a(a){var i,e,o={},c=[],l={},t=1;function n(e,n){o[t]=e,c.push([e,n]),t+=new RegExp(n.toString()+"|").exec("").length-1+1}for(var r=0;r<a.c.length;r++){n(e=a.c[r],e.bK?"\\.?(?:"+e.b+")\\.?":e.b)}a.tE&&n("end",a.tE),a.i&&n("illegal",a.i);var u=c.map(function(e){return e[1]});return i=f(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var o=r+=1,c=s(e[i]);for(0<i&&(a+=n),a+="(";0<c.length;){var l=t.exec(c);if(null==l){a+=c;break}a+=c.substring(0,l.index),c=c.substring(l.index+l[0].length),"\\"==l[0][0]&&l[1]?a+="\\"+String(Number(l[1])+o):(a+=l[0],"("==l[0]&&r++)}a+=
|
||
|
|
||
|
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
||
|
/* Edited by Hakim for reveal.js; removed async timeout */
|
||
|
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=g(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[v,L,b]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"interactive"===e.readyState||"complete"===e.readyState?i(t):n.addEventListener("DOMContentLoaded",function(){i(t)})}function i(t){try{var r=e.querySelectorAll("code.hljs,code.nohighlight");for(var i in r)r.hasOwnProperty(i)&&l(r[i],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function l(n,e){"object"==typeof n&&f(function(){n.innerHTML=s(n,e)})}function o(n,e){if("string"==typeof n){var t=document.createElement("code");return t.innerHTML=n,s(t,e)}}function s(n,e){e=e||{singleLine:!1};var t=e.singleLine?0:1;return c(n),a(n.innerHTML,t)}function a(n,e){var t=u(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",i=0,l=t.length;i<l;i++)r+=g('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[j,m,L,b,p,i+1,t[i].length>0?t[i]:" "]);return g('<table class="{0}">{1}</table>',[v,r])}return n}function c(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];h(r.textContent)>0&&(r.childNodes.length>0?c(r):d(r.parentNode))}}function d(n){var e=n.className;if(/hljs-/.test(e)){for(var t=u(n.innerHTML),r=0,i="";r<t.length;r++){var l=t[r].length>0?t[r]:" ";i+=g('<span class="{0}">{1}</span>\n',[e,l])}n.innerHTML=i.trim()}}function u(n){return 0===n.length?[]:n.split(y)}function h(n){return(n.trim().match(y)||[]).length}function f(e){e()}function g(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var v="hljs-ln",m="hljs-ln-line",p="hljs-ln-code",j="hljs-ln-numbers",L="hljs-ln-n",b="data-line-number",y=/\r\n|\r|\n/g;n.hljs?(n.hljs.initLineNumbersOnLoad=r,n.hljs.lineNumbersBlock=l,n.hljs.lineNumbersValue=o,t()):n.console.error("highlight.js not detected!")}(window,document);
|
||
|
|
||
|
/**
|
||
|
* This reveal.js plugin is wrapper around the highlight.js
|
||
|
* syntax highlighting library.
|
||
|
*/
|
||
|
(function( root, factory ) {
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
root.RevealHighlight = factory();
|
||
|
} else if( typeof exports === 'object' ) {
|
||
|
module.exports = factory();
|
||
|
} else {
|
||
|
// Browser globals (root is window)
|
||
|
root.RevealHighlight = factory();
|
||
|
}
|
||
|
}( this, function() {
|
||
|
|
||
|
// Function to perform a better "data-trim" on code snippets
|
||
|
// Will slice an indentation amount on each line of the snippet (amount based on the line having the lowest indentation length)
|
||
|
function betterTrim(snippetEl) {
|
||
|
// Helper functions
|
||
|
function trimLeft(val) {
|
||
|
// Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
|
||
|
return val.replace(/^[\s\uFEFF\xA0]+/g, '');
|
||
|
}
|
||
|
function trimLineBreaks(input) {
|
||
|
var lines = input.split('\n');
|
||
|
|
||
|
// Trim line-breaks from the beginning
|
||
|
for (var i = 0; i < lines.length; i++) {
|
||
|
if (lines[i].trim() === '') {
|
||
|
lines.splice(i--, 1);
|
||
|
} else break;
|
||
|
}
|
||
|
|
||
|
// Trim line-breaks from the end
|
||
|
for (var i = lines.length-1; i >= 0; i--) {
|
||
|
if (lines[i].trim() === '') {
|
||
|
lines.splice(i, 1);
|
||
|
} else break;
|
||
|
}
|
||
|
|
||
|
return lines.join('\n');
|
||
|
}
|
||
|
|
||
|
// Main function for betterTrim()
|
||
|
return (function(snippetEl) {
|
||
|
var content = trimLineBreaks(snippetEl.innerHTML);
|
||
|
var lines = content.split('\n');
|
||
|
// Calculate the minimum amount to remove on each line start of the snippet (can be 0)
|
||
|
var pad = lines.reduce(function(acc, line) {
|
||
|
if (line.length > 0 && trimLeft(line).length > 0 && acc > line.length - trimLeft(line).length) {
|
||
|
return line.length - trimLeft(line).length;
|
||
|
}
|
||
|
return acc;
|
||
|
}, Number.POSITIVE_INFINITY);
|
||
|
// Slice each line with this amount
|
||
|
return lines.map(function(line, index) {
|
||
|
return line.slice(pad);
|
||
|
})
|
||
|
.join('\n');
|
||
|
})(snippetEl);
|
||
|
}
|
||
|
|
||
|
var RevealHighlight = {
|
||
|
|
||
|
HIGHLIGHT_STEP_DELIMITER: '|',
|
||
|
HIGHLIGHT_LINE_DELIMITER: ',',
|
||
|
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
||
|
|
||
|
init: function() {
|
||
|
|
||
|
// Read the plugin config options and provide fallbacks
|
||
|
var config = Reveal.getConfig().highlight || {};
|
||
|
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
||
|
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
||
|
|
||
|
[].slice.call( document.querySelectorAll( '.reveal pre code' ) ).forEach( function( block ) {
|
||
|
|
||
|
// Trim whitespace if the "data-trim" attribute is present
|
||
|
if( block.hasAttribute( 'data-trim' ) && typeof block.innerHTML.trim === 'function' ) {
|
||
|
block.innerHTML = betterTrim( block );
|
||
|
}
|
||
|
|
||
|
// Escape HTML tags unless the "data-noescape" attrbute is present
|
||
|
if( config.escapeHTML && !block.hasAttribute( 'data-noescape' )) {
|
||
|
block.innerHTML = block.innerHTML.replace( /</g,"<").replace(/>/g, '>' );
|
||
|
}
|
||
|
|
||
|
// Re-highlight when focus is lost (for contenteditable code)
|
||
|
block.addEventListener( 'focusout', function( event ) {
|
||
|
hljs.highlightBlock( event.currentTarget );
|
||
|
}, false );
|
||
|
|
||
|
if( config.highlightOnLoad ) {
|
||
|
RevealHighlight.highlightBlock( block );
|
||
|
}
|
||
|
} );
|
||
|
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Highlights a code block. If the <code> node has the
|
||
|
* 'data-line-numbers' attribute we also generate slide
|
||
|
* numbers.
|
||
|
*
|
||
|
* If the block contains multiple line highlight steps,
|
||
|
* we clone the block and create a fragment for each step.
|
||
|
*/
|
||
|
highlightBlock: function( block ) {
|
||
|
|
||
|
hljs.highlightBlock( block );
|
||
|
|
||
|
// Don't generate line numbers for empty code blocks
|
||
|
if( block.innerHTML.trim().length === 0 ) return;
|
||
|
|
||
|
if( block.hasAttribute( 'data-line-numbers' ) ) {
|
||
|
hljs.lineNumbersBlock( block, { singleLine: true } );
|
||
|
|
||
|
// If there is at least one highlight step, generate
|
||
|
// fragments
|
||
|
var highlightSteps = RevealHighlight.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
||
|
if( highlightSteps.length > 1 ) {
|
||
|
|
||
|
// If the original code block has a fragment-index,
|
||
|
// each clone should follow in an incremental sequence
|
||
|
var fragmentIndex = parseInt( block.getAttribute( 'data-fragment-index' ), 10 );
|
||
|
if( typeof fragmentIndex !== 'number' || isNaN( fragmentIndex ) ) {
|
||
|
fragmentIndex = null;
|
||
|
}
|
||
|
|
||
|
// Generate fragments for all steps except the original block
|
||
|
highlightSteps.slice(1).forEach( function( highlight ) {
|
||
|
|
||
|
var fragmentBlock = block.cloneNode( true );
|
||
|
fragmentBlock.setAttribute( 'data-line-numbers', RevealHighlight.serializeHighlightSteps( [ highlight ] ) );
|
||
|
fragmentBlock.classList.add( 'fragment' );
|
||
|
block.parentNode.appendChild( fragmentBlock );
|
||
|
RevealHighlight.highlightLines( fragmentBlock );
|
||
|
|
||
|
if( typeof fragmentIndex === 'number' ) {
|
||
|
fragmentBlock.setAttribute( 'data-fragment-index', fragmentIndex );
|
||
|
fragmentIndex += 1;
|
||
|
}
|
||
|
else {
|
||
|
fragmentBlock.removeAttribute( 'data-fragment-index' );
|
||
|
}
|
||
|
|
||
|
} );
|
||
|
|
||
|
block.removeAttribute( 'data-fragment-index' )
|
||
|
block.setAttribute( 'data-line-numbers', RevealHighlight.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
||
|
|
||
|
}
|
||
|
|
||
|
RevealHighlight.highlightLines( block );
|
||
|
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Visually emphasize specific lines within a code block.
|
||
|
* This only works on blocks with line numbering turned on.
|
||
|
*
|
||
|
* @param {HTMLElement} block a <code> block
|
||
|
* @param {String} [linesToHighlight] The lines that should be
|
||
|
* highlighted in this format:
|
||
|
* "1" = highlights line 1
|
||
|
* "2,5" = highlights lines 2 & 5
|
||
|
* "2,5-7" = highlights lines 2, 5, 6 & 7
|
||
|
*/
|
||
|
highlightLines: function( block, linesToHighlight ) {
|
||
|
|
||
|
var highlightSteps = RevealHighlight.deserializeHighlightSteps( linesToHighlight || block.getAttribute( 'data-line-numbers' ) );
|
||
|
|
||
|
if( highlightSteps.length ) {
|
||
|
|
||
|
highlightSteps[0].forEach( function( highlight ) {
|
||
|
|
||
|
var elementsToHighlight = [];
|
||
|
|
||
|
// Highlight a range
|
||
|
if( typeof highlight.end === 'number' ) {
|
||
|
elementsToHighlight = [].slice.call( block.querySelectorAll( 'table tr:nth-child(n+'+highlight.start+'):nth-child(-n+'+highlight.end+')' ) );
|
||
|
}
|
||
|
// Highlight a single line
|
||
|
else if( typeof highlight.start === 'number' ) {
|
||
|
elementsToHighlight = [].slice.call( block.querySelectorAll( 'table tr:nth-child('+highlight.start+')' ) );
|
||
|
}
|
||
|
|
||
|
if( elementsToHighlight.length ) {
|
||
|
elementsToHighlight.forEach( function( lineElement ) {
|
||
|
lineElement.classList.add( 'highlight-line' );
|
||
|
} );
|
||
|
|
||
|
block.classList.add( 'has-highlights' );
|
||
|
}
|
||
|
|
||
|
} );
|
||
|
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Parses and formats a user-defined string of line
|
||
|
* numbers to highlight.
|
||
|
*
|
||
|
* @example
|
||
|
* RevealHighlight.deserializeHighlightSteps( '1,2|3,5-10' )
|
||
|
* // [
|
||
|
* // [ { start: 1 }, { start: 2 } ],
|
||
|
* // [ { start: 3 }, { start: 5, end: 10 } ]
|
||
|
* // ]
|
||
|
*/
|
||
|
deserializeHighlightSteps: function( highlightSteps ) {
|
||
|
|
||
|
// Remove whitespace
|
||
|
highlightSteps = highlightSteps.replace( /\s/g, '' );
|
||
|
|
||
|
// Divide up our line number groups
|
||
|
highlightSteps = highlightSteps.split( RevealHighlight.HIGHLIGHT_STEP_DELIMITER );
|
||
|
|
||
|
return highlightSteps.map( function( highlights ) {
|
||
|
|
||
|
return highlights.split( RevealHighlight.HIGHLIGHT_LINE_DELIMITER ).map( function( highlight ) {
|
||
|
|
||
|
// Parse valid line numbers
|
||
|
if( /^[\d-]+$/.test( highlight ) ) {
|
||
|
|
||
|
highlight = highlight.split( RevealHighlight.HIGHLIGHT_LINE_RANGE_DELIMITER );
|
||
|
|
||
|
var lineStart = parseInt( highlight[0], 10 ),
|
||
|
lineEnd = parseInt( highlight[1], 10 );
|
||
|
|
||
|
if( isNaN( lineEnd ) ) {
|
||
|
return {
|
||
|
start: lineStart
|
||
|
};
|
||
|
}
|
||
|
else {
|
||
|
return {
|
||
|
start: lineStart,
|
||
|
end: lineEnd
|
||
|
};
|
||
|
}
|
||
|
|
||
|
}
|
||
|
// If no line numbers are provided, no code will be highlighted
|
||
|
else {
|
||
|
|
||
|
return {};
|
||
|
|
||
|
}
|
||
|
|
||
|
} );
|
||
|
|
||
|
} );
|
||
|
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Serializes parsed line number data into a string so
|
||
|
* that we can store it in the DOM.
|
||
|
*/
|
||
|
serializeHighlightSteps: function( highlightSteps ) {
|
||
|
|
||
|
return highlightSteps.map( function( highlights ) {
|
||
|
|
||
|
return highlights.map( function( highlight ) {
|
||
|
|
||
|
// Line range
|
||
|
if( typeof highlight.end === 'number' ) {
|
||
|
return highlight.start + RevealHighlight.HIGHLIGHT_LINE_RANGE_DELIMITER + highlight.end;
|
||
|
}
|
||
|
// Single line
|
||
|
else if( typeof highlight.start === 'number' ) {
|
||
|
return highlight.start;
|
||
|
}
|
||
|
// All lines
|
||
|
else {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
} ).join( RevealHighlight.HIGHLIGHT_LINE_DELIMITER );
|
||
|
|
||
|
} ).join( RevealHighlight.HIGHLIGHT_STEP_DELIMITER );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Reveal.registerPlugin( 'highlight', RevealHighlight );
|
||
|
|
||
|
return RevealHighlight;
|
||
|
|
||
|
}));
|