# micromark-extension-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]
[micromark][] extension to support [MDX][mdxjs] JSX (`
a f
``` …which is useless: go to a syntax tree with [`mdast-util-from-markdown`][mdast-util-from-markdown] and [`mdast-util-mdx-jsx`][mdast-util-mdx-jsx] instead. ## API This package exports the identifier [`mdxJsx`][api-mdx-jsx]. There is no default export. The export map supports the [`development` condition][development]. Run `node --conditions development module.js` to get instrumented dev code. Without this condition, production code is loaded. ### `mdxJsx(options?)` Create an extension for `micromark` to enable MDX JSX syntax. ###### Parameters * `options` ([`Options`][api-options], optional) — configuration ###### Returns Extension for `micromark` that can be passed in `extensions` to enable MDX JSX syntax ([`Extension`][micromark-extension]). ### `Options` Configuration (TypeScript type). ###### Fields * `acorn` ([`Acorn`][acorn], optional) — acorn parser to use * `acornOptions` ([`AcornOptions`][acorn-options], default: `{ecmaVersion: 2020, locations: true, sourceType: 'module'}`) — configuration for acorn; all fields except `locations` can be set * `addResult` (`boolean`, default: `false`) — whether to add `estree` fields to tokens with results from acorn ## Authoring When authoring markdown with JSX, keep in mind that MDX is a whitespace sensitive and line-based language, while JavaScript is insensitive to whitespace. This affects how markdown and JSX interleave with eachother in MDX. For more info on how it works, see [§ Interleaving][mdxjs-interleaving] on the MDX site. ###### Comments inside tags JavaScript comments in JSX are not supported. Incorrect: ```jsxmdx_jsx_flow ::= mdx_jsx *space_or_tab [mdx_jsx *space_or_tab]
mdx_jsx_text ::= mdx_jsx
; constraint: markdown whitespace (`space_or_tab | eol`) is NOT
; allowed directly after `<` in order to allow `1 < 3` in markdown.
mdx_jsx ::=
'<' [closing]
[*whitespace name [attributes_after_identifier] [closing]]
*whitespace '>'
attributes_after_identifier ::=
1*whitespace (attributes_boolean | attributes_value) |
*whitespace attributes_expression |
attributes_after_value ::=
*whitespace (attributes_boolean | attributes_expression | attributes_value)
attributes_boolean ::= key [attributes_after_identifier]
; Note: in gnostic mode the value of the expression must instead be a single valid ES spread
; expression
attributes_expression ::= expression [attributes_after_value]
attributes_value ::= key initializer [attributes_after_value]
closing ::= *whitespace '/'
name ::= identifier [local | members]
key ::= identifier [local]
local ::= *whitespace ':' *whitespace identifier
members ::= member *member
member ::= *whitespace '.' *whitespace identifier
identifier ::= identifier_start *identifier_part
initializer ::= *whitespace '=' *whitespace value
value ::= double_quoted | single_quoted | expression
; Note: in gnostic mode the value must instead be a single valid ES expression
expression ::= '{' *(expression_text | expression) '}'
double_quoted ::= '"' *double_quoted_text '"'
single_quoted ::= "'" *single_quoted_text "'"
whitespace ::= es_whitespace
double_quoted_text ::= char - '"'
single_quoted_text ::= char - "'"
expression_text ::= char - '{' - '}'
identifier_start ::= es_identifier_start
identifier_part ::= es_identifier_part | '-'
space_or_tab ::= '\t' | ' '
eol ::= '\n' | '\r' | '\r\n'
; ECMAScript
; See “IdentifierStart”: <https://tc39.es/ecma262/#prod-IdentifierStart>
es_identifier_start ::= ?
; See “IdentifierPart”: <https://tc39.es/ecma262/#prod-IdentifierPart>
es_identifier_part ::= ?
; See “Whitespace”: <https://tc39.es/ecma262/#prod-WhiteSpace>
es_whitespace ::= ?
As the flow construct occurs in flow, like all flow constructs, it must be
followed by an eol (line ending) or eof (end of file).
The grammar for JSX in markdown is much stricter than that of HTML in
markdown.
The primary benefit of this is that tags are parsed into tokens, and thus
can be processed.
Another, arguable, benefit of this is that it comes with syntax errors: if
an author types something that is nonsensical, an error is thrown with
information about where it happened, what occurred, and what was expected
instead.
This extension supports expressions both aware and unaware to JavaScript
(respectively gnostic and agnostic).
Depending on whether acorn is passed, either valid JavaScript must be used in
expressions, or arbitrary text (such as Rust code or so) can be used.
More on this can be found in
[§ Syntax of `micromark-extension-mdx-expression`][expression-syntax].
## Errors
In aware (gnostic) mode, expressions are parsed with
[`micromark-extension-mdx-expression`][micromark-extension-mdx-expression],
which throws some more errors.
### Unexpected end of file $at, expected $expect
This error occurs for many different reasons if something was opened but not
closed (source: `micromark-extension-mdx-jsx`, rule id: `unexpected-eof`).
Some examples are:
```markdown
<
`)
* `mdxJsxTextTagAttributeValueLiteral` ^
* `mdxJsxFlowTagAttributeValueLiteralMarker` for the quotes around a string
attribute value (`"` or `'`)
* `mdxJsxTextTagAttributeValueLiteralMarker` ^
* `mdxJsxFlowTagAttributeValueLiteralValue` for chunks of what’s inside
string attribute values
* `mdxJsxTextTagAttributeValueLiteralValue` ^
* `mdxJsxFlowTagAttributeValueExpression` for an expression attribute value
(``)
* `mdxJsxTextTagAttributeValueExpression` ^
* `mdxJsxFlowTagAttributeValueExpressionMarker` for the `{` and `}` of
expression attribute values
* `mdxJsxTextTagAttributeValueExpressionMarker` ^
* `mdxJsxFlowTagAttributeValueExpressionValue` for chunks of what’s inside
expression attribute values
* `mdxJsxTextTagAttributeValueExpressionValue` ^
## Types
This package is fully typed with [TypeScript][].
It exports the additional type [`Options`][api-options].
## Compatibility
Projects maintained by the unified collective are compatible with all maintained
versions of Node.js.
As of now, that is Node.js 16+.
Our projects sometimes work with older versions, but this is not guaranteed.
These extensions work with `micromark` version 3+.
## Security
This package is safe.
## Related
* [`micromark-extension-mdxjs`][micromark-extension-mdxjs]
— support all MDX syntax
* [`mdast-util-mdx-jsx`][mdast-util-mdx-jsx]
— support MDX JSX in mdast
* [`remark-mdx`][remark-mdx]
— support all MDX syntax in remark
## Contribute
See [`contributing.md` in `micromark/.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/micromark/micromark-extension-mdx-jsx/workflows/main/badge.svg
[build]: https://github.com/micromark/micromark-extension-mdx-jsx/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/micromark/micromark-extension-mdx-jsx.svg
[coverage]: https://codecov.io/github/micromark/micromark-extension-mdx-jsx
[downloads-badge]: https://img.shields.io/npm/dm/micromark-extension-mdx-jsx.svg
[downloads]: https://www.npmjs.com/package/micromark-extension-mdx-jsx
[size-badge]: https://img.shields.io/bundlephobia/minzip/micromark-extension-mdx-jsx.svg
[size]: https://bundlephobia.com/result?p=micromark-extension-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/micromark/micromark/discussions
[npm]: https://docs.npmjs.com/cli/install
[esmsh]: https://esm.sh
[license]: license
[author]: https://wooorm.com
[contributing]: https://github.com/micromark/.github/blob/HEAD/contributing.md
[support]: https://github.com/micromark/.github/blob/HEAD/support.md
[coc]: https://github.com/micromark/.github/blob/HEAD/code-of-conduct.md
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[typescript]: https://www.typescriptlang.org
[development]: https://nodejs.org/api/packages.html#packages_resolving_user_conditions
[micromark]: https://github.com/micromark/micromark
[micromark-extension]: https://github.com/micromark/micromark#syntaxextension
[micromark-extension-mdxjs]: https://github.com/micromark/micromark-extension-mdxjs
[micromark-extension-mdx-expression]: https://github.com/micromark/micromark-extension-mdx-expression
[expression-syntax]: https://github.com/micromark/micromark-extension-mdx-expression/blob/main/packages/micromark-extension-mdx-expression/readme.md#syntax
[mdast-util-mdx-jsx]: https://github.com/syntax-tree/mdast-util-mdx-jsx
[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown
[remark-mdx]: https://mdxjs.com/packages/remark-mdx/
[mdxjs]: https://mdxjs.com
[mdxjs-interleaving]: https://mdxjs.com/docs/what-is-mdx/#interleaving
[acorn]: https://github.com/acornjs/acorn
[acorn-options]: https://github.com/acornjs/acorn/blob/96c721dbf89d0ccc3a8c7f39e69ef2a6a3c04dfa/acorn/dist/acorn.d.ts#L16
[api-mdx-jsx]: #mdxjsxoptions
[api-options]: #options