MarkdownItPlugins
(This package might best be regarded as deprecated given the changes in Meteor 1.3.)
A bunch of plugins for markdown-it wrapped for Meteor.
Table of Contents
- Install
- Usage
- The Plugins
- markdown-it-abbr
- markdown-it-anchor
- markdown-it-attrs
- markdown-it-center-text
- markdown-it-checkbox
- markdown-it-container
- markdown-it-emoji
- markdown-it-expand-tabs
- markdown-it-footnote
- markdown-it-implicit-figures
- markdown-it-imsize-no-autofill
- markdown-it-ins-del
- markdown-it-mark
- markdown-it-modify-token
- markdown-it-modify-token-modified
- markdown-it-regexp
- markdown-it-sanitizer
- markdown-it-smartarrows
- markdown-it-sub
- markdown-it-sup
- markdown-it-table-of-contents
- markdown-it-video
- mdvariables
- mdvariables-enhanced
- My Big Usage Example
Install
This is available as convexset:markdown-it-plugins on Atmosphere. (Install with meteor add convexset:markdown-it-plugins.)
If you get an error message like:
WARNING: npm peer requirements not installed: - package-utils@^0.2.1 not installed. Read more about installing npm peer dependencies: http://guide.meteor.com/using-packages.html#peer-npm-dependencies
It is because, by design, the package does not include instances of these from npm to avoid repetition. (In this case, meteor npm install --save package-utils will deal with the problem.)
See this or this for more information.
Now, if you see a message like
WARNING: npm peer requirements not installed: underscore@1.5.2 installed, underscore@^1.8.3 needed
it is because you or something you are using is using Meteor's cruddy old underscore package. Install a new version from npm. (And, of course, you may use the npm version in a given scope via require("underscore").)
Usage
Suppose one already has markdown-it installed, e.g. via smoiz:markdown-it. First, instantiate a renderer...
1var markdownRenderer = markdownit({ 2 // Enable HTML tags in source 3 html: true, 4 // Use '/' to close single tags (<br />). 5 xhtmlOut: true, 6 7 // This is only for full CommonMark compatibility. 8 // Convert '\n' in paragraphs into <br> 9 breaks: true, 10 // CSS language prefix for fenced blocks. Can be useful for external highlighters. 11 langPrefix: '', 12 // Autoconvert URL-like text to links 13 linkify: true, 14 15 // Enable some language-neutral replacement + quotes beautification 16 typographer: true, 17 18 // Double + single quotes replacement pairs, when typographer enabled, 19 // and smartquotes on. Could be either a String or an Array. 20 // 21 // For example, you can use '«»„“' for Russian, '„“‚‘' for German, 22 // and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). 23 quotes: '“”‘’', 24});
Then to load plugins, do the following:
1var markdownItSubPlugin = MarkdownItPlugins.getPlugin('markdown-it-sub'); 2var markdownItSupPlugin = MarkdownItPlugins.getPlugin('markdown-it-sup'); 3 4markdownRenderer 5 .use(markdownItSubPlugin) 6 .use(markdownItSupPlugin); 7 8// or add them one by one
Some plugins admit options and may be loaded as outlined in the documentation of markdown-it:
1markdownRenderer 2 .use(somePlugin1) 3 .use(somePlugin2, opts);
Default options can be loaded as follows:
1var opts = MarkdownItPlugins.getDefaultOptions('pluginName'); 2var plugin = MarkdownItPlugins.getPlugin('pluginName'); 3 4markdownRenderer 5 .use(plugin, opts)
Here's an alternative way to load both:
1var thing = MarkdownItPlugins.get('pluginName'); 2var opts = thing.defaultOptions; 3var plugin = thing.plugin; 4 5markdownRenderer 6 .use(plugin, opts)
The Plugins
markdown-it-abbr
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItAbbrPlugin = MarkdownItPlugins.getPlugin('markdown-it-abbr'); 2markdownRenderer.use(markdownItAbbrPlugin);
The following
*[HTML]: Hyper Text Markup Language *[W3C]: World Wide Web Consortium The HTML specification is maintained by the W3C.
generates
1<p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification 2is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p>
markdown-it-anchor
Header anchors for [markdown-it].
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItAnchorPlugin = MarkdownItPlugins.getPlugin('markdown-it-abbr'); 2var markdownItAnchorOptions = MarkdownItPlugins.getDefaultOptions('markdown-it-abbr'); 3markdownRenderer.use(markdownItAnchorPlugin, markdownItAnchorOptions); 4 5// or... 6// markdownRenderer.use(markdownItAnchorPlugin, opts);
The opts object can contain:
| Name | Description | Default |
|---|---|---|
level | Minimum level to apply anchors on. | 1 |
slugify | A custom slugification function. | string.js' slugify |
permalink | Whether to add permalinks next to titles. | false |
renderPermalink | A custom permalink rendering function. | See index.es6.js |
permalinkClass | The class of the permalink anchor. | header-anchor |
permalinkSymbol | The symbol in the permalink anchor. | ¶ |
permalinkBefore | Place the permalink before the title. | false |
callback | Called with token and info after rendering. | undefined |
The renderPermalink function takes the slug, an options object with
the above options, and then all the usual markdown-it rendering
arguments.
All headers above level will then have an id attribute with a slug
of their content, and if permalink is true, a ¶ symbol linking to
the header itself.
You may want to use the link symbol as
permalinkSymbol, or a symbol from your favorite web font.
The callback option is a function that will be called at the end of
rendering with the token and an info object. The info object has
title and slug properties with the token content and the slug used
for the identifier.
markdown-it-attrs
Add classes, identifiers and attributes to your markdown with {.class #identifier attr=value attr2="spaced value"} curly brackets, similar to pandoc's header attributes.
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItAttrsPlugin = MarkdownItPlugins.getPlugin('markdown-it-attrs'); 2markdownRenderer.use(markdownItAbbrPlugin);
Example input:
paragraph {data-toggle=modal}
Output:
1<p data-toggle="modal">paragraph</p>
Works with inline elements too:
paragraph *style me*{.red} more text
Output:
1<p>paragraph <em class="red">style me</em> more text</p>
Note: Plugin does not validate any input, so you should validate the attributes in your html output if security is a concern.
** Ambiguity**
When class can be applied to both inline or block element, inline element will take precedence:
- list item **bold**{.red}
Output:
1<ul> 2<li>list item <strong class="red">bold</strong></li> 3<ul>
If you need the class to apply to the list item instead:
- list item **bold** {.red}
Output:
1<ul> 2<li class="red">list item <strong>bold</strong> 3</li> 4</ul>
If you need finer control, look into decorate.
markdown-it-center-text
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItCenterTextPlugin = MarkdownItPlugins.getPlugin('markdown-it-center-text'); 2markdownRenderer 3 .use(markdownItCenterTextPlugin); 4 5markdownRenderer.render('->Centered Text<-') // => 6// <div style="text-align: center;">Centered Text</div>
markdown-it-checkbox
This plugin allows to create checkboxes for tasklists as discussed here.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItCheckboxPlugin = MarkdownItPlugins.getPlugin('markdown-it-checkbox'); 2markdownRenderer 3 .use(markdownItCheckboxPlugin); 4 5markdownRenderer.render('[ ] unchecked') // => 6// <p> 7// <input type="checkbox" id="checkbox0"> 8// <label for="checkbox0">unchecked</label> 9// </p> 10 11markdownRenderer.render('[x] checked') // => 12// <p> 13// <input type="checkbox" id="checkbox0" checked="true"> 14// <label for="checkbox0">checked</label> 15// </p>
A number of options may be passed in:
divWrap: wrap div arround checkbox. this makes it possible to use it for example with Awesome Bootstrap Checkbox- Type:
Boolean - Default:
false
- Type:
divClass: classname of div wrapper. will only be used ifdivWrapis enanbled.- Type:
String - Default:
"checkbox"
- Type:
idPrefix: the id of the checkboxs input contains the prefix and an incremental number starting with0. i.e.checkbox1for the 2nd checkbox.- Type:
String - Default:
"checkbox"
- Type:
1var markdownItCheckboxPlugin = MarkdownItPlugins.getPlugin('markdown-it-checkbox'); 2markdownRenderer 3 .use(markdownItCheckboxPlugin, { 4 divWrap: true, 5 divClass: 'cb', 6 idPrefix: 'cbx_' 7 }); 8 9markdownRenderer.render('[ ] unchecked') // => 10// <p> 11// <div classname="cb"> 12// <input type="checkbox" id="cbx_0"> 13// <label for="cbx_0">unchecked</label> 14// </div> 15// </p>
markdown-it-container
With this plugin you can create block containers like:
::: warning *here be dragons* :::
.... and specify how they should be rendered. If no renderer defined, <div> with
container name class will be created:
1<div class="warning"> 2<em>here be dragons</em> 3</div>
Markup is the same as for fenced code blocks. Difference is, that marker use another character and content is rendered as markdown markup.
- Original Source: npm
- Defaults: No
- Is Modified Package: No
1var markdownItContainerPlugin = MarkdownItPlugins.getPlugin('markdown-it-container'); 2markdownRenderer 3 .use(markdownItContainerPlugin, name, [, options]);
Params:
- name - container name (mandatory)
- options:
- validate - optional, function to validate tail after opening marker, should
return
trueon success. - render - optional, renderer function for opening/closing tokens.
- marker - optional (
:), character to use in delimiter.
- validate - optional, function to validate tail after opening marker, should
return
Example:
1var markdownItContainerPlugin = MarkdownItPlugins.getPlugin('markdown-it-container'); 2 3markdownRenderer.use(markdownItContainerPlugin, 'spoiler', { 4 5 validate: function(params) { 6 return params.trim().match(/^spoiler\s+(.*)$/); 7 }, 8 9 render: function (tokens, idx) { 10 var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/); 11 12 if (tokens[idx].nesting === 1) { 13 // opening tag 14 return '<details><summary>' + m[1] + '</summary>\n'; 15 16 } else { 17 // closing tag 18 return '</details>\n'; 19 } 20 } 21}); 22 23console.log(md.render('::: spoiler click me\n*content*\n:::\n')); 24 25// Output: 26// 27// <details><summary>click me</summary> 28// <p><em>content</em></p> 29// </details>
markdown-it-emoji
Two versions:
- Full (default), with all github supported emojies.
- Light, with only well supported unicode emojies and reduced size.
Also supports emoticons shortcuts like :), :-(, and other. See full list in link above.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItEmojiPlugin = MarkdownItPlugins.getPlugin('markdown-it-emoji'); 2markdownRenderer 3 .use(markdownItEmojiPlugin); 4 5// or... 6// markdownRenderer 7// .use(markdownItEmojiPlugin, options); 8 9markdownRenderer.render('H~2~0') // => '<p>H<sub>2</sub>O</p>'
Options:
- defs (Object) - rewrite available emojies definitions
- example:
{ name1: char1, name2: char2, ... }
- example:
- enabled (Array) - disable all emojies except whitelisted
- shortcuts (Object) - rewrite default shortcuts
- example:
{ "smile": [ ":)", ":-)" ], "laughing": ":D" }
- example:
By default, emojies are rendered as appropriate unicode chars. But you can change renderer function as you wish.
Render as span blocks (for example, to use custom iconic font):
1// ... 2// initialize 3 4markdownRenderer.renderer.rules.emoji = function(token, idx) { 5 return '<span class="emoji emoji_' + token[idx].markup + '"></span>'; 6};
Or use twemoji:
1// ... 2// initialize 3 4var twemoji = require('twemoji') 5 6markdownRenderer.renderer.rules.emoji = function(token, idx) { 7 return twemoji.parse(token[idx].content); 8};
NB 1. Read twemoji docs! May be you need more options to change image size & type.
NB 2. For twemoji you can like to fit image height to line height with this style:
1.emoji { 2 height: 1.2em; 3}
markdown-it-expand-tabs
What it does
- Replaces leading tabs with spaces in fenced code blocks
- Nothing else
Why is this useful?
Say you have tab-indented code in a markdown file and you want the rendered code to take up less visual space horizontally. This plugin will help. If you're not in that situation, then this plugin probably isn't for you.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItExpandTabsPlugin = MarkdownItPlugins.getPlugin('markdown-it-expand-tabs'); 2markdownRenderer 3 .use(markdownItExpandTabsPlugin); 4 5markdownRenderer.render('\tsomething\n\t\tsmtg') // => ' something\n smtg'
The default behavior is to convert leading tabs into two spaces each. You can choose an alternate tab width thusly:
1markdownRenderer 2 .use(markdownItExpandTabsPlugin, {tabWidth: 4});
markdown-it-footnote
Footnotes plugin for markdown-it markdown parser.
- Original Source: npm
- Defaults: No
- Is Modified Package: No
1var markdownItFootnotePlugin = MarkdownItPlugins.getPlugin('markdown-it-footnote'); 2markdownRenderer 3 .use(markdownItFootnotePlugin);
Normal footnote:
Here is a footnote reference,[^1] and another.[^longnote] [^1]: Here is the footnote. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous footnote.
html:
1<p>Here is a footnote reference,<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and another.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p> 2<p>This paragraph won’t be part of the note, because it 3isn’t indented.</p> 4<hr class="footnotes-sep"> 5<section class="footnotes"> 6<ol class="footnotes-list"> 7<li id="fn1" class="footnote-item"><p>Here is the footnote. <a href="#fnref1" class="footnote-backref">↩</a></p> 8</li> 9<li id="fn2" class="footnote-item"><p>Here’s one with multiple blocks.</p> 10<p>Subsequent paragraphs are indented to show that they 11belong to the previous footnote. <a href="#fnref2" class="footnote-backref">↩</a></p> 12</li> 13</ol> 14</section>
Inline footnote:
Here is an inline note.^[Inlines notes are easier to write, since you don't have to pick an identifier and move down to type the note.]
html:
1<p>Here is an inline note.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p> 2<hr class="footnotes-sep"> 3<section class="footnotes"> 4<ol class="footnotes-list"> 5<li id="fn1" class="footnote-item"><p>Inlines notes are easier to write, since 6you don’t have to pick an identifier and move down to type the 7note. <a href="#fnref1" class="footnote-backref">↩</a></p> 8</li> 9</ol> 10</section>
markdown-it-implicit-figures
Render images occurring by itself in a paragraph as <figure><img ...></figure>, similar to pandoc's implicit figures.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItImplicitFiguresPlugin = MarkdownItPlugins.getPlugin('markdown-it-implicit-figures'); 2markdownRenderer 3 .use(markdownItImplicitFiguresPlugin, { 4 dataType: false, // declares data-type like <figure data-type="image">, default: false 5 figcaption: false // adds <figcaption>alternative text</figcaption>, default: false 6 });
Example input:
text with   another paragraph
Output:
1<p>text with <img src="img.png" alt=""></p> 2<figure><img src="fig.png" alt=""></figure> 3<p>another paragraph</p>
Options:
-
dataType: SetdataTypetotrueto declare the data-type being wrapped, e.g.:<figure data-type="image">. This can be useful for applying special styling for different kind of figures. -
figcaption: Setfigcaptiontotrueto put the alternative text in a<figcaption>-block after the image. E.g.:renders to1<figure> 2 <img src="img.png" alt="text"> 3 <figcaption>text</figcaption> 4</figure>
markdown-it-imsize-no-autofill
Modified to remove the autofill option which requires fs and other things.
- Original Source: npm
- Defaults: None
- Is Modified Package: Yes
1var markdownImsizeMinusPlugin = MarkdownItPlugins.getPlugin('markdown-it-imsize-no-autofill'); 2markdownRenderer 3 .use(markdownImsizeMinusPlugin); 4 5markdownRenderer.render('') 6// => '<p><img src="image.png" alt="test" width="100" height="200"></p>'
markdown-it-ins-del
<ins> and <s> tag plugin for markdown-it markdown parser with editor attributions.
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItInsDelPlugin = MarkdownItPlugins.getPlugin('markdown-it-ins-del'); 2markdownRenderer 3 .use(markdownItInsDelPlugin) 4 .disable('strikethrough'); 5 6markdownRenderer.render('++insert++[WZ]') // => '<p><ins>insert</ins><sup>WZ</sup></p>' 7markdownRenderer.render('~~delete~~[WZ]') // => '<p><s>delete</s><sup>WZ</sup></p>'
markdown-it-mark
<mark> tag plugin for markdown-it markdown parser.
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItMarkPlugin = MarkdownItPlugins.getPlugin('markdown-it-mark'); 2markdownRenderer 3 .use(markdownItMarkPlugin); 4 5markdownRenderer.render('==marked==') // => '<p><mark>marked</mark></p>'
markdown-it-modify-token
Note: May not work perfectly for MarkdownIt 5.0. (A polyfill of the Token prototype was necessary.)
markdown-it plugin for modifying tokens including content or element attributes in the markdown document. For example it can modify image or link attributes.
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownRenderer = markdownit({ 2 /* 3 * other options 4 */ 5 6 // modify token parameters 7 modifyToken: function (token, env) { 8 switch (token.type) { 9 case 'image': 10 token.attrObj['width'] = '640px'; 11 break; 12 } 13 } 14}); 15var markdownItModifyTokenPlugin = MarkdownItPlugins.getPlugin('markdown-it-modify-token'); 16markdownRenderer 17 .use(markdownItModifyTokenPlugin);
markdown-it-modify-token-modified
Note: May not work perfectly for MarkdownIt 5.0. (A polyfill of the Token prototype was necessary.)
markdown-it plugin for modifying tokens including content or element attributes in the markdown document. For example it can modify image or link attributes. Modified to move options off from renderer creation.
- Original Source: See markdown-it-modify-token
- Defaults: None
- Is Modified Package: Yes
1var markdownItModifyTokenModPlugin = MarkdownItPlugins.getPlugin('markdown-it-modify-token-modified'); 2markdownRenderer 3 .use(markdownItModifyTokenModPlugin, function (token, env) { 4 switch (token.type) { 5 case 'image': 6 token.attrObj['width'] = '640px'; 7 break; 8 } 9 });
markdown-it-regexp
- Original Source: npm
- Defaults: None
- Is Modified Package: No.
1var MarkdownItRegExp = MarkdownItPlugins.getPlugin('markdown-it-regexp-enhanced'); 2markdownRenderer.use(MarkdownItRegExp(/@(\w+)/, 3 function(match, utils) { 4 var url = 'http://example.org/u/' + match[1]; 5 return '<a href="' + utils.escape(url) + '">' + utils.escape(match[1]) + '</a>'; 6 } 7));
Note that utils here only contains the escape method.
markdown-it-sanitizer
sanitizer plugin for markdown-it markdown parser.
** Accepted tags
All tags are parsed case insensitive.
** Balanced **
<b>, <blockquote>, <code>, <em>, <h1>, ..., <h6>, <li>, <ol>, <ol start="42">, <p>, <pre>, <sub>, <sup>, <strong>, <strike>, <ul>
** Standalone **
<br>, <hr>
Links
<a href="http://example.com" title="link">text</a>
The title attribute is optional.
Images
<img src="http://example.com" alt="cat" title="image">
The alt and title attributes are optional.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItSanitizerPlugin = MarkdownItPlugins.getPlugin('markdown-it-sanitizer'); 2markdownRenderer 3 .use(markdownItSanitizerPlugin); 4 5markdownRenderer.render('<b>test<p></b>'); // => '<p><b>test</b></p>'
Advanced
For not whitelisted tags and tags that don't have a matching opening/closing tag you can define whether you would like to remove or escape them. You can also define a class attribute that will be added to image tags. Here is an example with default values:
1var markdownItSanitizerPlugin = MarkdownItPlugins.getPlugin('markdown-it-sanitizer'); 2markdownRenderer 3 .use(markdownItSanitizerPlugin, { 4 imageClass: '', // default: '' 5 removeUnbalanced: false, // default: false 6 removeUnknown: false // default: false 7 }); 8 9// unknown tag 10markdownRenderer.render('<u>test</u>'); // => '<p><u>test</u></p>' 11// unknown tag with removeUnknown: true 12markdownRenderer.render('<u>test</u>'); // => '<p>test</p>' 13 14// unbalanced tags 15markdownRenderer.render('<b>test</em>'); // => '<p><b>test</em></p>' 16// unbalanced tags with removeUnbalanced: true 17markdownRenderer.render('<b>test</em>'); // => '<p>test</p>' 18 19// imageClass: 'img-responsive' 20markdownRenderer.render('<img src="http://example.com/image.png" alt="image" title="example">'); // => '<p><img src="http://example.com/image.png" alt="image" title="example" class="img-responsive"></p>'
markdown-it-smartarrows
This is a markdown-it plugin that adds "smart arrows" to markdown-it's typographic enhancements.
--> → <-- ← <--> ↔ ==> ⇒ <== ⇐ <==> ⇔
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItSmartArrowsPlugin = MarkdownItPlugins.getPlugin('markdown-it-smartarrows'); 2markdownRenderer 3 .use(markdownItSmartArrowsPlugin);
Note that using this plugin will interfere with using HTML comments in your Markdown.
markdown-it-sub
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItSubPlugin = MarkdownItPlugins.getPlugin('markdown-it-sub'); 2markdownRenderer 3 .use(markdownItSubPlugin); 4 5markdownRenderer.render('H~2~0') // => '<p>H<sub>2</sub>O</p>'
markdown-it-sup
- Original Source: npm
- Defaults: None
- Is Modified Package: No
1var markdownItSupPlugin = MarkdownItPlugins.getPlugin('markdown-it-sup'); 2markdownRenderer 3 .use(markdownItSupPlugin); 4 5markdownRenderer.render('29^th^') // => '<p>29<sup>th</sup></p>'
markdown-it-table-of-contents
A table of contents plugin for Markdown-it. Based on https://github.com/samchrisinger/markdown-it-toc but simpler, a bit more customizable and with a default slugifier that matches that of https://www.npmjs.com/package/markdown-it-anchor.
- Original Source: npm
- Defaults: Yes
- Is Modified Package: No
1var markdownItTableOfContentsPlugin = MarkdownItPlugins.getPlugin('markdown-it-table-of-contents'); 2var markdownItAnchorPlugin = MarkdownItPlugins.getPlugin('markdown-it-abbr'); 3markdownRenderer 4 .use(markdownItAnchorPlugin, markdownItAnchorOptions) // for links 5 .use(markdownItTableOfContentsPlugin);
Then add [[toc]] where you want the table of contents to be added in your markdown.
For example, this markdown:
# Heading [[toc]] ## Sub heading 1 Some nice text ## Sub heading 2 Some even nicer text
... would render this HTML using the default options specified in "usage" above:
1<h1 id="heading">Heading</h1> 2 3<div class="table-of-contents"> 4 <ul> 5 <li><a href="#heading">Heading</a> 6 <ul> 7 <li><a href="#sub-heading-1">Sub heading 1</a></li> 8 <li><a href="#sub-heading-2">Sub heading 2</a></li> 9 </ul> 10 </li> 11 </ul> 12</div> 13 14<h2 id="sub-heading-1">Sub heading 1</h2> 15<p>Some nice text</p> 16 17<h2 id="sub-heading-2">Sub heading 2</h2> 18<p>Some even nicer text</p>
** Options **
You may specify options when useing the plugin. like so:
1markdownRenderer 2 .use(markdownItTableOfContentsPlugin, options);
These options are available:
| Name | Description | Default |
|---|---|---|
| "includeLevel" | Headings levels to use (2 for h2:s etc) | [1, 2] |
| "containerClass" | The class for the container DIV | "table-of-contents" |
| "slugify" | A custom slugification function | string.js' slugify |
markdown-it-video
markdown-it plugin for embedding hosted videos.
- Original Source: npm
- Defaults: No
- Is Modified Package: No
1var markdownItVideoPlugin = MarkdownItPlugins.getPlugin('markdown-it-video'); 2markdownRenderer 3 .use(markdownItVideoPlugin);
@[youtube](dQw4w9WgXcQ)
is interpreted as
1<p><div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" id="ytplayer" type="text/html" width="640" height="390" 2 src="http://www.youtube.com/embed/dQw4w9WgXcQ" 3 frameborder="0"/></div></p>
Alternately, you could use a number of different YouTube URL formats rather than just the video id.
@[youtube](http://www.youtube.com/embed/dQw4w9WgXcQ) @[youtube](https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=feedrec_centerforopenscience_index) @[youtube](http://www.youtube.com/user/IngridMichaelsonVEVO#p/a/u/1/QdK8U-VIH_o) @[youtube](http://www.youtube.com/v/dQw4w9WgXcQ?fs=1&hl=en_US&rel=0) @[youtube](http://www.youtube.com/watch?v=dQw4w9WgXcQ#t=0m10s) @[youtube](http://www.youtube.com/embed/dQw4w9WgXcQ?rel=0) @[youtube](http://www.youtube.com/watch?v=dQw4w9WgXcQ) @[youtube](http://youtu.be/dQw4w9WgXcQ)
Currently supported services
- YouTube
- Vimeo
mdvariables
- Original Source: npm
- Defaults: None
- Is Modified Package: No. Modified version at mdvariables-enhanced
1var MdVariables = MarkdownItPlugins.getPlugin('mdvariables'); 2markdownRenderer.use(MdVariables(function() { 3 return { 4 title: $('title').val() 5 }; 6}); 7 8//In your mark up add "@title" to replicate what is in your title input.
mdvariables-enhanced
- Original Source: See mdvariables
- Defaults: None
- Is Modified Package: Yes
1var MdVariablesEnhanced = MarkdownItPlugins.getPlugin('mdvariables-enhanced');
which takes a few arguments in the following order:
dataFunction: a function that takes an argument (a key) and returns the replacement textregex: a regular expression with one or more match blocks (see example below)matchMapper: a maps the outcome ofs.match(regex)forsto a key (arguments for ); defaults tomatch => match[1]
1markdownRenderer.use( 2 MdVariablesEnhanced( 3 function mdVariablesDataDirectory(name) { 4 switch(name) { 5 case 'title': 6 return $('title').text(); 7 break; 8 case "random-number": 9 return Math.random(); 10 break; 11 default: 12 } 13 }, 14 /\[\[\[([a-zA-Z\-_0-9]+)\]\]\]/, // defaults to /@(\w+)/ if nothing is 15 // passed in 16 match => match[1], // which the argument defaults to if 17 // nothing is passed in 18 ) 19); 20 21// In your mark up add "[[[title]]]" to replicate what is in your title input. 22// In your mark up add "[[[random-number]]]" to generate a random number 23 24markdownRenderer.use( 25 MdVariablesEnhanced( 26 function(name) { 27 var split = name.split('|').map(x => x.trim()); 28 var tag = split[0]; 29 var thing = split[1]; 30 return "<" + tag + ">" + thing + "</" + tag + ">"; 31 }, 32 /\[\[\[([a-zA-Z\-_0-9]+)\|([a-zA-Z\-_0-9\s]+)\]\]\]/, 33 match => match[1].toLowerCase() + "|" + match[2] 34 ) 35); 36 37// "[[[strong|something something]]]" => "<strong>something something</strong>"
My Big Usage Example
This is how one might use all of these together. Here, I already have markdown-it installed thorugh smoiz:markdown-it.
1// 2// Some stuff for accessing the next three items globally... 3// 4 5var markdownRendererCommonmark; 6var markdownRendererPlain; 7var markdownRenderer; 8 9if (Meteor.isClient) { 10 Template.registerHelper('markdownIt', function markdownIt(s) { 11 return markdownRenderer.render(s); 12 }); 13 Template.registerHelper('markdownItInline', function markdownItInline(s) { 14 return markdownRenderer.renderInline(s); 15 }); 16 Template.registerHelper('markdownItCommonmark', function markdownItCommonmark(s) { 17 return markdownRendererCommonmark.render(s); 18 }); 19 Template.registerHelper('markdownItCommonmarkInline', function markdownItCommonmarkInline(s) { 20 return markdownRendererCommonmark.renderInline(s); 21 }); 22 Template.registerHelper('markdownItPlain', function markdownRendererPlain(s) { 23 return markdownRendererPlain.render(s); 24 }); 25 Template.registerHelper('markdownItPlainInline', function markdownItPlainInline(s) { 26 return markdownRendererPlain.renderInline(s); 27 }); 28} else { 29 initMarkdown(); 30} 31 32function initMarkdown() { 33 console.info("Initializing Markdown renderer..."); 34 35 markdownRendererCommonmark = markdownit('commonmark'); 36 markdownRendererPlain = markdownit(); 37 markdownRenderer = markdownit({ 38 // Enable HTML tags in source 39 html: true, 40 // Use '/' to close single tags (<br />). 41 xhtmlOut: true, 42 43 // This is only for full CommonMark compatibility. 44 // Convert '\n' in paragraphs into <br> 45 breaks: true, 46 // CSS language prefix for fenced blocks. Can be useful for external highlighters. 47 langPrefix: '', 48 // Autoconvert URL-like text to links 49 linkify: true, 50 51 // Enable some language-neutral replacement + quotes beautification 52 typographer: true, 53 54 // Double + single quotes replacement pairs, when typographer enabled, 55 // and smartquotes on. Could be either a String or an Array. 56 // 57 // For example, you can use '«»„“' for Russian, '„“‚‘' for German, 58 // and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). 59 quotes: '“”‘’', 60 }); 61 62 // markdown-it-imsize 63 var markdownImsizeMinusPlugin = MarkdownItPlugins.getPlugin('markdown-it-imsize-no-autofill'); 64 markdownRenderer 65 .use(markdownImsizeMinusPlugin); 66 67 // markdown-it-sub and markdown-it-sup 68 // 'H~2~0' => '<p>H<sub>2</sub>O</p>' 69 // '29^th^' => '<p>29<sup>th</sup></p>' 70 markdownRenderer.use(MarkdownItPlugins.getPlugin('markdown-it-sub')); 71 markdownRenderer.use(MarkdownItPlugins.getPlugin('markdown-it-sup')); 72 73 // markdown-it-regexp 74 var MarkdownItRegExp = MarkdownItPlugins.getPlugin('markdown-it-regexp-enhanced'); 75 markdownRenderer.use(MarkdownItRegExp(/@@([\w\s]+)@@/, 76 function(match, utils) { 77 return '<i class="icon ' + match[1] + '"></i>'; 78 } 79 )); 80 81 // MdVariables Enhanced 82 var MdVariablesEnhanced = MarkdownItPlugins.getPlugin('mdvariables-enhanced'); 83 // '[[[title]]]' => '<p>The Title of this Page</p>' 84 function mdVariablesDataDirectory(name) { 85 switch (name) { 86 case "title": 87 return $("title").text(); 88 break; 89 case "random-number": 90 return Math.random(); 91 break; 92 case "notes-id": 93 return FlowRouter.getParam('notesId'); 94 break; 95 case "notes-title": 96 return CourseNotes.getItemProperty(FlowRouter.getParam('notesId'), 'name'); 97 break; 98 case "course-id": 99 return FlowRouter.getParam('courseId'); 100 break; 101 case "course-title": 102 return Course.getItemProperty(FlowRouter.getParam('courseId'), 'name'); 103 break; 104 case "course-session-id": 105 return FlowRouter.getParam('sessionId'); 106 break; 107 case "course-session-title": 108 return CourseSession.getItemProperty(FlowRouter.getParam('sessionId'), 'name'); 109 break; 110 default: 111 } 112 } 113 markdownRenderer.use( 114 MdVariablesEnhanced( 115 mdVariablesDataDirectory, 116 /\[\[\[([a-zA-Z\-_0-9]+)\]\]\]/ 117 ) 118 ); 119 120 markdownRenderer.use( 121 MdVariablesEnhanced( 122 function(name) { 123 var split = name.split('|').map(x => x.trim()); 124 var tag = split[0]; 125 var thing = split[1]; 126 return "<" + tag + ">" + thing + "</" + tag + ">"; 127 }, 128 /\[\[\[([a-zA-Z\-_0-9]+)\|([a-zA-Z\-_0-9\s]+)\]\]\]/, 129 match => match[1].toLowerCase() + "|" + match[2] 130 ) 131 ); 132 133 // markdown-it-abbr 134 var markdownItAbbrPlugin = MarkdownItPlugins.getPlugin('markdown-it-abbr'); 135 markdownRenderer.use(markdownItAbbrPlugin); 136 137 // markdown-it-anchor 138 markdownRenderer.use( 139 MarkdownItPlugins.getPlugin('markdown-it-anchor'), 140 _.extend(MarkdownItPlugins.getDefaultOptions('markdown-it-anchor'), { 141 level: 1, 142 // permalink: true, 143 // permalinkSymbol: "🔗", 144 }) 145 ); 146 147 // markdown-it-attrs 148 var markdownItAttrsPlugin = MarkdownItPlugins.getPlugin('markdown-it-attrs'); 149 markdownRenderer.use(markdownItAttrsPlugin); 150 151 // markdown-it-center-text 152 var markdownItCenterTextPlugin = MarkdownItPlugins.getPlugin('markdown-it-center-text'); 153 markdownRenderer 154 .use(markdownItCenterTextPlugin); 155 156 // markdown-it-checkbox 157 var markdownItCheckboxPlugin = MarkdownItPlugins.getPlugin('markdown-it-checkbox'); 158 markdownRenderer.use(markdownItCheckboxPlugin, { 159 divWrap: true, 160 divClass: 'ui checkbox', 161 idPrefix: 'markdown_checkbox_' 162 }); 163 164 // markdown-it-container 165 var markdownItContainerPlugin = MarkdownItPlugins.getPlugin('markdown-it-container'); 166 markdownRenderer.use(markdownItContainerPlugin, 'spoiler', { 167 validate: function(params) { 168 return params.trim().match(/^spoiler\s+(.*)$/); 169 }, 170 render: function(tokens, idx) { 171 var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/); 172 173 if (tokens[idx].nesting === 1) { 174 // opening tag 175 return '<details><summary>' + m[1] + '</summary>\n'; 176 } else { 177 // closing tag 178 return '</details>\n'; 179 } 180 } 181 }); 182 183 // markdown-it-emoji 184 var markdownItEmojiPlugin = MarkdownItPlugins.getPlugin('markdown-it-emoji'); 185 markdownRenderer.use(markdownItEmojiPlugin); 186 187 // markdown-it-expand-tabs 188 var markdownItExpandTabsPlugin = MarkdownItPlugins.getPlugin('markdown-it-expand-tabs'); 189 markdownRenderer.use(markdownItExpandTabsPlugin, { 190 tabWidth: 4 191 }); 192 193 // markdown-it-footnote 194 markdownRenderer.use(MarkdownItPlugins.getPlugin('markdown-it-footnote')); 195 196 // markdown-it-sanitizer 197 markdownRenderer.use(MarkdownItPlugins.getPlugin('markdown-it-sanitizer')); 198 199 // markdown-it-expand-tabs 200 var markdownItImplicitFiguresPlugin = MarkdownItPlugins.getPlugin('markdown-it-implicit-figures'); 201 markdownRenderer 202 .use(markdownItImplicitFiguresPlugin, { 203 dataType: true, 204 figcaption: true 205 }); 206 207 // markdown-it-table-of-contents 208 // the anchors have already been added... 209 var markdownItTableOfContentsPlugin = MarkdownItPlugins.getPlugin('markdown-it-table-of-contents'); 210 markdownRenderer 211 .use(markdownItTableOfContentsPlugin, 212 _.extend(MarkdownItPlugins.getDefaultOptions('markdown-it-table-of-contents'), { 213 includeLevel: [1, 2, 3] 214 })); 215 216 // markdown-it-video 217 var markdownItVideoPlugin = MarkdownItPlugins.getPlugin('markdown-it-video'); 218 markdownRenderer 219 .use(markdownItVideoPlugin); 220 221 // markdown-it-mark 222 var markdownItMarkPlugin = MarkdownItPlugins.getPlugin('markdown-it-mark'); 223 markdownRenderer 224 .use(markdownItMarkPlugin); 225 226 // markdown-it-smartarrows 227 // markdownRenderer.use(MarkdownItPlugins.getPlugin('markdown-it-smartarrows')); 228 229 // markdown-it-ins-del 230 // var markdownItInsDelPlugin = MarkdownItPlugins.getPlugin('markdown-it-ins-del'); 231 // markdownRenderer 232 // .use(markdownItInsDelPlugin) 233 // .disable('strikethrough'); 234 235 // markdown-it-modify-token 236 // do this last! 237 var markdownItModifyTokenModPlugin = MarkdownItPlugins.getPlugin('markdown-it-modify-token-modified'); 238 markdownRenderer 239 .use(markdownItModifyTokenModPlugin, function(token, env) { 240 // console.log(token) // do this to have a look at the token stream 241 switch (token.type) { 242 case 'link_open': 243 if (token.attrObj['href'] && (token.attrObj['href'].toString().indexOf("://") !== -1)) { 244 token.attrObj['target'] = '_blank'; 245 } 246 break; 247 case 'checkbox_input': 248 token.attrObj['disabled'] = true; 249 } 250 }); 251}