diff --git a/deno.json b/deno.json
index 4766fd7..665129d 100644
--- a/deno.json
+++ b/deno.json
@@ -1,6 +1,6 @@
{
"name": "@dbushell/hyperless",
- "version": "0.11.0",
+ "version": "0.12.0",
"exports": {
".": "./mod.ts"
},
diff --git a/package.json b/package.json
index 6951d23..335cb67 100644
--- a/package.json
+++ b/package.json
@@ -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"
diff --git a/src/html-parser.ts b/src/html-parser.ts
index bd9cab4..cf4935d 100644
--- a/src/html-parser.ts
+++ b/src/html-parser.ts
@@ -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
parents */
+const listTags = new Set(['ol', 'ul', 'menu']);
+
/** HTML parser state */
type ParseState = 'DATA' | 'RAWTEXT';
@@ -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 `` if new `` item is found
+ if (
+ node.tag === 'li' &&
+ parent.tag === 'li' &&
+ listTags.has(parent.parent?.tag!)
+ ) {
+ parent = parent.parent!;
+ }
parent.append(node);
parent = node;
}
diff --git a/test/html_test.ts b/test/html_test.ts
index 4c5eead..807f3a9 100644
--- a/test/html_test.ts
+++ b/test/html_test.ts
@@ -64,6 +64,35 @@ Deno.test('leftover text', () => {
assertEquals(root.at(1)!.raw, 'Leftover');
});
+Deno.test('unclosed ', () => {
+ const html = `
+
+ - 1b
+
- 2
+ - 3
+
+ - 4i
+
- 5
+
+
`.replace(/\s+/g, '');
+ const root = parseHTML(html);
+ assertEquals(root.at(0)!.size, 3);
+ assertEquals(
+ root.toString(),
+ `
+
+ - 1b
+ - 2
+ - 3
+
+ - 4i
+ - 5
+
+
+
`.replace(/\s+/g, '')
+ );
+});
+
Deno.test('comments', () => {
const html = `