303 lines
588 KiB
JavaScript
303 lines
588 KiB
JavaScript
|
/*! highlight.js v9.15.10 | 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=[],u=Object.keys,N={},c={},n=/^(no-?highlight|plain|text)$/i,s=/\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",relevance:"r",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"},b="</span>",h={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function _(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function E(e){return e.nodeName.toLowerCase()}function v(e,n){var t=e&&e.exec(n);return t&&0===t.index}function l(e){return n.test(e)}function g(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 R(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),E(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function i(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(i)}}function m(o){function s(e){return e&&e.source||e}function c(e,n){return new RegExp(s(e),"m"+(o.cI?"i":"")+(n?"g":""))}!function n(t,e){if(!t.compiled){if(t.compiled=!0,t.k=t.k||t.bK,t.k){function r(t,e){o.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,n[1]?Number(n[1]):1]})}var a={};"string"==typeof t.k?r("keyword",t.k):u(t.k).forEach(function(e){r(e,t.k[e])}),t.k=a}t.lR=c(t.l||/\w+/,!0),e&&(t.bK&&(t.b="\\b("+t.bK.split(" ").join("|")+")\\b"),t.b||(t.b=/\B|\b/),t.bR=c(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\B|\b/),t.e&&(t.eR=c(t.e)),t.tE=s(t.e)||"",t.eW&&e.tE&&(t.tE+=(t.e?"|":"")+e.tE)),t.i&&(t.iR=c(t.i)),null==t.r&&(t.r=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return function(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return g(n,{v:null},e)})),n.cached_variants||n.eW&&[g(n)]||[n]}("self"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e);var i=t.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([t.tE,t.i]).map(s).filter(Boolean);t.t=i.length?c(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var o=r,c=s(e[i]);for(0<i&&(a+=n);0<c.length;){var u=t.exec(c);if(null==u){a+=c;break}a+=c.substring(0,u.index),c=c.substring(u.index+u[0].length),"\\"==u[0][0]&&u[1]?a+="\\"+String(Number(u[1])+o):(a+=u[0],"("==u[0]&&r++)}}return a}(i,"|"),!0):{exec:function(){return null}}}}(o)}function C(e,n,i,t){function c(e,n,t,r){var a='<span class="'+(r?"":h.classPrefix);return e?(a+=e+'">')+n+(t?"":b):n}function o(){E+=null!=l.sL?function(){var e="string"==typeof l.sL;if(e&&!N[l.sL])return _(g);var n=e?C(l.sL,g,!0,f[l.sL]):O(g,l.sL.length?l.sL:void 0);return 0<l.r&&(R+=n.r),e&&(f[l.sL]=n.top),c(n.language,n.value,!1,!0)}():function(){var e,n,t,r,a,i,o;if(!l.k)return _(g);for(r="",n=0,l.lR.lastIndex=0,t=l.lR.exec(g);t;)r+=_(g.substring(n,t.index)),a=l,i=t,void 0,o=s.cI?i[0].toLowerCase():i[0],(e=a.k.hasOwnProperty(o)&&a.k[o])?(R+=e[1],r+=c(e[0],_(t[0]))):r+
|
||
|
|
||
|
/* 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;
|
||
|
|
||
|
}));
|