-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Description
docusaurus/packages/docusaurus-mdx-loader/src/index.js
Lines 24 to 58 in ae45b11
| module.exports = async function docusaurusMdxLoader(fileString) { | |
| const callback = this.async(); | |
| const {data, content} = matter(fileString); | |
| const reqOptions = getOptions(this) || {}; | |
| const options = { | |
| ...reqOptions, | |
| remarkPlugins: [ | |
| ...(reqOptions.beforeDefaultRemarkPlugins || []), | |
| ...DEFAULT_OPTIONS.remarkPlugins, | |
| [ | |
| transformImage, | |
| {staticDir: reqOptions.staticDir, filePath: this.resourcePath}, | |
| ], | |
| [ | |
| transformLinks, | |
| {staticDir: reqOptions.staticDir, filePath: this.resourcePath}, | |
| ], | |
| ...(reqOptions.remarkPlugins || []), | |
| ], | |
| rehypePlugins: [ | |
| ...(reqOptions.beforeDefaultRehypePlugins || []), | |
| ...DEFAULT_OPTIONS.rehypePlugins, | |
| ...(reqOptions.rehypePlugins || []), | |
| ], | |
| filepath: this.resourcePath, | |
| }; | |
| let result; | |
| try { | |
| result = await mdx(content, options); | |
| } catch (err) { | |
| return callback(err); | |
| } |
I am writing an plugin that adds the source file + line number to every heading element.
Below you can see that the frontmatter is being parsed and then only the remaining markdown content is passed onwards.
const {data, content} = matter(fileString);
// ...
result = await mdx(content, options);
This means that in a rehype plugin the vfile.history[].position.start.line will not be correct, it not take into account the frontmatter lines.
I think a better approach would be to parse the frontmatter using a remark plugin so to retain the original line numbers. Like this: https://www.npmjs.com/package/remark-extract-frontmatter
This should also be corrected on https://mdxjs.com/guides/custom-loader#custom-loader page I think.
Workaround
I could use grey matter to parse the gray matter again in my plugin but that means a lot of duplicate file read operations.
Remark
In remark plugins, I am just using the first comment to apply config.
<!-- {tocMaxDepth: 1, tocMaxDepth: 4} -->
# foo
const plugin = (options = {}) => {
const name = options.name || 'toc';
const transformer = (node) => {
const firstComment = node.children.find(node => node.type === 'comment')
let config = {}
if (firstComment) {
config = JSON.parse(firstComment.value)
}
// stuff...
}
}