wooorm / xdm

Just a *really* good MDX compiler. No runtime. With esbuild, Rollup, and webpack plugins
http://wooorm.com/xdm/
MIT License
595 stars 18 forks source link

meta support #8

Closed chenxsan closed 3 years ago

chenxsan commented 3 years ago

There's a meta field defined in mdast https://github.com/syntax-tree/mdast#code with code below:

```js filename=index.js
const a = 5;
```

And it's available under mdx-js/mdx, you can check the playground https://mdxjs.com/playground:

image

However it doesn't seem available under xdm:

image

I'm wondering if there's any way I can get it under xdm?

wooorm commented 3 years ago

Good question.

I removed it here because a) it leaks <code ... metastring="..."> to HTML (an invalid attribute) if no component is set or a component is set that that passes props through, and b) the attribute parsing in mdx-js/mdx is not what folks expect, it splits on spaces and does not understand quotes (which in your case is fine but breaks on filename=index title="some title"). There has been some talk on using JSX attribute syntax there, but then why not write a whole JSX component instead?

I yesterday made sure that the property is passed from mdast through to hast (and the estrees used here) though (https://github.com/syntax-tree/mdast-util-to-hast/commit/c3397021866c90bfbefb3dc3c5668dded1613f13), so any remark/rehype/recma plugin can access it.

So this might be something for a plugin?

chenxsan commented 3 years ago

Thanks, it makes sense, I'll access the data with remark plugin.

wooorm commented 3 years ago

Wrote something about meta in the readme: https://github.com/wooorm/xdm#syntax-highlighting-with-the-meta-field

wooorm commented 3 years ago

Oh and here’s an idea, injecting a helper 🤔:

diff --git a/current.js b/idea.js
--- a/current.js
+++ b/idea.js
@@ -1,14 +1,23 @@
 /* @jsxRuntime automatic @jsxImportSource react */
 import {jsx as _jsx} from 'react/jsx-runtime'

+function _createCode(x) {
+  return (props) => {
+    if (typeof x === 'string')
+      props = Object.assign({}, props, {meta: undefined})
+    return _jsx(x, props)
+  }
+}

 function MDXContent(_props) {
   const _components = Object.assign(
     {pre: 'pre', code: 'code'},
     _props.components
   )
   const {wrapper: MDXLayout} = _components
+  const _code = _createCode(_components.code)
   const _content = _jsx(_components.pre, {
-    children: _jsx(_components.code, {className: 'language-js'})
+    children: _jsx(_code, {className: 'language-js', meta: 'things'})
   })
   return MDXLayout
     ? _jsx(MDXLayout, Object.assign({}, _props, {children: _content}))