Skip to content
Snippets Groups Projects
Commit b968dfef authored by Hakim El Hattab's avatar Hakim El Hattab
Browse files

update markdown plugin formatting to match reveal.js core

parent f2155285
Branches
No related tags found
No related merge requests found
......@@ -2,219 +2,230 @@
// Modified by Hakim to handle Markdown indented with tabs
(function(){
if( typeof marked === 'undefined' ) {
throw 'The reveal.js Markdown plugin requires marked to be loaded';
}
if (typeof hljs !== 'undefined') {
marked.setOptions({
highlight: function (lang, code) {
return hljs.highlightAuto(lang, code).value;
}
});
}
var stripLeadingWhitespace = function(section) {
var template = section.querySelector( 'script' );
// strip leading whitespace so it isn't evaluated as code
var text = ( template || section ).textContent;
var leadingWs = text.match(/^\n?(\s*)/)[1].length,
leadingTabs = text.match(/^\n?(\t*)/)[1].length;
if( leadingTabs > 0 ) {
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
}
else if( leadingWs > 1 ) {
text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
}
return text;
};
var twrap = function(el) {
var content = el.content || el;
content += el.asideContent ? ('<aside class="notes" data-markdown>' + el.asideContent + '</aside>') : '';
return '<script type="text/template">' + content + '</script>';
};
var getForwardedAttributes = function(section) {
var attributes = section.attributes;
var result = [];
for( var i = 0, len = attributes.length; i < len; i++ ) {
var name = attributes[i].name,
value = attributes[i].value;
// disregard attributes that are used for markdown loading/parsing
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
if( value ) {
result.push( name + '=' + value );
}
else {
result.push( name );
}
}
return result.join( ' ' );
};
var slidifyMarkdown = function(markdown, separator, vertical, notes, attributes) {
separator = separator || '^\n---\n$';
notes = notes || 'note:';
var separatorRegex = new RegExp( separator + ( vertical ? '|' + vertical : '' ), 'mg' ),
horizontalSeparatorRegex = new RegExp( separator ),
notesSeparatorRegex = new RegExp( notes, 'mgi' ),
matches,
noteMatch,
lastIndex = 0,
isHorizontal,
wasHorizontal = true,
content,
asideContent,
slide,
sectionStack = [],
markdownSections = '';
// iterate until all blocks between separators are stacked up
while( matches = separatorRegex.exec( markdown ) ) {
asideContent = null;
// determine direction (horizontal by default)
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
if( !isHorizontal && wasHorizontal ) {
// create vertical stack
sectionStack.push( [] );
}
// pluck slide content from markdown input
content = markdown.substring( lastIndex, matches.index );
noteMatch = content.split( notesSeparatorRegex );
if( noteMatch.length === 2 ) {
content = noteMatch[0];
asideContent = noteMatch[1].trim();
}
if( typeof marked === 'undefined' ) {
throw 'The reveal.js Markdown plugin requires marked to be loaded';
}
slide = {
content: content,
asideContent: asideContent || ""
};
if( typeof hljs !== 'undefined' ) {
marked.setOptions({
highlight: function( lang, code ) {
return hljs.highlightAuto( lang, code ).value;
}
});
}
if( isHorizontal && wasHorizontal ) {
// add to horizontal stack
sectionStack.push(slide);
} else {
// add to vertical stack
sectionStack[sectionStack.length-1].push(slide);
}
var stripLeadingWhitespace = function( section ) {
lastIndex = separatorRegex.lastIndex;
wasHorizontal = isHorizontal;
}
var template = section.querySelector( 'script' );
// add the remaining slide
(wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1]).push(markdown.substring(lastIndex));
// strip leading whitespace so it isn't evaluated as code
var text = ( template || section ).textContent;
// flatten the hierarchical stack, and insert <section data-markdown> tags
for( var k = 0, klen = sectionStack.length; k < klen; k++ ) {
// vertical
if( sectionStack[k].propertyIsEnumerable(length) && typeof sectionStack[k].splice === 'function' ) {
markdownSections += '<section '+ attributes +'>' +
'<section data-markdown>' + sectionStack[k].map(twrap).join('</section><section data-markdown>') + '</section>' +
'</section>';
} else {
markdownSections += '<section '+ attributes +' data-markdown>' + twrap( sectionStack[k] ) + '</section>';
}
}
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
return markdownSections;
};
if( leadingTabs > 0 ) {
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
}
else if( leadingWs > 1 ) {
text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
}
var querySlidingMarkdown = function() {
return text;
var sections = document.querySelectorAll( '[data-markdown]'),
section;
};
for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
var twrap = function( el ) {
section = sections[j];
var content = el.content || el;
if( el.asideContent ) {
content += '<aside class="notes" data-markdown>' + el.asideContent + '</aside>';
}
return '<script type="text/template">' + content + '</script>';
};
var getForwardedAttributes = function( section ) {
if( section.getAttribute('data-markdown').length ) {
var attributes = section.attributes;
var result = [];
var xhr = new XMLHttpRequest(),
url = section.getAttribute('data-markdown');
for( var i = 0, len = attributes.length; i < len; i++ ) {
var name = attributes[i].name,
value = attributes[i].value;
datacharset = section.getAttribute('data-charset');
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if (datacharset != null && datacharset != '') {
xhr.overrideMimeType('text/html; charset=' + datacharset);
}
// disregard attributes that are used for markdown loading/parsing
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
xhr.onreadystatechange = function () {
if( xhr.readyState === 4 ) {
if (xhr.status >= 200 && xhr.status < 300) {
section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), section.getAttribute('data-notes'), getForwardedAttributes(section) );
} else {
section.outerHTML = '<section data-state="alert">ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status +
'. Check your browser\'s JavaScript console for more details.' +
'<p>Remember that you need to serve the presentation HTML from a HTTP server and the Markdown file must be there too.</p></section>';
}
}
};
if( value ) {
result.push( name + '=' + value );
}
else {
result.push( name );
}
}
xhr.open('GET', url, false);
try {
xhr.send();
} catch (e) {
alert('Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e);
}
return result.join( ' ' );
} else if( section.getAttribute('data-separator') ) {
};
var markdown = stripLeadingWhitespace(section);
section.outerHTML = slidifyMarkdown( markdown, section.getAttribute('data-separator'), section.getAttribute('data-vertical'), section.getAttribute('data-notes'), getForwardedAttributes(section) );
var slidifyMarkdown = function( markdown, separator, vertical, notes, attributes ) {
}
}
separator = separator || '^\n---\n$';
notes = notes || 'note:';
};
var separatorRegex = new RegExp( separator + ( vertical ? '|' + vertical : '' ), 'mg' ),
horizontalSeparatorRegex = new RegExp( separator ),
notesSeparatorRegex = new RegExp( notes, 'mgi' ),
matches,
noteMatch,
lastIndex = 0,
isHorizontal,
wasHorizontal = true,
content,
asideContent,
slide,
sectionStack = [],
markdownSections = '';
// iterate until all blocks between separators are stacked up
while( matches = separatorRegex.exec( markdown ) ) {
asideContent = null;
var queryMarkdownSlides = function() {
// determine direction (horizontal by default)
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
var sections = document.querySelectorAll( '[data-markdown]');
if( !isHorizontal && wasHorizontal ) {
// create vertical stack
sectionStack.push( [] );
}
for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
// pluck slide content from markdown input
content = markdown.substring( lastIndex, matches.index );
noteMatch = content.split( notesSeparatorRegex );
makeHtml(sections[j]);
if( noteMatch.length === 2 ) {
content = noteMatch[0];
asideContent = noteMatch[1].trim();
}
}
slide = {
content: content,
asideContent: asideContent || ''
};
};
if( isHorizontal && wasHorizontal ) {
// add to horizontal stack
sectionStack.push(slide);
} else {
// add to vertical stack
sectionStack[sectionStack.length-1].push(slide);
}
var makeHtml = function(section) {
lastIndex = separatorRegex.lastIndex;
wasHorizontal = isHorizontal;
}
var notes = section.querySelector( 'aside.notes' );
// add the remaining slide
(wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1]).push(markdown.substring(lastIndex));
var markdown = stripLeadingWhitespace(section);
// flatten the hierarchical stack, and insert <section data-markdown> tags
for( var k = 0, klen = sectionStack.length; k < klen; k++ ) {
// vertical
if( sectionStack[k].propertyIsEnumerable( length ) && typeof sectionStack[k].splice === 'function' ) {
markdownSections += '<section '+ attributes +'>' +
'<section data-markdown>' + sectionStack[k].map( twrap ).join( '</section><section data-markdown>' ) + '</section>' +
'</section>';
} else {
markdownSections += '<section '+ attributes +' data-markdown>' + twrap( sectionStack[k] ) + '</section>';
}
}
section.innerHTML = marked(markdown);
return markdownSections;
};
if( notes ) {
section.appendChild( notes );
}
var queryExternalMarkdown = function() {
};
var sections = document.querySelectorAll( '[data-markdown]'),
section;
querySlidingMarkdown();
for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
queryMarkdownSlides();
section = sections[j];
if( section.getAttribute( 'data-markdown' ).length ) {
var xhr = new XMLHttpRequest(),
url = section.getAttribute( 'data-markdown' );
datacharset = section.getAttribute( 'data-charset' );
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if( datacharset != null && datacharset != '' ) {
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
}
xhr.onreadystatechange = function() {
if( xhr.readyState === 4 ) {
if ( xhr.status >= 200 && xhr.status < 300 ) {
section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute( 'data-separator' ), section.getAttribute( 'data-vertical' ), section.getAttribute( 'data-notes' ), getForwardedAttributes( section ) );
}
else {
section.outerHTML = '<section data-state="alert">ERROR: The attempt to fetch ' + url + ' failed with the HTTP status ' + xhr.status +
'. Check your browser\'s JavaScript console for more details.' +
'<p>Remember that you need to serve the presentation HTML from a HTTP server and the Markdown file must be there too.</p></section>';
}
}
};
xhr.open( 'GET', url, false );
try {
xhr.send();
}
catch ( e ) {
alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
}
} else if( section.getAttribute( 'data-separator' ) ) {
var markdown = stripLeadingWhitespace( section );
section.outerHTML = slidifyMarkdown( markdown, section.getAttribute( 'data-separator' ), section.getAttribute( 'data-vertical' ), section.getAttribute( 'data-notes' ), getForwardedAttributes( section ) );
}
}
};
var queryMarkdownSlides = function() {
var sections = document.querySelectorAll( '[data-markdown]');
for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
makeHtml( sections[j] );
}
};
var makeHtml = function( section ) {
var notes = section.querySelector( 'aside.notes' );
var markdown = stripLeadingWhitespace( section );
section.innerHTML = marked( markdown );
if( notes ) {
section.appendChild( notes );
}
};
queryExternalMarkdown();
queryMarkdownSlides();
})();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment