# mdast-util-mdx-jsx [![Build][build-badge]][build] [![Coverage][coverage-badge]][coverage] [![Downloads][downloads-badge]][downloads] [![Size][size-badge]][size] [![Sponsors][sponsors-badge]][collective] [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat] Extension for [`mdast-util-from-markdown`][from-markdown] and/or [`mdast-util-to-markdown`][to-markdown] to support MDX (or MDX.js) JSX. When parsing (`from-markdown`), must be combined with [`micromark-extension-mdx-jsx`][extension]. This utility handles parsing and serializing. See [`micromark-extension-mdx-jsx`][extension] for how the syntax works. You probably should use either [`micromark-extension-mdx`][mdx] or [`micromark-extension-mdxjs`][mdxjs] with [`mdast-util-mdx`][mdast-util-mdx] (which both include this package) to support all of MDX (or MDX.js). Or use it all through [`remark-mdx`][remark-mdx] (**[remark][]**). ## Install [npm][]: ```sh npm install mdast-util-mdx-jsx ``` ## Use Say we have an MDX.js file, `example.mdx`: ```mdx - a list HTML is a lovely language. ``` And our script, `example.js`, looks as follows: ```js var fs = require('fs') var acorn = require('acorn') var syntax = require('micromark-extension-mdx-jsx') var fromMarkdown = require('mdast-util-from-markdown') var toMarkdown = require('mdast-util-to-markdown') var mdxJsx = require('mdast-util-mdx-jsx') var doc = fs.readFileSync('example.mdx') var tree = fromMarkdown(doc, { extensions: [syntax({acorn: acorn, addResult: true})], mdastExtensions: [mdxJsx.fromMarkdown] }) console.log(tree) var out = toMarkdown(tree, {extensions: [mdxJsx.toMarkdown]}) console.log(out) ``` Now, running `node example` yields (positional info removed for brevity): ```js { 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.'} ] } ] } ``` ```markdown * a list HTML is a lovely language. ``` ## API ### `mdxJsx.fromMarkdown` ### `mdxJsx.toMarkdown` > Note: the separate extensions are also available at > `mdast-util-mdx-jsx/from-markdown` and > `mdast-util-mdx-jsx/to-markdown`. Support MDX (or MDX.js) JSX. The exports are extensions, respectively for [`mdast-util-from-markdown`][from-markdown] and [`mdast-util-to-markdown`][to-markdown]. When using the [syntax extension][extension] with `addResult`, nodes will have a `data.estree` field set to an [ESTree][]. There are no options, but passing [`options.quote`][quote] to `mdast-util-to-markdown` is honored for attributes. this extension configures [`mdast-util-to-markdown`][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` ```idl interface MDXJsxFlowElement <: Parent { type: "mdxJsxFlowElement" } MDXJsxFlowElement includes MDXJsxElement ``` **MDXJsxFlowElement** (**[Parent][dfn-parent]**) represents JSX in flow (block). It can be used where **[flow][dfn-content-flow]** content is expected. It includes the mixin **[MDXJsxElement][dfn-mixin-mdx-jsx-element]**. For example, the following markdown: ```markdown z ``` Yields: ```js { type: 'mdxJsxFlowElement', name: 'w', attributes: [{type: 'mdxJsxAttribute', name: 'x', value: 'y'}], children: [{type: 'paragraph', children: [{type: 'text', value: 'z'}]}] } ``` #### `MDXJsxTextElement` ```idl interface MDXJsxTextElement <: Parent { type: "mdxJsxTextElement" } MDXJsxTextElement includes MDXJsxElement ``` **MDXJsxTextElement** (**[Parent][dfn-parent]**) represents JSX in text (span, inline). It can be used where **[phrasing][dfn-content-phrasing]** content is expected. It includes the mixin **[MDXJsxElement][dfn-mixin-mdx-jsx-element]**. For example, the following markdown: ```markdown a d e. ``` Yields: ```js { type: 'mdxJsxTextElement', name: 'b', attributes: [{type: 'mdxJsxAttribute', name: 'c', value: null}], children: [{type: 'text', value: 'd'}] } ``` ### Mixin ### `MDXJsxElement` ```idl 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) ```idl type MDXJsxFlowContent = MDXJsxFlowElement | FlowContent ``` #### `PhrasingContent` (MDX JSX) ```idl type MDXJsxPhrasingContent = MDXJsxTextElement | PhrasingContent ``` ## Related * [`remarkjs/remark`][remark] — markdown processor powered by plugins * [`remarkjs/remark-mdx`][remark-mdx] — remark plugin to support MDX * [`syntax-tree/mdast-util-from-markdown`][from-markdown] — mdast parser using `micromark` to create mdast from markdown * [`syntax-tree/mdast-util-to-markdown`][to-markdown] — mdast serializer to create markdown from mdast * [`syntax-tree/mdast-util-mdx`][mdast-util-mdx] — mdast utility to support all of MDX * [`micromark/micromark`][micromark] — the smallest commonmark-compliant markdown parser that exists * [`micromark/micromark-extension-mdx-jsx`][extension] — micromark extension to parse JSX ## Contribute See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get started. See [`support.md`][support] for ways to get help. This project has a [code of conduct][coc]. By interacting with this repository, organization, or community you agree to abide by its terms. ## License [MIT][license] © [Titus Wormer][author] [build-badge]: https://github.com/syntax-tree/mdast-util-mdx-jsx/workflows/main/badge.svg [build]: https://github.com/syntax-tree/mdast-util-mdx-jsx/actions [coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/mdast-util-mdx-jsx.svg [coverage]: https://codecov.io/github/syntax-tree/mdast-util-mdx-jsx [downloads-badge]: https://img.shields.io/npm/dm/mdast-util-mdx-jsx.svg [downloads]: https://www.npmjs.com/package/mdast-util-mdx-jsx [size-badge]: https://img.shields.io/bundlephobia/minzip/mdast-util-mdx-jsx.svg [size]: https://bundlephobia.com/result?p=mdast-util-mdx-jsx [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg [backers-badge]: https://opencollective.com/unified/backers/badge.svg [collective]: https://opencollective.com/unified [chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg [chat]: https://github.com/syntax-tree/unist/discussions [npm]: https://docs.npmjs.com/cli/install [license]: license [author]: https://wooorm.com [contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md [support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md [coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md [mdast]: https://github.com/syntax-tree/mdast [remark]: https://github.com/remarkjs/remark [from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown [to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown [micromark]: https://github.com/micromark/micromark [extension]: https://github.com/micromark/micromark-extension-mdxjs-esm [mdx]: https://github.com/micromark/micromark-extension-mdx [mdxjs]: https://github.com/micromark/micromark-extension-mdxjs [mdast-util-mdx]: https://github.com/syntax-tree/mdast-util-mdx [quote]: https://github.com/syntax-tree/mdast-util-to-markdown#optionsquote [estree]: https://github.com/estree/estree [dfn-parent]: https://github.com/syntax-tree/mdast#parent [dfn-content-flow]: #flowcontent-mdx-jsx [dfn-content-phrasing]: #phrasingcontent-mdx-jsx [dfn-mixin-mdx-jsx-element]: #mdxjsxelement [remark-mdx]: https://github.com/mdx-js/mdx/tree/main/packages/remark-mdx