1
0
Fork 0
freesewing/packages/freesewing.shared/prebuild/remark-intro-plugin.mjs

75 lines
2 KiB
JavaScript
Raw Normal View History

import { visit } from 'unist-util-visit'
/*
* This is a remark plugin that will pull the (text of the)
* first paragraph out of a markdown document and add it as
* the `intro` field in the documents's frontmatter.
*
* As such, it will only do anything if the document has
* frontmatter.
*
* I wrote this specifically to pull the intro out of our
* markdown content for SEO and open graph.
* I'm not publishing this as a proper remark plugin because
* while this works for our use-cases, it may or may not
* work for the many different ways people use markdown and
* remark out there.
*/
// These are child types of a paragraph of which we'll extract the text
const asText = [
'text',
'strong',
'emphasis',
'inlineCode',
]
// The actual plugin starts here
export const remarkIntroPlugin = () => {
// Check to see whether the node has frontmatter
const hasFrontmatter = node => (node.children[0].type === 'yaml')
// Pulls text out of a paragraph
const extractIntro = node => {
const text = []
for (const child of node.children) {
if (asText.indexOf(child.type) !== -1) text.push(child.value)
else if (child.type === 'link') text.push(child.children[0].value)
}
return text.map(item => item ? item.trim() : '').join(' ')
}
// Pulls the first paragraph out of a root node
const extractFirstParagraph = node => {
for (const child of node.children) {
if (child.type === 'paragraph') return extractIntro(child)
}
return 'FIXME_no_intro'
}
// Tree visitor
const visitor = (node) => {
const intro = extractFirstParagraph(node)
if (hasFrontmatter(node)) {
2021-12-17 17:51:20 +01:00
node.children[0].value += `\nintro: "${intro}"\n`
//console.log(node.children[0])
} else {
node.children.unshift({
type: 'yaml',
value: `intro: "${intro}"`
})
}
}
// Transformer method using the visitor pattern
const transform = (tree) => {
visit(tree, 'root', visitor)
}
return transform
}