README
Uttori Renderer - Markdown - MarkdownIt
Uttori renderer support for Markdown powered by MarkdownIt.
This also includes a MarkdownIt plugin you can use seperately that supports:
- Generate a Table of Contents based on
H#
header tags with[toc]
- Adding a URL prefix
- Properly handle external domains with
noopener noreferrer
and optionally set up allowed domains fornofollow
SEO support to curb spam - Support for WikiLinks style linking
- Support for adding Lazy Loading tags to
img
tags - Support for adding YouTube iframe videos
Install
npm install --save @uttori/plugin-renderer-markdown-it
Config
Configuration outside of registration events and Uttori specific items is avaliable by passing in MarkdownIt config.
{
// Registration Events
events: {
renderContent: [],
renderCollection: [],
validateConfig: [],
},
// MarkdownIt Configuration
// Enable HTML tags in source
html: false,
// Use '/' to close single tags (<br />).
xhtmlOut: false,
// Convert '\n' in paragraphs into <br>, this is only for full CommonMark compatibility.
breaks: false,
// CSS language prefix for fenced blocks. Can be useful for external highlighters.
langPrefix: 'language-',
// Autoconvert URL-like text to links.
linkify: false,
// Enable some language-neutral replacement + quotes beautification.
typographer: false,
// Double + single quotes replacement pairs, when typographer enabled, and smartquotes on. Could be either a String or an Array.
// For example, you can use '«»„“' for Russian, '„“‚‘' for German, and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp).
quotes: '“”‘’',
// Highlighter function. Should return escaped HTML, or '' if the source string is not changed and should be escaped externally.
// If result starts with <pre... internal wrapper is skipped.
// highlight: (/* str, lang */) => '',
// Any other supported MarkdownIt configuration
...,
// Custom Values for Uttori Specific Use
uttori: {
// Prefix for relative URLs, useful when the Express app is not at root.
baseUrl: '',
// Good Noodle List, f a domain is not in this list, it is set to 'external nofollow noreferrer'.
allowedExternalDomains: [],
// Open external domains in a new window.
openNewWindow: true,
// Add lazy loading params to image tags.
lazyImages: true,
// Footnotes
footnotes: {
// A funciton to return the default HTML for a footnote reference.
referenceTag: ({ id, label }) => {
return `...`;
},
// A funciton to return the default opening HTML for a footnote definition.
definitionOpenTag: ({ id, label }) => {
return `...`;
},
// The default closing HTML for a footnote definition.
definitionCloseTag: '</div>\n',
},
// Table of Contents
toc: {
// The opening DOM tag for the TOC container.
openingTag: '<nav class="table-of-contents">',
// The closing DOM tag for the TOC container.
closingTag: '</nav>',
// Slugify options for convering headings to anchor links.
slugify: {
lower: true,
},
},
// WikiLinks
wikilinks: {
// Slugify options for convering Wikilinks to anchor links.
slugify: {
lower: true,
},
},
},
}
Table of Contents Generation
You can generate a table of contents based on the headers in a file. Example:
# First
## Second
### Third
### Third Again
#### Fouth
## Second Again
### Third Last
Content
[toc]
Will render to a minified version of:
<p>
<nav class="table-of-contents">
<ul class="table-of-contents-h1">
<li><a href="#first-0" title="First">First</a></li>
<li><ul class="table-of-contents-h2">
<li><a href="#second-1" title="Second">Second</a></li>
<li><ul class="table-of-contents-h3">
<li><a href="#third-2" title="Third">Third</a></li>
<li><a href="#third-again-3" title="Third Again">Third Again</a></li>
<li><ul class="table-of-contents-h4">
<li><a href="#fouth-4" title="Fouth">Fouth</a></li>
</ul></li>
</ul></li>
<li><a href="#second-again-6" title="Second Again">Second Again</a></li>
<li><ul class="table-of-contents-h3">
<li><a href="#third-last-7" title="Third Last">Third Last</a></li>
</ul></li>
</ul></li>
</ul>
</nav>
Content Content
</p>
Footnotes
This allos for adding footnotes & their definitions.
`ADC (dp,X)`[^1]
[^1]: Add 1 cycle if m=0 (16-bit memory/accumulator)
YouTube Embedding
This allows safe embedding of YouTube videos. Example:
<youtube v="XG9dCoTlJYA" start="0" width="560" height="315" title="YouTube Video Player" start="0">
Will render to a minified version of:
<div class="youtube-embed">
<iframe class="youtube-embed-video" width="560" height="315" src="https://www.youtube-nocookie.com/embed/aR3fVuLEtj8?start=0" title="YouTube Video Player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="true"></iframe>
</div>
The only required parameter is v
:
<youtube v="aR3fVuLEtj8">
Will render to a minified version of:
<div class="youtube-embed">
<iframe class="youtube-embed-video" width="560" height="315" src="https://www.youtube-nocookie.com/embed/aR3fVuLEtj8?start=0" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="true"></iframe>
</div>
API Reference
Classes
- MarkdownItRenderer
Uttori MarkdownIt Renderer
Functions
- debug() :
function
Typedefs
- MarkdownItRendererOptions :
object
MarkdownItRenderer
Uttori MarkdownIt Renderer
Kind: global class
- MarkdownItRenderer
- .configKey ⇒
string
- .defaultConfig() ⇒
MarkdownItRendererOptions
- .extendConfig([config]) ⇒
MarkdownItRendererOptions
- .validateConfig(config, _context)
- .register(context)
- .renderContent(content, context) ⇒
string
- .renderCollection(collection, context) ⇒
Array.<object>
- .render(content, config) ⇒
string
- .configKey ⇒
string
MarkdownItRenderer.configKey ⇒ The configuration key for plugin to look for in the provided configuration.
Kind: static property of MarkdownItRenderer
Returns: string
- The configuration key.
Example (MarkdownItRenderer.configKey)
const config = { ...MarkdownItRenderer.defaultConfig(), ...context.config[MarkdownItRenderer.configKey] };
MarkdownItRendererOptions
MarkdownItRenderer.defaultConfig() ⇒ The default configuration.
Kind: static method of MarkdownItRenderer
Returns: MarkdownItRendererOptions
- The default configuration.
Example (MarkdownItRenderer.defaultConfig())
const config = { ...MarkdownItRenderer.defaultConfig(), ...context.config[MarkdownItRenderer.configKey] };
MarkdownItRendererOptions
MarkdownItRenderer.extendConfig([config]) ⇒ Create a config that is extended from the default config.
Kind: static method of MarkdownItRenderer
Returns: MarkdownItRendererOptions
- The new configration.
Param | Type | Default | Description |
---|---|---|---|
[config] | MarkdownItRendererOptions |
{} |
The user provided configuration. |
MarkdownItRenderer.validateConfig(config, _context)
Validates the provided configuration for required entries.
Kind: static method of MarkdownItRenderer
Param | Type | Description |
---|---|---|
config | object |
A configuration object. |
config.configKey | MarkdownItRendererOptions |
A configuration object specifically for this plugin. |
_context | object |
Unused |
Example (MarkdownItRenderer.validateConfig(config, _context))
MarkdownItRenderer.validateConfig({ ... });
MarkdownItRenderer.register(context)
Register the plugin with a provided set of events on a provided Hook system.
Kind: static method of MarkdownItRenderer
Param | Type | Description |
---|---|---|
context | object |
A Uttori-like context. |
context.hooks | object |
An event system / hook system to use. |
context.hooks.on | function |
An event registration function. |
context.config | object |
A provided configuration to use. |
context.config.events | object |
An object whose keys correspong to methods, and contents are events to listen for. |
Example (MarkdownItRenderer.register(context))
const context = {
hooks: {
on: (event, callback) => { ... },
},
config: {
[MarkdownItRenderer.configKey]: {
...,
events: {
renderContent: ['render-content', 'render-meta-description'],
renderCollection: ['render-search-results'],
validateConfig: ['validate-config'],
},
},
},
};
MarkdownItRenderer.register(context);
string
MarkdownItRenderer.renderContent(content, context) ⇒ Renders Markdown for a provided string with a provided context.
Kind: static method of MarkdownItRenderer
Returns: string
- The rendered content.
Param | Type | Description |
---|---|---|
content | string |
Markdown content to be converted to HTML. |
context | object |
A Uttori-like context. |
context.config | object |
A provided configuration to use. |
Example (MarkdownItRenderer.renderContent(content, context))
const context = {
config: {
[MarkdownItRenderer.configKey]: {
...,
},
},
};
MarkdownItRenderer.renderContent(content, context);
Array.<object>
MarkdownItRenderer.renderCollection(collection, context) ⇒ Renders Markdown for a collection of Uttori documents with a provided context.
Kind: static method of MarkdownItRenderer
Returns: Array.<object>
- } The rendered documents.
Param | Type | Description |
---|---|---|
collection | Array.<object> |
A collection of Uttori documents. |
context | object |
A Uttori-like context. |
context.config | object |
A provided configuration to use. |
Example (MarkdownItRenderer.renderCollection(collection, context))
const context = {
config: {
[MarkdownItRenderer.configKey]: {
...,
},
},
};
MarkdownItRenderer.renderCollection(collection, context);
string
MarkdownItRenderer.render(content, config) ⇒ Renders Markdown for a provided string with a provided MarkdownIt configuration.
Kind: static method of MarkdownItRenderer
Returns: string
- The rendered content.
Param | Type | Description |
---|---|---|
content | string |
Markdown content to be converted to HTML. |
config | object |
A provided MarkdownIt configuration to use. |
Example (MarkdownItRenderer.render(content, config))
const html = MarkdownItRenderer.render(content, config);
function
debug() :
object
MarkdownItRendererOptions : Kind: global typedef
Properties
Name | Type | Default | Description |
---|---|---|---|
[html] | boolean |
false |
Enable HTML tags in source. |
[xhtmlOut] | boolean |
false |
Use '/' to close single tags ( ). |
[breaks] | boolean |
false |
Convert '\n' in paragraphs into , this is only for full CommonMark compatibility. |
[langPrefix] | string |
"'language-'" |
CSS language prefix for fenced blocks. Can be useful for external highlighters. |
[linkify] | boolean |
false |
Autoconvert URL-like text to links. |
[typographer] | boolean |
false |
Enable some language-neutral replacement + quotes beautification. |
[quotes] | string |
"'“”‘’'" |
Double + single quotes replacement pairs, when typographer enabled, and smartquotes on. Could be either a String or an Array. For example, you can use '«»„“' for Russian, '„“‚‘' for German, and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). |
[highlight] | function |
Highlighter function. Should return escaped HTML, or '' if the source string is not changed and should be escaped externally. If result starts with <pre... internal wrapper is skipped. | |
[uttori] | object |
{} |
Custom values for Uttori specific use. |
[uttori.baseUrl] | string |
"''" |
Prefix for relative URLs, useful when the Express app is not at URI root. |
[uttori.allowedExternalDomains] | Array.<string> |
[] |
Allowed External Domains, if a domain is not in this list, it is set to 'nofollow'. Values should be strings of the hostname portion of the URL object (like example.org). |
[uttori.openNewWindow] | boolean |
true |
Open external domains in a new window. |
[uttori.lazyImages] | boolean |
true |
Add lazy loading params to image tags. |
[uttori.footnotes] | object |
{} |
Footnote settings. |
[uttori.footnotes.referenceTag] | function |
A funciton to return the default HTML for a footnote reference. | |
[uttori.footnotes.definitionOpenTag] | function |
A funciton to return the default opening HTML for a footnote definition. | |
[uttori.footnotes.definitionCloseTag] | string |
"'</div>\n'" |
The default closing HTML for a footnote definition. |
[uttori.toc] | object |
{} |
Table of Contents settings. |
[uttori.toc.openingTag] | string |
"'<nav class="table-of-contents">'" |
The opening DOM tag for the TOC container. |
[uttori.toc.closingTag] | string |
"'</nav>'" |
The closing DOM tag for the TOC container. |
[uttori.toc.slugify] | object |
{ lower: true } |
Slugify options for convering headings to anchor links. |
[uttori.wikilinks] | object |
{} |
WikiLinks settings. |
[uttori.wikilinks.slugify] | object |
{ lower: true } |
Slugify options for convering Wikilinks to anchor links. |
Tests
To run the test suite, first install the dependencies, then run npm test
:
npm install
npm test
DEBUG=Uttori* npm test