This document describes the Markdown plugin for reveal.js, which enables authoring presentation slides using Markdown syntax instead of HTML. The plugin integrates the marked.js library to parse Markdown content, provides mechanisms for splitting Markdown into multiple slides using separator patterns, supports loading Markdown from external files, and offers attribute extraction syntax for customizing individual elements and slides.
For information about the HTML slide structure that the Markdown plugin generates, see HTML Structure. For details about speaker notes that can be extracted from Markdown, see Speaker Notes. For slide attributes that can be applied to Markdown-generated slides, see Slide Attributes.
The Markdown plugin follows the standard reveal.js plugin interface defined by the Plugins controller (see Plugin Architecture). It exposes an id of 'markdown' and an init() function that receives the Reveal instance. The plugin is distributed in three formats: unminified source at plugin/markdown/plugin.js1-492 UMD bundle at plugin/markdown/markdown.js1-8 and ES module at plugin/markdown/markdown.esm.js1-8
Sources: plugin/markdown/plugin.js29-492
The Markdown plugin accepts configuration through the markdown property in Reveal's configuration object. Configuration options are accessed via deck.getConfig().markdown and provide defaults for separator patterns and marked.js options.
| Option | Type | Default | Description |
|---|---|---|---|
separator | String | '\r?\n---\r?\n' | Regex pattern for horizontal slide breaks |
verticalSeparator | String | null | Regex pattern for vertical slide breaks |
notesSeparator | String | '^\s*notes?:' | Regex pattern for speaker notes |
renderer | marked.Renderer | Custom renderer | Renderer instance for marked.js |
animateLists | Boolean | false | Wrap list items in .fragment class |
...markedOptions | Object | - | Additional options passed to marked.setOptions() |
The getSlidifyOptions() function at plugin/markdown/plugin.js97-108 normalizes these options, with per-section overrides possible via data attributes.
Sources: plugin/markdown/plugin.js97-108 plugin/markdown/plugin.js429-476
Markdown slides are identified and configured using data attributes on <section> elements:
| Attribute | Purpose | Example |
|---|---|---|
data-markdown | Mark section for Markdown processing or specify external file URL | data-markdown="slides.md" |
data-markdown-parsed | Internal flag preventing double-processing | Set by plugin |
data-separator | Override horizontal slide separator | data-separator="^\n\n\n" |
data-separator-vertical | Override vertical slide separator | data-separator-vertical="^\n\n" |
data-separator-notes | Override notes separator | data-separator-notes="^Note:" |
data-charset | Character encoding for external files | data-charset="utf-8" |
data-element-attributes | Regex pattern for element attributes | See Attribute Extraction |
data-attributes | Regex pattern for slide attributes | See Attribute Extraction |
data-template | Mark template container (alternative to <script>) | Applied to wrapper element |
Sources: plugin/markdown/plugin.js69-91 plugin/markdown/plugin.js214-253
Inline Markdown is written directly in <section data-markdown> elements. The plugin extracts the text content, normalizes leading whitespace, parses it with marked.js, and replaces the section's innerHTML.
The getMarkdownFromSlide() function at plugin/markdown/plugin.js38-61 handles extraction. It searches for a [data-template] attribute or <script> element to support templates, then normalizes leading tabs or spaces using regex replacement. The SCRIPT_END_PLACEHOLDER constant at plugin/markdown/plugin.js15 prevents premature script tag closure.
The convertSlides() function at plugin/markdown/plugin.js381-410 performs this conversion for all sections with data-markdown attributes.
Sources: plugin/markdown/plugin.js38-61 plugin/markdown/plugin.js381-410
When data-markdown contains a URL, the plugin loads the file via XMLHttpRequest. The loaded content is then processed by the slidify() function to generate multiple slides.
The loadExternalMarkdown() function at plugin/markdown/plugin.js261-303 creates an XMLHttpRequest, handles charset via overrideMimeType() if data-charset is specified, and returns a Promise. Status codes 200-299 or 0 (file protocol) resolve successfully.
The processSlides() function at plugin/markdown/plugin.js208-259 collects all external promises and waits for Promise.all() before resolving. Error handling generates an alert section with diagnostic information.
Sources: plugin/markdown/plugin.js208-259 plugin/markdown/plugin.js261-303
The slidify() function at plugin/markdown/plugin.js135-201 splits a single Markdown string into multiple slides based on separator patterns. It supports both horizontal (new top-level slide) and vertical (nested slide) separators.
The function creates a combined regex from both separators: new RegExp(options.separator + (options.verticalSeparator ? '|' + options.verticalSeparator : ''), 'mg') at plugin/markdown/plugin.js139
Default separators:
\r?\n---\r?\n (three dashes on a line)null (disabled by default)The algorithm at plugin/markdown/plugin.js150-178 maintains a sectionStack array that contains either strings (horizontal slides) or arrays (vertical slide groups):
The flattening loop at plugin/markdown/plugin.js183-197 generates HTML:
The createMarkdownSlide() helper at plugin/markdown/plugin.js113-129 wraps content in <script type="text/template"> tags and extracts speaker notes if the notesSeparator pattern matches.
Sources: plugin/markdown/plugin.js135-201 plugin/markdown/plugin.js113-129
Markdown comments can specify attributes for elements and slides using special syntax patterns. The addAttributes() function at plugin/markdown/plugin.js342-375 recursively traverses the DOM looking for comment nodes.
Pattern: .element: attribute="value" or .element: data-attribute
The default pattern is \.element\s*?(.+?)$ at plugin/markdown/plugin.js12 The function addAttributeInElement() at plugin/markdown/plugin.js314-336 uses regex ([^"= ]+?)="([^"]+?)"|(data-[^"= ]+?)(?=[" ]) to parse attribute pairs from the captured group.
Pattern: .slide: attribute="value"
The default pattern is \.slide:\s*?(\S.+?)$ at plugin/markdown/plugin.js13 This applies attributes to the containing <section> element.
The addAttributes() function at plugin/markdown/plugin.js342-375 implements a recursive tree traversal:
<section>, update parent section contextSources: plugin/markdown/plugin.js314-336 plugin/markdown/plugin.js342-375
The plugin provides a custom marked.js renderer that extends marked.Renderer with specialized handling for code blocks and optionally list items.
The custom renderer.code() function at plugin/markdown/plugin.js434-466 parses a special line number syntax from the language identifier:
Syntax: [offset: ranges] where:
offset (optional): Starting line numberranges: Comma-separated line numbers or ranges (e.g., 1,4-8)Examples:
The regex pattern `CODE_LINE_NUMBER_REGEX` at <FileRef file-url="https://github.com/hakimel/reveal.js/blob/0753c057/plugin/markdown/plugin.js#L19-L19" min=19 file-path="plugin/markdown/plugin.js">Hii</FileRef> is `/\[\s*((\d*):)?\s*([\s\d,|-]*)\]/`. The renderer extracts these values and generates data attributes:
- `data-line-numbers`: Line ranges to highlight
- `data-ln-start-from`: Starting line number offset
HTML escaping is performed via `escapeForHTML()` at <FileRef file-url="https://github.com/hakimel/reveal.js/blob/0753c057/plugin/markdown/plugin.js#L412-L416" min=412 max=416 file-path="plugin/markdown/plugin.js">Hii</FileRef> to prevent the HTML parser from altering code before syntax highlighting.
**Output:**
```html
<pre><code data-line-numbers="1,4-8" data-ln-start-from="25" class="javascript">
escaped code content
</code></pre>
When animateLists: true is configured, the renderer wraps each list item in a fragment:
This causes list items to appear one at a time during presentation (see Fragments).
Sources: plugin/markdown/plugin.js434-471 plugin/markdown/plugin.js19
The plugin's init() function at plugin/markdown/plugin.js425-480 orchestrates the complete initialization sequence:
The function returns a Promise chain: processSlides(deck.getRevealElement()).then(convertSlides) at plugin/markdown/plugin.js478 This ensures external files are loaded before inline markdown is converted.
Sources: plugin/markdown/plugin.js425-480
The complete Markdown processing pipeline involves two main phases: external file handling and inline conversion.
Sources: plugin/markdown/plugin.js208-259 plugin/markdown/plugin.js381-410
The plugin uses marked.js (version embedded in minified builds) for Markdown parsing. The library follows a lexer → parser → renderer pipeline. The plugin customizes the renderer but uses default lexer and parser behavior.
Marked.js API Usage:
marked(markdown) - Parse markdown string to HTML (used at plugin/markdown/plugin.js392)marked.Renderer - Base renderer class (instantiated at plugin/markdown/plugin.js432)marked.setOptions({ renderer, ...options }) - Configure marked (called at plugin/markdown/plugin.js473-476)The plugin forwards all additional configuration options (after extracting renderer and animateLists) directly to marked.setOptions() using spread syntax: ...markedOptions at plugin/markdown/plugin.js429
Sources: plugin/markdown/plugin.js429-476 plugin/markdown/plugin.js7
The plugin exposes the following methods in addition to the standard id and init():
| Method | Parameters | Returns | Description |
|---|---|---|---|
processSlides | scope (Element) | Promise | Load external markdown and run slidify |
convertSlides | None | Promise | Convert inline data-markdown sections |
slidify | markdown (String), options (Object) | String | Split markdown into section HTML |
marked | Varies | Varies | Reference to marked.js library |
These are exported at plugin/markdown/plugin.js483-486 for potential external usage, though the comment at line 482 questions whether they belong in the public API.
Sources: plugin/markdown/plugin.js418-489
Refresh this wiki