@@ -26,25 +26,36 @@ export async function li(node: ComarkElement, state: State) {
2626 }
2727
2828 const prefixWidth = prefix . length
29+
30+ // Direct text children render sibling components inline.
31+ const hasInlineContent = children . some ( ( child ) => typeof child === 'string' )
32+
2933 let result = ''
3034
3135 for ( const child of children ) {
32- const rendered = await state . one ( child , state , node )
33- if ( result && Array . isArray ( child ) ) {
34- if ( blockElements . has ( child [ 0 ] as string ) ) {
35- // Block-level child: put on its own line and indent to align with list prefix
36- const indented = indent ( rendered , { width : prefixWidth } )
36+ if ( Array . isArray ( child ) ) {
37+ const tag = child [ 0 ] as string
38+
39+ if ( result && blockElements . has ( tag ) ) {
40+ const indented = indent ( await state . one ( child , state , node ) , { width : prefixWidth } )
3741 result = result . trimEnd ( ) + '\n' + indented . trimEnd ( ) + '\n'
3842 continue
3943 }
4044
41- if ( child [ 0 ] === 'p' ) {
42- const indented = indent ( rendered , { width : prefixWidth } )
45+ if ( result && tag === 'p' ) {
46+ const indented = indent ( await state . one ( child , state , node ) , { width : prefixWidth } )
4347 result = result . trimEnd ( ) + '\n\n' + indented . trimEnd ( ) + '\n'
4448 continue
4549 }
50+
51+ // No parent → mdc skips its own nesting indentation, so li owns it here.
52+ if ( ! hasInlineContent && ! ( tag in state . handlers ) ) {
53+ const indented = indent ( await state . one ( child , state ) , { width : prefixWidth , ignoreFirstLine : ! result } )
54+ result = result ? result . trimEnd ( ) + '\n' + indented . trimEnd ( ) + '\n' : indented . trimEnd ( ) + '\n'
55+ continue
56+ }
4657 }
47- result += rendered
58+ result += await state . one ( child , state , node )
4859 }
4960 result = result . trim ( )
5061
0 commit comments