From fdfe3cfa29a0bfc5d0686ab880d03d39f700cf51 Mon Sep 17 00:00:00 2001
From: Farnabaz bold and more
+
+
bold
+`.
+ return nodes.map((child) => {
+ if (
+ Array.isArray(child) &&
+ child[0] === 'p' &&
+ !(child[1] as Record
this is **markdown** @@ -64,9 +64,7 @@ this is **markdown**
`) expect(result.nodes).toEqual([ - ['p', { $: { html: 1, block: 1 } }], - ['p', {}, 'this is ', ['strong', {}, 'markdown']], - ['p', { $: { html: 1, block: 1 } }], + ['p', { $: { html: 1, block: 1 } }, 'this is ', ['strong', {}, 'markdown']], ]) }) @@ -88,7 +86,7 @@ this is **markdown** ]) }) - it('parses markdown and raw HTML as siblings when blank lines separate them', async () => { + it('nests blank-line markdown and HTML under a matching open/close pair', async () => { const result = await parseMarkdown(`` structure.
---
.../HTML/details-inside-details-no-unwrap.md | 94 ++++++++++++++++++
.../SPEC/HTML/details-inside-details.md | 4 +-
.../SPEC/HTML/p-details-inside-details.md | 99 +++++++++++++++++++
.../comark/src/internal/parse/auto-unwrap.ts | 64 ++++++++++--
.../src/internal/parse/token-processor.ts | 25 +----
.../src/internal/stringify/handlers/html.ts | 27 +++--
6 files changed, 273 insertions(+), 40 deletions(-)
create mode 100644 packages/comark/SPEC/HTML/details-inside-details-no-unwrap.md
create mode 100644 packages/comark/SPEC/HTML/p-details-inside-details.md
diff --git a/packages/comark/SPEC/HTML/details-inside-details-no-unwrap.md b/packages/comark/SPEC/HTML/details-inside-details-no-unwrap.md
new file mode 100644
index 00000000..0fd3b9d0
--- /dev/null
+++ b/packages/comark/SPEC/HTML/details-inside-details-no-unwrap.md
@@ -0,0 +1,94 @@
+---
+options:
+ autoUnwrap: false
+---
+
+## Input
+
+```md
+ Nested contentTop
+
+Nested
+
+Nested content
+
+
+ Top
+
+
+ Nested
+
+
+Top
+
+Nested
+
+
+Nested content
+
Nested
-
Nested content
+
+
+Nested content
Nested content
+Nested content2
+`.
- return nodes.map((child) => {
- if (
- Array.isArray(child) &&
- child[0] === 'p' &&
- !(child[1] as Record ` here; `applyAutoUnwrap` lifts
+ // them when `autoUnwrap` is on (default).
const bodyTokens = tokens.slice(startIndex + 1, closeIndex)
const body = processBlockChildren(bodyTokens, 0, '\0', false, false, false, state)
@@ -246,7 +229,7 @@ function processHtmlBlockTokens(
}
return {
- nodes: [[element[0], attrs, ...openerChildren, ...finalizeIncompleteHtmlChildren(body.nodes)] as Node],
+ nodes: [[element[0], attrs, ...openerChildren, ...body.nodes] as Node],
// Consume the closer as well.
nextIndex: closeIndex + 1,
}
diff --git a/packages/comark/src/internal/stringify/handlers/html.ts b/packages/comark/src/internal/stringify/handlers/html.ts
index a60687b1..4644e7aa 100644
--- a/packages/comark/src/internal/stringify/handlers/html.ts
+++ b/packages/comark/src/internal/stringify/handlers/html.ts
@@ -79,10 +79,11 @@ export async function html(node: ElementNode, state: State, parent?: ElementNode
}
// In markdown mode, block children already append their own blockSeparator, so
- // we must not inject extra newlines between them. In HTML mode the separator
- // is the pretty-print block gap. A blank line inside a *raw* HTML body would
- // terminate the block on reparse — markdown children of incomplete openers
- // (`$.block === 0`) intentionally use blank lines like normal markdown.
+ // we must not inject extra newlines between *markdown* siblings. HTML element
+ // closers (``) do not carry a trailing separator, so a following
+ // markdown body would otherwise glue on (`Nested content`). Insert
+ // a blank line when the previous render ends with an HTML closer and the next
+ // is not itself an HTML open tag. In HTML mode use the pretty-print gap.
const childSeparator = state.context.html ? state.context.blockSeparator : ''
let content = ''
@@ -90,17 +91,27 @@ export async function html(node: ElementNode, state: State, parent?: ElementNode
for (let i = 0; i < children.length; i++) {
const childContent = childrenContent[i]
const child = children[i]
- const isBlock =
+ const childIsBlock =
typeof child !== 'string' &&
(blockTags.has(String(child?.[0])) || (!inlineTags.has(String(child?.[0])) && !hasTextSibling))
- if (i > 0 && !isPrevBlock && isBlock) {
+ if (i > 0 && !isPrevBlock && childIsBlock) {
content += childSeparator
}
+
+ if (i > 0 && !state.context.html) {
+ const prevContent = childrenContent[i - 1]
+ // `…` + `Nested content` → blank line so the body re-parses as
+ // a separate markdown block. Keep HTML→HTML tight (`
Here

Here



Text content
Line one
-Middle line
-Line three
Above
-Middle text
-Below
Here

Here









Nested content
Nested content
Nested content2
Paragraph
-Paragraph
-
+
# comark
@@ -46,7 +46,7 @@ A high-performance markdown parser and renderer.
## HTML
```html
-
+
A high-performance markdown parser and renderer.
``` @@ -54,7 +54,7 @@ A high-performance markdown parser and renderer. ## Markdown ```md -
+
# comark
diff --git a/packages/comark/SPEC/common-mark/image-title.md b/packages/comark/SPEC/common-mark/image-title.md
index 1ea11b02..659ab4cf 100644
--- a/packages/comark/SPEC/common-mark/image-title.md
+++ b/packages/comark/SPEC/common-mark/image-title.md
@@ -30,7 +30,7 @@
## HTML
```html
-

Hello
World
Hello
World


This is a simple paragraph
And continues in next line
This is a simple paragraph
And continues in next line
This is another paragraph
``` diff --git a/packages/comark/SPEC/common-mark/xyz.md b/packages/comark/SPEC/common-mark/xyz.md index bc390447..aaf4369c 100644 --- a/packages/comark/SPEC/common-mark/xyz.md +++ b/packages/comark/SPEC/common-mark/xyz.md @@ -313,7 +313,7 @@ And here's a code block:Here's an image:
-

And here's a code block:
``` diff --git a/packages/comark/SPEC/markdown-directive/directive-no-content.md b/packages/comark/SPEC/markdown-directive/directive-no-content.md index 0d6212ae..b015ad25 100644 --- a/packages/comark/SPEC/markdown-directive/directive-no-content.md +++ b/packages/comark/SPEC/markdown-directive/directive-no-content.md @@ -58,10 +58,10 @@ a :br with no content or attributes ```htmla -
a
with no content or attributes
a
with no content or attributes

', async () => { const result = await parseMarkdown('

` here; `applyAutoUnwrap` lifts
- // them when `autoUnwrap` is on (default).
- const bodyTokens = tokens.slice(startIndex + 1, closeIndex)
- const body = processBlockChildren(bodyTokens, 0, '\0', false, false, false, state)
-
- const attrs: Record