blazeui:markdown

v1.0.0Published 2 months ago

Meteor BlazeUI Markdown

This package allows to render given Markdown using BlazeUI components. The result is an output that is 100% compatible to your TailwindCSS theme.

You can try it out in the live demo.

Installation and usage

First, you need to add this package, then you need to install the npm dependencies marked and a DOM sanitizer of your choice (tested with dompurify):

$ meteor add blazeui:markdown
$ meteor npm install --save marked dompurify

Once they're installed you need to register the respective components and transformers:

1import { BlazeUI } from 'meteor/blazeui:core'
2import { Markdown } from 'meteor/blazeui:markdown'
3import DOMPurify from 'dompurify'
4
5// register all dependencies as BlazeUI components,
6// if not already done
7BlazeUI.register(...Markdown.dependencies())
8
9Markdown.sanitize = code => DOMPurify.sanitize(code)

Note that you are not forced to use DOMPurify but any sanitation library that suits your needs.

Finally you can render Markdown either by passing the source as attribute (reactive) or as contentblock (non-reactive).

Render from attribute (reactive)

Consider the following tag:

{{> Markdown source=mdSource}}

For this to reactively render markdown, you need a reactive data source and pass the markdown to it:

1Template.myTemplate.onCreated(function () {
2  const instance = this
3  instance.md = new ReactiveVar(`# Fetching Markdown...`)
4})
5
6Template.myTemplate.onRendered(function () {
7  const instance = this
8  
9  // fetches a Markdown file from a given location and sets it as 
10  // reactive source for our markdown renderer
11  fetch('https://raw.githubusercontent.com/blazeui/blazeui/refs/heads/main/core/README.md')
12    .then(response => instance.md.set(response.text()))
13    .catch(e => instance.md.set(`# Error fetching from source
14${e.message}
15${e.stack}
16`))
17})
18
19Template.myTemplate.helpers({
20  mdSource () {
21    return Template.instance().md.get()
22  }
23})

Render as content block (non-reactive)

You can also write your entire content Blog-style using the Markdown in contentblock:

{{#Markdown}}
# Markdown

BlazeUI provides a full-scale Markdown rendering component, which you can install via
`meteor add blazeui:markdown`.
It's different from other Markdown renderers in the way, that it uses BlazeUI components
to render tokens, instead of plain HTML. As a result, your Markdown-rendered output looks exactly the same
as if you'd manually write markup using BlazeUI components.

> In fact, this entire section is written using this Markdown component.
{{/Markdown}}

This enables to write new content blazingly fast.

Advanced topics

While this library comes with great defaults, it is very flexible to suit more specific needs.

Add code highlighting

By default, no code highlight is applied to your code segments. However, you can register a highlighter that does the job. Let's take a look at an example that uses Prims JS:

1import 'path/to/prism'
2import 'path/to/prism.css'
3
4Markdown.highlight = (code, lang) => {
5  const isSupported = lang && Prism.languages[lang]
6  return {
7    transformed: isSupported,
8    code: isSupported
9      ? Prism.highlight(code, Prism.languages[lang], lang)
10      : code
11  }
12}

The return value of the highlighter always has to be

1{
2  transformed: Boolean, 
3  code: String
4}

Customize Markdown behaviour

Under the hood this package uses marked as Markdown engine. The current default settings are

attributevalue
breaksfalse
pedanticfalse
gfmtrue
rendererMarkdown.renderer

You can change / update these configs by passing respective MarkedJS options to Markdown.config.

Override internal

You can also override rendering output (destructive) to use raw HTML:

1const renderLink = function (options) {
2  const { href, text, title } = opions
3  return `<a href="${href}" target="_blank" title="${title}">${text}</a>`
4}
5
6Markdown.render.link = renderLink

The change will only apply, if you update this via Markdown.config({ renderer: Markdown.renderer }).

Override via external

A non-destructive override would be instead:

1Markdown.config({
2  renderer: {
3    link: renderLink
4  }
5})

This config could then be reset via Markdown.config({ renderer: Markdown.renderer }).

License

This package is MIT licensed, see LICENSE file.