Skip to content

Commit 08dfe8a

Browse files
Copilotquantizor
andauthored
Fix tables within list items regression (#757)
* Initial plan * fix: enable table parsing within list items Tables within list items were not being parsed correctly because processListContinuationLine passed single lines to parseBlocksWithState, but parseTable requires multiple consecutive lines. The fix adds table parsing similar to fenced code blocks - calling parseTable directly when the continuation line starts with |, allowing the table parser to read multiple lines. Added regression tests to prevent this issue from recurring. Co-authored-by: quantizor <[email protected]> * chore: add changeset for tables in lists fix Co-authored-by: quantizor <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: quantizor <[email protected]>
1 parent b197466 commit 08dfe8a

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

.changeset/fix-tables-in-lists.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"markdown-to-jsx": patch
3+
---
4+
5+
Fix regression: Tables within list items are now properly parsed.

src/parse.spec.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,84 @@ describe('HTML tags interrupting lists', () => {
14461446
})
14471447
})
14481448

1449+
describe('tables in lists', () => {
1450+
it('should parse tables within list items (regression test for issue #1)', () => {
1451+
const md = `- **Browser Stats**:
1452+
1453+
| Computer | Memory Usage |
1454+
| -------- | ------------ |
1455+
| FireFox | 86% |
1456+
| Chrome | 80% |
1457+
| Safari | 79% |
1458+
`
1459+
const result = p.parser(md)
1460+
1461+
// Should have a single unordered list
1462+
expect(result.length).toBe(1)
1463+
expect(result[0].type).toBe(RuleType.unorderedList)
1464+
1465+
const list = result[0] as MarkdownToJSX.UnorderedListNode
1466+
expect(list.items.length).toBe(1)
1467+
1468+
// The first item should contain both content and a table
1469+
const item = list.items[0]
1470+
expect(item.length).toBe(2)
1471+
1472+
// First element is the paragraph with "Browser Stats"
1473+
expect(item[0].type).toBe(RuleType.paragraph)
1474+
const paragraph = item[0] as MarkdownToJSX.ParagraphNode
1475+
expect(paragraph.children.length).toBeGreaterThan(0)
1476+
1477+
// Second element should be a table
1478+
expect(item[1].type).toBe(RuleType.table)
1479+
const table = item[1] as MarkdownToJSX.TableNode
1480+
expect(table.header.length).toBe(2)
1481+
expect(table.cells.length).toBe(3) // FireFox, Chrome, Safari rows
1482+
})
1483+
1484+
it('should parse standalone table', () => {
1485+
const md = `| Computer | Memory Usage |
1486+
| -------- | ------------ |
1487+
| FireFox | 86% |
1488+
`
1489+
const result = p.parser(md)
1490+
1491+
expect(result.length).toBe(1)
1492+
expect(result[0].type).toBe(RuleType.table)
1493+
const table = result[0] as MarkdownToJSX.TableNode
1494+
expect(table.header.length).toBe(2)
1495+
expect(table.cells.length).toBe(1)
1496+
})
1497+
1498+
it('should parse multiple tables in separate list items', () => {
1499+
const md = `- Item 1:
1500+
1501+
| A | B |
1502+
| - | - |
1503+
| 1 | 2 |
1504+
1505+
- Item 2:
1506+
1507+
| C | D |
1508+
| - | - |
1509+
| 3 | 4 |
1510+
`
1511+
const result = p.parser(md)
1512+
1513+
expect(result.length).toBe(1)
1514+
expect(result[0].type).toBe(RuleType.unorderedList)
1515+
1516+
const list = result[0] as MarkdownToJSX.UnorderedListNode
1517+
expect(list.items.length).toBe(2)
1518+
1519+
// Both items should have tables
1520+
for (const item of list.items) {
1521+
const tables = item.filter(node => node.type === RuleType.table)
1522+
expect(tables.length).toBe(1)
1523+
}
1524+
})
1525+
})
1526+
14491527
describe('initializeParseMetrics', () => {
14501528
it('should initialize parse metrics', () => {
14511529
p.initializeParseMetrics()

src/parse.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4793,6 +4793,21 @@ function processListContinuationLine(
47934793
}
47944794
}
47954795
}
4796+
// Try parsing as table when line starts with |
4797+
if (firstCharAfterIndent === '|') {
4798+
const tableResult = parseTable(source, continuationStart, state, options)
4799+
if (tableResult) {
4800+
const tableNode = tableResult as MarkdownToJSX.TableNode & {
4801+
endPos: number
4802+
}
4803+
lastItem.push(tableNode)
4804+
return {
4805+
processed: true,
4806+
newPos: tableNode.endPos,
4807+
wasBlank: false,
4808+
}
4809+
}
4810+
}
47964811
}
47974812
}
47984813

0 commit comments

Comments
 (0)