asciidoctor-revealjs 4.1.0 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +11 -1350
- data/asciidoctor-revealjs.gemspec +0 -2
- data/examples/auto-animate-code.adoc +47 -0
- data/examples/auto-animate.adoc +351 -0
- data/examples/favicon.adoc +13 -0
- data/examples/mathjax-cdn.adoc +1 -1
- data/examples/mathjax.adoc +1 -1
- data/examples/revealjs-custom-theme.adoc +1 -1
- data/examples/revealjs-plugin-activation.adoc +3 -2
- data/examples/revealjs-plugins/chalkboard/README.md +94 -61
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-black.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-blue.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-green.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-orange.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-purple.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-red.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/boardmarker-yellow.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-blue.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-green.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-orange.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-purple.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-red.png +0 -0
- data/examples/revealjs-plugins/chalkboard/img/{chalk.png → chalk-white.png} +0 -0
- data/examples/revealjs-plugins/chalkboard/img/chalk-yellow.png +0 -0
- data/examples/revealjs-plugins/chalkboard/plugin.js +1836 -0
- data/examples/revealjs-plugins/chalkboard/style.css +38 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/LICENSE +1 -1
- data/examples/revealjs-plugins/menu/README.md +368 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/LICENSE.txt +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/all.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/brands.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/fontawesome.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/regular.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/solid.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/svg-with-js.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/css/v4-shims.min.css +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.eot +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.svg +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.ttf +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-brands-400.woff2 +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.eot +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.svg +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.ttf +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-regular-400.woff2 +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.eot +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.svg +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.ttf +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/font-awesome/webfonts/fa-solid-900.woff2 +0 -0
- data/examples/revealjs-plugins/{reveal.js-menu → menu}/menu.css +116 -115
- data/examples/revealjs-plugins/menu/menu.esm.js +1 -0
- data/examples/revealjs-plugins/menu/menu.js +1 -0
- data/examples/revealjs-plugins/menu/plugin.js +1252 -0
- data/examples/revealjs-plugins-docinfo-footer.html +20 -0
- data/examples/revealjs-plugins.adoc +2 -3
- data/examples/search-plugin.adoc +26 -0
- data/examples/source-rouge.adoc +1 -1
- data/examples/text-formatting.adoc +34 -0
- data/lib/asciidoctor-revealjs/converter.rb +1029 -966
- data/lib/asciidoctor-revealjs/highlightjs.rb +155 -14
- data/lib/asciidoctor-revealjs/version.rb +1 -1
- data/templates/asciidoctor-compatibility.css +26 -1
- data/templates/document.html.slim +28 -44
- data/templates/helpers.rb +83 -9
- data/templates/inline_quoted.html.slim +2 -2
- data/templates/listing.html.slim +2 -1
- data/templates/section.html.slim +7 -1
- data/templates/title_slide.html.slim +1 -2
- metadata +57 -69
- data/examples/revealjs-plugins/chalkboard/chalkboard.js +0 -1288
- data/examples/revealjs-plugins/chalkboard/img/boardmarker.png +0 -0
- data/examples/revealjs-plugins/reveal.js-menu/CONTRIBUTING.md +0 -9
- data/examples/revealjs-plugins/reveal.js-menu/README.md +0 -334
- data/examples/revealjs-plugins/reveal.js-menu/bower.json +0 -21
- data/examples/revealjs-plugins/reveal.js-menu/menu.js +0 -949
- data/examples/revealjs-plugins/reveal.js-menu/package.json +0 -22
- data/examples/revealjs-plugins-conf.js +0 -10
- data/examples/revealjs-plugins.js +0 -2
@@ -6,7 +6,10 @@ module Asciidoctor
|
|
6
6
|
class HighlightJsAdapter < Asciidoctor::SyntaxHighlighter::Base
|
7
7
|
register_for 'highlightjs', 'highlight.js'
|
8
8
|
|
9
|
-
|
9
|
+
# REMIND: we cannot use Highlight.js 11+ because unescaped HTML support has been removed:
|
10
|
+
# https://github.com/highlightjs/highlight.js/issues/2889
|
11
|
+
# We are using unescaped HTML in source blocks for callout.
|
12
|
+
HIGHLIGHT_JS_VERSION = '10.7.3'
|
10
13
|
|
11
14
|
def initialize *args
|
12
15
|
super
|
@@ -19,19 +22,25 @@ module Asciidoctor
|
|
19
22
|
# The steps are split using the | character
|
20
23
|
# For example, this method makes "1..3|6,7" into "1,2,3|6,7"
|
21
24
|
def _convert_highlight_to_revealjs node
|
22
|
-
|
23
|
-
node.resolve_lines_to_highlight(node.content, linenums).join(
|
24
|
-
}.join(
|
25
|
+
node.attributes['highlight'].split('|').collect { |linenums|
|
26
|
+
node.resolve_lines_to_highlight(node.content, linenums).join(',')
|
27
|
+
}.join('|')
|
25
28
|
end
|
26
29
|
|
27
30
|
def format node, lang, opts
|
28
|
-
super node, lang, (opts.merge transform: proc { |
|
31
|
+
super node, lang, (opts.merge transform: proc { |pre, code|
|
29
32
|
code['class'] = %(language-#{lang || 'none'} hljs)
|
30
33
|
code['data-noescape'] = true
|
34
|
+
if (id = node.attr('data-id'))
|
35
|
+
pre['data-id'] = id
|
36
|
+
end
|
37
|
+
if node.option?('trim')
|
38
|
+
code['data-trim'] = ''
|
39
|
+
end
|
31
40
|
|
32
|
-
if node.attributes.key?(
|
41
|
+
if node.attributes.key?('highlight')
|
33
42
|
code['data-line-numbers'] = self._convert_highlight_to_revealjs(node)
|
34
|
-
elsif node.attributes.key?(
|
43
|
+
elsif node.attributes.key?('linenums')
|
35
44
|
code['data-line-numbers'] = ''
|
36
45
|
end
|
37
46
|
})
|
@@ -50,7 +59,7 @@ module Asciidoctor
|
|
50
59
|
if doc.attr? 'highlightjs-theme'
|
51
60
|
theme_href = doc.attr 'highlightjs-theme'
|
52
61
|
else
|
53
|
-
theme_href = "#{revealjsdir}/
|
62
|
+
theme_href = "#{revealjsdir}/plugin/highlight/monokai.css"
|
54
63
|
end
|
55
64
|
base_url = doc.attr 'highlightjsdir', %(#{opts[:cdn_base_url]}/highlight.js/#{HIGHLIGHT_JS_VERSION})
|
56
65
|
%(<link rel="stylesheet" href="#{theme_href}"#{opts[:self_closing_tag_slash]}>
|
@@ -58,11 +67,14 @@ module Asciidoctor
|
|
58
67
|
#{(doc.attr? 'highlightjs-languages') ? ((doc.attr 'highlightjs-languages').split ',').map {|lang| %[<script src="#{base_url}/languages/#{lang.lstrip}.min.js"></script>\n] }.join : ''}
|
59
68
|
<script>
|
60
69
|
#{HIGHLIGHT_PLUGIN_SOURCE}
|
61
|
-
hljs.
|
70
|
+
hljs.configure({
|
71
|
+
ignoreUnescapedHTML: true,
|
72
|
+
});
|
73
|
+
hljs.highlightAll();
|
62
74
|
</script>)
|
63
75
|
end
|
64
76
|
|
65
|
-
# this file was copied-pasted from https://raw.githubusercontent.com/hakimel/reveal.js/
|
77
|
+
# this file was copied-pasted from https://raw.githubusercontent.com/hakimel/reveal.js/4.1.2/plugin/highlight/plugin.js
|
66
78
|
# please note that the bundled highlight.js code was removed so we can use the latest version from cdnjs.
|
67
79
|
HIGHLIGHT_PLUGIN_SOURCE = %q{
|
68
80
|
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
@@ -137,14 +149,25 @@ hljs.initHighlightingOnLoad();
|
|
137
149
|
HIGHLIGHT_LINE_DELIMITER: ',',
|
138
150
|
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
139
151
|
|
140
|
-
init: function() {
|
152
|
+
init: function( reveal ) {
|
141
153
|
|
142
154
|
// Read the plugin config options and provide fallbacks
|
143
155
|
var config = Reveal.getConfig().highlight || {};
|
144
156
|
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
145
157
|
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
146
158
|
|
147
|
-
[].slice.call(
|
159
|
+
[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( function( block ) {
|
160
|
+
|
161
|
+
block.parentNode.className = 'code-wrapper';
|
162
|
+
|
163
|
+
// Code can optionally be wrapped in script template to avoid
|
164
|
+
// HTML being parsed by the browser (i.e. when you need to
|
165
|
+
// include <, > or & in your code).
|
166
|
+
let substitute = block.querySelector( 'script[type="text/template"]' );
|
167
|
+
if( substitute ) {
|
168
|
+
// textContent handles the HTML entity escapes for us
|
169
|
+
block.textContent = substitute.innerHTML;
|
170
|
+
}
|
148
171
|
|
149
172
|
// Trim whitespace if the "data-trim" attribute is present
|
150
173
|
if( block.hasAttribute( 'data-trim' ) && typeof block.innerHTML.trim === 'function' ) {
|
@@ -158,7 +181,7 @@ hljs.initHighlightingOnLoad();
|
|
158
181
|
|
159
182
|
// Re-highlight when focus is lost (for contenteditable code)
|
160
183
|
block.addEventListener( 'focusout', function( event ) {
|
161
|
-
hljs.
|
184
|
+
hljs.highlightElement( event.currentTarget );
|
162
185
|
}, false );
|
163
186
|
|
164
187
|
if( config.highlightOnLoad ) {
|
@@ -166,6 +189,13 @@ hljs.initHighlightingOnLoad();
|
|
166
189
|
}
|
167
190
|
} );
|
168
191
|
|
192
|
+
// If we're printing to PDF, scroll the code highlights of
|
193
|
+
// all blocks in the deck into view at once
|
194
|
+
reveal.on( 'pdf-ready', function() {
|
195
|
+
[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code[data-line-numbers].current-fragment' ) ).forEach( function( block ) {
|
196
|
+
RevealHighlight.scrollHighlightedLineIntoView( block, {}, true );
|
197
|
+
} );
|
198
|
+
} );
|
169
199
|
},
|
170
200
|
|
171
201
|
/**
|
@@ -178,7 +208,7 @@ hljs.initHighlightingOnLoad();
|
|
178
208
|
*/
|
179
209
|
highlightBlock: function( block ) {
|
180
210
|
|
181
|
-
hljs.
|
211
|
+
hljs.highlightElement( block );
|
182
212
|
|
183
213
|
// Don't generate line numbers for empty code blocks
|
184
214
|
if( block.innerHTML.trim().length === 0 ) return;
|
@@ -186,6 +216,8 @@ hljs.initHighlightingOnLoad();
|
|
186
216
|
if( block.hasAttribute( 'data-line-numbers' ) ) {
|
187
217
|
hljs.lineNumbersBlock( block, { singleLine: true } );
|
188
218
|
|
219
|
+
var scrollState = { currentBlock: block };
|
220
|
+
|
189
221
|
// If there is at least one highlight step, generate
|
190
222
|
// fragments
|
191
223
|
var highlightSteps = RevealHighlight.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
@@ -194,6 +226,7 @@ hljs.initHighlightingOnLoad();
|
|
194
226
|
// If the original code block has a fragment-index,
|
195
227
|
// each clone should follow in an incremental sequence
|
196
228
|
var fragmentIndex = parseInt( block.getAttribute( 'data-fragment-index' ), 10 );
|
229
|
+
|
197
230
|
if( typeof fragmentIndex !== 'number' || isNaN( fragmentIndex ) ) {
|
198
231
|
fragmentIndex = null;
|
199
232
|
}
|
@@ -215,6 +248,10 @@ hljs.initHighlightingOnLoad();
|
|
215
248
|
fragmentBlock.removeAttribute( 'data-fragment-index' );
|
216
249
|
}
|
217
250
|
|
251
|
+
// Scroll highlights into view as we step through them
|
252
|
+
fragmentBlock.addEventListener( 'visible', RevealHighlight.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock, scrollState ) );
|
253
|
+
fragmentBlock.addEventListener( 'hidden', RevealHighlight.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousSibling, scrollState ) );
|
254
|
+
|
218
255
|
} );
|
219
256
|
|
220
257
|
block.removeAttribute( 'data-fragment-index' )
|
@@ -222,12 +259,116 @@ hljs.initHighlightingOnLoad();
|
|
222
259
|
|
223
260
|
}
|
224
261
|
|
262
|
+
// Scroll the first highlight into view when the slide
|
263
|
+
// becomes visible. Note supported in IE11 since it lacks
|
264
|
+
// support for Element.closest.
|
265
|
+
var slide = typeof block.closest === 'function' ? block.closest( 'section:not(.stack)' ) : null;
|
266
|
+
if( slide ) {
|
267
|
+
var scrollFirstHighlightIntoView = function() {
|
268
|
+
RevealHighlight.scrollHighlightedLineIntoView( block, scrollState, true );
|
269
|
+
slide.removeEventListener( 'visible', scrollFirstHighlightIntoView );
|
270
|
+
}
|
271
|
+
slide.addEventListener( 'visible', scrollFirstHighlightIntoView );
|
272
|
+
}
|
273
|
+
|
225
274
|
RevealHighlight.highlightLines( block );
|
226
275
|
|
227
276
|
}
|
228
277
|
|
229
278
|
},
|
230
279
|
|
280
|
+
/**
|
281
|
+
* Animates scrolling to the first highlighted line
|
282
|
+
* in the given code block.
|
283
|
+
*/
|
284
|
+
scrollHighlightedLineIntoView: function( block, scrollState, skipAnimation ) {
|
285
|
+
|
286
|
+
cancelAnimationFrame( scrollState.animationFrameID );
|
287
|
+
|
288
|
+
// Match the scroll position of the currently visible
|
289
|
+
// code block
|
290
|
+
if( scrollState.currentBlock ) {
|
291
|
+
block.scrollTop = scrollState.currentBlock.scrollTop;
|
292
|
+
}
|
293
|
+
|
294
|
+
// Remember the current code block so that we can match
|
295
|
+
// its scroll position when showing/hiding fragments
|
296
|
+
scrollState.currentBlock = block;
|
297
|
+
|
298
|
+
var highlightBounds = RevealHighlight.getHighlightedLineBounds( block )
|
299
|
+
var viewportHeight = block.offsetHeight;
|
300
|
+
|
301
|
+
// Subtract padding from the viewport height
|
302
|
+
var blockStyles = getComputedStyle( block );
|
303
|
+
viewportHeight -= parseInt( blockStyles.paddingTop ) + parseInt( blockStyles.paddingBottom );
|
304
|
+
|
305
|
+
// Scroll position which centers all highlights
|
306
|
+
var startTop = block.scrollTop;
|
307
|
+
var targetTop = highlightBounds.top + ( Math.min( highlightBounds.bottom - highlightBounds.top, viewportHeight ) - viewportHeight ) / 2;
|
308
|
+
|
309
|
+
// Account for offsets in position applied to the
|
310
|
+
// <table> that holds our lines of code
|
311
|
+
var lineTable = block.querySelector( '.hljs-ln' );
|
312
|
+
if( lineTable ) targetTop += lineTable.offsetTop - parseInt( blockStyles.paddingTop );
|
313
|
+
|
314
|
+
// Make sure the scroll target is within bounds
|
315
|
+
targetTop = Math.max( Math.min( targetTop, block.scrollHeight - viewportHeight ), 0 );
|
316
|
+
|
317
|
+
if( skipAnimation === true || startTop === targetTop ) {
|
318
|
+
block.scrollTop = targetTop;
|
319
|
+
}
|
320
|
+
else {
|
321
|
+
|
322
|
+
// Don't attempt to scroll if there is no overflow
|
323
|
+
if( block.scrollHeight <= viewportHeight ) return;
|
324
|
+
|
325
|
+
var time = 0;
|
326
|
+
var animate = function() {
|
327
|
+
time = Math.min( time + 0.02, 1 );
|
328
|
+
|
329
|
+
// Update our eased scroll position
|
330
|
+
block.scrollTop = startTop + ( targetTop - startTop ) * RevealHighlight.easeInOutQuart( time );
|
331
|
+
|
332
|
+
// Keep animating unless we've reached the end
|
333
|
+
if( time < 1 ) {
|
334
|
+
scrollState.animationFrameID = requestAnimationFrame( animate );
|
335
|
+
}
|
336
|
+
};
|
337
|
+
|
338
|
+
animate();
|
339
|
+
|
340
|
+
}
|
341
|
+
|
342
|
+
},
|
343
|
+
|
344
|
+
/**
|
345
|
+
* The easing function used when scrolling.
|
346
|
+
*/
|
347
|
+
easeInOutQuart: function( t ) {
|
348
|
+
|
349
|
+
// easeInOutQuart
|
350
|
+
return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t;
|
351
|
+
|
352
|
+
},
|
353
|
+
|
354
|
+
getHighlightedLineBounds: function( block ) {
|
355
|
+
|
356
|
+
var highlightedLines = block.querySelectorAll( '.highlight-line' );
|
357
|
+
if( highlightedLines.length === 0 ) {
|
358
|
+
return { top: 0, bottom: 0 };
|
359
|
+
}
|
360
|
+
else {
|
361
|
+
var firstHighlight = highlightedLines[0];
|
362
|
+
var lastHighlight = highlightedLines[ highlightedLines.length -1 ];
|
363
|
+
|
364
|
+
return {
|
365
|
+
top: firstHighlight.offsetTop,
|
366
|
+
bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
},
|
371
|
+
|
231
372
|
/**
|
232
373
|
* Visually emphasize specific lines within a code block.
|
233
374
|
* This only works on blocks with line numbering turned on.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
float: right
|
3
3
|
}
|
4
4
|
|
5
|
-
/*
|
5
|
+
/* source blocks */
|
6
6
|
.reveal .listingblock.stretch > .content {
|
7
7
|
height: 100%
|
8
8
|
}
|
@@ -16,6 +16,21 @@
|
|
16
16
|
max-height: 100%
|
17
17
|
}
|
18
18
|
|
19
|
+
/* auto-animate feature */
|
20
|
+
/* hide the scrollbar when auto-animating source blocks */
|
21
|
+
.reveal pre[data-auto-animate-target] {
|
22
|
+
overflow: hidden;
|
23
|
+
}
|
24
|
+
|
25
|
+
.reveal pre[data-auto-animate-target] code {
|
26
|
+
overflow: hidden;
|
27
|
+
}
|
28
|
+
|
29
|
+
/* add a min width to avoid horizontal shift on line numbers */
|
30
|
+
code.hljs .hljs-ln-line.hljs-ln-n {
|
31
|
+
min-width: 1.25em;
|
32
|
+
}
|
33
|
+
|
19
34
|
/* tables */
|
20
35
|
table {
|
21
36
|
border-collapse: collapse;
|
@@ -388,3 +403,13 @@ td.hdlist1 {
|
|
388
403
|
font-size: 0.65em;
|
389
404
|
margin-top: 4em;
|
390
405
|
}
|
406
|
+
|
407
|
+
.byline {
|
408
|
+
font-size:.8em
|
409
|
+
}
|
410
|
+
ul.byline {
|
411
|
+
list-style-type: none;
|
412
|
+
}
|
413
|
+
ul.byline li + li {
|
414
|
+
margin-top: 0.25em;
|
415
|
+
}
|
@@ -1,3 +1,14 @@
|
|
1
|
+
- slides_content = self.content
|
2
|
+
- content_for :slides
|
3
|
+
- unless noheader
|
4
|
+
- unless (header_docinfo = docinfo :header, '-revealjs.html').empty?
|
5
|
+
= header_docinfo
|
6
|
+
- if header?
|
7
|
+
include title_slide.html.slim
|
8
|
+
= slides_content
|
9
|
+
- unless (footer_docinfo = docinfo :footer, '-revealjs.html').empty?
|
10
|
+
= footer_docinfo
|
11
|
+
|
1
12
|
doctype 5
|
2
13
|
html lang=(attr :lang, 'en' unless attr? :nolang)
|
3
14
|
head
|
@@ -16,12 +27,21 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
|
|
16
27
|
- [:description, :keywords, :author, :copyright].each do |key|
|
17
28
|
- if attr? key
|
18
29
|
meta name=key content=(attr key)
|
30
|
+
- if attr? 'favicon'
|
31
|
+
- if (icon_href = attr 'favicon').empty?
|
32
|
+
- icon_href = 'favicon.ico'
|
33
|
+
- icon_type = 'image/x-icon'
|
34
|
+
- elsif (icon_ext = File.extname icon_href)
|
35
|
+
- icon_type = icon_ext == '.ico' ? 'image/x-icon' : %(image/#{icon_ext.slice 1, icon_ext.length})
|
36
|
+
- else
|
37
|
+
- icon_type = 'image/x-icon'
|
38
|
+
link rel="icon" type="#{icon_type}" href="#{icon_href}"
|
19
39
|
- linkcss = (attr? 'linkcss')
|
20
|
-
link rel="stylesheet" href="#{revealjsdir}/
|
21
|
-
link rel="stylesheet" href="#{revealjsdir}/
|
40
|
+
link rel="stylesheet" href="#{revealjsdir}/dist/reset.css"
|
41
|
+
link rel="stylesheet" href="#{revealjsdir}/dist/reveal.css"
|
22
42
|
|
23
43
|
/ Default theme required even when using custom theme
|
24
|
-
link rel='stylesheet' href=(attr :revealjs_customtheme, %(#{revealjsdir}/
|
44
|
+
link rel='stylesheet' href=(attr :revealjs_customtheme, %(#{revealjsdir}/dist/theme/#{attr 'revealjs_theme', 'black'}.css)) id='theme'
|
25
45
|
/! This CSS is generated by the Asciidoctor reveal.js converter to further integrate AsciiDoc's existing semantic with reveal.js
|
26
46
|
style type="text/css"
|
27
47
|
include asciidoctor-compatibility.css
|
@@ -37,38 +57,10 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
|
|
37
57
|
link rel='stylesheet' href=%(#{cdn_base}/font-awesome/#{font_awesome_version}/css/v4-shims.min.css)
|
38
58
|
- else
|
39
59
|
link rel='stylesheet' href=(normalize_web_path %(#{attr 'iconfont-name', 'font-awesome'}.css), (attr 'stylesdir', ''), false)
|
40
|
-
|
41
|
-
- eqnums_val = (attr 'eqnums', 'none')
|
42
|
-
- eqnums_val = 'AMS' if eqnums_val == ''
|
43
|
-
- eqnums_opt = %( equationNumbers: { autoNumber: "#{eqnums_val}" } )
|
44
|
-
- mathjaxdir = (attr 'mathjaxdir', "#{cdn_base}/mathjax/2.7.6")
|
45
|
-
script type='text/x-mathjax-config'
|
46
|
-
| MathJax.Hub.Config({
|
47
|
-
tex2jax: {
|
48
|
-
inlineMath: [#{Asciidoctor::INLINE_MATH_DELIMITERS[:latexmath].to_s}],
|
49
|
-
displayMath: [#{Asciidoctor::BLOCK_MATH_DELIMITERS[:latexmath].to_s}],
|
50
|
-
ignoreClass: "nostem|nolatexmath"
|
51
|
-
},
|
52
|
-
asciimath2jax: {
|
53
|
-
delimiters: [#{Asciidoctor::BLOCK_MATH_DELIMITERS[:asciimath].to_s}],
|
54
|
-
ignoreClass: "nostem|noasciimath"
|
55
|
-
},
|
56
|
-
TeX: {#{eqnums_opt}}
|
57
|
-
});
|
58
|
-
script src='#{mathjaxdir}/MathJax.js?config=TeX-MML-AM_HTMLorMML'
|
59
|
-
|
60
|
+
= generate_stem(cdn_base)
|
60
61
|
- syntax_hl = self.syntax_highlighter
|
61
62
|
- if syntax_hl && (syntax_hl.docinfo? :head)
|
62
63
|
=syntax_hl.docinfo :head, self, cdn_base_url: cdn_base, linkcss: linkcss, self_closing_tag_slash: '/'
|
63
|
-
|
64
|
-
/! Printing and PDF exports
|
65
|
-
javascript:
|
66
|
-
var link = document.createElement( 'link' );
|
67
|
-
link.rel = 'stylesheet';
|
68
|
-
link.type = 'text/css';
|
69
|
-
link.href = window.location.search.match( /print-pdf/gi ) ? "#{revealjsdir}/css/print/pdf.css" : "#{revealjsdir}/css/print/paper.css";
|
70
|
-
document.getElementsByTagName( 'head' )[0].appendChild( link );
|
71
|
-
|
72
64
|
- if attr? :customcss
|
73
65
|
link rel='stylesheet' href=((customcss = attr :customcss).empty? ? 'asciidoctor-revealjs.css' : customcss)
|
74
66
|
- unless (_docinfo = docinfo :head, '-revealjs.html').empty?
|
@@ -77,15 +69,8 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
|
|
77
69
|
.reveal
|
78
70
|
/ Any section element inside of this container is displayed as a slide
|
79
71
|
.slides
|
80
|
-
-
|
81
|
-
|
82
|
-
= _docinfo
|
83
|
-
- if header?
|
84
|
-
include title_slide.html.slim
|
85
|
-
= content
|
86
|
-
- unless (_docinfo = docinfo :footer, '-revealjs.html').empty?
|
87
|
-
= _docinfo
|
88
|
-
script src="#{revealjsdir}/js/reveal.js"
|
72
|
+
- yield_content :slides
|
73
|
+
script src="#{revealjsdir}/dist/reveal.js"
|
89
74
|
/ Supports easy AsciiDoc syntax for background color
|
90
75
|
javascript:
|
91
76
|
Array.prototype.slice.call(document.querySelectorAll('.slides section')).forEach(function(slide) {
|
@@ -248,12 +233,11 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
|
|
248
233
|
dependencies: [
|
249
234
|
#{revealjs_dependencies(document, self, revealjsdir)}
|
250
235
|
],
|
251
|
-
|
252
|
-
#{(attr? 'revealjs_plugins_configuration') ? File.read(attr('revealjs_plugins_configuration', '')) : ""}
|
253
|
-
|
254
236
|
});
|
255
237
|
/ Workaround the "Only direct descendants of a slide section can be stretched" limitation in reveal.js
|
256
238
|
/ https://github.com/hakimel/reveal.js/issues/2584
|
239
|
+
|
240
|
+
|
257
241
|
include stretch_nested_elements.js.slim
|
258
242
|
|
259
243
|
- if syntax_hl && (syntax_hl.docinfo? :footer)
|
data/templates/helpers.rb
CHANGED
@@ -4,6 +4,8 @@ unless RUBY_ENGINE == 'opal'
|
|
4
4
|
require 'asciidoctor'
|
5
5
|
end
|
6
6
|
|
7
|
+
require 'json'
|
8
|
+
|
7
9
|
# This module gets mixed in to every node (the context of the template) at the
|
8
10
|
# time the node is being converted. The properties and methods in this module
|
9
11
|
# effectively become direct members of the template.
|
@@ -193,15 +195,9 @@ module Slim::Helpers
|
|
193
195
|
|
194
196
|
def revealjs_dependencies(document, node, revealjsdir)
|
195
197
|
dependencies = []
|
196
|
-
dependencies << "{ src: '#{revealjsdir}/plugin/zoom
|
197
|
-
dependencies << "{ src: '#{revealjsdir}/plugin/notes/notes.js', async: true }" unless (node.attr? 'revealjs_plugin_notes', 'disabled')
|
198
|
-
dependencies << "{ src: '#{revealjsdir}/plugin/
|
199
|
-
dependencies << "{ src: '#{revealjsdir}/plugin/markdown/markdown.js', async: true }" if (node.attr? 'revealjs_plugin_markdown', 'enabled')
|
200
|
-
if (node.attr? 'revealjs_plugins') &&
|
201
|
-
!(revealjs_plugins_file = (node.attr 'revealjs_plugins', '').strip).empty? &&
|
202
|
-
!(revealjs_plugins_content = (File.read revealjs_plugins_file).strip).empty?
|
203
|
-
dependencies << revealjs_plugins_content
|
204
|
-
end
|
198
|
+
dependencies << "{ src: '#{revealjsdir}/plugin/zoom/zoom.js', async: true, callback: function () { Reveal.registerPlugin(RevealZoom) } }" unless (node.attr? 'revealjs_plugin_zoom', 'disabled')
|
199
|
+
dependencies << "{ src: '#{revealjsdir}/plugin/notes/notes.js', async: true, callback: function () { Reveal.registerPlugin(RevealNotes) } }" unless (node.attr? 'revealjs_plugin_notes', 'disabled')
|
200
|
+
dependencies << "{ src: '#{revealjsdir}/plugin/search/search.js', async: true, callback: function () { Reveal.registerPlugin(RevealSearch) } }" if (node.attr? 'revealjs_plugin_search', 'enabled')
|
205
201
|
dependencies.join(",\n ")
|
206
202
|
end
|
207
203
|
|
@@ -279,6 +275,84 @@ module Slim::Helpers
|
|
279
275
|
end
|
280
276
|
nil
|
281
277
|
end
|
278
|
+
|
279
|
+
# Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
|
280
|
+
# @todo remove this code when the new converter becomes available in the main gem
|
281
|
+
def generate_authors node
|
282
|
+
return if node.authors.empty?
|
283
|
+
|
284
|
+
if node.authors.length == 1
|
285
|
+
%(<p class="byline">
|
286
|
+
#{format_author node, node.authors.first}
|
287
|
+
</p>)
|
288
|
+
else
|
289
|
+
result = ['<ul class="byline">']
|
290
|
+
node.authors.each do |author|
|
291
|
+
result << "<li>#{format_author node, author}</li>"
|
292
|
+
end
|
293
|
+
result << '</ul>'
|
294
|
+
result.join Asciidoctor::LF
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
|
299
|
+
# @todo remove this code when the new converter becomes available in the main gem
|
300
|
+
def format_author node, author
|
301
|
+
in_context 'author' do
|
302
|
+
%(<span class="author">#{node.sub_replacements author.name}#{author.email ? %( #{node.sub_macros author.email}) : ''}</span>)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# Copied from asciidoctor/lib/asciidoctor/converter/semantic-html5.rb which is not yet shipped
|
307
|
+
# @todo remove this code when the new converter becomes available in the main gem
|
308
|
+
def in_context name
|
309
|
+
(@convert_context ||= []).push name
|
310
|
+
result = yield
|
311
|
+
@convert_context.pop
|
312
|
+
result
|
313
|
+
end
|
314
|
+
|
315
|
+
STEM_EQNUMS_AMS = 'ams'
|
316
|
+
STEM_EQNUMS_NONE = 'none'
|
317
|
+
STEM_EQNUMS_VALID_VALUES = [
|
318
|
+
STEM_EQNUMS_NONE,
|
319
|
+
STEM_EQNUMS_AMS,
|
320
|
+
'all'
|
321
|
+
]
|
322
|
+
|
323
|
+
MATHJAX_VERSION = '3.2.0'
|
324
|
+
|
325
|
+
# Generate the Mathjax markup to process STEM expressions
|
326
|
+
# @param cdn_base [String]
|
327
|
+
# @return [String]
|
328
|
+
def generate_stem(cdn_base)
|
329
|
+
if attr?(:stem)
|
330
|
+
eqnums_val = attr('eqnums', STEM_EQNUMS_NONE).downcase
|
331
|
+
unless STEM_EQNUMS_VALID_VALUES.include?(eqnums_val)
|
332
|
+
eqnums_val = STEM_EQNUMS_AMS
|
333
|
+
end
|
334
|
+
mathjax_configuration = {
|
335
|
+
tex: {
|
336
|
+
inlineMath: [Asciidoctor::INLINE_MATH_DELIMITERS[:latexmath]],
|
337
|
+
displayMath: [Asciidoctor::BLOCK_MATH_DELIMITERS[:latexmath]],
|
338
|
+
processEscapes: false,
|
339
|
+
tags: eqnums_val,
|
340
|
+
},
|
341
|
+
options: {
|
342
|
+
ignoreHtmlClass: 'nostem|nolatexmath'
|
343
|
+
},
|
344
|
+
asciimath: {
|
345
|
+
delimiters: [Asciidoctor::BLOCK_MATH_DELIMITERS[:asciimath]],
|
346
|
+
},
|
347
|
+
loader: {
|
348
|
+
load: ['input/asciimath', 'output/chtml', 'ui/menu']
|
349
|
+
}
|
350
|
+
}
|
351
|
+
mathjaxdir = attr('mathjaxdir', "#{cdn_base}/mathjax/#{MATHJAX_VERSION}/es5")
|
352
|
+
%(<script>window.MathJax = #{JSON.generate(mathjax_configuration)};</script>) +
|
353
|
+
%(<script async src="#{mathjaxdir}/tex-mml-chtml.js"></script>)
|
354
|
+
end
|
355
|
+
end
|
282
356
|
#--
|
283
357
|
end
|
284
358
|
|