const async = require('async'); const Remarkable = require('remarkable'); const compile = require('./compile'); const evaluate = require('./eval'); const uuid = require('uuid').v4; const templates = { plain: (style, body) => ` ${body} `, iframe: (style, body) => { const _body = body.replace(/"/g, '\''); return ` `; }, shadow: (style, body) => { const id = uuid(); const script = `(function() { const element = document.getElementById('${id}').attachShadow({ mode: 'closed' }); const template = document.getElementById('${id}-template'); element.appendChild(document.importNode(template.content, true)); })();`; return `
`; } }; module.exports = ({ mode = 'shadow', fullname, source, config = {} }, fn) => { const instance = new Remarkable(config.renderer); const { parse, renderer, options } = instance; const entrypoint = fullname.replace(/\.md$/, '.js'); const tokens = parse.call(instance, source, options, {}); async.map(tokens, (token, fn) => { if ((token.type !== 'fence') || (token.params !== 'embed')) { return fn(null, token); } compile({ source: token.content, config: config.webpack, entrypoint }, (err, { body, style }) => { if (err) { return fn(err); } const evaluated = evaluate({ entrypoint, source: body }); const content = templates[mode](style, evaluated); return fn(null, { type: 'htmlblock', content }); }); }, (err, tokens) => { if (err) { return fn(err); } fn(err, renderer.render.call(instance.renderer, tokens, options, {})); }); };