Skip to content

Commit ba751fe

Browse files
committed
Add options.quote for attribute values
Related to: GH-3.
1 parent f73220a commit ba751fe

File tree

4 files changed

+64
-26
lines changed

4 files changed

+64
-26
lines changed

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* @typedef {import('./lib/index.js').MdxJsxExpressionAttribute} MdxJsxExpressionAttribute
55
* @typedef {import('./lib/index.js').MdxJsxFlowElement} MdxJsxFlowElement
66
* @typedef {import('./lib/index.js').MdxJsxTextElement} MdxJsxTextElement
7+
* @typedef {import('./lib/index.js').ToMarkdownOptions} ToMarkdownOptions
78
*/
89

910
export {mdxJsxFromMarkdown, mdxJsxToMarkdown} from './lib/index.js'

lib/index.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* @typedef {import('./complex-types').MdxJsxFlowElement} MdxJsxFlowElement
1717
* @typedef {import('./complex-types').MdxJsxTextElement} MdxJsxTextElement
1818
* @typedef {{name: string|null, attributes: (MdxJsxAttribute|MdxJsxExpressionAttribute)[], close?: boolean, selfClosing?: boolean, start: Token['start'], end: Token['start']}} Tag
19+
*
20+
* @typedef ToMarkdownOptions
21+
* @property {'"'|"'"} [quote='"']
1922
*/
2023

2124
import {parseEntities} from 'parse-entities'
@@ -24,7 +27,6 @@ import {VFileMessage} from 'vfile-message'
2427
import {stringifyEntitiesLight} from 'stringify-entities'
2528
import {containerFlow} from 'mdast-util-to-markdown/lib/util/container-flow.js'
2629
import {containerPhrasing} from 'mdast-util-to-markdown/lib/util/container-phrasing.js'
27-
import {checkQuote} from 'mdast-util-to-markdown/lib/util/check-quote.js'
2830
import {indentLines} from 'mdast-util-to-markdown/lib/util/indent-lines.js'
2931

3032
/** @return {FromMarkdownExtension} */
@@ -351,8 +353,22 @@ export function mdxJsxFromMarkdown() {
351353
}
352354
}
353355

