11/**
2- * @typedef {import('mdast ').Literal } Literal
3- * @typedef { import('mdast').Parent } Parent
2+ * @typedef {import('estree-jsx ').Program } Program
3+ *
44 * @typedef {import('mdast-util-from-markdown').CompileContext } CompileContext
55 * @typedef {import('mdast-util-from-markdown').Extension } FromMarkdownExtension
66 * @typedef {import('mdast-util-from-markdown').Handle } FromMarkdownHandle
77 * @typedef {import('mdast-util-from-markdown').Token } Token
88 * @typedef {import('mdast-util-from-markdown').OnEnterError } OnEnterError
99 * @typedef {import('mdast-util-from-markdown').OnExitError } OnExitError
10+ *
1011 * @typedef {import('mdast-util-to-markdown').Options } ToMarkdownExtension
1112 * @typedef {import('mdast-util-to-markdown').Handle } ToMarkdownHandle
1213 * @typedef {import('mdast-util-to-markdown').Map } ToMarkdownMap
13- * @typedef { import('estree-jsx').Program } Program
14+ *
1415 * @typedef {import('./complex-types.js').MdxJsxAttributeValueExpression } MdxJsxAttributeValueExpression
1516 * @typedef {import('./complex-types.js').MdxJsxAttribute } MdxJsxAttribute
1617 * @typedef {import('./complex-types.js').MdxJsxExpressionAttribute } MdxJsxExpressionAttribute
1718 * @typedef {import('./complex-types.js').MdxJsxFlowElement } MdxJsxFlowElement
1819 * @typedef {import('./complex-types.js').MdxJsxTextElement } MdxJsxTextElement
19- * @typedef {{name: string|null, attributes: (MdxJsxAttribute|MdxJsxExpressionAttribute)[], close?: boolean, selfClosing?: boolean, start: Token['start'], end: Token['start']} } Tag
20+ */
21+
22+ /**
23+ * @typedef Tag
24+ * Single tag.
25+ * @property {string | undefined } name
26+ * Name of tag, or `undefined` for fragment.
27+ *
28+ * > 👉 **Note**: `null` is used in the AST for fragments, as it serializes in
29+ * > JSON.
30+ * @property {Array<MdxJsxAttribute | MdxJsxExpressionAttribute> } attributes
31+ * Attributes.
32+ * @property {boolean } close
33+ * Whether the tag is closing (`</x>`).
34+ * @property {boolean } selfClosing
35+ * Whether the tag is self-closing (`<x/>`).
36+ * @property {Token['start'] } start
37+ * Start point.
38+ * @property {Token['start'] } end
39+ * End point.
2040 *
2141 * @typedef ToMarkdownOptions
22- * @property {'"'|"'" } [quote='"']
42+ * Configuration.
43+ * @property {'"' | "'" | null | undefined } [quote='"']
2344 * Preferred quote to use around attribute values.
24- * @property {boolean } [quoteSmart=false]
45+ * @property {boolean | null | undefined } [quoteSmart=false]
2546 * Use the other quote if that results in less bytes.
26- * @property {boolean } [tightSelfClosing=false]
47+ * @property {boolean | null | undefined } [tightSelfClosing=false]
2748 * Do not use an extra space when closing self-closing elements: `<img/>`
2849 * instead of `<img />`.
29- * @property {number } [printWidth=Infinity]
50+ * @property {number | null | undefined } [printWidth=Infinity]
3051 * Specify the line length that the printer will wrap on.
3152 * This is not a hard maximum width: things will be printed longer and
3253 * shorter.
@@ -45,7 +66,17 @@ import {containerPhrasing} from 'mdast-util-to-markdown/lib/util/container-phras
4566import { indentLines } from 'mdast-util-to-markdown/lib/util/indent-lines.js'
4667import { track } from 'mdast-util-to-markdown/lib/util/track.js'
4768
48- /** @return {FromMarkdownExtension } */
69+ // To do: next major: use `state`, use utilities from state, rename `safeOptions` to `info`.
70+
71+ /**
72+ * Create an extension for `mdast-util-from-markdown` to enable MDX JSX.
73+ *
74+ * @returns {FromMarkdownExtension }
75+ * Extension for `mdast-util-from-markdown` to enable MDX JSX.
76+ *
77+ * When using the syntax extension with `addResult`, nodes will have a
78+ * `data.estree` field set to an ESTree `Program` node.
79+ */
4980export function mdxJsxFromMarkdown ( ) {
5081 return {
5182 canContainEols : [ 'mdxJsxTextElement' ] ,
@@ -124,7 +155,14 @@ export function mdxJsxFromMarkdown() {
124155 */
125156 function enterMdxJsxTag ( token ) {
126157 /** @type {Tag } */
127- const tag = { name : null , attributes : [ ] , start : token . start , end : token . end }
158+ const tag = {
159+ name : undefined ,
160+ attributes : [ ] ,
161+ close : false ,
162+ selfClosing : false ,
163+ start : token . start ,
164+ end : token . end
165+ }
128166 // @ts -expect-error: to do: register.
129167 if ( ! this . getData ( 'mdxJsxTagStack' ) ) this . setData ( 'mdxJsxTagStack' , [ ] )
130168 // @ts -expect-error: to do: register.
@@ -138,7 +176,7 @@ export function mdxJsxFromMarkdown() {
138176 */
139177 function enterMdxJsxTagClosingMarker ( token ) {
140178 // @ts -expect-error: to do: register.
141- const stack = /** @type {Tag[] } */ ( this . getData ( 'mdxJsxTagStack' ) )
179+ const stack = /** @type {Array< Tag> } */ ( this . getData ( 'mdxJsxTagStack' ) )
142180
143181 if ( stack . length === 0 ) {
144182 throw new VFileMessage (
@@ -256,7 +294,7 @@ export function mdxJsxFromMarkdown() {
256294 const tail = /** @type {MdxJsxExpressionAttribute } */ (
257295 tag . attributes [ tag . attributes . length - 1 ]
258296 )
259- /** @type {Program| undefined } */
297+ /** @type {Program | undefined } */
260298 // @ts -expect-error: custom.
261299 const estree = token . estree
262300
@@ -318,7 +356,7 @@ export function mdxJsxFromMarkdown() {
318356 )
319357 /** @type {MdxJsxAttributeValueExpression } */
320358 const node = { type : 'mdxJsxAttributeValueExpression' , value : this . resume ( ) }
321- /** @type {Program| undefined } */
359+ /** @type {Program | undefined } */
322360 // @ts -expect-error: custom.
323361 const estree = token . estree
324362
@@ -348,7 +386,7 @@ export function mdxJsxFromMarkdown() {
348386 // @ts -expect-error: to do: register.
349387 const tag = /** @type {Tag } */ ( this . getData ( 'mdxJsxTag' ) )
350388 // @ts -expect-error: to do: register.
351- const stack = /** @type {Tag[] } */ ( this . getData ( 'mdxJsxTagStack' ) )
389+ const stack = /** @type {Array< Tag> } */ ( this . getData ( 'mdxJsxTagStack' ) )
352390 const tail = stack [ stack . length - 1 ]
353391
354392 if ( tag . close && tail . name !== tag . name ) {
@@ -377,7 +415,7 @@ export function mdxJsxFromMarkdown() {
377415 token . type === 'mdxJsxTextTag'
378416 ? 'mdxJsxTextElement'
379417 : 'mdxJsxFlowElement' ,
380- name : tag . name ,
418+ name : tag . name || null ,
381419 attributes : tag . attributes ,
382420 children : [ ]
383421 } ,
@@ -454,17 +492,19 @@ export function mdxJsxFromMarkdown() {
454492}
455493
456494/**
457- * @param {ToMarkdownOptions } [options={}]
458- * Configuration (optional).
495+ * Create an extension for `mdast-util-to-markdown` to enable MDX JSX.
496+ *
497+ * @param {ToMarkdownOptions | null | undefined } [options]
498+ * Configuration.
459499 * @returns {ToMarkdownExtension }
500+ * Extension for `mdast-util-to-markdown` to enable MDX JSX.
460501 */
461- export function mdxJsxToMarkdown ( options = { } ) {
462- const {
463- quote = '"' ,
464- quoteSmart,
465- tightSelfClosing,
466- printWidth = Number . POSITIVE_INFINITY
467- } = options
502+ export function mdxJsxToMarkdown ( options ) {
503+ const options_ = options || { }
504+ const quote = options_ . quote || '"'
505+ const quoteSmart = options_ . quoteSmart || false
506+ const tightSelfClosing = options_ . tightSelfClosing || false
507+ const printWidth = options_ . printWidth || Number . POSITIVE_INFINITY
468508 const alternative = quote === '"' ? "'" : '"'
469509
470510 if ( quote !== '"' && quote !== "'" ) {
@@ -486,13 +526,15 @@ export function mdxJsxToMarkdown(options = {}) {
486526 { character : '<' , inConstruct : [ 'phrasing' ] } ,
487527 { atBreak : true , character : '<' }
488528 ] ,
529+ // Always generate fenced code (never indented code).
489530 fences : true ,
531+ // Always generate links with resources (never autolinks).
490532 resourceLink : true
491533 }
492534
493535 /**
494536 * @type {ToMarkdownHandle }
495- * @param {MdxJsxFlowElement| MdxJsxTextElement } node
537+ * @param {MdxJsxFlowElement | MdxJsxTextElement } node
496538 */
497539 // eslint-disable-next-line complexity
498540 function mdxElement ( node , _ , context , safeOptions ) {
0 commit comments