It appears that you can't currently use < or > characters in text.
For example, this markdown:
# Hello, MDX
I <3 Markdown and JSX
Produces this JSX:
export default ({components}) => <MDXTag name="wrapper"><MDXTag name="h1" components={components}>Hello, MDX</MDXTag>
<MDXTag name="p" components={components}> I <3 Markdown and JSX</MDXTag></MDXTag>
Which fails to compile in babel.
MDXC compiles this the following way:
export default function({ factories={} }) {
const {
h1 = createFactory('h1'),
p = createFactory('p'),
wrapper = createFactory('div'),
} = factories
return wrapper({},
h1({"id": "Hello-MDX"},
"Hello, MDX",
),
p({},
"I <3 Markdown and JSX",
)
)
}
Sounds like we have to escape them 馃槃
cc @johno
Added a failing test
Thanks for opening this issue!
Just opened a PR with an escaping fix. I wonder if going the factory route will be more resilient to these types of bugs? Though, JSX syntax only has a handful of gotchas so there prolly aren't too many escaping bugs that we need to flush out.
Thanks for fixing it!
I do think that factories are more resilient and have other advantages (e.g. smaller produced code size). Here's another one I just found where the produced code can't be compiled by babel:
# Hello, MDX
:-}
Produces:
export default ({components}) => <MDXTag name="wrapper"><MDXTag name="h1" components={components}>Hello, MDX</MDXTag>
<MDXTag name="p" components={components}> :-}</MDXTag></MDXTag>
Regarding curly braces, I feel like they should be automatically escaped when they're not inside a JSX block, so that {Hello} compiles to "{Hello}", but <span>{Hello}</span> compiles to React.createElement('span', null, Hello). My thinking here is that MDX may be used in publishing systems where the authors don't actually know JavaScript, and who will be confused when curly braces cause their document to crash their blogging/publishing tool.
I'm going to fix this once and for all in a bit 馃憤 We just need to turn text nodes into
{`CONTENT`}
And then escape backticks. Exactly the same as code/inlineCode works right now.
@jamesknelson so how mdx works:
Input:
import Foo from './foo'
# Hello world
<Foo />
The output is a javascript file like:
import Foo from './foo'
export default ({components}) => {
return <MDXTag name="root" components={components}>
<MDXTag name="h1" components={components} parentName="root">Hello world</MDXTag>
<Foo />
</MDXTag>
}
So in short we turn HTML nodes into JSX nodes, JSX nodes are not touched, but instead just pasted into the output without any transformations, same for import and export, the only difference with import/export is that they're applied outside of the function scope (import/export) doesn't work otherwise. The "bug" here is that we need to treat all text nodes the same way, instead of having an exception for code/inlinecode.
Most helpful comment
I'm going to fix this once and for all in a bit 馃憤 We just need to turn text nodes into
And then escape backticks. Exactly the same as
code/inlineCodeworks right now.