354-
/** @returns {ToMarkdownExtension} */
355-
export function mdxJsxToMarkdown() {
356+
/**
357+
* @param {ToMarkdownOptions} [options={}]
358+
* Configuration (optional).
359+
* @returns {ToMarkdownExtension}
360+
*/
361+
export function mdxJsxToMarkdown(options = {}) {
362+
const {quote = '"'} = options
363+
364+
if (quote !== '"' && quote !== "'") {
365+
throw new Error(
366+
'Cannot serialize attribute values with `' +
367+
quote +
368+
'` for `options.quote`, expected `"`, or `\'`'
369+
)
370+
}
371+
356372
mdxElement.peek = peekElement
357373

358374
return {
@@ -376,7 +392,6 @@ export function mdxJsxToMarkdown() {
376392
function mdxElement(node, _, context) {
377393
const selfClosing =
378394
node.name && (!node.children || node.children.length === 0)
379-
const quote = checkQuote(context)
380395
const exit = context.enter(node.type)
381396
let attributeValue = ''
382397
let index = -1

readme.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Extensions to parse and serialize JSX between mdast and markdown
1818
* [Use](#use)
1919
* [API](#api)
2020
* [`mdxJsxFromMarkdown()`](#mdxjsxfrommarkdown)
21-
* [`mdxJsxToMarkdown()`](#mdxjsxtomarkdown)
21+
* [`mdxJsxToMarkdown(options?)`](#mdxjsxtomarkdownoptions)
2222
* [Syntax tree](#syntax-tree)
2323
* [Nodes](#nodes)
2424
* [Mixin](#mixin)
@@ -220,7 +220,7 @@ When using [`micromark-extension-mdx-jsx`][micromark-extension-mdx-jsx]
220220
with `options.addResult`, nodes will have a `data.estree` field set to an
221221
[ESTree][].
222222

223-
### `mdxJsxToMarkdown()`
223+
### `mdxJsxToMarkdown(options?)`
224224

225225
Function that can be called to get an extension for
226226
[`mdast-util-to-markdown`][mdast-util-to-markdown].
@@ -230,9 +230,13 @@ This extension configures `mdast-util-to-markdown` with
230230
[`options.resourceLink: true`][mdast-util-to-markdown-resourcelink] too, do not
231231
overwrite them!
232232

233-
Passing [`options.quote`][mdast-util-to-markdown-quote] to
234-
`mdast-util-to-markdown` is honored for
235-
attributes.
233+
##### `options`
234+
235+
Configuration (optional).
236+
237+
###### `options.quote`
238+
239+
Quote to use around attribute values (`'"'` or `"'"`, default: `'"'`).
236240

237241
## Syntax tree
238242

@@ -368,7 +372,10 @@ type MdxJsxPhrasingContent = MdxJsxTextElement | PhrasingContent
368372

369373
This package is fully typed with [TypeScript][].
370374
It exports the `MdxJsxAttributeValueExpression`, `MdxJsxAttribute`,
371-
`MdxJsxExpressionAttribute`, `MdxJsxFlowElement`, and `MdxJsxTextElement` types.
375+
`MdxJsxExpressionAttribute`, `MdxJsxFlowElement`, and `MdxJsxTextElement` types
376+
that represents the supported nodes.
377+
It also exports `ToMarkdownOptions`, which represents the structure of the
378+
respective options.
372379

373380
It also registers the node types with `@types/mdast`
374381

@@ -493,8 +500,6 @@ abide by its terms.
493500

494501
[micromark-extension-mdx-jsx]: https://github.com/micromark/micromark-extension-mdx-jsx
495502

496-
[mdast-util-to-markdown-quote]: https://github.com/syntax-tree/mdast-util-to-markdown#optionsquote
497-
498503
[mdast-util-to-markdown-fences]: https://github.com/syntax-tree/mdast-util-to-markdown#optionsfences
499504

500505
[mdast-util-to-markdown-resourcelink]: https://github.com/syntax-tree/mdast-util-to-markdown#optionsresourcelink

test.js

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,20 +1652,6 @@ test('mdast -> markdown', (t) => {
16521652
'should serialize value attributes'
16531653
)
16541654

1655-
t.deepEqual(
1656-
toMarkdown(
1657-
{
1658-
type: 'mdxJsxFlowElement',
1659-
name: 'x',
1660-
attributes: [{type: 'mdxJsxAttribute', name: 'y', value: 'z'}],
1661-
children: []
1662-
},
1663-
{extensions: [mdxJsxToMarkdown()], quote: "'"}
1664-
),
1665-
"<x y='z'/>\n",
1666-
'should serialize value attributes honoring `quote`'
1667-
)
1668-
16691655
t.deepEqual(
16701656
toMarkdown(
16711657
{
@@ -1850,5 +1836,36 @@ test('mdast -> markdown', (t) => {
18501836
'should not serialize code as indented'
18511837
)
18521838

1839+
t.deepEqual(
1840+
toMarkdown(
1841+
{
1842+
type: 'mdxJsxFlowElement',
1843+
name: 'x',
1844+
attributes: [{type: 'mdxJsxAttribute', name: 'y', value: 'z'}],
1845+
children: []
1846+
},
1847+
{extensions: [mdxJsxToMarkdown({quote: "'"})]}
1848+
),
1849+
"<x y='z'/>\n",
1850+
'should support `options.quote` to quote attribute values'
1851+
)
1852+
1853+
t.throws(
1854+
() => {
1855+
toMarkdown(
1856+
{
1857+
type: 'mdxJsxFlowElement',
1858+
name: 'x',
1859+
attributes: [],
1860+
children: []
1861+
},
1862+
// @ts-expect-error: runtime exception.
1863+
{extensions: [mdxJsxToMarkdown({quote: '!'})]}
1864+
)
1865+
},
1866+
/Cannot serialize attribute values with `!` for `options.quote`, expected `"`, or `'`/,
1867+
'should crash on an unclosed text jsx (agnostic)'
1868+
)
1869+
18531870
t.end()
18541871
})

0 commit comments

Comments
 (0)