mdast-util-mdx-jsx
Extension for mdast-util-from-markdown
and/or
mdast-util-to-markdown
to support MDX (or MDX.js) JSX.
When parsing (from-markdown
), must be combined with
micromark-extension-mdx-jsx
.
This utility handles parsing and serializing.
See micromark-extension-mdx-jsx
for how the syntax works.
When to use this
Use mdast-util-mdx
if you want all of MDX / MDX.js.
Use this otherwise.
Install
This package is ESM only:
Node 12+ is needed to use it and it must be import
ed instead of require
d.
npm:
npm install mdast-util-mdx-jsx
Use
Say we have an MDX.js file, example.mdx
:
<Box>
- a list
</Box>
<MyComponent {...props} />
<abbr title="Hypertext Markup Language">HTML</abbr> is a lovely language.
And our module, example.js
, looks as follows:
import fs from 'node:fs'
import * as acorn from 'acorn'
import {fromMarkdown} from 'mdast-util-from-markdown'
import {toMarkdown} from 'mdast-util-to-markdown'
import {mdxJsx} from 'micromark-extension-mdx-jsx'
import {mdxJsxFromMarkdown, mdxJsxToMarkdown} from 'mdast-util-mdx-jsx'
const doc = fs.readFileSync('example.mdx')
const tree = fromMarkdown(doc, {
extensions: [mdxJsx({acorn: acorn, addResult: true})],
mdastExtensions: [mdxJsxFromMarkdown]
})
console.log(tree)
const out = toMarkdown(tree, {extensions: [mdxJsxToMarkdown]})
console.log(out)
Now, running node example
yields (positional info removed for brevity):
{
type: 'root',
children: [
{
type: 'mdxJsxFlowElement',
name: 'Box',
attributes: [],
children: [
{
type: 'list',
ordered: false,
start: null,
spread: false,
children: [
{
type: 'listItem',
spread: false,
checked: null,
children: [
{type: 'paragraph', children: [{type: 'text', value: 'a list'}]}
]
}
]
}
]
},
{
type: 'mdxJsxFlowElement',
name: 'MyComponent',
attributes: [
{
type: 'mdxJsxExpressionAttribute',
value: '...props',
data: {
estree: {
type: 'Program',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'ObjectExpression',
properties: [
{
type: 'SpreadElement',
argument: {type: 'Identifier', name: 'props'}
}
]
}
}
],
sourceType: 'module'
}
}
}
],
children: []
},
{
type: 'paragraph',
children: [
{
type: 'mdxJsxTextElement',
name: 'abbr',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'title',
value: 'Hypertext Markup Language'
}
],
children: [{type: 'text', value: 'HTML'}]
},
{type: 'text', value: ' is a lovely language.'}
]
}
]
}
<Box>
* a list
</Box>
<MyComponent {...props}/>
<abbr title="Hypertext Markup Language">HTML</abbr> is a lovely language.
API
mdxJsxFromMarkdown
mdxJsxToMarkdown
Support MDX (or MDX.js) JSX.
The exports are extensions, respectively for
mdast-util-from-markdown
and
mdast-util-to-markdown
.
When using the syntax extension with addResult
, nodes will have a
data.estree
field set to an ESTree.
There are no options, but passing options.quote
to
mdast-util-to-markdown
is honored for attributes.
this extension configures mdast-util-to-markdown
with
fences: true
and resourceLink: true
too, do not overwrite them!
Syntax tree
The following interfaces are added to mdast by this utility.
Nodes
MDXJsxFlowElement
interface MDXJsxFlowElement <: Parent {
type: "mdxJsxFlowElement"
}
MDXJsxFlowElement includes MDXJsxElement
MDXJsxFlowElement (Parent) represents JSX in flow (block).
It can be used where flow content is expected.
It includes the mixin MDXJsxElement.
For example, the following markdown:
<w x="y">
z
</w>
Yields:
{
type: 'mdxJsxFlowElement',
name: 'w',
attributes: [{type: 'mdxJsxAttribute', name: 'x', value: 'y'}],
children: [{type: 'paragraph', children: [{type: 'text', value: 'z'}]}]
}
MDXJsxTextElement
interface MDXJsxTextElement <: Parent {
type: "mdxJsxTextElement"
}
MDXJsxTextElement includes MDXJsxElement
MDXJsxTextElement (Parent) represents JSX in text (span,
inline).
It can be used where phrasing content is
expected.
It includes the mixin MDXJsxElement.
For example, the following markdown:
a <b c>d</b> e.
Yields:
{
type: 'mdxJsxTextElement',
name: 'b',
attributes: [{type: 'mdxJsxAttribute', name: 'c', value: null}],
children: [{type: 'text', value: 'd'}]
}
Mixin
MDXJsxElement
interface mixin MDXJsxElement {
name: string?
attributes: [MDXJsxExpressionAttribute | MDXJsxAttribute]
}
interface MDXJsxExpressionAttribute <: Literal {
type: "mdxJsxExpressionAttribute"
}
interface MDXJsxAttribute <: Node {
type: "mdxJsxAttribute"
name: string
value: MDXJsxAttributeValueExpression | string?
}
interface MDXJsxAttributeValueExpression <: Literal {
type: "mdxJsxAttributeValueExpression"
}
MDXJsxElement represents a JSX element.
The name
field can be present and represents an identifier.
Without name
, the element represents a fragment, in which case no attributes
must be present.
The attributes
field represents information associated with the node.
The value of the attributes
field is a list of MDXJsxExpressionAttribute
and MDXJsxAttribute nodes.
MDXJsxExpressionAttribute represents an expression (typically in a
programming language) that when evaluated results in multiple attributes.
MDXJsxAttribute represents a single attribute.
The name
field must be present.
The value
field can be present, in which case it is either a string (a static
value) or an expression (typically in a programming language) that when
evaluated results in an attribute value.
Content model
FlowContent
(MDX JSX)
type MDXJsxFlowContent = MDXJsxFlowElement | FlowContent
PhrasingContent
(MDX JSX)
type MDXJsxPhrasingContent = MDXJsxTextElement | PhrasingContent
Related
Contribute
See contributing.md
in syntax-tree/.github
for ways to get
started.
See support.md
for ways to get help.
This project has a code of conduct.
By interacting with this repository, organization, or community you agree to
abide by its terms.
License
MIT © Titus Wormer