From 1b6c2bdc9b71299646d2f662b28dc5d28623ecb0 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 12 Sep 2017 23:59:07 -0700 Subject: [PATCH] parse titles from nearest heading or fence lang --- .storybook/lib/storiesFromMarkdown.js | 54 ++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/.storybook/lib/storiesFromMarkdown.js b/.storybook/lib/storiesFromMarkdown.js index 2e0057d7..a475e697 100644 --- a/.storybook/lib/storiesFromMarkdown.js +++ b/.storybook/lib/storiesFromMarkdown.js @@ -1,16 +1,60 @@ import remark from 'remark' +import visit from 'unist-util-visit' import select from 'unist-util-select' import htmlToReact from 'html-to-react' +import {createParser} from 'parse-pairs' + +const htmlParser = new htmlToReact.Parser() + +const parsePairs = (parse => { + return str => { + try { + return parse(str) + } catch (error) { + return {} + } + } +})(createParser()) + +const nodeToStory = (node, heading, file, index) => { + const html = node.value + const pairs = node.lang.replace(/^html\s+/, '') + const data = pairs ? parsePairs(pairs) : {} + const title = data.title || heading || `story #${index} (${file})` + return { + story: htmlParser.parse(html), + title, + html, + file, + node, + } +} export default req => { - const parser = new htmlToReact.Parser() return req.keys() .reduce((stories, file) => { const content = req(file) const ast = remark.parse(content) - return stories.concat( - select(ast, 'code[lang^=html]') - .map(node => parser.parse(node.value)) - ) + let heading + + visit(ast, node => { + switch (node.type) { + case 'heading': + heading = node.children + .map(child => child.value) + .join('') + break + case 'code': + if (node.lang && node.lang.match(/^html\b/)) { + stories.push( + nodeToStory(node, heading, file, stories.length + 1) + ) + heading = undefined + } + break + } + }) + + return stories }, []) }