59 lines
1.9 KiB
JavaScript
59 lines
1.9 KiB
JavaScript
/*
|
|
* This is a remark plugin that will pull the (text of the)
|
|
* first few paragraph out of a markdown document and add it
|
|
* as the `lead` field in the documents's frontmatter.
|
|
*
|
|
* It will only do anything if the document has frontmatter.
|
|
* It also places this in the *lead* frontmatter key so that
|
|
* people can manually specify a *intro* key that will take
|
|
* precendence.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
const extractIntro = (node) => {
|
|
const intro = []
|
|
for (const el of node.children.filter((node) => node.type === 'paragraph').slice(0, 3)) {
|
|
for (const child of el.children) {
|
|
if (child.type === 'text' && child.value) intro.push(child.value)
|
|
else if (['link', 'strong', 'emphasis'].includes(child.type) && child.children) {
|
|
for (const grandchild of child.children) {
|
|
if (grandchild.type === 'text' && grandchild.value) intro.push(grandchild.value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return intro.length < 1 ? 'FIXME -- No intro found' : intro.join('')
|
|
}
|
|
|
|
const introAsProperty = (intro) => ({
|
|
type: 'Property',
|
|
method: false,
|
|
shorthand: false,
|
|
computed: false,
|
|
kind: 'init',
|
|
key: { type: 'Literal', value: 'lead' },
|
|
value: { type: 'Literal', value: intro },
|
|
})
|
|
|
|
export function remarkIntroAsFrontmatter() {
|
|
return (node) => {
|
|
const esm = node.children.filter((child) => child.type === 'mdxjsEsm')
|
|
if (
|
|
esm &&
|
|
esm.length === 1 &&
|
|
esm[0].data?.estree?.body?.[0]?.declaration?.declarations?.[0]?.init?.properties
|
|
)
|
|
esm[0].data.estree.body[0].declaration.declarations[0].init.properties.push(
|
|
introAsProperty(extractIntro(node))
|
|
)
|
|
|
|
return node
|
|
}
|
|
}
|