add markdown support for code line numbers and line highlights #2371

This commit is contained in:
Hakim El Hattab 2020-04-27 10:43:56 +02:00
parent a040ba3b41
commit 951f5d04c2
4 changed files with 105 additions and 18 deletions

View file

@ -151,7 +151,7 @@
Write content using inline or external Markdown. Write content using inline or external Markdown.
Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown). Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
``` ```[]
<section data-markdown> <section data-markdown>
## Markdown support ## Markdown support

File diff suppressed because one or more lines are too long

View file

@ -13,6 +13,8 @@ const DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__'; const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
const Plugin = () => { const Plugin = () => {
// The reveal.js instance this plugin is attached to // The reveal.js instance this plugin is attached to
@ -408,12 +410,31 @@ const Plugin = () => {
deck = reveal; deck = reveal;
// marked can be configured via reveal.js config options let renderer = new marked.Renderer();
var options = deck.getConfig().markdown;
if( options ) { renderer.code = ( code, language ) => {
marked.setOptions( options );
// Off by default
let lineNumbers = '';
// Users can opt in to show line numbers and highlight
// specific lines.
// ```javascript [] show line numbers
// ```javascript [1,4-8] highlights lines 1 and 4-8
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
lineNumbers = `data-line-numbers="${lineNumbers}"`;
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
} }
return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
};
marked.setOptions( {
renderer,
...deck.getConfig().markdown
} );
return processSlides( deck.getRevealElement() ).then( convertSlides ); return processSlides( deck.getRevealElement() ).then( convertSlides );
}, },

View file

@ -244,11 +244,52 @@
</div> </div>
</div> </div>
<div class="reveal deck6" style="display: block;">
<div class="slides">
<section data-markdown class="defaults">
<script type="text/template">
```
code
```
</script>
</section>
<section data-markdown class="with-language">
<script type="text/template">
```javascript
code
```
</script>
</section>
<section data-markdown class="with-line-numbers">
<script type="text/template">
```[]
code
```
</script>
</section>
<section data-markdown class="with-line-highlights">
<script type="text/template">
```[1,2,3]
code
```
</script>
</section>
<section data-markdown class="with-line-highlights-and-lanugage">
<script type="text/template">
```javascript [1,2,3]
code
```
</script>
</section>
</div>
</div>
<script type="module"> <script type="module">
import Reveal from '../js/reveal.js' import Reveal from '../js/reveal.js'
import markdown from '../plugin/markdown/markdown.js' import Markdown from '../plugin/markdown/markdown.js'
import Highlight from '../plugin/highlight/highlight.js'
let deck1 = new Reveal( document.querySelector( '.deck1' ), { plugins: [ markdown() ] }) let deck1 = new Reveal( document.querySelector( '.deck1' ), { plugins: [ Markdown ] })
deck1.addEventListener( 'ready', function() { deck1.addEventListener( 'ready', function() {
QUnit.module( 'Inline' ); QUnit.module( 'Inline' );
@ -263,7 +304,7 @@
} ); } );
let deck2 = new Reveal( document.querySelector( '.deck2' ), { plugins: [ markdown() ] }) let deck2 = new Reveal( document.querySelector( '.deck2' ), { plugins: [ Markdown ] })
deck2.addEventListener( 'ready', function() { deck2.addEventListener( 'ready', function() {
QUnit.module( 'External' ); QUnit.module( 'External' );
@ -278,7 +319,7 @@
} ); } );
let deck3 = new Reveal( document.querySelector( '.deck3' ), { plugins: [ markdown() ] }) let deck3 = new Reveal( document.querySelector( '.deck3' ), { plugins: [ Markdown ] })
deck3.addEventListener( 'ready', function() { deck3.addEventListener( 'ready', function() {
QUnit.module( 'Slide Attributes' ); QUnit.module( 'Slide Attributes' );
@ -322,7 +363,7 @@
markdown: { markdown: {
smartypants: true smartypants: true
}, },
plugins: [ markdown() ] plugins: [ Markdown ]
}) })
deck4.addEventListener( 'ready', function() { deck4.addEventListener( 'ready', function() {
@ -341,7 +382,7 @@
} ); } );
let deck5 = new Reveal( document.querySelector( '.deck5' ), { plugins: [ markdown() ] }) let deck5 = new Reveal( document.querySelector( '.deck5' ), { plugins: [ Markdown ] })
deck5.addEventListener( 'ready', function() { deck5.addEventListener( 'ready', function() {
QUnit.module( 'Element Attributes' ); QUnit.module( 'Element Attributes' );
@ -385,11 +426,41 @@
} ); } );
let deck6 = new Reveal( document.querySelector( '.deck6' ), {
plugins: [ Markdown, Highlight ]
})
deck6.addEventListener( 'ready', function() {
QUnit.module( 'Code Blocks' );
QUnit.test( 'Defaults to no line numbers', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.defaults .hljs:not([data-line-numbers])' ).length, 1 );
});
QUnit.test( 'Can set language', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-language .hljs.javascript:not([data-line-numbers])' ).length, 1 );
});
QUnit.test( '```[] enables line numbers', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-numbers .hljs[data-line-numbers=""]' ).length, 1 );
});
QUnit.test( '```[1,2,3] enables line highlights', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights .hljs[data-line-numbers="1,2,3"]' ).length, 1 );
});
QUnit.test( '```javascript [1,2,3] enables line highlights and sets language', function( assert ) {
assert.strictEqual( deck6.getRevealElement().querySelectorAll( '.with-line-highlights-and-lanugage .hljs.javascript[data-line-numbers="1,2,3"]' ).length, 1 );
});
} );
deck1.initialize(); deck1.initialize();
deck2.initialize(); deck2.initialize();
deck3.initialize(); deck3.initialize();
deck4.initialize(); deck4.initialize();
deck5.initialize(); deck5.initialize();
deck6.initialize();
</script> </script>
</body> </body>