feat(fs.dev): Added OG intro for description
This commit is contained in:
parent
d71a8246ac
commit
b59c5036ed
8 changed files with 51 additions and 150 deletions
77
packages/freesewing.shared/mdx/remark-intro-plugin.mjs
Normal file
77
packages/freesewing.shared/mdx/remark-intro-plugin.mjs
Normal file
|
@ -0,0 +1,77 @@
|
|||
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 = (opts={}) => {
|
||||
|
||||
const { intro=[] } = opts
|
||||
|
||||
// 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 nodeIntro = extractFirstParagraph(node)
|
||||
// Forgive me for this hack
|
||||
intro.push(nodeIntro)
|
||||
if (hasFrontmatter(node)) {
|
||||
node.children[0].value += `\nintro: "${nodeIntro}"\n`
|
||||
} else {
|
||||
node.children.unshift({
|
||||
type: 'yaml',
|
||||
value: `intro: "${nodeIntro}"`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Transformer method using the visitor pattern
|
||||
const transform = (tree) => {
|
||||
visit(tree, 'root', visitor)
|
||||
}
|
||||
|
||||
return transform
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue