Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

644/table cell parsing #646

Merged
merged 7 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/serious-coins-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'markdown-to-jsx': patch
---

Adjust table row parsing to better handle inline syntaxes and improve performance.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ node_modules/
coverage/
*.log
package-lock.json
npm-shrinkwrap.json

# yarn
.yarn/*
!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
Expand Down
3 changes: 3 additions & 0 deletions .windsurfrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1. This project uses the `yarn` package manager
2. The priorities of this library are bundle size, performance, and functionality in that order
3. Optimize code for best minification and tree shaking
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
556 changes: 278 additions & 278 deletions .yarn/releases/yarn-4.5.1.cjs → .yarn/releases/yarn-4.6.0.cjs

Large diffs are not rendered by default.

8 changes: 1 addition & 7 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@ enableGlobalCache: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.5.1.cjs

supportedArchitectures:
os:
- linux
- win32
- darwin
yarnPath: .yarn/releases/yarn-4.6.0.cjs
15 changes: 9 additions & 6 deletions __snapshots__/index.compiler.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -542,12 +542,15 @@ Markdown's email-style
Setext-style headers are "underlined" using equal signs (for first-level
headers) and dashes (for second-level headers). For example:
</p>
<h1>
This is an H1
</h1>
<h2>
This is an H2
</h2>
<pre>
<code>
This is an H1
=============

This is an H2
-------------
</code>
</pre>
<p>
Any number of underlining
<code>
Expand Down
44 changes: 44 additions & 0 deletions index.compiler.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2530,6 +2530,50 @@ describe('GFM tables', () => {
</table>
`)
})

it('#644 handles nested inlines within table cells', () => {
render(
compiler(theredoc`
| Nested HTML | Link |
| ---------------------------------- | ---------------------------- |
| <div><strong>Nested</strong></div> | [I'm a \`link\`](www.google.com) |
`)
)

expect(root.innerHTML).toMatchInlineSnapshot(`
<table>
<thead>
<tr>
<th>
Nested HTML
</th>
<th>
Link
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div>
<strong>
Nested
</strong>
</div>
</td>
<td>
<a href="www.google.com">
I'm a
<code>
link
</code>
</a>
</td>
</tr>
</tbody>
</table>
`)
})
})

describe('arbitrary HTML', () => {
Expand Down
70 changes: 39 additions & 31 deletions index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export const RuleType = {
unorderedList: '33',
} as const

if (process.env.NODE_ENV !== 'production') {
Object.keys(RuleType).forEach(key => (RuleType[key] = key))
}

export type RuleType = (typeof RuleType)[keyof typeof RuleType]

const enum Priority {
Expand Down Expand Up @@ -622,42 +626,46 @@ function parseTableRow(
tableOutput: boolean
): MarkdownToJSX.ParserResult[][] {
const prevInTable = state.inTable

state.inTable = true
let tableRow = source

let cells: MarkdownToJSX.ParserResult[][] = [[]]
let acc = ''

function flush() {
if (!acc) return

const cell = cells[cells.length - 1]
cell.push.apply(cell, parse(acc, state))
acc = ''
}

source
.trim()
// isolate situations where a pipe should be ignored (inline code, escaped, etc)
.split(/( *(?:`[^`]*`|\\\||\|) *)/)
.reduce((nodes, fragment) => {
if (fragment.trim() === '|')
nodes.push(
tableOutput
? { type: RuleType.tableSeparator }
: { type: RuleType.text, text: fragment }
)
else if (fragment !== '') nodes.push.apply(nodes, parse(fragment, state))
return nodes
}, [] as MarkdownToJSX.ParserResult[])
state.inTable = prevInTable
.split(/(`[^`]*`|\\\||\|)/)
.filter(Boolean)
.forEach((fragment, i, arr) => {
if (fragment.trim() === '|') {
flush()

if (tableOutput) {
if (i !== 0 && i !== arr.length - 1) {
// Split the current row
cells.push([])
}

let cells = [[]]
tableRow.forEach(function (node, i) {
if (node.type === RuleType.tableSeparator) {
// Filter out empty table separators at the start/end:
if (i !== 0 && i !== tableRow.length - 1) {
// Split the current row:
cells.push([])
}
} else {
if (
node.type === RuleType.text &&
(tableRow[i + 1] == null ||
tableRow[i + 1].type === RuleType.tableSeparator)
) {
node.text = node.text.trimEnd()
return
}
}
cells[cells.length - 1].push(node)
}
})

acc += fragment
})

flush()

state.inTable = prevInTable

return cells
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@
"jest-serializer-html"
]
},
"packageManager": "yarn@4.5.1"
"packageManager": "yarn@4.6.0"
}
Loading