You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
renderMarkdown inserts blank lines inside raw-HTML elements, splitting them on reparse #301
Comark Version: 0.5.1 (reproduces on current main)
Framework: None
Comark Version
v0.5.1
Reproduction
import{parse}from'comark'import{renderMarkdown}from'comark/render'constmd='<picture>\n<source srcset="a.avif">\n<img src="a.jpg">\n</picture>'constrendered=awaitrenderMarkdown(awaitparse(md))// '<picture>\n<source srcset="a.avif" />\n\n<img src="a.jpg" />\n</picture>'// ^^ blank lineconsole.log(JSON.stringify((awaitparse(rendered)).nodes))// [["picture",{…}, ["source",…]], ["img",…]] ← img split out of the element
Description
The child-join loop in the html handler joins a raw-HTML element's children with blockSeparator whenever a child classifies as block (the catch-all arm classifies any unlisted tag as block, so source, figcaption, option… all hit it). A blank line terminates the HTML block per CommonMark, so the rendered markdown can't reparse to the original tree — parse → renderMarkdown → parse splits the element.
Anything with ≥2 children where one is not a known inline tag fails: figure>img+figcaption, details>summary+p, dl, select, audio with two sources, nested divs. Single-child elements escape it.
The inline variant is worse: text <picture><source…><img…></picture> tail gets the separator too (the loop runs regardless of oneLiner), which splits the containing paragraph in two on reparse.
Since the parser never nests markdown blocks inside a $.html element (blank-line-separated markdown is parsed outside the element), a blank line inside one is never legitimate in markdown output — children should be joined with \n, or nothing at all in inline position.
Fix + tests ready locally, PR incoming
Additional context
Parse-side relative: #235 / #236 are about the parser tolerating hand-written blank lines inside <details>; this one is about the stringifier introducing them. No overlap in touched files.
Filing two more round-trip issues alongside this one, all independent, will cross-link once up
import{parse}from'comark'constmarkdown=`<details><summary>Original summary in English</summary>xxx</details>`console.log(JSON.stringify((awaitparse(markdown)).nodes,null,2))
Activity
rock53770 commentedon Aug 26, 2026
This still seems to have a problem