@uttori/plugin-renderer-markdown-it

Uttori plugin for rendering Markdown powered by MarkdownIt.

Usage no npm install needed!

<script type="module">
  import uttoriPluginRendererMarkdownIt from 'https://cdn.skypack.dev/@uttori/plugin-renderer-markdown-it';
</script>

README

view on npm npm module downloads Build Status Dependency Status Coverage Status Tree-Shaking Support Dependency Count Minified + GZip Minified

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 for nofollow 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

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 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);

MarkdownItRenderer.renderContent(content, context) ⇒ string

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);

MarkdownItRenderer.renderCollection(collection, context) ⇒ Array.<object>

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);

MarkdownItRenderer.render(content, config) ⇒ string

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);

debug() : function

Kind: global function

MarkdownItRendererOptions : object

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&#61;&quot;table-of-contents&quot;>'" 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

Contributors

License