1
1
/**
2
- * @typedef {import('mdast ').Literal } Literal
3
- * @typedef { import('mdast').Parent } Parent
2
+ * @typedef {import('estree-jsx ').Program } Program
3
+ *
4
4
* @typedef {import('mdast-util-from-markdown').CompileContext } CompileContext
5
5
* @typedef {import('mdast-util-from-markdown').Extension } FromMarkdownExtension
6
6
* @typedef {import('mdast-util-from-markdown').Handle } FromMarkdownHandle
7
7
* @typedef {import('mdast-util-from-markdown').Token } Token
8
8
* @typedef {import('mdast-util-from-markdown').OnEnterError } OnEnterError
9
9
* @typedef {import('mdast-util-from-markdown').OnExitError } OnExitError
10
+ *
10
11
* @typedef {import('mdast-util-to-markdown').Options } ToMarkdownExtension
11
12
* @typedef {import('mdast-util-to-markdown').Handle } ToMarkdownHandle
12
13
* @typedef {import('mdast-util-to-markdown').Map } ToMarkdownMap
13
- * @typedef { import('estree-jsx').Program } Program
14
+ *
14
15
* @typedef {import('./complex-types.js').MdxJsxAttributeValueExpression } MdxJsxAttributeValueExpression
15
16
* @typedef {import('./complex-types.js').MdxJsxAttribute } MdxJsxAttribute
16
17
* @typedef {import('./complex-types.js').MdxJsxExpressionAttribute } MdxJsxExpressionAttribute
17
18
* @typedef {import('./complex-types.js').MdxJsxFlowElement } MdxJsxFlowElement
18
19
* @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.
20
40
*
21
41
* @typedef ToMarkdownOptions
22
- * @property {'"'|"'" } [quote='"']
42
+ * Configuration.
43
+ * @property {'"' | "'" | null | undefined } [quote='"']
23
44
* Preferred quote to use around attribute values.
24
- * @property {boolean } [quoteSmart=false]
45
+ * @property {boolean | null | undefined } [quoteSmart=false]
25
46
* Use the other quote if that results in less bytes.
26
- * @property {boolean } [tightSelfClosing=false]
47
+ * @property {boolean | null | undefined } [tightSelfClosing=false]
27
48
* Do not use an extra space when closing self-closing elements: `<img/>`
28
49
* instead of `<img />`.
29
- * @property {number } [printWidth=Infinity]
50
+ * @property {number | null | undefined } [printWidth=Infinity]
30
51
* Specify the line length that the printer will wrap on.
31
52
* This is not a hard maximum width: things will be printed longer and
32
53
* shorter.
@@ -45,7 +66,17 @@ import {containerPhrasing} from 'mdast-util-to-markdown/lib/util/container-phras
45
66
import { indentLines } from 'mdast-util-to-markdown/lib/util/indent-lines.js'
46
67
import { track } from 'mdast-util-to-markdown/lib/util/track.js'
47
68
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
+ */
49
80
export function mdxJsxFromMarkdown ( ) {
50
81
return {
51
82
canContainEols : [ 'mdxJsxTextElement' ] ,
@@ -124,7 +155,14 @@ export function mdxJsxFromMarkdown() {
124
155
*/
125
156
function enterMdxJsxTag ( token ) {
126
157
/** @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
+ }
128
166
// @ts -expect-error: to do: register.
129
167
if ( ! this . getData ( 'mdxJsxTagStack' ) ) this . setData ( 'mdxJsxTagStack' , [ ] )
130
168
// @ts -expect-error: to do: register.
@@ -138,7 +176,7 @@ export function mdxJsxFromMarkdown() {
138
176
*/
139
177
function enterMdxJsxTagClosingMarker ( token ) {
140
178
// @ts -expect-error: to do: register.
141
- const stack = /** @type {Tag[] } */ ( this . getData ( 'mdxJsxTagStack' ) )
179
+ const stack = /** @type {Array< Tag> } */ ( this . getData ( 'mdxJsxTagStack' ) )
142
180
143
181
if ( stack . length === 0 ) {
144
182
throw new VFileMessage (
@@ -256,7 +294,7 @@ export function mdxJsxFromMarkdown() {
256
294
const tail = /** @type {MdxJsxExpressionAttribute } */ (
257
295
tag . attributes [ tag . attributes . length - 1 ]
258
296
)
259
- /** @type {Program| undefined } */
297
+ /** @type {Program | undefined } */
260
298
// @ts -expect-error: custom.
261
299
const estree = token . estree
262
300
@@ -318,7 +356,7 @@ export function mdxJsxFromMarkdown() {
318
356
)
319
357
/** @type {MdxJsxAttributeValueExpression } */
320
358
const node = { type : 'mdxJsxAttributeValueExpression' , value : this . resume ( ) }
321
- /** @type {Program| undefined } */
359
+ /** @type {Program | undefined } */
322
360
// @ts -expect-error: custom.
323
361
const estree = token . estree
324
362
@@ -348,7 +386,7 @@ export function mdxJsxFromMarkdown() {
348
386
// @ts -expect-error: to do: register.
349
387
const tag = /** @type {Tag } */ ( this . getData ( 'mdxJsxTag' ) )
350
388
// @ts -expect-error: to do: register.
351
- const stack = /** @type {Tag[] } */ ( this . getData ( 'mdxJsxTagStack' ) )
389
+ const stack = /** @type {Array< Tag> } */ ( this . getData ( 'mdxJsxTagStack' ) )
352
390
const tail = stack [ stack . length - 1 ]
353
391
354
392
if ( tag . close && tail . name !== tag . name ) {
@@ -377,7 +415,7 @@ export function mdxJsxFromMarkdown() {
377
415
token . type === 'mdxJsxTextTag'
378
416
? 'mdxJsxTextElement'
379
417
: 'mdxJsxFlowElement' ,
380
- name : tag . name ,
418
+ name : tag . name || null ,
381
419
attributes : tag . attributes ,
382
420
children : [ ]
383
421
} ,
@@ -454,17 +492,19 @@ export function mdxJsxFromMarkdown() {
454
492
}
455
493
456
494
/**
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.
459
499
* @returns {ToMarkdownExtension }
500
+ * Extension for `mdast-util-to-markdown` to enable MDX JSX.
460
501
*/
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
468
508
const alternative = quote === '"' ? "'" : '"'
469
509
470
510
if ( quote !== '"' && quote !== "'" ) {
@@ -486,13 +526,15 @@ export function mdxJsxToMarkdown(options = {}) {
486
526
{ character : '<' , inConstruct : [ 'phrasing' ] } ,
487
527
{ atBreak : true , character : '<' }
488
528
] ,
529
+ // Always generate fenced code (never indented code).
489
530
fences : true ,
531
+ // Always generate links with resources (never autolinks).
490
532
resourceLink : true
491
533
}
492
534
493
535
/**
494
536
* @type {ToMarkdownHandle }
495
- * @param {MdxJsxFlowElement| MdxJsxTextElement } node
537
+ * @param {MdxJsxFlowElement | MdxJsxTextElement } node
496
538
*/
497
539
// eslint-disable-next-line complexity
498
540
function mdxElement ( node , _ , context , safeOptions ) {
0 commit comments