Skip to content

Commit

Permalink
fix: HTML block with markdown heading causes wrong HTML sectioning (#174
Browse files Browse the repository at this point in the history
)

- fix #171
  • Loading branch information
MurakamiShinyu authored Oct 12, 2023
1 parent 1015ed0 commit c551024
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/plugins/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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('</')) {
// it's HTML end tag, check if it has corresponding start tag
const tag = /^<\/([^>\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);
Expand Down
35 changes: 35 additions & 0 deletions tests/section.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,38 @@ it('Sample', () => {
`;
expect(received).toBe(expected);
});

it('HTML block with headings', () => {
const md = `# Heading 1
## Heading 2-1
<aside class="note">
### NOTE
This is a note.
</aside>
## Heading 2-2`;
const received = stringify(md, { partial: true });
const expected = `
<section class="level1" aria-labelledby="heading-1">
<h1 id="heading-1">Heading 1</h1>
<section class="level2" aria-labelledby="heading-2-1">
<h2 id="heading-2-1">Heading 2-1</h2>
<aside class="note">
<section class="level3" aria-labelledby="note">
<h3 id="note">NOTE</h3>
<p>This is a note.</p>
</section>
</aside>
</section>
<section class="level2" aria-labelledby="heading-2-2">
<h2 id="heading-2-2">Heading 2-2</h2>
</section>
</section>
`;
expect(received).toBe(expected);
});

0 comments on commit c551024

Please sign in to comment.