aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md208
1 files changed, 185 insertions, 23 deletions
diff --git a/README.md b/README.md
index 33956e9..d069dd9 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,11 @@
-# reveal.js [![Build Status](https://travis-ci.org/hakimel/reveal.js.svg?branch=master)](https://travis-ci.org/hakimel/reveal.js) <a href="https://slides.com?ref=github"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
+# reveal.js ![tests](https://github.com/hakimel/reveal.js/workflows/tests/badge.svg) <a href="https://slides.com?ref=github"><img src="https://s3.amazonaws.com/static.slid.es/images/slides-github-banner-320x40.png?1" alt="Slides" width="160" height="20"></a>
-A framework for easily creating beautiful presentations using HTML. [Check out the live demo](http://revealjs.com/).
+A framework for easily creating beautiful presentations using HTML. [Check out the live demo](https://revealjs.com/).
-reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [Markdown contents](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). There's also a fully featured visual editor and platform for sharing reveal.js presentations at [slides.com](https://slides.com?ref=github).
+reveal.js comes with a broad range of features including [nested slides](https://github.com/hakimel/reveal.js#markup), [Markdown support](https://github.com/hakimel/reveal.js#markdown), [PDF export](https://github.com/hakimel/reveal.js#pdf-export), [speaker notes](https://github.com/hakimel/reveal.js#speaker-notes) and a [JavaScript API](https://github.com/hakimel/reveal.js#api). There's also a fully featured visual editor and platform for sharing reveal.js presentations at [slides.com](https://slides.com?ref=github).
+
+### Supporting reveal.js
+This project was started and is maintained by [@hakimel](https://github.com/hakimel/) with the help of many [contributions from the community](https://github.com/hakimel/reveal.js/graphs/contributors). The best way to support the project is to [become a paying member of Slides.com](https://slides.com/pricing)—the reveal.js presentation platform that Hakim is building.
## Table of contents
@@ -21,12 +24,14 @@ reveal.js comes with a broad range of features including [nested slides](https:/
- [Presentation Size](#presentation-size)
- [Dependencies](#dependencies)
- [Ready Event](#ready-event)
-- [Auto-sliding](#auto-sliding)
+- [Auto-Slide](#auto-slide)
+- [Auto-Animate](#auto-animate)
- [Keyboard Bindings](#keyboard-bindings)
- [Vertical Slide Navigation](#vertical-slide-navigation)
- [Touch Navigation](#touch-navigation)
- [Lazy Loading](#lazy-loading)
- [API](#api)
+ - [Custom Key Bindings](#custom-key-bindings)
- [Slide Changed Event](#slide-changed-event)
- [Presentation State](#presentation-state)
- [Slide States](#slide-states)
@@ -86,7 +91,7 @@ The core of reveal.js is very easy to install. You'll simply need to download a
Some reveal.js features, like external Markdown and speaker notes, require that presentations run from a local web server. The following instructions will set up such a server as well as all of the development tasks needed to make edits to the reveal.js source code.
-1. Install [Node.js](http://nodejs.org/) (4.0.0 or later)
+1. Install [Node.js](https://nodejs.org/) (9.0.0 or later)
1. Clone the reveal.js repository
```sh
@@ -162,7 +167,7 @@ The presentation markup hierarchy needs to be `.reveal > .slides > section` wher
### Markdown
-It's possible to write your slides using Markdown. To enable Markdown, add the `data-markdown` attribute to your `<section>` elements and wrap the contents in a `<textarea data-template>` like the example below. You'll also need to add the `plugin/markdown/marked.js` and `plugin/markdown/markdown.js` scripts (in that order) to your HTML file.
+It's possible to write your slides using Markdown. To enable Markdown, add the `data-markdown` attribute to your `<section>` elements and wrap the contents in a `<textarea data-template>` like the example below. You'll also need to add the `plugin/markdown/marked.js` and `plugin/markdown/markdown.js` scripts (in that order) to your HTML file. _Note: both these dependencies are already included in the default `index.html`._
This is based on [data-markdown](https://gist.github.com/1343518) from [Paul Irish](https://github.com/paulirish) modified to use [marked](https://github.com/chjj/marked) to support [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown). Sensitive to indentation (avoid mixing tabs and spaces) and line breaks (avoid consecutive breaks).
@@ -324,6 +329,37 @@ Reveal.initialize({
// - false: All iframes with data-src will be loaded only when visible
preloadIframes: null,
+ // Can be used to globally disable auto-animation
+ autoAnimate: true,
+
+ // Optionally provide a custom element matcher that will be
+ // used to dictate which elements we can animate between.
+ autoAnimateMatcher: null,
+
+ // Default settings for our auto-animate transitions, can be
+ // overridden per-slide or per-element via data arguments
+ autoAnimateEasing: 'ease',
+ autoAnimateDuration: 1.0,
+ autoAnimateUnmatched: true,
+
+ // CSS properties that can be auto-animated. Position & scale
+ // is matched separately so there's no need to include styles
+ // like top/right/bottom/left, width/height or margin.
+ autoAnimateStyles: [
+ 'opacity',
+ 'color',
+ 'background-color',
+ 'padding',
+ 'font-size',
+ 'line-height',
+ 'letter-spacing',
+ 'border-width',
+ 'border-color',
+ 'border-radius',
+ 'outline',
+ 'outline-offset'
+ ],
+
// Number of milliseconds between automatically proceeding to the
// next slide, disabled when set to 0, this value can be overwritten
// by using a data-autoslide attribute on your slides
@@ -340,6 +376,19 @@ Reveal.initialize({
// speaker view
defaultTiming: 120,
+ // Specify the total time in seconds that is available to
+ // present. If this is set to a nonzero value, the pacing
+ // timer will work out the time available for each slide,
+ // instead of using the defaultTiming value
+ totalTime: 0,
+
+ // Specify the minimum amount of time you want to allot to
+ // each slide, if using the totalTime calculation method. If
+ // the automated time allocation causes slide pacing to fall
+ // below this threshold, then you will see an alert in the
+ // speaker notes window
+ minimumTimePerSlide: 0,
+
// Enable slide navigation via mouse wheel
mouseWheel: false,
@@ -369,6 +418,11 @@ Reveal.initialize({
// Number of slides away from the current that are visible
viewDistance: 3,
+ // Number of slides away from the current that are visible on mobile
+ // devices. It is advisable to set this to a lower number than
+ // viewDistance in order to save resources.
+ mobileViewDistance: 2,
+
// Parallax background image
parallaxBackgroundImage: '', // e.g. "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'"
@@ -483,7 +537,7 @@ Reveal.addEventListener( 'ready', function( event ) {
Note that we also add a `.ready` class to the `.reveal` element so that you can hook into this with CSS.
-### Auto-sliding
+### Auto-Slide
Presentations can be configured to progress through slides automatically, without any user input. To enable this you will need to tell the framework how many milliseconds it should wait between slides:
@@ -524,6 +578,71 @@ Reveal.configure({
});
```
+### Auto-Animate
+
+reveal.js can automatically animate elements across slides. All you need to do is add `data-auto-animate` to two adjacent slide `<section>` elements and Auto-Animate will animate all matching elements between the two.
+
+Here's a simple example to give you a better idea of how it can be used. The resulting animation will be the word "Magic" sliding 100px downwards.
+```html
+<section data-auto-animate>
+ <h1>Magic</h1>
+</section>
+<section data-auto-animate>
+ <h1 style="position: relative; top: 100px;">Magic</h1>
+</section>
+```
+
+This example uses the `top` property to move the element but internally reveal.js will use a CSS transform to ensure smooth movement. This same approach to animation works with most animatable CSS properties meaning you can transition things like `position`, `font-size`, `line-height`, `color`, `background-color` and `padding`.
+
+#### How Elements are Matched
+When you navigate between two auto-animated slides we'll do our best to automatically find matching elements between the two slides. For text, we consider it a match if both the text contents and node type are identical. For images, videos and iframes we compare the `src` attribute. We also take into account the order in which the element appears in the DOM.
+
+In situations where automatic matching is not feasible you can give the objects that you want to animate between a matching `data-id` attribute. We prioritize matching `data-id` values above our automatic matching.
+
+Here's an example where we've given both blocks a matching ID since automatic matching has no content to go on.
+
+```html
+<section data-auto-animate>
+ <div data-id="box" style="padding: 20px; background: salmon;"></div>
+</section>
+<section data-auto-animate>
+ <div data-id="box" style="padding: 20px; background: blue;"></div>
+</section>
+```
+
+#### Animation Settings
+You can override specific animation settings such as easing and duration either for the whole presentation, per-slide or individually for each animated element. The following configuration attributes can be used to change the settings for a specific slide or element:
+
+| Attribute&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Default | Description
+| :------------------------------- | ---------: | :----------
+| data-auto-animate-easing | ease | A CSS [easing function](https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function).
+| data-auto-animate-unmatched | true | Determines whether elements with no matching auto-animate target should fade in. Set to false to make them appear instantly.
+| data-auto-animate-duration | 1.0 | Animation duration in seconds.
+| data-auto-animate-delay | 0 | Animation delay in seconds (can only be set for specific elements, not at the slide level).
+
+If you'd like to change the defaults for the whole deck, use the following config options:
+```javascript
+Reveal.initialize({
+ autoAnimateEasing: 'ease-out',
+ autoAnimateDuration: 0.8,
+ autoAnimateUnmatched: false
+})
+```
+
+#### API: State Attributes and Events
+We add state attributes to the different elements involved in an auto-animation. These attributes can be tied into if you want to, for example, fine-tune the animation behavior with custom CSS.
+
+Right before an auto-animation starts we add `data-auto-animate="pending"` to the slide `<section>`. At this point the upcoming slide is visible and all of the animated elements have been moved to their starting positions. Next we switch to `data-auto-animate="running"` to indicate when the elements start animating towards their final properties.
+
+Each individual element is decorated with a `data-auto-animate-target` attribute. The value of the attribute is a unique ID for this particular animation OR "unmatched" if this element should animate as unmatched content.
+
+Each time a presentation navigates between two auto-animated slides it dispatches the `autoanimate` event.
+```javascript
+Reveal.addEventListener( 'autoanimate', function( event ) {
+ // event.fromSlide, event.toSlide
+} );
+```
+
### Vertical Slide Navigation
Slides can be nested within other slides to create vertical stacks (see [Markup](#markup)). When presenting, you use the left/right arrows to step through the main (horizontal) slides. When you arrive at a vertical stack you can optionally press the up/down arrows to view the vertical slides or skip past them by pressing the right arrow. Here's an example showing a bird's-eye view of what this looks like in action:
@@ -531,7 +650,7 @@ Slides can be nested within other slides to create vertical stacks (see [Markup]
<img src="https://static.slid.es/support/reveal.js-vertical-slides.gif" width="450">
#### Navigation Mode
-You can finetune the reveal.js navigation behavior by using the `navigationMode` config option. Note that these options are only useful for presnetations that use a mix of horizontal and vertical slides. The following navigation modes are available:
+You can fine tune the reveal.js navigation behavior by using the `navigationMode` config option. Note that these options are only useful for presentations that use a mix of horizontal and vertical slides. The following navigation modes are available:
| Value | Description |
| :--------------------------- | :---------- |
@@ -619,6 +738,8 @@ Reveal.getConfig();
// Fetch the current scale of the presentation
Reveal.getScale();
+Reveal.getComputedSlideSize(); // Returns object with width, height keys, and (scaled) presentationWidth and presentationHeight.
+
// Retrieves the previous and current slide elements
Reveal.getPreviousSlide();
Reveal.getCurrentSlide();
@@ -629,6 +750,15 @@ Reveal.getProgress(); // (0 == first slide, 1 == last slide)
Reveal.getSlides(); // Array of all slides
Reveal.getTotalSlides(); // Total number of slides
+// Returns an array with all horizontal/vertical slides in the deck
+Reveal.getHorizontalSlides();
+Reveal.getVerticalSlides();
+
+// Checks if the presentation contains two or more
+// horizontal/vertical slides
+Reveal.hasHorizontalSlides();
+Reveal.hasVerticalSlides();
+
// Returns the speaker notes for the current slide
Reveal.getSlideNotes();
@@ -640,7 +770,7 @@ Reveal.isPaused();
Reveal.isAutoSliding();
// Returns the top-level DOM element
-getRevealElement(); // <div class="reveal">...</div>
+Reveal.getRevealElement(); // <div class="reveal">...</div>
```
### Custom Key Bindings
@@ -715,6 +845,11 @@ Reveal.addEventListener( 'somestate', function() {
}, false );
```
+### Slide Visibility
+When preparing a presentation it can sometimes be helpful to prepare optional slides that you may or may not have time to show. This is easily done by appending a few slides at the end of the presentation, however this means that the reveal.js progress bar and slide numbering will hint that there are additional slides.
+
+To "hide" those slides from reveal.js' numbering system you can add a `data-visibility` attribute to the slide like so `<section data-visibility="uncounted">`.
+
### Slide Backgrounds
Slides are contained within a limited portion of the screen by default to allow them to fit any display and scale uniformly. You can apply full page backgrounds outside of the slide area by adding a `data-background` attribute to your `<section>` elements. Four different types of backgrounds are supported: color, image, video and iframe.
@@ -778,6 +913,8 @@ Embeds a web page as a slide background that covers 100% of the reveal.js width
</section>
```
+Iframes are lazy-loaded when they become visible. If you'd like to preload iframes ahead of time, you can append a `data-preload` attribute to the slide `<section>`. You can also enable preloading globally for all iframes using the `preloadIframes` configuration option.
+
#### Background Transitions
Backgrounds transition using a fade animation by default. This can be changed to a linear sliding transition by passing `backgroundTransition: 'slide'` to the `Reveal.initialize()` call. Alternatively you can set `data-background-transition` on any section with a background to override that specific transition.
@@ -969,6 +1106,10 @@ function Example() {
<img width="300" alt="line-numbers" src="https://user-images.githubusercontent.com/629429/55332077-eb3c4780-5494-11e9-8854-ba33cd0fa740.png">
+#### Step-by-step Highlights
+
+You can step through multiple code highlights on the same code block. Delimit each of your highlight steps with the `|` character. For example `data-line-numbers="1|2-3|4,6-10"` will produce three steps. It will start by highlighting line 1, next step is lines 2-3, and finally line 4 and 6 through 10.
+
### Slide number
@@ -987,9 +1128,9 @@ Reveal.configure({ slideNumber: true });
Reveal.configure({ slideNumber: 'c/t' });
// You can provide a function to fully customize the number:
-Reveal.configure({ slideNumber: function() {
+Reveal.configure({ slideNumber: function( slide ) {
// Ignore numbering of vertical slides
- return [ Reveal.getIndices().h ];
+ return [ Reveal.getIndices( slide ).h ];
}});
// Control which views the slide number displays on using the "showSlideNumber" value:
@@ -1065,18 +1206,38 @@ The framework has a built-in postMessage API that can be used when communicating
<window>.postMessage( JSON.stringify({ method: 'slide', args: [ 2 ] }), '*' );
```
+#### postMessage Events
+
When reveal.js runs inside of an iframe it can optionally bubble all of its events to the parent. Bubbled events are stringified JSON with three fields: namespace, eventName and state. Here's how you subscribe to them from the parent window:
```javascript
window.addEventListener( 'message', function( event ) {
var data = JSON.parse( event.data );
- if( data.namespace === 'reveal' && data.eventName ==='slidechanged' ) {
+ if( data.namespace === 'reveal' && data.eventName === 'slidechanged' ) {
// Slide changed, see data.state for slide number
}
} );
```
-This cross-window messaging can be toggled on or off using configuration flags.
+#### postMessage Callbacks
+
+When you call any method via the postMessage API, reveal.js will dispatch a message with the return value. This is done so that you can call a getter method and see what the result is. Check out this example:
+
+```javascript
+<revealWindow>.postMessage( JSON.stringify({ method: 'getTotalSlides' }), '*' );
+
+window.addEventListener( 'message', function( event ) {
+ var data = JSON.parse( event.data );
+ // `data.method`` is the method that we invoked
+ if( data.namespace === 'reveal' && data.eventName === 'callback' && data.method === 'getTotalSlides' ) {
+ data.result // = the total number of slides
+ }
+} );
+```
+
+#### Turning postMessage on/off
+
+This cross-window messaging can be toggled on or off using configuration flags. These are the default values.
```javascript
Reveal.initialize({
@@ -1157,6 +1318,7 @@ Each theme is available as a separate stylesheet. To change theme you will need
If you want to add a theme of your own see the instructions here: [/css/theme/README.md](https://github.com/hakimel/reveal.js/blob/master/css/theme/README.md).
+All theme variables are exposed as CSS custom properties in the pseudo-class `:root`. See [the list of exposed variables](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/exposer.scss).
## Speaker Notes
@@ -1208,7 +1370,7 @@ The speaker notes window will also show:
- Current wall-clock time
- (Optionally) a pacing timer which indicates whether the current pace of the presentation is on track for the right timing (shown in green), and if not, whether the presenter should speed up (shown in red) or has the luxury of slowing down (blue).
-The pacing timer can be enabled by configuring by the `defaultTiming` parameter in the `Reveal` configuration block, which specifies the number of seconds per slide. 120 can be a reasonable rule of thumb. Timings can also be given per slide `<section>` by setting the `data-timing` attribute. Both values are in numbers of seconds.
+The pacing timer can be enabled by configuring the `defaultTiming` parameter in the `Reveal` configuration block, which specifies the number of seconds per slide. 120 can be a reasonable rule of thumb. Alternatively, you can enable the timer by setting `totalTime`, which sets the total length of your presentation (also in seconds). If both values are specified, `totalTime` wins and `defaultTiming` is ignored. Regardless of the baseline timing method, timings can also be given per slide `<section>` by setting the `data-timing` attribute (again, in seconds).
## Server Side Speaker Notes
@@ -1228,7 +1390,7 @@ Reveal.initialize({
Then:
-1. Install [Node.js](http://nodejs.org/) (4.0.0 or later)
+1. Install [Node.js](http://nodejs.org/) (9.0.0 or later)
2. Run `npm install`
3. Run `node plugin/notes-server`
@@ -1237,7 +1399,7 @@ Then:
Plugins should register themselves with reveal.js by calling `Reveal.registerPlugin( 'myPluginID', MyPlugin )`. Registered plugin instances can optionally expose an "init" function that reveal.js will call to initialize them.
-When reveal.js is booted up via `Reveal.initialize()`, it will go through all registered plugins and invoke their "init" methods. If the "init" method returns a Promise, reveal.js will wait for that promise to be fullfilled before finshing the startup sequence and firing the [ready](#ready-event) event. Here's an example of a plugin that does some asynchronous work before reveal.js can proceed:
+When reveal.js is booted up via `Reveal.initialize()`, it will go through all registered plugins and invoke their "init" methods. If the "init" method returns a Promise, reveal.js will wait for that promise to be fulfilled before finishing the startup sequence and firing the [ready](#ready-event) event. Here's an example of a plugin that does some asynchronous work before reveal.js can proceed:
```javascript
let MyPlugin = {
@@ -1248,7 +1410,7 @@ Reveal.addEventListener( 'ready', () => console.log( 'Three seconds later...' )
Reveal.initialize();
```
-If the init method does _not_ return a Promise, the plugin is considered ready right away and will not hold up the reveal.js startup sequence.
+Note that reveal.js will *not* wait for init Promise fulfillment if the plugin is loaded as an [async dependency](#dependencies). If the plugin's init method does _not_ return a Promise, the plugin is considered ready right away and will not hold up the reveal.js startup sequence.
### Retrieving Plugins
@@ -1304,7 +1466,7 @@ Reveal.initialize({
#### Client presentation
-Served from a publicly accessible static file server. Examples include: GitHub Pages, Amazon S3, Dreamhost, Akamai, etc. The more reliable, the better. Your audience can then access the client presentation via `http://example.com/path/to/presentation/client/index.html`, with the configuration below causing them to connect to the socket.io server as clients.
+Served from a publicly accessible static file server. Examples include: GitHub Pages, Amazon S3, Dreamhost, Akamai, etc. The more reliable, the better. Your audience can then access the client presentation via `https://example.com/path/to/presentation/client/index.html`, with the configuration below causing them to connect to the socket.io server as clients.
Example configuration:
@@ -1338,7 +1500,7 @@ Server that receives the `slideChanged` events from the master presentation and
Or you can use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/).
-You'll need to generate a unique secret and token pair for your master and client presentations. To do so, visit `http://example.com/token`, where `http://example.com` is the location of your socket.io server. Or if you're going to use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), visit [https://reveal-js-multiplex-ccjbegmaii.now.sh/token](https://reveal-js-multiplex-ccjbegmaii.now.sh/token).
+You'll need to generate a unique secret and token pair for your master and client presentations. To do so, visit `https://example.com/token`, where `https://example.com` is the location of your socket.io server. Or if you're going to use the socket.io server at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), visit [https://reveal-js-multiplex-ccjbegmaii.now.sh/token](https://reveal-js-multiplex-ccjbegmaii.now.sh/token).
You are very welcome to point your presentations at the Socket.io server running at [https://reveal-js-multiplex-ccjbegmaii.now.sh/](https://reveal-js-multiplex-ccjbegmaii.now.sh/), but availability and stability are not guaranteed.
@@ -1401,7 +1563,7 @@ Reveal.initialize({
If you want to display math equations in your presentation you can easily do so by including this plugin. The plugin is a very thin wrapper around the [MathJax](http://www.mathjax.org/) library. To use it you'll need to include it as a reveal.js dependency, [find our more about dependencies here](#dependencies).
-The plugin defaults to using [LaTeX](http://en.wikipedia.org/wiki/LaTeX) but that can be adjusted through the `math` configuration object. Note that MathJax is loaded from a remote server. If you want to use it offline you'll need to download a copy of the library and adjust the `mathjax` configuration value.
+The plugin defaults to using [LaTeX](https://en.wikipedia.org/wiki/LaTeX) but that can be adjusted through the `math` configuration object. Note that MathJax is loaded from a remote server. If you want to use it offline you'll need to download a copy of the library and adjust the `mathjax` configuration value.
Below is an example of how the plugin can be configured. If you don't intend to change these values you do not need to include the `math` config object at all.
@@ -1411,9 +1573,9 @@ Reveal.initialize({
math: {
mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
- config: 'TeX-AMS_HTML-full' // See http://docs.mathjax.org/en/latest/config-files.html
+ config: 'TeX-AMS_HTML-full', // See http://docs.mathjax.org/en/latest/config-files.html
// pass other options into `MathJax.Hub.Config()`
- TeX: { Macros: macros }
+ TeX: { Macros: { RR: "{\\bf R}" } }
},
dependencies: [
@@ -1435,4 +1597,4 @@ If you want to include math inside of a presentation written in Markdown you nee
MIT licensed
-Copyright (C) 2019 Hakim El Hattab, http://hakim.se
+Copyright (C) 2020 Hakim El Hattab, http://hakim.se