Skip to content

GitHub-style <details> block content is parsed outside the details element #235

Description

@pynickle

Environment

  • Operating System: Windows 11
  • Node Version: v24.16.0
  • Package Manager: bun@1.3.14
  • Comark Version: 0.4.0
  • Framework: Vue / Nuxt

Comark Version

v0.4.0

Reproduction

import { parse } from 'comark'

const markdown = `<details>
<summary>Original summary in English</summary>

xxx
</details>`

console.log(JSON.stringify((await parse(markdown)).nodes, null, 2))

Actual output:

[
  [
    "details",
    {
      "$": {
        "html": 1,
        "block": 1
      }
    },
    [
      "summary",
      {
        "$": {
          "html": 1,
          "block": 1
        }
      },
      "Original summary in English"
    ]
  ],
  [
    "p",
    {},
    "xxx"
  ]
]

Expected output should keep xxx inside the details node, for example:

[
  [
    "details",
    {
      "$": {
        "html": 1,
        "block": 1
      }
    },
    [
      "summary",
      {
        "$": {
          "html": 1,
          "block": 1
        }
      },
      "Original summary in English"
    ],
    [
      "p",
      {},
      "xxx"
    ]
  ]
]

Description

GitHub-style collapsed sections using <details> / <summary> are not parsed correctly when the <summary> line is followed by a blank line.

Input:

<details>
<summary>Original summary in English</summary>

xxx
</details>

In GitHub Markdown, the body content remains inside the <details> block and is hidden until expanded. GitHub's Markdown API renders this as:

Original summary in English

xxx

Comark currently parses xxx as a sibling after the details node. Framework renderers then faithfully render the AST as:

Original summary in English

xxx

This breaks GitHub-compatible rendering for collapsed sections.

The issue appears related to raw HTML block handling. <details> / <summary> are treated as block HTML, and the blank line after <summary> appears to terminate the HTML block before is reached.

Additional context

No response

Logs

Activity

  1. self-assigned this
    on Jun 9, 2026
  2. c-harding commented on Jun 26, 2026

    @c-harding

    It seems like all type-6 blocks (HTML block elements) containing blank lines parse incorrectly according to the specification:

    compare commonmark demo (see the HTML tab) with the same code in the comark editor.

    <details>
    <summary>Original summary in English</summary>
    
    xxx
    </details>
    
    <div class=foo">
    
    *Markdown*
    
    </div>

    The correct result according to the reference implementation:

    <details>
    <summary>Original summary in English</summary>
    <p>xxx</p>
    </details>
    <div class=foo">
    <p><em>Markdown</em></p>
    </div>
  3. rock53770 commented on Aug 26, 2026

    @rock53770

    This bug is very serious. Who can solve this problem? I beg for your help

  4. arashsheyda commented on Aug 27, 2026

    @arashsheyda
    Collaborator

    I already have a PR for it, I'll resolve the conflict tomorrow, @farnabaz could you reivew it please #236

  5. adamdehaven commented on Sep 29, 2026

    @adamdehaven
    Contributor

    The same problem affects plain wrapper elements:

    <div class="note">
    
    **Bold** text
    
    </div>

    Output (comark@0.7.0):

    <div class="note"></div>
    <p><strong>Bold</strong> text</p>

    Expected (GitHub, @nuxtjs/mdc):

    <div class="note"><p><strong>Bold</strong> text</p></div>

    Nested wrappers lose their structure the same way:

    <div class="a">
    <div class="b">
    
    Text
    
    </div>
    </div>

    Output (comark@0.7.0):

    <div class="a"><div class="b"></div></div>
    <p>Text</p>

    Expected:

    <div class="a"><div class="b"><p>Text</p></div></div>

    The opening tag, the Markdown, and the closing tag are three html_block tokens. processBlockToken returns only result.nodes[0] and never looks ahead for the closing block. Comark emits element nodes, so nothing re-nests the siblings later.

    When an html_block leaves an element open, the code should find the later html_block that closes it, parse the tokens in between as its children, and consume the closer. Keep the current behavior when no closer exists.

  6. farnabaz commented on Sep 29, 2026

    @farnabaz
    Collaborator

    This issue will also be fixed with #401

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions