diff --git a/src/plugins/section.ts b/src/plugins/section.ts index 1a41ed9..d53fa9e 100644 --- a/src/plugins/section.ts +++ b/src/plugins/section.ts @@ -69,8 +69,29 @@ const sectionizeIfRequired = (node: any, ancestors: Parent[], file: VFile) => { const start = node; const depth = start.depth; + // check if it's HTML end tag without corresponding start tag in sibling nodes. + const isHtmlEnd = (node: any) => { + if (node.type === 'html' && node.value.startsWith('\s]+)/.exec(node.value)?.[1]; + const isHtmlStart = (node: any) => + node.type === 'html' && /^<([^>\s]+)/.exec(node.value)?.[1] === tag; + const htmlStart = findAfter(parent, start, isHtmlStart); + if ( + !htmlStart || + parent.children.indexOf(htmlStart) > parent.children.indexOf(node) + ) { + // corresponding start tag not found in sibling nodes + return true; + } + } + return false; + }; + const isEnd = (node: any) => - (node.type === 'heading' && node.depth <= depth) || node.type === 'export'; + (node.type === 'heading' && node.depth <= depth) || + node.type === 'export' || + isHtmlEnd(node); const end = findAfter(parent, start, isEnd); const startIndex = parent.children.indexOf(start); diff --git a/tests/section.test.ts b/tests/section.test.ts index 9a9ae99..aed68ef 100644 --- a/tests/section.test.ts +++ b/tests/section.test.ts @@ -184,3 +184,38 @@ it('Sample', () => { `; expect(received).toBe(expected); }); + +it('HTML block with headings', () => { + const md = `# Heading 1 + +## Heading 2-1 + + + +## Heading 2-2`; + const received = stringify(md, { partial: true }); + const expected = ` +
+

Heading 1

+
+

Heading 2-1

+ +
+
+

Heading 2-2

+
+
+`; + expect(received).toBe(expected); +});