Open kettanaito opened 2 years ago
You can try a plugin for this: https://github.com/remcohaszing/remark-mdx-code-meta
From https://github.com/wooorm/xdm#syntax-highlighting-with-the-meta-field
import { visit } from 'unist-util-visit'
const re = /\b([-\w]+(?![^{]*}))(?:=(?:"([^"]*)"|'([^']*)'|([^"'\s]+)))?/g
export const rehypeMetaAttribute = (options = {}) => {
return (tree) => {
visit(tree, 'element', visitor)
}
function visitor(node, index, parentNode) {
let match
if (node.tagName === 'code' && node.data && node.data.meta) {
re.lastIndex = 0 // Reset regex.
while ((match = re.exec(node.data.meta))) {
parentNode.properties[match[1]] = match[2] || match[3] || match[4] || ''
}
}
}
}
Then in bundleMDX
pass the above as a plugin,
options.rehypePlugins = [
...(options.rehypePlugins ?? []),
rehypeMetaAttribute,
...
]
For the given markdown,
```js a=1 b=2
function foo() {}
you will get `a` and `b` as props
I'm also having this problem using v9.0.1
. @PsyGik the problem is that the "meta" field doesn't exist inside node
I only have this:
My 'index.mdx'
UI:
HTML output:
This is a problem with @mdx-js/esbuild
?
@allangrds I am on "mdx-bundler": "^9.0.1"
and it works for my projects. Mind sharing a min reproducible code of the issue that you are facing?
Hello @PsyGik, thanks for helping me. I'm creating a boilerplate using Next.js: https://github.com/allangrds/laxus-nextjs-blog/pull/5 - you just need to run npm install and npm run dev to run the project. You can access my repo and the actual code using this url, and cloning the repo.
I have the folling code there:
index.mdx
'''js filename="awesome.js"
var num1, num2, sum
num1 = prompt('Enter first number')
num2 = prompt('Enter second number')
sum = parseInt(num1) + parseInt(num2) // "+" means "add"
alert('Sum = ' + sum) // "+" means combine into a string "+" means combine into a string "+" means combine into a string
'''
api.ts
which generate the post detail content:
export const getPostDetail = async (slug: string) => {
const post = getPostBySlug(slug)
const categories = getCategoriesFromPosts()
const tags = getTagsFromPosts()
const toc = []
const { code, frontmatter } = await bundleMDX({
source: post?.content,
cwd: path.join(root),
mdxOptions (options) {
options.remarkPlugins = [
...(options.remarkPlugins ?? []),
remarkPrism,
remarkCodeTitles,
[remarkTocHeadings, { exportRef: toc }],
]
options.rehypePlugins = [
...(options.rehypePlugins ?? []),
rehypeSlug,
rehypeAutolinkHeadings,
]
return options
},
})
return {
categories,
post: {
content: code,
frontmatter: post?.frontmatter,
toc,
},
tags,
}
}
The content from the function remarkCodeTitles
export default function remarkCodeTitles (options) {
return (tree) => visit(tree, 'element', (node, index, parent) => {
if (node.tagName === 'code') {
console.log(node)
console.log('----')
}
if (node.tagName === 'code' && node.data && node.data.meta) {
node.properties.meta = node.data.meta
console.log({ data: node.data })
}
})
}
I know I'm doing nothing on this function, I'm trying to access the custom props from remarkCodeTitles
.
{
type: 'element',
tagName: 'code',
data: {
hName: 'code',
hProperties: { className: 'language-js' },
hChildren: [
[Object], [Object], [Object], [Object],
...rest of unused props
Thank you for the code samples @allangrds. Couple of things to note here:
'''
(quotes) instead of ```
(backticks) to render a code block.I've created a bare-bones sample repo here. https://github.com/PsyGik/mdx-bundler-nextjs/tree/main.
Follow the usual steps, npm install && npm run dev
and navigate to localhost:3000/hello
. In your terminal, you should see the logs which prints the meta values.
❯ npm run dev
> dev
> next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - compiled client and server successfully in 382 ms (178 modules)
wait - compiling...
event - compiled client and server successfully in 91 ms (178 modules)
wait - compiling /hello (client and server)...
event - compiled client and server successfully in 159 ms (193 modules)
node.data.meta title='code.js'
node.data.meta filename="awesome.js"
Thanks a lot @PsyGik. I'm using '''
only here, to create this comments, but as you can see here(https://user-images.githubusercontent.com/4103305/184169786-1283655e-7b70-434d-9bc3-df93a9d84c4b.png), I'm using backticks correctly. Thanks a lot for you pacience.
Checking you code and mine, I've noticed that 'remark-prismjs' was removing meta, so I've changed to rehypePrism
and it's all good now :)
mdx-bundler
version: 7.0.0node
version: 14.18.1npm
version: 6.14.15Relevant code or config
Here's how I handle an MDX file with
mdx-bundler
:Here's how I define the React component:
What you did:
Here's my MDX file that's not parsing correctly:
I wish for the
a
andb
props given to the code block to be exposed underprops
when writing custom components object for thegetMDXComponent
.What happened:
The
props
of thecode
component do not have thea
andb
keys. I've noticed that onlyclassName
andchildren
props are passed to thecode
component (may be that only the HTML props are supported).Suggested solution:
I believe the issue lies somewhere in MDX parsing, which is likely to be done by a different library (
xdm
). Still, this is where it's surfaced for me, I think it's nice to keep track of it in this repository for posterity (we may create an issue inxdm
if necessary).