Skip to content

Commit 8eb8a13

Browse files
authoredMar 21, 2024··
fix: handle newlines inside HTML tag brackets (#557)
* refactor: trim style keys * fix: handle newlines inside HTML tag brackets Closes #540
1 parent 1486aa4 commit 8eb8a13

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed
 

‎.changeset/fast-months-play.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"markdown-to-jsx": patch
3+
---
4+
5+
Handle newlines inside of HTML tags themselves (not just nested children.)

‎index.compiler.spec.tsx

+31
Original file line numberDiff line numberDiff line change
@@ -3213,6 +3213,7 @@ comment -->`)
32133213
</span>
32143214
`)
32153215
})
3216+
32163217
it('should not fail with lots of \\n in the middle of the text', () => {
32173218
render(
32183219
compiler(
@@ -3362,6 +3363,36 @@ print("hello world")
33623363
</span>
33633364
`)
33643365
})
3366+
3367+
it('#540 multiline attributes are supported', () => {
3368+
render(
3369+
compiler(
3370+
`<p>
3371+
Item detail
3372+
<span
3373+
style="
3374+
color: #fddb67;
3375+
font-size: 11px;
3376+
font-style: normal;
3377+
font-weight: 500;
3378+
line-height: 18px;
3379+
text-decoration-line: underline;
3380+
"
3381+
>debug item 1</span
3382+
>
3383+
</p>`
3384+
)
3385+
)
3386+
3387+
expect(root.innerHTML).toMatchInlineSnapshot(`
3388+
<p>
3389+
Item detail
3390+
<span style="color: rgb(253, 219, 103); font-size: 11px; font-style: normal; font-weight: 500; line-height: 18px; text-decoration-line: underline;">
3391+
debug item 1
3392+
</span>
3393+
</p>
3394+
`)
3395+
})
33653396
})
33663397

33673398
describe('horizontal rules', () => {

‎index.tsx

+8-7
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ const HEADING_SETEXT_R = /^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/
241241
* ([^ >/]+)
242242
*
243243
* 3. Ignore a space after the starting tag and capture the attribute portion of the tag (capture 2)
244-
* ?([^>]*)\/{0}>
244+
* ?([^>]*)>
245245
*
246246
* 4. Ensure a matching closing tag is present in the rest of the input string
247247
* (?=[\s\S]*<\/\1>)
@@ -254,7 +254,7 @@ const HEADING_SETEXT_R = /^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/
254254
* \n*
255255
*/
256256
const HTML_BLOCK_ELEMENT_R =
257-
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?([^>]*)\/{0}>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1)[\s\S])*?)<\/\1>\n*/i
257+
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?([^>]*)>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1)[\s\S])*?)<\/\1>\n*/i
258258

259259
const HTML_CHAR_CODE_R = /&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-fA-F]{1,6});/gi
260260

@@ -716,9 +716,9 @@ function attributeValueToJSXPropValue(
716716

717717
// snake-case to camelCase
718718
// also handles PascalCasing vendor prefixes
719-
const camelCasedKey = key.replace(/(-[a-z])/g, substr =>
720-
substr[1].toUpperCase()
721-
)
719+
const camelCasedKey = key
720+
.trim()
721+
.replace(/(-[a-z])/g, substr => substr[1].toUpperCase())
722722

723723
// key.length + 1 to skip over the colon
724724
styles[camelCasedKey] = kvPair.slice(key.length + 1).trim()
@@ -1456,6 +1456,7 @@ export function compiler(
14561456
order: Priority.HIGH,
14571457
parse(capture, parse, state) {
14581458
const [, whitespace] = capture[3].match(HTML_LEFT_TRIM_AMOUNT_R)
1459+
14591460
const trimmer = new RegExp(`^${whitespace}`, 'gm')
14601461
const trimmed = capture[3].replace(trimmer, '')
14611462

@@ -1470,7 +1471,7 @@ export function compiler(
14701471
const ast = {
14711472
attrs: attrStringToMap(capture[2]),
14721473
noInnerParse: noInnerParse,
1473-
tag: noInnerParse ? tagName : capture[1],
1474+
tag: (noInnerParse ? tagName : capture[1]).trim(),
14741475
} as {
14751476
attrs: ReturnType<typeof attrStringToMap>
14761477
children?: ReturnType<MarkdownToJSX.NestedParser> | undefined
@@ -1513,7 +1514,7 @@ export function compiler(
15131514
parse(capture /*, parse, state*/) {
15141515
return {
15151516
attrs: attrStringToMap(capture[2] || ''),
1516-
tag: capture[1],
1517+
tag: capture[1].trim(),
15171518
}
15181519
},
15191520
render(node, output, state) {

0 commit comments

Comments
 (0)
Please sign in to comment.