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
[^1] ... [^1]: Footnote
Footnotes based on markdown-it-footnote - Support for WikiLinks style linking
- Support for adding Lazy Loading tags to
img
tags - Support for adding YouTube iframe videos
- Support for
<br> or <br/> or <br />
style line breaks anywhere, useful for tables - Support for
<video src="/uploads/example.mp4">
video embeds with allowed domains filtering - Support for adding color to spans with
[Text](color:#ffadad)
- Parse to tokens for building an AST (abstract syntax tree) using
MarkdownItRenderer.parse(content, config)
npm install --save @uttori/plugin-renderer-markdown-it
Configuration outside of registration events and Uttori specific items is avaliable by passing in MarkdownIt config.
{
// Registration Events
events: {
renderContent: [],
renderCollection: [],
validateConfig: [],
viewModelDetail: [],
},
// 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,
},
},
},
}
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>
This allos for adding footnotes & their definitions.
`ADC (dp,X)`[^1]
[^1]: Add 1 cycle if m=0 (16-bit memory/accumulator)
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>
You can add colored text with special links:
[Text](color:#ffadad)
[Text](color:#ffd6a5)
[Text](color:#fdffb6)
[Text](color:#caffbf)
[Text](color:#9bf6ff)
[Text](color:#A0C4FF)
[Text](color:#bdb2ff)
[Text](color:#ffcff8)
[Text](color:#fffffc)
[Text](color:rgba(0,0,0,0.5))
- MarkdownItRenderer
Uttori MarkdownIt Renderer
- MarkdownItRendererOptions :
object
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
- .parse(content, [config]) ⇒
Array.<module:markdown-it/lib/token>
- .cleanContent(content) ⇒
string
- .viewModelDetail(viewModel, context) ⇒
object
- .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] };
MarkdownItRenderer.defaultConfig() ⇒ MarkdownItRendererOptions
The default configuration.
Kind: static method of MarkdownItRenderer
Returns: MarkdownItRendererOptions
- The default configuration.
Example (MarkdownItRenderer.defaultConfig())
const config = { ...MarkdownItRenderer.defaultConfig(), ...context.config[MarkdownItRenderer.configKey] };
MarkdownItRenderer.extendConfig(config) ⇒ MarkdownItRendererOptions
Create a config that is extended from the default config.
Kind: static method of MarkdownItRenderer
Returns: MarkdownItRendererOptions
- The new configration.
Param | Type | Description |
---|---|---|
config | MarkdownItRendererOptions |
The user provided configuration. |
Validates the provided configuration for required entries.
Kind: static method of MarkdownItRenderer
Param | Type | Description |
---|---|---|
config | Record.<string, MarkdownItRendererOptions> |
A provided configuration to use. |
_context | object |
Unused |
Example (MarkdownItRenderer.validateConfig(config, _context))
MarkdownItRenderer.validateConfig({ ... });
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 | MarkdownItRendererOptions |
A provided configuration to use. |
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);
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 | MarkdownItRendererOptions |
A provided configuration to use. |
Example (MarkdownItRenderer.renderContent(content, context))
const context = {
config: {
[MarkdownItRenderer.configKey]: {
...,
},
},
};
MarkdownItRenderer.renderContent(content, 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 | MarkdownItRendererOptions |
A provided MarkdownIt configuration to use. |
Example (MarkdownItRenderer.renderCollection(collection, context))
const context = {
config: {
[MarkdownItRenderer.configKey]: {
...,
},
},
};
MarkdownItRenderer.renderCollection(collection, context);
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] | MarkdownItRendererOptions |
A provided MarkdownIt configuration to use. |
Example (MarkdownItRenderer.render(content, config))
const html = MarkdownItRenderer.render(content, config);
Parse Markdown for a provided string with a provided MarkdownIt configuration.
Kind: static method of MarkdownItRenderer
Returns: Array.<module:markdown-it/lib/token>
- The rendered content.
See: MarkdownIt.parse
Param | Type | Description |
---|---|---|
content | string |
Markdown content to be converted to HTML. |
[config] | MarkdownItRendererOptions |
A provided MarkdownIt configuration to use. |
Example (MarkdownItRenderer.parse(content, config))
const tokens = MarkdownItRenderer.parse(content, config);
Removes empty links, as these have caused issues. Find missing links, and link them to the slug from the provided text.
Kind: static method of MarkdownItRenderer
Returns: string
- The rendered content.
Param | Type | Description |
---|---|---|
content | string |
Markdown content to be converted to HTML. |
Will attempt to extract the table of contents when set to and add it to the view model.
Kind: static method of MarkdownItRenderer
Returns: object
- The view model.
Param | Type | Description |
---|---|---|
viewModel | object |
Markdown content to be converted to HTML. |
context | object |
A Uttori-like context. |
context.config | MarkdownItRendererOptions |
A provided configuration to use. |
Example (MarkdownItRenderer.viewModelDetail(viewModel, context))
viewModel = MarkdownItRenderer.viewModelDetail(viewModel, context);
Kind: global typedef
Properties
Name | Type | Description |
---|---|---|
baseUrl | string |
Prefix for relative URLs, useful when the Express app is not at URI root. |
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). |
disableValidation | boolean |
Optionally disable the built in Markdown-It link validation, large security risks when link validation is disabled. |
openNewWindow | boolean |
Open external domains in a new window. |
lazyImages | boolean |
Add lazy loading params to image tags. |
footnotes | object |
Footnote settings. |
footnotes.referenceTag | function |
A funciton to return the default HTML for a footnote reference. |
footnotes.definitionOpenTag | function |
A funciton to return the default opening HTML for a footnote definition. |
footnotes.definitionCloseTag | string |
The default closing HTML for a footnote definition. |
toc | object |
Table of Contents settings. |
toc.extract | boolean |
When true, extract the table of contents to the view model from the content. |
toc.openingTag | string |
The opening DOM tag for the TOC container. |
toc.closingTag | string |
The closing DOM tag for the TOC container. |
toc.slugify | object |
Slugify options for convering headings to anchor links. |
wikilinks | object |
WikiLinks settings. |
wikilinks.slugify | object |
Slugify options for convering Wikilinks to anchor links. |
To run the test suite, first install the dependencies, then run npm test
:
npm install
npm test
DEBUG=Uttori* npm test