UNPKG

marked-ast-crel

Version:

Using the AST generated my marked-ast create appropriate HTML elements with crel

118 lines (88 loc) 2.44 kB
const crel = require('crel'); const entities = require('entities'); const languageMappings = { js: 'javascript', }; // lookup mappings and functions // NOTE: the functions mutate the attr and children argument values const lookup = { paragraph: 'p', link: 'a', codeblock: 'code', codespan: 'code', listitem: 'li', image: (node, attr) => { const { href } = node; delete attr['href']; attr.src = href; return 'img'; }, blockquote: (node, attr, children) => { node.quote.forEach(function (item) { children.push(item); }); }, list: (node, attr, children) => { node.body.forEach(function (item) { children.push(item); }); return node.ordered ? 'ol' : 'ul'; }, heading: node => `h${node.level}`, code: (node, attr, children) => { const lang = node.lang || ''; children.push({ class: 'hljs' + (lang ? ' ' + (languageMappings[lang] || lang) : ''), type: 'codeblock', text: node.code, }); return 'pre'; }, }; const IGNORE_KEYS = ['type', 'text', 'code', 'body', 'ordered']; /** # marked-ast-crel Using the AST generated by [marked-ast](https://github.com/pdubroy/marked-ast) create HTML elements using [crel](https://github.com/KoryNunn/crel). Saves doing any nasty `innerHTML` like things... ## Example Usage Simple example: ``` npm run simple ``` <<< examples/simple.js A little more complex (uses `brfs`): ``` npm run complex ``` <<< examples/complex.js **/ const createNode = input => { let attr = {}; if (Array.isArray(input)) { return input.map(createNode); } // if we have a string for the node, pass through if (typeof input == 'string' || input instanceof String) { return entities.decodeHTML(input); } // if we have string node text, then encapsulate as an array if (typeof input.text == 'string' || input.text instanceof String) { input.text = [entities.decodeHTML(input.text)]; } Object.keys(input).forEach(key => { if (IGNORE_KEYS.indexOf(key) >= 0) { return; } if (input[key]) { attr[key] = input[key]; } }); const children = input.text || []; let tagName = lookup[input.type] || input.type; if (typeof tagName == 'function') { tagName = tagName(input, attr, children) || input.type; } return crel.apply(null, [tagName, attr].concat(children.map(createNode))); }; module.exports = createNode;