Skip to content

Commit e9b9546

Browse files
authored
fix(stringify): handle multiple paragraphs in a list item (#169)
1 parent e5b0843 commit e9b9546

24 files changed

Lines changed: 289 additions & 84 deletions

packages/comark-ansi/src/handlers/li.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { NodeHandler } from 'comark/render'
22
import type { ComarkElement, ComarkNode } from 'comark'
3+
import { indent } from 'comark/utils'
4+
5+
// Block elements that need explicit indentation in list items.
6+
// Note: ol/ul are handled by their own handlers which manage indentation via listIndent context.
7+
const blockElements = new Set(['pre', 'blockquote', 'table'])
38

49
export const li: NodeHandler = async (node, state) => {
510
const children = node.slice(2) as ComarkNode[]
@@ -14,15 +19,31 @@ export const li: NodeHandler = async (node, state) => {
1419
prefix += input[1].checked || input[1][':checked'] ? '[x] ' : '[ ] '
1520
}
1621

17-
let content = ''
22+
const prefixWidth = prefix.length
23+
let result = ''
1824
for (const child of children) {
19-
content += await state.one(child, state, node)
25+
const rendered = await state.one(child, state, node)
26+
if (result && Array.isArray(child)) {
27+
if (blockElements.has(child[0] as string)) {
28+
// Block-level child: put on its own line and indent to align with list prefix
29+
const indented = indent(rendered, { width: prefixWidth })
30+
result = result.trimEnd() + '\n' + indented.trimEnd() + '\n'
31+
continue
32+
}
33+
34+
if (child[0] === 'p') {
35+
const indented = indent(rendered, { width: prefixWidth })
36+
result = result.trimEnd() + '\n\n' + indented.trimEnd() + '\n'
37+
continue
38+
}
39+
}
40+
result += rendered
2041
}
21-
content = content.trim()
42+
result = result.trim()
2243

2344
if (typeof order === 'number') {
2445
state.applyContext({ order: order + 1 })
2546
}
2647

27-
return `${prefix}${content}\n`
48+
return `${prefix}${result}\n`
2849
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import type { NodeHandler } from 'comark/render'
22
import type { ComarkNode } from 'comark'
33

4-
export const p: NodeHandler = async (node, state) => {
4+
export const p: NodeHandler = async (node, state, parent) => {
55
const children = node.slice(2) as ComarkNode[]
66
let result = ''
77
for (const child of children) {
88
result += await state.one(child, state, node)
99
}
10+
11+
if (parent?.[0] === 'li') {
12+
return result
13+
}
14+
1015
return result + '\n\n'
1116
}

packages/comark/SPEC/COMARK/shiki-ordered-list-nested-codeblock.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ options:
3232
[
3333
"li",
3434
{},
35-
"Setup:",
35+
[
36+
"p",
37+
{},
38+
"Setup:"
39+
],
3640
[
3741
"pre",
3842
{
@@ -100,7 +104,8 @@ options:
100104
```html
101105
<ol>
102106
<li>
103-
Setup:<pre language="rust" class="shiki shiki-themes github-dark dark:github-dark" tabindex="0"><code class="language-rust"><span class="line" style="display: inline"><span style="color:#F97583">let</span><span style="color:#E1E4E8"> x </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 1</span><span style="color:#E1E4E8">;</span></span></code></pre>
107+
<p>Setup:</p>
108+
<pre language="rust" class="shiki shiki-themes github-dark dark:github-dark" tabindex="0"><code class="language-rust"><span class="line" style="display: inline"><span style="color:#F97583">let</span><span style="color:#E1E4E8"> x </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 1</span><span style="color:#E1E4E8">;</span></span></code></pre>
104109
</li>
105110
</ol>
106111
```

packages/comark/SPEC/common-mark/ordered-list-mixed-blocks-nested.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@
2929
[
3030
"li",
3131
{},
32-
"Complex item:",
32+
[
33+
"p",
34+
{},
35+
"Complex item:"
36+
],
3337
[
3438
"pre",
3539
{
@@ -54,7 +58,11 @@
5458
[
5559
"li",
5660
{},
57-
"Nested with table:",
61+
[
62+
"p",
63+
{},
64+
"Nested with table:"
65+
],
5866
[
5967
"table",
6068
{},
@@ -108,13 +116,14 @@
108116
```html
109117
<ol>
110118
<li>
111-
Complex item:<pre language="js"><code class="language-js">code()</code></pre>
119+
<p>Complex item:</p>
120+
<pre language="js"><code class="language-js">code()</code></pre>
112121
<blockquote>
113122
A note
114123
</blockquote>
115124
<ul>
116125
<li>
117-
Nested with table:
126+
<p>Nested with table:</p>
118127
<table>
119128
<thead>
120129
<tr>

packages/comark/SPEC/common-mark/ordered-list-multiple-blocks.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
[
2626
"li",
2727
{},
28-
"First point:",
28+
[
29+
"p",
30+
{},
31+
"First point:"
32+
],
2933
[
3034
"blockquote",
3135
{},
@@ -60,7 +64,7 @@
6064
```html
6165
<ol>
6266
<li>
63-
First point:
67+
<p>First point:</p>
6468
<blockquote>
6569
A quote here
6670
</blockquote>

packages/comark/SPEC/common-mark/ordered-list-nested-codeblock.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,22 @@
2222
[
2323
"li",
2424
{},
25-
"First level",
25+
[
26+
"p",
27+
{},
28+
"First level"
29+
],
2630
[
2731
"ol",
2832
{},
2933
[
3034
"li",
3135
{},
32-
"Second level with code:",
36+
[
37+
"p",
38+
{},
39+
"Second level with code:"
40+
],
3341
[
3442
"pre",
3543
{
@@ -56,10 +64,11 @@
5664
```html
5765
<ol>
5866
<li>
59-
First level
67+
<p>First level</p>
6068
<ol>
6169
<li>
62-
Second level with code:<pre language="rust"><code class="language-rust">let x = 42;</code></pre>
70+
<p>Second level with code:</p>
71+
<pre language="rust"><code class="language-rust">let x = 42;</code></pre>
6372
</li>
6473
</ol>
6574
</li>

packages/comark/SPEC/common-mark/ordered-list-nested.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
[
3333
"li",
3434
{},
35-
"Third item",
35+
[
36+
"p",
37+
{},
38+
"Third item"
39+
],
3640
[
3741
"ol",
3842
{},
@@ -65,7 +69,7 @@
6569
<li>First item</li>
6670
<li>Second item</li>
6771
<li>
68-
Third item
72+
<p>Third item</p>
6973
<ol>
7074
<li>Indented item</li>
7175
<li>Indented item</li>

packages/comark/SPEC/common-mark/unordered-list-blockquote.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
[
2020
"li",
2121
{},
22-
"Item with quote:",
22+
[
23+
"p",
24+
{},
25+
"Item with quote:"
26+
],
2327
[
2428
"blockquote",
2529
{},
@@ -36,7 +40,7 @@
3640
```html
3741
<ul>
3842
<li>
39-
Item with quote:
43+
<p>Item with quote:</p>
4044
<blockquote>
4145
This is a blockquote
4246
</blockquote>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
## Input
2+
3+
```md
4+
- para1
5+
6+
para2
7+
```
8+
9+
## AST
10+
11+
```json
12+
{
13+
"frontmatter": {},
14+
"meta": {},
15+
"nodes": [
16+
[
17+
"ul",
18+
{},
19+
[
20+
"li",
21+
{},
22+
[
23+
"p",
24+
{},
25+
"para1"
26+
],
27+
[
28+
"p",
29+
{},
30+
"para2"
31+
]
32+
]
33+
]
34+
]
35+
}
36+
```
37+
38+
## HTML
39+
40+
```html
41+
<ul>
42+
<li>
43+
<p>para1</p>
44+
<p>para2</p>
45+
</li>
46+
</ul>
47+
```
48+
49+
## Markdown
50+
51+
```md
52+
- para1
53+
54+
para2
55+
```

packages/comark/SPEC/common-mark/unordered-list-nested-blockquotes.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
[
2424
"li",
2525
{},
26-
"Item with quote:",
26+
[
27+
"p",
28+
{},
29+
"Item with quote:"
30+
],
2731
[
2832
"blockquote",
2933
{},
@@ -35,7 +39,11 @@
3539
[
3640
"li",
3741
{},
38-
"Nested item with quote:",
42+
[
43+
"p",
44+
{},
45+
"Nested item with quote:"
46+
],
3947
[
4048
"blockquote",
4149
{},
@@ -54,13 +62,13 @@
5462
```html
5563
<ul>
5664
<li>
57-
Item with quote:
65+
<p>Item with quote:</p>
5866
<blockquote>
5967
Quote level 1
6068
</blockquote>
6169
<ul>
6270
<li>
63-
Nested item with quote:
71+
<p>Nested item with quote:</p>
6472
<blockquote>
6573
Quote level 2
6674
</blockquote>

0 commit comments

Comments
 (0)