Skip to content

Commit

Permalink
auto-close unclosed list items
Browse files Browse the repository at this point in the history
  • Loading branch information
dbushell committed Oct 4, 2024
1 parent 85cf4ac commit de6f604
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dbushell/hyperless",
"version": "0.11.0",
"version": "0.12.0",
"exports": {
".": "./mod.ts"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dbushell/hyperless",
"version": "0.11.0",
"version": "0.12.0",
"repository": {
"type": "git",
"url": "git+https://github.com/dbushell/hyperless.git"
Expand Down
13 changes: 12 additions & 1 deletion src/html-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {anyTag, comment} from './regexp.ts';
/** Regular expression to match HTML comment or tag */
const commentTag = new RegExp(`^${comment.source}|^${anyTag.source}`);

/** List of valid <li> parents */
const listTags = new Set(['ol', 'ul', 'menu']);

/** HTML parser state */
type ParseState = 'DATA' | 'RAWTEXT';

Expand Down Expand Up @@ -107,7 +110,15 @@ export const parseHTML = (html: string, options = parseOptions): Node => {
}
// Append opening tag and ascend
else {
const node = new Node(parent, 'ELEMENT', tagText, tagRaw);
const node = new Node(null, 'ELEMENT', tagText, tagRaw);
// Close unclosed `<li>` if new `<li>` item is found
if (
node.tag === 'li' &&
parent.tag === 'li' &&
listTags.has(parent.parent?.tag!)
) {
parent = parent.parent!;
}
parent.append(node);
parent = node;
}
Expand Down
29 changes: 29 additions & 0 deletions test/html_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,35 @@ Deno.test('leftover text', () => {
assertEquals(root.at(1)!.raw, 'Leftover');
});

Deno.test('unclosed <li>', () => {
const html = `
<ul>
<li>1<b>b</b>
<li>2</li>
<li>3
<ol>
<li>4<i>i</i>
<li>5
</ol>
</ul>`.replace(/\s+/g, '');
const root = parseHTML(html);
assertEquals(root.at(0)!.size, 3);
assertEquals(
root.toString(),
`
<ul>
<li>1<b>b</b></li>
<li>2</li>
<li>3
<ol>
<li>4<i>i</i></li>
<li>5</li>
</ol>
</li>
</ul>`.replace(/\s+/g, '')
);
});

Deno.test('comments', () => {
const html = `
<!--
Expand Down

0 comments on commit de6f604

Please sign in to comment.