-
Notifications
You must be signed in to change notification settings - Fork 194
Provide a way to populate field values from Markdown/MDX processing pipeline #216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
As a temporary workaround, one could consider defining a computedField that parses the raw output from contentlayer. Here's an example of extracting the table of contents of a markdown file and making it available as a // Assume a remark plugin that stores the information in `vfile.data.toc`
export async function extractTocHeadings(markdown) {
const vfile = await remark().use(remarkTocHeadings).process(markdown)
return vfile.data.toc
}
const computedFields: ComputedFields = {
toc: { type: 'string', resolve: (doc) => extractTocHeadings(doc.body.raw) },
...
} |
@motleydev would having access to the Something along those lines const computedFields: ComputedFields = {
toc: { type: 'string', resolve: (_doc, { vfile }) => vfile.data.toc },
...
} |
When do computed fields get executed? At run time or at compilation? At the end of the day, what I'm trying to get is the data added to static output. |
|
in that case, that would probably work just fine! Would still be nice to do the work during the original transform process to not need to revisit each file, but for a static output process, that's probably shaving the yack a bit too close. |
The more I think about it, accessing vfile.data from computed fields would totally solve my use-case. It'd still be nice to be able to do all the work "in" the handler, but being able to do visit work during the initial parsing and then passing that along with the payload would be more than sufficient. What do you think a reasonable timeline on that would be? |
Any update on this? I'd be willing to try my hand at a PR to pass |
I've spent the evening trying to work on a solution myself (for At this point, I think the way to resolve this would be
I'm still willing to try and help further progress on this issue. Currently carrying around a lot of hacks in my code ;) |
Thanks for your comment @essential-randomness. Very helpful. I hope I'll get some capacity soon to take a stab at this! |
Need this~ |
I tried the code above to no avail... did someone manage to read the mdx content and add data to frontmatter using a custom remark plugin in this context? thanks! |
hope it helps someone, in the end I managed like this // this is a bit too custom maybe but you get the idea
function extractHtmlHeadings(tree) {
const headings = []
visit(
tree,
(node) =>
['mdxJsxFlowElement', 'mdxJsxTextElement'].includes(node.type) &&
node.name.match(/h[2-3]/g),
(node) => {
if (['mdxJsxFlowElement'].includes(node.type)) {
headings.push({
id: node.attributes[0].value,
text: node.children[0].children[0].value,
type: node.name === 'h2' ? 'heading2' : 'heading3',
})
return
}
headings.push({
id: node.attributes[0].value,
text: node.children[0].value,
type: node.name === 'h2' ? 'heading2' : 'heading3',
})
}
)
return buildTreeFromHeadings(headings)
}
export const InstructionsForUse = defineDocumentType(() => ({
contentType: 'mdx',
computedFields: {
toc: {
type: 'nested',
of: Toc,
resolve(doc) {
return remark()
.use(remarkMdx)
.use(function searchMeta() {
return function transformer(tree, file) {
const headings = extractHtmlHeadings(tree)
file.data = headings
}
})
.process(doc.body.raw)
.then((vFile) => {
return vFile.data
})
},
},
}, |
Relates to #566 |
Feature:
I'd like to use an MDX plugin to create programmatic meta (variable declarations) that can then be exposed in the final object contentlayer provides.
Use case:
An example of here this would be useful is generating a TOC, creating a list of unique keywords, etc.
Work around:
Use computed fields (which don't expose the the raw AST)
Related issues: kentcdodds/mdx-bundler#169
Consider the following config structure
Where
searchMeta
looks at paragraph nodes of mhast, grabs a list of unique words, and adds them to the metadata assearchMeta
.A markdown file with the structure of:
Would generate a final object of:
For sake of complete, if not ugly code, here's a working example of the plugin that adds
searchMeta
to the data attribute of the vFile in the rehype plugin chain.The text was updated successfully, but these errors were encountered: