Skip to content

Commit

Permalink
fix: handle newlines inside HTML tag brackets (#557)
Browse files Browse the repository at this point in the history
* refactor: trim style keys

* fix: handle newlines inside HTML tag brackets

Closes #540
  • Loading branch information
quantizor committed Mar 21, 2024
1 parent 1486aa4 commit 8eb8a13
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/fast-months-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"markdown-to-jsx": patch
---

Handle newlines inside of HTML tags themselves (not just nested children.)
31 changes: 31 additions & 0 deletions index.compiler.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3213,6 +3213,7 @@ comment -->`)
</span>
`)
})

it('should not fail with lots of \\n in the middle of the text', () => {
render(
compiler(
Expand Down Expand Up @@ -3362,6 +3363,36 @@ print("hello world")
</span>
`)
})

it('#540 multiline attributes are supported', () => {
render(
compiler(
`<p>
Item detail
<span
style="
color: #fddb67;
font-size: 11px;
font-style: normal;
font-weight: 500;
line-height: 18px;
text-decoration-line: underline;
"
>debug item 1</span
>
</p>`
)
)

expect(root.innerHTML).toMatchInlineSnapshot(`
<p>
Item detail
<span style="color: rgb(253, 219, 103); font-size: 11px; font-style: normal; font-weight: 500; line-height: 18px; text-decoration-line: underline;">
debug item 1
</span>
</p>
`)
})
})

describe('horizontal rules', () => {
Expand Down
15 changes: 8 additions & 7 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ const HEADING_SETEXT_R = /^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/
* ([^ >/]+)
*
* 3. Ignore a space after the starting tag and capture the attribute portion of the tag (capture 2)
* ?([^>]*)\/{0}>
* ?([^>]*)>
*
* 4. Ensure a matching closing tag is present in the rest of the input string
* (?=[\s\S]*<\/\1>)
Expand All @@ -254,7 +254,7 @@ const HEADING_SETEXT_R = /^([^\n]+)\n *(=|-){3,} *(?:\n *)+\n/
* \n*
*/
const HTML_BLOCK_ELEMENT_R =
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?([^>]*)\/{0}>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1)[\s\S])*?)<\/\1>\n*/i
/^ *(?!<[a-z][^ >/]* ?\/>)<([a-z][^ >/]*) ?([^>]*)>\n?(\s*(?:<\1[^>]*?>[\s\S]*?<\/\1>|(?!<\1)[\s\S])*?)<\/\1>\n*/i

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

Expand Down Expand Up @@ -716,9 +716,9 @@ function attributeValueToJSXPropValue(

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

// key.length + 1 to skip over the colon
styles[camelCasedKey] = kvPair.slice(key.length + 1).trim()
Expand Down Expand Up @@ -1456,6 +1456,7 @@ export function compiler(
order: Priority.HIGH,
parse(capture, parse, state) {
const [, whitespace] = capture[3].match(HTML_LEFT_TRIM_AMOUNT_R)

const trimmer = new RegExp(`^${whitespace}`, 'gm')
const trimmed = capture[3].replace(trimmer, '')

Expand All @@ -1470,7 +1471,7 @@ export function compiler(
const ast = {
attrs: attrStringToMap(capture[2]),
noInnerParse: noInnerParse,
tag: noInnerParse ? tagName : capture[1],
tag: (noInnerParse ? tagName : capture[1]).trim(),
} as {
attrs: ReturnType<typeof attrStringToMap>
children?: ReturnType<MarkdownToJSX.NestedParser> | undefined
Expand Down Expand Up @@ -1513,7 +1514,7 @@ export function compiler(
parse(capture /*, parse, state*/) {
return {
attrs: attrStringToMap(capture[2] || ''),
tag: capture[1],
tag: capture[1].trim(),
}
},
render(node, output, state) {
Expand Down

0 comments on commit 8eb8a13

Please sign in to comment.