-
Notifications
You must be signed in to change notification settings - Fork 194
Investigate table of content use case #137
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 an initial "user-land" solution I've come up with the following: import { defineDocumentType } from 'contentlayer/source-files'
import type * as unified from 'unified'
import { toMarkdown } from 'mdast-util-to-markdown'
import { mdxToMarkdown } from 'mdast-util-mdx'
import { bundleMDX } from 'mdx-bundler'
export type DocHeading = { level: 1 | 2 | 3; title: string }
export const Doc = defineDocumentType(() => ({
name: 'Doc',
filePathPattern: `docs/**/*.mdx`,
contentType: 'mdx',
fields: {
title: {
type: 'string',
description: 'The title of the page',
required: true,
},
},
computedFields: {
headings: {
type: 'json',
resolve: async (doc) => {
const headings: DocHeading[] = []
await bundleMDX({
source: doc.body.raw,
xdmOptions: (opts) => {
opts.remarkPlugins = [...(opts.remarkPlugins ?? []), tocPlugin(headings)]
return opts
},
})
return [{ level: 1, title: doc.title }, ...headings]
},
},
},
}))
const tocPlugin =
(headings: DocHeading[]): unified.Plugin =>
() => {
return (node: any) => {
node.children
.filter((_: any) => _.type === 'heading')
.forEach((heading: any) => {
const title = toMarkdown({ type: 'paragraph', children: heading.children }, { extensions: [mdxToMarkdown()] })
.trim()
// removes MDX in headlines
.replace(/<.*$/g, '')
.trim()
return headings.push({ level: heading.depth, title })
})
}
} This is definitely not an ideal solution and should be improved further. One approach could be to make this an "out of the box" feature of Contentlayer. |
A more elegant foundation for this feature could be #216. |
I think it'd be great if the TOC would be available separately, and not as a part of the body. This is a current limitation of Remark-toc, which doesn't work when you want the TOC to be rendered outside of content. I've made a custom solution for this, but would be great if it was built-in into Contentlayer. |
My first approach would be to try to use computed fields for this.
Related
The text was updated successfully, but these errors were encountered: