Skip to content

Commit a52362b

Browse files
committed
Add support for MDX@2 comment expressions
Related-to: remarkjs/remark-message-control#9.
1 parent 15d8c6b commit a52362b

File tree

3 files changed

+79
-24
lines changed

3 files changed

+79
-24
lines changed

index.js

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
/**
22
* @typedef {string|number|boolean} MarkerParameterValue
3+
* @typedef {import('mdast').Root} Root
4+
* @typedef {import('mdast').Content} Content
5+
* @typedef {import('mdast').HTML} HTML
6+
* @typedef {import('mdast-util-mdx-expression').MDXFlowExpression} MDXFlowExpression
7+
* @typedef {import('mdast-util-mdx-expression').MDXTextExpression} MDXTextExpression
8+
* @typedef {Root|Content} Node
39
* @typedef {Object.<string, MarkerParameterValue>} MarkerParameters
410
*
5-
* @typedef HtmlNode
6-
* @property {'html'} type
7-
* @property {string} value
8-
*
9-
* @typedef CommentNode
11+
* @typedef Mdx1CommentNode
1012
* @property {'comment'} type
1113
* @property {string} value
1214
*
1315
* @typedef Marker
1416
* @property {string} name
1517
* @property {string} attributes
1618
* @property {MarkerParameters|null} parameters
17-
* @property {HtmlNode|CommentNode} node
19+
* @property {HTML|Mdx1CommentNode|MDXFlowExpression|MDXTextExpression} node
1820
*/
1921

2022
const commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/
21-
23+
const esCommentExpression = new RegExp(
24+
'(\\s*\\/\\*' + commentExpression.source + '\\*\\/\\s*)'
25+
)
2226
const markerExpression = new RegExp(
2327
'(\\s*<!--' + commentExpression.source + '-->\\s*)'
2428
)
@@ -29,19 +33,39 @@ const markerExpression = new RegExp(
2933
* @returns {Marker|null}
3034
*/
3135
export function commentMarker(value) {
32-
if (applicable(value)) {
33-
const match = value.value.match(
34-
value.type === 'comment' ? commentExpression : markerExpression
35-
)
36+
if (
37+
isNode(value) &&
38+
(value.type === 'html' ||
39+
// @ts-expect-error: MDX@1
40+
value.type === 'comment' ||
41+
value.type === 'mdxFlowExpression' ||
42+
value.type === 'mdxTextExpression')
43+
) {
44+
let offset = 2
45+
/** @type {RegExpMatchArray|null|undefined} */
46+
let match
47+
48+
// @ts-expect-error: MDX@1
49+
if (value.type === 'comment') {
50+
// @ts-expect-error: MDX@1
51+
match = value.value.match(commentExpression)
52+
offset = 1
53+
} else if (value.type === 'html') {
54+
match = value.value.match(markerExpression)
55+
} else if (
56+
value.type === 'mdxFlowExpression' ||
57+
value.type === 'mdxTextExpression'
58+
) {
59+
match = value.value.match(esCommentExpression)
60+
}
3661

3762
if (match && match[0].length === value.value.length) {
38-
const offset = value.type === 'comment' ? 1 : 2
3963
const parameters = parseParameters(match[offset + 1] || '')
4064

4165
if (parameters) {
4266
return {
4367
name: match[offset],
44-
attributes: match[offset + 2] || '',
68+
attributes: (match[offset + 2] || '').trim(),
4569
parameters,
4670
node: value
4771
}
@@ -99,14 +123,8 @@ function parseParameters(value) {
99123

100124
/**
101125
* @param {unknown} value
102-
* @returns {value is HtmlNode | CommentNode}
126+
* @returns {value is Node}
103127
*/
104-
function applicable(value) {
105-
return Boolean(
106-
value &&
107-
typeof value === 'object' &&
108-
'type' in value &&
109-
// @ts-expect-error hush
110-
(value.type === 'html' || value.type === 'comment')
111-
)
128+
function isNode(value) {
129+
return Boolean(value && typeof value === 'object' && 'type' in value)
112130
}

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"index.js"
3333
],
3434
"devDependencies": {
35-
"@types/mdast": "^3.0.0",
35+
"@types/mdast": "^3.0.10",
3636
"@types/tape": "^4.0.0",
3737
"c8": "^7.0.0",
3838
"prettier": "^2.0.0",
@@ -61,7 +61,10 @@
6161
"trailingComma": "none"
6262
},
6363
"xo": {
64-
"prettier": true
64+
"prettier": true,
65+
"rules": {
66+
"unicorn/prefer-switch": "off"
67+
}
6568
},
6669
"remarkConfig": {
6770
"plugins": [
@@ -72,5 +75,8 @@
7275
"atLeast": 100,
7376
"detail": true,
7477
"strict": true
78+
},
79+
"dependencies": {
80+
"mdast-util-mdx-expression": "^1.1.0"
7581
}
7682
}

test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* @typedef {import('mdast').Literal} Literal
33
* @typedef {import('mdast').Paragraph} Paragraph
44
* @typedef {import('mdast').HTML} HTML
5+
* @typedef {import('mdast-util-mdx-expression').MDXFlowExpression} MDXFlowExpression
6+
* @typedef {import('mdast-util-mdx-expression').MDXTextExpression} MDXTextExpression
57
*/
68

79
import test from 'tape'
@@ -280,3 +282,32 @@ test('comment node', (t) => {
280282

281283
t.end()
282284
})
285+
286+
test('MDX@2 expressions', (t) => {
287+
/** @type {MDXFlowExpression|MDXTextExpression} */
288+
let node = {
289+
type: 'mdxFlowExpression',
290+
value: '/* lint disable heading-style */'
291+
}
292+
293+
t.deepEqual(
294+
commentMarker(node),
295+
{
296+
name: 'lint',
297+
attributes: 'disable heading-style',
298+
parameters: {disable: true, 'heading-style': true},
299+
node
300+
},
301+
'should work for comments'
302+
)
303+
304+
node = {type: 'mdxTextExpression', value: '/* lint enable */'}
305+
306+
t.deepEqual(
307+
commentMarker(node),
308+
{name: 'lint', attributes: 'enable', parameters: {enable: true}, node},
309+
'should work for comments'
310+
)
311+
312+
t.end()
313+
})

0 commit comments

Comments
 (0)