unified

Project: vmarkdown/remark-render

Package: remark-render@0.0.16

  1. Dependents: 0
  2. Compile markdown to Virtual DOM with remark.
  1. remark 214
  2. markdown 154
  3. react 14
  4. vue 5
  5. vdom 3

remark-render

Compiles markdown to Virtual DOM. Built on remark, an extensively tested and pluggable markdown processor.

Installation

npm:

npm install remark-render

Usage

Say we have the following file, example.js:

var renderer = require('remark-preact-renderer');

unified().use(render, {
  renderer: renderer,
  h: h,
  rootClassName: 'markdown-body',
  rootTagName: 'main'
})

=> <main class="markdown-body"></main>

options

remark
rendererframework renderer
hcreate element function
rootClassNamevdom root element class name
rootTagNamevdom root element tag type. default is div
var unified = require('unified')
var parse = require('remark-parse')
var render = require('remark-render')
  
var h = require('hyperscript');
unified()
  .use(parse)
  .use(render, {
     h: h, // create element function
     rootClassName: 'markdown-body' // vdom root element class name,
     rootTagName: 'main'
  })
  .process('# h1  \n## h2', function(err, file) {
    if (err) throw err
    console.dir(file.contents, {depth: null})
  })
 

Renderers

renderers
Reactremark-preact-renderer
Preactremark-react-renderer
Vueremark-vue-renderer
HyperScriptremark-hyperscript-renderer
snabbdomremark-snabbdom-renderer
virtual-domremark-virtual-dom-renderer
morphdommorphdom

Examples

Presets provide a potentially sharable way to render. They can contain multiple modes and optionally settings as well.

html
<div id="preview"></div>
HyperScript
npm install remark-render remark-hyperscript-renderer
var unified = require('unified')
var parse = require('remark-parse')
var render = require('remark-render')
var renderer = require('remark-hyperscript-renderer');

var h = require('hyperscript');
unified()
  .use(parse)
  .use(render, {
     renderer: renderer,
     h: h,
     rootClassName: 'markdown-body'
  })
  .process('# h1  \n## h2', function(err, file) {
    if (err) throw err
    console.dir(file.contents, {depth: null})
    var preview = document.getElementById('preview');
    preview.appendChild(vdom);
  })
 
React
npm install remark-react-renderer
var unified = require('unified')
var parse = require('remark-parse')
var render = require('remark-render')
var renderer = require('remark-react-renderer');
var React = require('react');
var h = React.createElement;

var processor = unified()
    .use(parse)
    .use(render, {
        renderer: renderer,
        h: h
    });
 
var file = processor.processSync('# h1');

ReactDOM.render(
    file.contents,
    document.getElementById('preview')
);
 
Vue
npm install remark-vue-renderer
var unified = require('unified')
var parse = require('remark-parse')
var render = require('remark-render')
var renderer = require('remark-vue-renderer');
var Vue = require('vue');
 
var processor = unified()
    .use(parse)
    .use(render, {
        renderer: renderer
    }).freeze();
 
const app = new Vue({
    el: '#preview',
    render(h) {
        var file = processor().data('h', h).processSync('# h1');
        return file.contents;
    }
}); 
Writing a custom renderer/Extend a renderer
var unified = require('unified')
var parse = require('remark-parse')
var render = require('remark-render')
var renderer = require('remark-hyperscript-renderer'); 
var h = require('hyperscript');

renderer.text = function(h, node, children) {
    return h('span', {
        key: node.properties.key,
        style: {'font-size': '60px'}
    }, node.value);
};

unified()
  .use(parse)
  .use(render, {
     h: h,
     renderer: renderer
  })
  .process('# h1  \n## h2', function(err, file) {
    if (err) throw err
    var preview = document.getElementById('preview');
    preview.appendChild(vdom);
  })
morphdom - Writing a custom renderer.

node MDAST

{
    "type": "heading",
    "depth": 1 <= number <= 6,
    "tagName": "a",
    "parent": parent,
    "properties": {
        "href": "href",
        "id": "id",
        "className": ["bravo"]
    },
    "children": []
}
renderer
{
    /**
     * root element (根元素)
     * @param {*} h create element function (构建元素节点函数)
     * @param {*} node  current node  (当前根元素节点)
     * node.key is node index if node in array for key. default is 0 (如果当前节点在数组中,返回当前节点在数组中的序列,这是为了构建数组key)
     * @param {*} children node create element children (当前节点的子节点)
     */
    root : function(h, node, children) {},

    text : function(h, node, children) {},

    ...
}
var unified = require('unified');
var parse = require('remark-parse');
var render = require('remark-render')
var morphdom = require('morphdom');

function createElement(type, props, children) {
    let dom = document.createElement(type);
    if(props.className) {
        dom.className = props.className;
    }
    if(props.hasOwnProperty('id')) {
        dom.id = props.id;
    }
    dom.appendChild( createElements(children) );
    return dom;
}

function createElements(children) {
    const doms = document.createDocumentFragment();
    children && children.length > 0 && children.forEach(function (dom) {
        dom && doms.appendChild(dom);
    });
    return doms;
}

var renderer = {
    root: function(h, node, children) {
        return h('div', node.props, children);
    },
    text: function(h, node, children) {
        return document.createTextNode(node.value);
    },
    blockquote: function(h, node, children) {
        return h('blockquote', node.props, children);
    },
    heading: function(h, node, children) {
        return h('h'+node.depth, node.props, children);
    }
    ...
}


var processor = unified()
    .use(parse, {})
    .use(render, {
        renderer: renderer,
        h: createElement
    });

var file = processor.processSync('# h1\n## h2');
var markdownContainer = file.contents;

var previewContainer = document.getElementById('preview');

morphdom(previewContainer, markdownContainer);

License

MIT © yucopowo