reveal.rb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -0
- data/LICENSE +21 -0
- data/README.md +23 -0
- data/bin/reveal +5 -0
- data/lib/reveal/cli.rb +83 -0
- data/lib/reveal/templates/revealjs/css/print/pdf.css +190 -0
- data/lib/reveal/templates/revealjs/css/reveal.min.css +7 -0
- data/lib/reveal/templates/revealjs/css/theme/default.css +148 -0
- data/lib/reveal/templates/revealjs/js/reveal.min.js +9 -0
- data/lib/reveal/templates/revealjs/lib/css/zenburn.css +114 -0
- data/lib/reveal/templates/revealjs/lib/font/league_gothic-webfont.eot +0 -0
- data/lib/reveal/templates/revealjs/lib/font/league_gothic-webfont.ttf +0 -0
- data/lib/reveal/templates/revealjs/lib/font/league_gothic-webfont.woff +0 -0
- data/lib/reveal/templates/revealjs/lib/js/classList.js +2 -0
- data/lib/reveal/templates/revealjs/lib/js/head.min.js +8 -0
- data/lib/reveal/templates/revealjs/plugin/highlight/highlight.js +32 -0
- data/lib/reveal/templates/revealjs/plugin/markdown/markdown.js +392 -0
- data/lib/reveal/templates/revealjs/plugin/markdown/marked.js +37 -0
- data/lib/reveal/templates/revealjs/plugin/notes/notes.js +78 -0
- data/lib/reveal/templates/revealjs/plugin/zoom-js/zoom.js +258 -0
- data/lib/reveal/templates/template.html +84 -0
- data/lib/reveal/version.rb +3 -0
- data/lib/reveal.rb +5 -0
- data/reveal.rb.gemspec +19 -0
- metadata +72 -0
@@ -0,0 +1,392 @@
|
|
1
|
+
/**
|
2
|
+
* The reveal.js markdown plugin. Handles parsing of
|
3
|
+
* markdown inside of presentations as well as loading
|
4
|
+
* of external markdown documents.
|
5
|
+
*/
|
6
|
+
(function( root, factory ) {
|
7
|
+
if( typeof exports === 'object' ) {
|
8
|
+
module.exports = factory( require( './marked' ) );
|
9
|
+
}
|
10
|
+
else {
|
11
|
+
// Browser globals (root is window)
|
12
|
+
root.RevealMarkdown = factory( root.marked );
|
13
|
+
root.RevealMarkdown.initialize();
|
14
|
+
}
|
15
|
+
}( this, function( marked ) {
|
16
|
+
|
17
|
+
if( typeof marked === 'undefined' ) {
|
18
|
+
throw 'The reveal.js Markdown plugin requires marked to be loaded';
|
19
|
+
}
|
20
|
+
|
21
|
+
if( typeof hljs !== 'undefined' ) {
|
22
|
+
marked.setOptions({
|
23
|
+
highlight: function( lang, code ) {
|
24
|
+
return hljs.highlightAuto( lang, code ).value;
|
25
|
+
}
|
26
|
+
});
|
27
|
+
}
|
28
|
+
|
29
|
+
var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$',
|
30
|
+
DEFAULT_NOTES_SEPARATOR = 'note:',
|
31
|
+
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
32
|
+
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
33
|
+
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Retrieves the markdown contents of a slide section
|
37
|
+
* element. Normalizes leading tabs/whitespace.
|
38
|
+
*/
|
39
|
+
function getMarkdownFromSlide( section ) {
|
40
|
+
|
41
|
+
var template = section.querySelector( 'script' );
|
42
|
+
|
43
|
+
// strip leading whitespace so it isn't evaluated as code
|
44
|
+
var text = ( template || section ).textContent;
|
45
|
+
|
46
|
+
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
|
47
|
+
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
|
48
|
+
|
49
|
+
if( leadingTabs > 0 ) {
|
50
|
+
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
|
51
|
+
}
|
52
|
+
else if( leadingWs > 1 ) {
|
53
|
+
text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
|
54
|
+
}
|
55
|
+
|
56
|
+
return text;
|
57
|
+
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Given a markdown slide section element, this will
|
62
|
+
* return all arguments that aren't related to markdown
|
63
|
+
* parsing. Used to forward any other user-defined arguments
|
64
|
+
* to the output markdown slide.
|
65
|
+
*/
|
66
|
+
function getForwardedAttributes( section ) {
|
67
|
+
|
68
|
+
var attributes = section.attributes;
|
69
|
+
var result = [];
|
70
|
+
|
71
|
+
for( var i = 0, len = attributes.length; i < len; i++ ) {
|
72
|
+
var name = attributes[i].name,
|
73
|
+
value = attributes[i].value;
|
74
|
+
|
75
|
+
// disregard attributes that are used for markdown loading/parsing
|
76
|
+
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
|
77
|
+
|
78
|
+
if( value ) {
|
79
|
+
result.push( name + '=' + value );
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
result.push( name );
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
return result.join( ' ' );
|
87
|
+
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Inspects the given options and fills out default
|
92
|
+
* values for what's not defined.
|
93
|
+
*/
|
94
|
+
function getSlidifyOptions( options ) {
|
95
|
+
|
96
|
+
options = options || {};
|
97
|
+
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
98
|
+
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
99
|
+
options.attributes = options.attributes || '';
|
100
|
+
|
101
|
+
return options;
|
102
|
+
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* Helper function for constructing a markdown slide.
|
107
|
+
*/
|
108
|
+
function createMarkdownSlide( content, options ) {
|
109
|
+
|
110
|
+
options = getSlidifyOptions( options );
|
111
|
+
|
112
|
+
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
113
|
+
|
114
|
+
if( notesMatch.length === 2 ) {
|
115
|
+
content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
|
116
|
+
}
|
117
|
+
|
118
|
+
return '<script type="text/template">' + content + '</script>';
|
119
|
+
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Parses a data string into multiple slides based
|
124
|
+
* on the passed in separator arguments.
|
125
|
+
*/
|
126
|
+
function slidify( markdown, options ) {
|
127
|
+
|
128
|
+
options = getSlidifyOptions( options );
|
129
|
+
|
130
|
+
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
131
|
+
horizontalSeparatorRegex = new RegExp( options.separator );
|
132
|
+
|
133
|
+
var matches,
|
134
|
+
lastIndex = 0,
|
135
|
+
isHorizontal,
|
136
|
+
wasHorizontal = true,
|
137
|
+
content,
|
138
|
+
sectionStack = [];
|
139
|
+
|
140
|
+
// iterate until all blocks between separators are stacked up
|
141
|
+
while( matches = separatorRegex.exec( markdown ) ) {
|
142
|
+
notes = null;
|
143
|
+
|
144
|
+
// determine direction (horizontal by default)
|
145
|
+
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
|
146
|
+
|
147
|
+
if( !isHorizontal && wasHorizontal ) {
|
148
|
+
// create vertical stack
|
149
|
+
sectionStack.push( [] );
|
150
|
+
}
|
151
|
+
|
152
|
+
// pluck slide content from markdown input
|
153
|
+
content = markdown.substring( lastIndex, matches.index );
|
154
|
+
|
155
|
+
if( isHorizontal && wasHorizontal ) {
|
156
|
+
// add to horizontal stack
|
157
|
+
sectionStack.push( content );
|
158
|
+
}
|
159
|
+
else {
|
160
|
+
// add to vertical stack
|
161
|
+
sectionStack[sectionStack.length-1].push( content );
|
162
|
+
}
|
163
|
+
|
164
|
+
lastIndex = separatorRegex.lastIndex;
|
165
|
+
wasHorizontal = isHorizontal;
|
166
|
+
}
|
167
|
+
|
168
|
+
// add the remaining slide
|
169
|
+
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
170
|
+
|
171
|
+
var markdownSections = '';
|
172
|
+
|
173
|
+
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
174
|
+
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
175
|
+
// vertical
|
176
|
+
if( sectionStack[i] instanceof Array ) {
|
177
|
+
markdownSections += '<section '+ options.attributes +'>';
|
178
|
+
|
179
|
+
sectionStack[i].forEach( function( child ) {
|
180
|
+
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
|
181
|
+
} );
|
182
|
+
|
183
|
+
markdownSections += '</section>';
|
184
|
+
}
|
185
|
+
else {
|
186
|
+
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
return markdownSections;
|
191
|
+
|
192
|
+
}
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Parses any current data-markdown slides, splits
|
196
|
+
* multi-slide markdown into separate sections and
|
197
|
+
* handles loading of external markdown.
|
198
|
+
*/
|
199
|
+
function processSlides() {
|
200
|
+
|
201
|
+
var sections = document.querySelectorAll( '[data-markdown]'),
|
202
|
+
section;
|
203
|
+
|
204
|
+
for( var i = 0, len = sections.length; i < len; i++ ) {
|
205
|
+
|
206
|
+
section = sections[i];
|
207
|
+
|
208
|
+
if( section.getAttribute( 'data-markdown' ).length ) {
|
209
|
+
|
210
|
+
var xhr = new XMLHttpRequest(),
|
211
|
+
url = section.getAttribute( 'data-markdown' );
|
212
|
+
|
213
|
+
datacharset = section.getAttribute( 'data-charset' );
|
214
|
+
|
215
|
+
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
216
|
+
if( datacharset != null && datacharset != '' ) {
|
217
|
+
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
218
|
+
}
|
219
|
+
|
220
|
+
xhr.onreadystatechange = function() {
|
221
|
+
if( xhr.readyState === 4 ) {
|
222
|
+
if ( xhr.status >= 200 && xhr.status < 300 ) {
|
223
|
+
|
224
|
+
section.outerHTML = slidify( xhr.responseText, {
|
225
|
+
separator: section.getAttribute( 'data-separator' ),
|
226
|
+
verticalSeparator: section.getAttribute( 'data-vertical' ),
|
227
|
+
notesSeparator: section.getAttribute( 'data-notes' ),
|
228
|
+
attributes: getForwardedAttributes( section )
|
229
|
+
});
|
230
|
+
|
231
|
+
}
|
232
|
+
else {
|
233
|
+
|
234
|
+
section.outerHTML = '<section data-state="alert">' +
|
235
|
+
'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
|
236
|
+
'Check your browser\'s JavaScript console for more details.' +
|
237
|
+
'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
|
238
|
+
'</section>';
|
239
|
+
|
240
|
+
}
|
241
|
+
}
|
242
|
+
};
|
243
|
+
|
244
|
+
xhr.open( 'GET', url, false );
|
245
|
+
|
246
|
+
try {
|
247
|
+
xhr.send();
|
248
|
+
}
|
249
|
+
catch ( e ) {
|
250
|
+
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 );
|
251
|
+
}
|
252
|
+
|
253
|
+
}
|
254
|
+
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) {
|
255
|
+
|
256
|
+
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
|
257
|
+
separator: section.getAttribute( 'data-separator' ),
|
258
|
+
verticalSeparator: section.getAttribute( 'data-vertical' ),
|
259
|
+
notesSeparator: section.getAttribute( 'data-notes' ),
|
260
|
+
attributes: getForwardedAttributes( section )
|
261
|
+
});
|
262
|
+
|
263
|
+
}
|
264
|
+
else {
|
265
|
+
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
|
266
|
+
}
|
267
|
+
}
|
268
|
+
|
269
|
+
}
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Check if a node value has the attributes pattern.
|
273
|
+
* If yes, extract it and add that value as one or several attributes
|
274
|
+
* the the terget element.
|
275
|
+
*
|
276
|
+
* You need Cache Killer on Chrome to see the effect on any FOM transformation
|
277
|
+
* directly on refresh (F5)
|
278
|
+
* http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
|
279
|
+
*/
|
280
|
+
function addAttributeInElement( node, elementTarget, separator ) {
|
281
|
+
|
282
|
+
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
283
|
+
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
|
284
|
+
var nodeValue = node.nodeValue;
|
285
|
+
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
|
286
|
+
|
287
|
+
var classes = matches[1];
|
288
|
+
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
|
289
|
+
node.nodeValue = nodeValue;
|
290
|
+
while( matchesClass = mardownClassRegex.exec( classes ) ) {
|
291
|
+
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
292
|
+
}
|
293
|
+
return true;
|
294
|
+
}
|
295
|
+
return false;
|
296
|
+
}
|
297
|
+
|
298
|
+
/**
|
299
|
+
* Add attributes to the parent element of a text node,
|
300
|
+
* or the element of an attribute node.
|
301
|
+
*/
|
302
|
+
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
303
|
+
|
304
|
+
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
|
305
|
+
previousParentElement = element;
|
306
|
+
for( var i = 0; i < element.childNodes.length; i++ ) {
|
307
|
+
childElement = element.childNodes[i];
|
308
|
+
if ( i > 0 ) {
|
309
|
+
j = i - 1;
|
310
|
+
while ( j >= 0 ) {
|
311
|
+
aPreviousChildElement = element.childNodes[j];
|
312
|
+
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
|
313
|
+
previousParentElement = aPreviousChildElement;
|
314
|
+
break;
|
315
|
+
}
|
316
|
+
j = j - 1;
|
317
|
+
}
|
318
|
+
}
|
319
|
+
parentSection = section;
|
320
|
+
if( childElement.nodeName == "section" ) {
|
321
|
+
parentSection = childElement ;
|
322
|
+
previousParentElement = childElement ;
|
323
|
+
}
|
324
|
+
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
|
325
|
+
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
326
|
+
}
|
327
|
+
}
|
328
|
+
}
|
329
|
+
|
330
|
+
if ( element.nodeType == Node.COMMENT_NODE ) {
|
331
|
+
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
|
332
|
+
addAttributeInElement( element, section, separatorSectionAttributes );
|
333
|
+
}
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
/**
|
338
|
+
* Converts any current data-markdown slides in the
|
339
|
+
* DOM to HTML.
|
340
|
+
*/
|
341
|
+
function convertSlides() {
|
342
|
+
|
343
|
+
var sections = document.querySelectorAll( '[data-markdown]');
|
344
|
+
|
345
|
+
for( var i = 0, len = sections.length; i < len; i++ ) {
|
346
|
+
|
347
|
+
var section = sections[i];
|
348
|
+
|
349
|
+
// Only parse the same slide once
|
350
|
+
if( !section.getAttribute( 'data-markdown-parsed' ) ) {
|
351
|
+
|
352
|
+
section.setAttribute( 'data-markdown-parsed', true )
|
353
|
+
|
354
|
+
var notes = section.querySelector( 'aside.notes' );
|
355
|
+
var markdown = getMarkdownFromSlide( section );
|
356
|
+
|
357
|
+
section.innerHTML = marked( markdown );
|
358
|
+
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
359
|
+
section.parentNode.getAttribute( 'data-element-attributes' ) ||
|
360
|
+
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
|
361
|
+
section.getAttribute( 'data-attributes' ) ||
|
362
|
+
section.parentNode.getAttribute( 'data-attributes' ) ||
|
363
|
+
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
|
364
|
+
|
365
|
+
// If there were notes, we need to re-add them after
|
366
|
+
// having overwritten the section's HTML
|
367
|
+
if( notes ) {
|
368
|
+
section.appendChild( notes );
|
369
|
+
}
|
370
|
+
|
371
|
+
}
|
372
|
+
|
373
|
+
}
|
374
|
+
|
375
|
+
}
|
376
|
+
|
377
|
+
// API
|
378
|
+
return {
|
379
|
+
|
380
|
+
initialize: function() {
|
381
|
+
processSlides();
|
382
|
+
convertSlides();
|
383
|
+
},
|
384
|
+
|
385
|
+
// TODO: Do these belong in the API?
|
386
|
+
processSlides: processSlides,
|
387
|
+
convertSlides: convertSlides,
|
388
|
+
slidify: slidify
|
389
|
+
|
390
|
+
};
|
391
|
+
|
392
|
+
}));
|
@@ -0,0 +1,37 @@
|
|
1
|
+
/**
|
2
|
+
* marked - a markdown parser
|
3
|
+
* Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
|
4
|
+
* https://github.com/chjj/marked
|
5
|
+
*/
|
6
|
+
|
7
|
+
(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
|
8
|
+
text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed",
|
9
|
+
/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1",
|
10
|
+
"\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};
|
11
|
+
Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,
|
12
|
+
"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,
|
13
|
+
"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]="center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].split(/ *\| */);this.tokens.push(item);continue}if(cap=this.rules.lheading.exec(src)){src=
|
14
|
+
src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[2]==="="?1:2,text:cap[1]});continue}if(cap=this.rules.hr.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"hr"});continue}if(cap=this.rules.blockquote.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"blockquote_start"});cap=cap[0].replace(/^ *> ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);
|
15
|
+
bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i<l;i++){item=cap[i];space=item.length;item=item.replace(/^ *([*+-]|\d+\.) +/,"");if(~item.indexOf("\n ")){space-=item.length;item=!this.options.pedantic?item.replace(new RegExp("^ {1,"+space+"}","gm"),""):item.replace(/^ {1,4}/gm,"")}if(this.options.smartLists&&i!==l-1){b=block.bullet.exec(cap[i+1])[0];if(bull!==b&&!(bull.length>1&&b.length>1)){src=cap.slice(i+
|
16
|
+
1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&&
|
17
|
+
(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i<item.align.length;i++)if(/^ *-+: *$/.test(item.align[i]))item.align[i]="right";else if(/^ *:-+: *$/.test(item.align[i]))item.align[i]=
|
18
|
+
"center";else if(/^ *:-+ *$/.test(item.align[i]))item.align[i]="left";else item.align[i]=null;for(i=0;i<item.cells.length;i++)item.cells[i]=item.cells[i].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(item);continue}if(top&&(cap=this.rules.paragraph.exec(src))){src=src.substring(cap[0].length);this.tokens.push({type:"paragraph",text:cap[1][cap[1].length-1]==="\n"?cap[1].slice(0,-1):cap[1]});continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"text",
|
19
|
+
text:cap[0]});continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return this.tokens};var inline={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
|
20
|
+
code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};inline._inside=/(?:\[[^\]]*\]|[^\]]|\](?=[^\[]*\]))*/;inline._href=/\s*<?([^\s]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
21
|
+
em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;
|
22
|
+
if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);
|
23
|
+
out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+='<a href="'+href+'">'+text+"</a>";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length);
|
24
|
+
out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src=
|
25
|
+
src.substring(cap[0].length);out+="<strong>"+this.output(cap[2]||cap[1])+"</strong>";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+="<em>"+this.output(cap[2]||cap[1])+"</em>";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+="<code>"+escape(cap[2],true)+"</code>";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="<br>";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+="<del>"+
|
26
|
+
this.output(cap[1])+"</del>";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'<a href="'+escape(link.href)+'"'+(link.title?' title="'+escape(link.title)+'"':"")+">"+this.output(cap[1])+"</a>";else return'<img src="'+escape(link.href)+'" alt="'+escape(cap[1])+'"'+(link.title?' title="'+
|
27
|
+
escape(link.title)+'"':"")+">"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i<l;i++){ch=text.charCodeAt(i);if(Math.random()>0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null;
|
28
|
+
this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;
|
29
|
+
while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"<hr>\n";case "heading":return"<h"+this.token.depth+">"+this.inline.output(this.token.text)+"</h"+this.token.depth+">\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text=
|
30
|
+
escape(this.token.text,true);return"<pre><code"+(this.token.lang?' class="'+this.options.langPrefix+this.token.lang+'"':"")+">"+this.token.text+"</code></pre>\n";case "table":var body="",heading,i,row,cell,j;body+="<thead>\n<tr>\n";for(i=0;i<this.token.header.length;i++){heading=this.inline.output(this.token.header[i]);body+=this.token.align[i]?'<th align="'+this.token.align[i]+'">'+heading+"</th>\n":"<th>"+heading+"</th>\n"}body+="</tr>\n</thead>\n";body+="<tbody>\n";for(i=0;i<this.token.cells.length;i++){row=
|
31
|
+
this.token.cells[i];body+="<tr>\n";for(j=0;j<row.length;j++){cell=this.inline.output(row[j]);body+=this.token.align[j]?'<td align="'+this.token.align[j]+'">'+cell+"</td>\n":"<td>"+cell+"</td>\n"}body+="</tr>\n"}body+="</tbody>\n";return"<table>\n"+body+"</table>\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"<blockquote>\n"+body+"</blockquote>\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+=
|
32
|
+
this.tok();return"<"+type+">\n"+body+"</"+type+">\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"<li>"+body+"</li>\n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"<li>"+body+"</li>\n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"<p>"+this.inline.output(this.token.text)+
|
33
|
+
"</p>\n";case "text":return"<p>"+this.parseText()+"</p>\n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=
|
34
|
+
1,target,key;for(;i<arguments.length;i++){target=arguments[i];for(key in target)if(Object.prototype.hasOwnProperty.call(target,key))obj[key]=target[key]}return obj}function marked(src,opt,callback){if(callback||typeof opt==="function"){if(!callback){callback=opt;opt=null}if(opt)opt=merge({},marked.defaults,opt);var tokens=Lexer.lex(tokens,opt),highlight=opt.highlight,pending=0,l=tokens.length,i=0;if(!highlight||highlight.length<3)return callback(null,Parser.parse(tokens,opt));var done=function(){delete opt.highlight;
|
35
|
+
var out=Parser.parse(tokens,opt);opt.highlight=highlight;return callback(null,out)};for(;i<l;i++)(function(token){if(token.type!=="code")return;pending++;return highlight(token.text,token.lang,function(err,code){if(code==null||code===token.text)return--pending||done();token.text=code;token.escaped=true;--pending||done()})})(tokens[i]);return}try{if(opt)opt=merge({},marked.defaults,opt);return Parser.parse(Lexer.lex(src,opt),opt)}catch(e){e.message+="\nPlease report this to https://github.com/chjj/marked.";
|
36
|
+
if((opt||marked.defaults).silent)return"<p>An error occured:</p><pre>"+escape(e.message+"",true)+"</pre>";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;
|
37
|
+
marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
|
@@ -0,0 +1,78 @@
|
|
1
|
+
/**
|
2
|
+
* Handles opening of and synchronization with the reveal.js
|
3
|
+
* notes window.
|
4
|
+
*/
|
5
|
+
var RevealNotes = (function() {
|
6
|
+
|
7
|
+
function openNotes() {
|
8
|
+
var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path
|
9
|
+
jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path
|
10
|
+
var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
|
11
|
+
|
12
|
+
// Fires when slide is changed
|
13
|
+
Reveal.addEventListener( 'slidechanged', post );
|
14
|
+
|
15
|
+
// Fires when a fragment is shown
|
16
|
+
Reveal.addEventListener( 'fragmentshown', post );
|
17
|
+
|
18
|
+
// Fires when a fragment is hidden
|
19
|
+
Reveal.addEventListener( 'fragmenthidden', post );
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Posts the current slide data to the notes window
|
23
|
+
*/
|
24
|
+
function post() {
|
25
|
+
var slideElement = Reveal.getCurrentSlide(),
|
26
|
+
slideIndices = Reveal.getIndices(),
|
27
|
+
messageData;
|
28
|
+
|
29
|
+
var notes = slideElement.querySelector( 'aside.notes' ),
|
30
|
+
nextindexh,
|
31
|
+
nextindexv;
|
32
|
+
|
33
|
+
if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
|
34
|
+
nextindexh = slideIndices.h;
|
35
|
+
nextindexv = slideIndices.v + 1;
|
36
|
+
} else {
|
37
|
+
nextindexh = slideIndices.h + 1;
|
38
|
+
nextindexv = 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
messageData = {
|
42
|
+
notes : notes ? notes.innerHTML : '',
|
43
|
+
indexh : slideIndices.h,
|
44
|
+
indexv : slideIndices.v,
|
45
|
+
indexf : slideIndices.f,
|
46
|
+
nextindexh : nextindexh,
|
47
|
+
nextindexv : nextindexv,
|
48
|
+
markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
|
49
|
+
};
|
50
|
+
|
51
|
+
notesPopup.postMessage( JSON.stringify( messageData ), '*' );
|
52
|
+
}
|
53
|
+
|
54
|
+
// Navigate to the current slide when the notes are loaded
|
55
|
+
notesPopup.addEventListener( 'load', function( event ) {
|
56
|
+
post();
|
57
|
+
}, false );
|
58
|
+
}
|
59
|
+
|
60
|
+
// If the there's a 'notes' query set, open directly
|
61
|
+
if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
|
62
|
+
openNotes();
|
63
|
+
}
|
64
|
+
|
65
|
+
// Open the notes when the 's' key is hit
|
66
|
+
document.addEventListener( 'keydown', function( event ) {
|
67
|
+
// Disregard the event if the target is editable or a
|
68
|
+
// modifier is present
|
69
|
+
if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
|
70
|
+
|
71
|
+
if( event.keyCode === 83 ) {
|
72
|
+
event.preventDefault();
|
73
|
+
openNotes();
|
74
|
+
}
|
75
|
+
}, false );
|
76
|
+
|
77
|
+
return { open: openNotes };
|
78
|
+
})();
|