justhtml 3.6.0__tar.gz → 3.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {justhtml-3.6.0 → justhtml-3.7.0}/CHANGELOG.md +20 -1
- {justhtml-3.6.0 → justhtml-3.7.0}/PKG-INFO +2 -2
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/correctness.py +1 -1
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/comparison.md +9 -9
- {justhtml-3.6.0 → justhtml-3.7.0}/pyproject.toml +2 -2
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/engine.py +1 -1
- justhtml-3.7.0/tests/justhtml-tests/character_preprocessing.dat +252 -0
- justhtml-3.7.0/tests/justhtml-tests/document_shell_recovery.dat +366 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/foreign_content.dat +118 -0
- justhtml-3.7.0/tests/justhtml-tests/frameset_recovery.dat +229 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/head_noscript_recovery.dat +24 -0
- justhtml-3.7.0/tests/justhtml-tests/in_body_recovery.dat +175 -0
- justhtml-3.7.0/tests/justhtml-tests/raw_text_recovery.dat +166 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/select_recovery.dat +66 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/selectedcontent.dat +10 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/table_recovery.dat +107 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/template_recovery.dat +250 -0
- justhtml-3.7.0/tests/justhtml-tests/tokenizer_recovery.dat +238 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/xml_coercion.dat +24 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_parser_engine.py +6 -127
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_parser_regressions.py +0 -37
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_parser_tree.py +1 -372
- justhtml-3.6.0/tests/justhtml-tests/character_preprocessing.dat +0 -110
- justhtml-3.6.0/tests/justhtml-tests/document_shell_recovery.dat +0 -106
- justhtml-3.6.0/tests/justhtml-tests/frameset_recovery.dat +0 -60
- justhtml-3.6.0/tests/justhtml-tests/in_body_recovery.dat +0 -66
- {justhtml-3.6.0 → justhtml-3.7.0}/.github/copilot-instructions.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/.github/workflows/ci.yml +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/.github/workflows/publish.yml +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/.gitignore +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/.pre-commit-config.yaml +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/AGENTS.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/CODE_OF_CONDUCT.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/CONTRIBUTING.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/LICENSE +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/Makefile +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/PERFORMANCE.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/README.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/SECURITY.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/assets/justhtml-readme-explainer.png +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/chromium_parser_diff.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/fuzz.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/html5lib_engine_diff.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/parser_engine_gate.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/performance.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/benchmarks/profile.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/_config.yml +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/_layouts/default.html +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/api.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/assets/search.js +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/bleach-migration.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/building.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/cli.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/correctness.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/encoding.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/errors.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/fragments.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/html-cleaning.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/index.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/linkify.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/migration-examples.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/app.js +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/index.html +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/py/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/py/install_latest_justhtml.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/py/render.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/playground/py/use_local_repo.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/quickstart.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/sanitization.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/selectors.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/streaming.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/text.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/transforms.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/unsafe-handling.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/docs/url-cleaning.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/llms.txt +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/project_ideas.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/run_tests.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/scripts/release.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/__main__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/constants.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/doctype.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/entities.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/errors.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/rawtext.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/text.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/core/types.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/dom/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/dom/builder.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/context.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/encoding.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/options.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/scanner.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/parser/stream.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/py.typed +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/css.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/dom.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/policy.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/policy_defaults.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/rawtext.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/url/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/url/policy.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/url/runtime.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/sanitizer/url/spec.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/selector/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/selector/core.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/serializer/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/serializer/html.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/serializer/markdown.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/compile.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/linkify.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/linkify_core.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/runtime.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/src/justhtml/transforms/spec.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/test-summary.txt +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/README.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/data/wikipedia.html +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/__init__.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/encoding.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/regressions.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/reporter.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/serializer.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/harness/tree.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-sanitize-tests/cases.json +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/entities.test +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/foreign_stack_recovery.dat +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/iframe_srcdoc.dat +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/tokenizer_state_transitions.test +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/tokenizer_states.test +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/justhtml-tests/xml_coercion_invalid_characters.test +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/linkify-it/LICENSE.txt +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/linkify-it/README.md +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/linkify-it/fixtures/links.txt +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/linkify-it/fixtures/not_links.txt +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_builder.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_cli.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_docs_examples.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_encoding.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_entities.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_errors.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_linkify_internals.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_linkify_it.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_linkify_transform.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_node.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_playground_local_repo_file_list.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_sanitize.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_sanitize_integration.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_sanitize_transform.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_selector.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_serialize.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_stream.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_transform_runtime.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_transforms.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_transforms_compiler.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_transforms_sanitize_integration.py +0 -0
- {justhtml-3.6.0 → justhtml-3.7.0}/tests/test_wikipedia.py +0 -0
|
@@ -5,7 +5,26 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [3.7.0] - 2026-07-15
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Keep templates open in the head when they contain a processing instruction, matching the latest web-platform-tests tree-construction fixture.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Refresh the web-platform-tests tree-construction fixtures and comparison scores.
|
|
17
|
+
- Make the correctness benchmark skip an optional `html5-parser` installation when its libxml2 ABI conflicts with `lxml`.
|
|
18
|
+
|
|
19
|
+
## [3.6.1] - 2026-07-13
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Keep processing instructions inside a scripting-disabled head `noscript`, and process them in body mode inside templates as required by the latest WHATWG parsing rules.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Move raw parser input/output regressions from Python unit tests into the shared tree-construction fixture format.
|
|
9
28
|
|
|
10
29
|
## [3.6.0] - 2026-07-13
|
|
11
30
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: justhtml
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: A pure Python HTML5 parser that just works.
|
|
5
5
|
Project-URL: Homepage, https://github.com/emilstenstrom/justhtml
|
|
6
6
|
Project-URL: Issues, https://github.com/emilstenstrom/justhtml/issues
|
|
@@ -40,7 +40,7 @@ Requires-Dist: html5-parser; extra == 'benchmark'
|
|
|
40
40
|
Requires-Dist: html5lib; extra == 'benchmark'
|
|
41
41
|
Requires-Dist: lxml; extra == 'benchmark'
|
|
42
42
|
Requires-Dist: markupever; extra == 'benchmark'
|
|
43
|
-
Requires-Dist: selectolax>=0.4.
|
|
43
|
+
Requires-Dist: selectolax>=0.4.11; extra == 'benchmark'
|
|
44
44
|
Requires-Dist: turbohtml>=1.3.1; extra == 'benchmark'
|
|
45
45
|
Requires-Dist: zstandard; extra == 'benchmark'
|
|
46
46
|
Provides-Extra: dev
|
|
@@ -11,22 +11,22 @@ Use a different tool when one narrow requirement matters more than the whole pip
|
|
|
11
11
|
| Tool | HTML5 parsing [1] | Speed | Query | Build | Sanitize | Notes |
|
|
12
12
|
|------|------------------------------------------|-------|----------|-------|------------------|-------|
|
|
13
13
|
| **JustHTML**<br>Pure Python | ✅ 100% | ⚡ Fast | ✅ CSS selectors | ✅ `element()` | ✅ Built-in | Correct, secure, easy to install, and fast enough. |
|
|
14
|
-
| **`selectolax`**<br>Python wrapper of C-based Lexbor |
|
|
15
|
-
| **Chromium**<br>browser engine | 🟡 95.
|
|
16
|
-
| **`turbohtml`**<br>Python wrapper of a C core | 🟡 94.
|
|
17
|
-
| **WebKit**<br>browser engine | 🟡
|
|
18
|
-
| **Firefox**<br>browser engine | 🟡 93.
|
|
14
|
+
| **`selectolax`**<br>Python wrapper of C-based Lexbor | ✅ 100% | 🚀 Very Fast | ✅ CSS selectors | ✅ `create_node()` | ❌ Needs sanitization | Very fast. |
|
|
15
|
+
| **Chromium**<br>browser engine | 🟡 95.0% [2] | 🚀 Very Fast | — | — | — | Current browser-harness result. |
|
|
16
|
+
| **`turbohtml`**<br>Python wrapper of a C core | 🟡 94.2% | 🚀 Very Fast | ✅ CSS selectors, XPath | ✅ `E.*` builder | ✅ Built-in | Broad, compiled alternative with parsing, querying, and sanitization. |
|
|
17
|
+
| **WebKit**<br>browser engine | 🟡 93.9% [2] | 🚀 Very Fast | — | — | — | Current browser-harness result. |
|
|
18
|
+
| **Firefox**<br>browser engine | 🟡 93.1% [2] | 🚀 Very Fast | — | — | — | Current browser-harness result. |
|
|
19
19
|
| **`html5lib`**<br>Pure Python | 🟡 82.3% | 🐢 Slow | 🟡 XPath (lxml) | 🟡 Tree API | 🔴 [Deprecated](https://github.com/html5lib/html5lib-python/issues/443) | Unmaintained reference implementation; incomplete coverage of the tree-construction fixtures. |
|
|
20
|
-
| **`markupever`**<br>Python wrapper of Rust-based html5ever | 🟡 79.4% | 🚀 Very Fast | ✅ CSS selectors | ✅ `TreeDom .create_*()` | ❌ Needs sanitization | Fast, but
|
|
20
|
+
| **`markupever`**<br>Python wrapper of Rust-based html5ever | 🟡 79.4% | 🚀 Very Fast | ✅ CSS selectors | ✅ `TreeDom .create_*()` | ❌ Needs sanitization | Fast, but many fixtures cases abort its current parser process. |
|
|
21
21
|
| **`html5_parser`**<br>Python wrapper of C-based Gumbo | 🔴 47.8% | 🚀 Very Fast | 🟡 XPath (lxml) | 🟡 `etree` (lxml) | ❌ Needs sanitization | Fast, but its public tree API loses information needed by many fixtures. |
|
|
22
22
|
| **`BeautifulSoup`**<br>Pure Python | 🔴 0.3% (default) | 🐢 Slow | 🟡 Custom API | ✅ `new_tag()` API | ❌ Needs sanitization | Wraps `html.parser` (default). Can use lxml or html5lib. |
|
|
23
23
|
| **`html.parser`**<br>Python stdlib | 🔴 0.3% | ⚡ Fast | ❌ None | ❌ None | ❌ Needs sanitization | Standard library. Chokes on malformed HTML. |
|
|
24
|
-
| **`lxml`**<br>Python wrapper of C-based libxml2 | 🔴 0.
|
|
24
|
+
| **`lxml`**<br>Python wrapper of C-based libxml2 | 🔴 0.9% | 🚀 Very Fast | 🟡 XPath | ✅ `etree` / E-factory | ❌ Needs sanitization | Fast but not HTML5 compliant. Context-fragment cases are skipped; supported cases still perform poorly. Don't use the old lxml.html.clean module! |
|
|
25
25
|
|
|
26
|
-
[1]:
|
|
26
|
+
[1]: Library correctness scores are counted against the [web-platform-tests tree-construction tests](https://github.com/web-platform-tests/wpt/tree/master/html/syntax/parsing/resources). They were run locally at [2026-07-15](https://github.com/web-platform-tests/wpt/commit/4830edb033cb486fd0cd6f85b5e937cfc718704d) and cover 1,880 cases after excluding scripting-directed fixtures. JustHTML and Selectolax 0.4.11 passed all 1,880 cases; MarkupEver's score counts its 103 process-aborting cases as errors.
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
[2]: Current local rerun with [`justhtml-html5lib-tests-bench`](https://github.com/EmilStenstrom/justhtml-html5lib-tests-bench) against WPT commit [`
|
|
29
|
+
[2]: Current local rerun with [`justhtml-html5lib-tests-bench`](https://github.com/EmilStenstrom/justhtml-html5lib-tests-bench) against WPT commit [`4830edb`](https://github.com/web-platform-tests/wpt/commit/4830edb033cb486fd0cd6f85b5e937cfc718704d). Chromium 143.0.7499.4, WebKit 26.0, and Firefox 144.0.2 were compared against 1,908 cases; the harness skips 12 `#script-on` cases but includes `#script-off` cases, so these scores are not directly comparable to the 1,880-case Python-parser scores above.
|
|
30
30
|
|
|
31
31
|
## Why JustHTML
|
|
32
32
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "justhtml"
|
|
3
3
|
authors = [{ name = "Emil Stenström", email = "emil@emilstenstrom.se" }]
|
|
4
|
-
version = "3.
|
|
4
|
+
version = "3.7.0"
|
|
5
5
|
description = "A pure Python HTML5 parser that just works."
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
license = { file = "LICENSE" }
|
|
@@ -18,7 +18,7 @@ benchmark = [
|
|
|
18
18
|
"html5lib",
|
|
19
19
|
"lxml",
|
|
20
20
|
"beautifulsoup4",
|
|
21
|
-
"selectolax>=0.4.
|
|
21
|
+
"selectolax>=0.4.11",
|
|
22
22
|
"html5-parser",
|
|
23
23
|
"markupever",
|
|
24
24
|
"turbohtml>=1.3.1",
|
|
@@ -1632,7 +1632,7 @@ class ParseEngine:
|
|
|
1632
1632
|
append_text(html[lt:end] if gt == -1 else html[lt : gt + 1], lt)
|
|
1633
1633
|
pos = end if gt == -1 else gt + 1
|
|
1634
1634
|
continue
|
|
1635
|
-
if self._raw_mode and len(self._stack) > 1 and self._stack[-1].name in
|
|
1635
|
+
if self._raw_mode and len(self._stack) > 1 and self._stack[-1].name in self._rawtext_element_tags:
|
|
1636
1636
|
comment_end = end if gt == -1 else gt
|
|
1637
1637
|
append_text(html[lt:comment_end] if gt == -1 else html[lt : gt + 1], lt)
|
|
1638
1638
|
pos = end if gt == -1 else gt + 1
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#data
|
|
2
|
+
<math><mi>\x00</mi></math>
|
|
3
|
+
#errors
|
|
4
|
+
(1,6): expected-doctype-but-got-start-tag
|
|
5
|
+
(1,11): unexpected-null-character
|
|
6
|
+
|
|
7
|
+
#document
|
|
8
|
+
| <html>
|
|
9
|
+
| <head>
|
|
10
|
+
| <body>
|
|
11
|
+
| <math math>
|
|
12
|
+
| <math mi>
|
|
13
|
+
|
|
14
|
+
#data
|
|
15
|
+
<math><mi>\x00\x0c</mi></math>
|
|
16
|
+
#errors
|
|
17
|
+
(1,6): expected-doctype-but-got-start-tag
|
|
18
|
+
(1,11): unexpected-null-character
|
|
19
|
+
|
|
20
|
+
#document
|
|
21
|
+
| <html>
|
|
22
|
+
| <head>
|
|
23
|
+
| <body>
|
|
24
|
+
| <math math>
|
|
25
|
+
| <math mi>
|
|
26
|
+
| ""
|
|
27
|
+
|
|
28
|
+
#data
|
|
29
|
+
<math><mi> </mi></math>
|
|
30
|
+
#errors
|
|
31
|
+
(1,1): expected-doctype-but-got-start-tag
|
|
32
|
+
|
|
33
|
+
#document
|
|
34
|
+
| <html>
|
|
35
|
+
| <head>
|
|
36
|
+
| <body>
|
|
37
|
+
| <math math>
|
|
38
|
+
| <math mi>
|
|
39
|
+
| " "
|
|
40
|
+
|
|
41
|
+
#data
|
|
42
|
+
<math><mi>\x0ctext</mi></math>
|
|
43
|
+
#errors
|
|
44
|
+
(1,1): expected-doctype-but-got-start-tag
|
|
45
|
+
|
|
46
|
+
#document
|
|
47
|
+
| <html>
|
|
48
|
+
| <head>
|
|
49
|
+
| <body>
|
|
50
|
+
| <math math>
|
|
51
|
+
| <math mi>
|
|
52
|
+
| "text"
|
|
53
|
+
|
|
54
|
+
#data
|
|
55
|
+
<select>\x0ctext</select>
|
|
56
|
+
#errors
|
|
57
|
+
(1,1): expected-doctype-but-got-start-tag
|
|
58
|
+
|
|
59
|
+
#document
|
|
60
|
+
| <html>
|
|
61
|
+
| <head>
|
|
62
|
+
| <body>
|
|
63
|
+
| <select>
|
|
64
|
+
| "text"
|
|
65
|
+
|
|
66
|
+
#data
|
|
67
|
+
<table>\x00</table>
|
|
68
|
+
#errors
|
|
69
|
+
(1,7): expected-doctype-but-got-start-tag
|
|
70
|
+
(1,8): unexpected-null-character
|
|
71
|
+
|
|
72
|
+
#document
|
|
73
|
+
| <html>
|
|
74
|
+
| <head>
|
|
75
|
+
| <body>
|
|
76
|
+
| <table>
|
|
77
|
+
|
|
78
|
+
#data
|
|
79
|
+
<head></head>\x00
|
|
80
|
+
#errors
|
|
81
|
+
(1,6): expected-doctype-but-got-start-tag
|
|
82
|
+
(1,14): unexpected-null-character
|
|
83
|
+
|
|
84
|
+
#document
|
|
85
|
+
| <html>
|
|
86
|
+
| <head>
|
|
87
|
+
| <body>
|
|
88
|
+
|
|
89
|
+
#data
|
|
90
|
+
<table>\x0c</table>
|
|
91
|
+
#errors
|
|
92
|
+
(1,1): expected-doctype-but-got-start-tag
|
|
93
|
+
|
|
94
|
+
#document
|
|
95
|
+
| <html>
|
|
96
|
+
| <head>
|
|
97
|
+
| <body>
|
|
98
|
+
| <table>
|
|
99
|
+
| ""
|
|
100
|
+
|
|
101
|
+
#data
|
|
102
|
+
<!doctype html>\x00
|
|
103
|
+
#errors
|
|
104
|
+
(1,16): unexpected-null-character
|
|
105
|
+
|
|
106
|
+
#document
|
|
107
|
+
| <!DOCTYPE html>
|
|
108
|
+
| <html>
|
|
109
|
+
| <head>
|
|
110
|
+
| <body>
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
#data
|
|
114
|
+
<!--a\x00b-->
|
|
115
|
+
#errors
|
|
116
|
+
(1,1): expected-doctype-but-got-chars
|
|
117
|
+
(1,6): unexpected-null-character
|
|
118
|
+
#document
|
|
119
|
+
| <!-- a�b -->
|
|
120
|
+
| <html>
|
|
121
|
+
| <head>
|
|
122
|
+
| <body>
|
|
123
|
+
|
|
124
|
+
#data
|
|
125
|
+
<frameset>\x0d\x0a
|
|
126
|
+
#errors
|
|
127
|
+
#document
|
|
128
|
+
| <html>
|
|
129
|
+
| <head>
|
|
130
|
+
| <frameset>
|
|
131
|
+
| "
|
|
132
|
+
"
|
|
133
|
+
#data
|
|
134
|
+
<!--a-
|
|
135
|
+
#errors
|
|
136
|
+
(1,1): expected-doctype-but-got-chars
|
|
137
|
+
(1,6): eof-in-comment
|
|
138
|
+
#document
|
|
139
|
+
| <!-- a -->
|
|
140
|
+
| <html>
|
|
141
|
+
| <head>
|
|
142
|
+
| <body>
|
|
143
|
+
|
|
144
|
+
#data
|
|
145
|
+
<!x\x0d\x0ay>
|
|
146
|
+
#errors
|
|
147
|
+
(1,1): expected-doctype-but-got-chars
|
|
148
|
+
#document
|
|
149
|
+
| <!-- x
|
|
150
|
+
y -->
|
|
151
|
+
| <html>
|
|
152
|
+
| <head>
|
|
153
|
+
| <body>
|
|
154
|
+
|
|
155
|
+
#data
|
|
156
|
+
<\x00div>
|
|
157
|
+
#errors
|
|
158
|
+
(1,1): expected-doctype-but-got-chars
|
|
159
|
+
(1,2): unexpected-null-character
|
|
160
|
+
#document
|
|
161
|
+
| <html>
|
|
162
|
+
| <head>
|
|
163
|
+
| <body>
|
|
164
|
+
| "<�div>"
|
|
165
|
+
|
|
166
|
+
#data
|
|
167
|
+
</>
|
|
168
|
+
#errors
|
|
169
|
+
(1,1): expected-doctype-but-got-chars
|
|
170
|
+
#document
|
|
171
|
+
| <html>
|
|
172
|
+
| <head>
|
|
173
|
+
| <body>
|
|
174
|
+
|
|
175
|
+
#data
|
|
176
|
+
\x00\x0cA
|
|
177
|
+
#errors
|
|
178
|
+
(1,1): unexpected-null-character
|
|
179
|
+
(1,1): expected-doctype-but-got-chars
|
|
180
|
+
#document
|
|
181
|
+
| <html>
|
|
182
|
+
| <head>
|
|
183
|
+
| <body>
|
|
184
|
+
| "A"
|
|
185
|
+
|
|
186
|
+
#data
|
|
187
|
+
<!DOCTYPE\x00html>
|
|
188
|
+
#errors
|
|
189
|
+
(1,10): unexpected-null-character
|
|
190
|
+
(1,15): unknown-doctype
|
|
191
|
+
#document
|
|
192
|
+
| <!DOCTYPE �html>
|
|
193
|
+
| <html>
|
|
194
|
+
| <head>
|
|
195
|
+
| <body>
|
|
196
|
+
|
|
197
|
+
#data
|
|
198
|
+
&#x;
|
|
199
|
+
#errors
|
|
200
|
+
(1,1): expected-doctype-but-got-chars
|
|
201
|
+
#document
|
|
202
|
+
| <html>
|
|
203
|
+
| <head>
|
|
204
|
+
| <body>
|
|
205
|
+
| "&#x;"
|
|
206
|
+
|
|
207
|
+
#data
|
|
208
|
+
<!--first--><!DOCTYPE\x0d\x0ahtml>
|
|
209
|
+
#errors
|
|
210
|
+
(1,1): expected-doctype-but-got-chars
|
|
211
|
+
#document
|
|
212
|
+
| <!-- first -->
|
|
213
|
+
| <!DOCTYPE html>
|
|
214
|
+
| <html>
|
|
215
|
+
| <head>
|
|
216
|
+
| <body>
|
|
217
|
+
|
|
218
|
+
#data
|
|
219
|
+
<o\x0ce="\x0d">
|
|
220
|
+
#errors
|
|
221
|
+
(1,9): expected-doctype-but-got-start-tag
|
|
222
|
+
#document
|
|
223
|
+
| <html>
|
|
224
|
+
| <head>
|
|
225
|
+
| <body>
|
|
226
|
+
| <o>
|
|
227
|
+
| e="
|
|
228
|
+
"
|
|
229
|
+
|
|
230
|
+
#data
|
|
231
|
+
<d 2="\x0d">
|
|
232
|
+
#errors
|
|
233
|
+
(1,9): expected-doctype-but-got-start-tag
|
|
234
|
+
#document
|
|
235
|
+
| <html>
|
|
236
|
+
| <head>
|
|
237
|
+
| <body>
|
|
238
|
+
| <d>
|
|
239
|
+
| 2="
|
|
240
|
+
"
|
|
241
|
+
|
|
242
|
+
#data
|
|
243
|
+
<a 8=
\x0d>
|
|
244
|
+
#errors
|
|
245
|
+
(1,11): expected-doctype-but-got-start-tag
|
|
246
|
+
#document
|
|
247
|
+
| <html>
|
|
248
|
+
| <head>
|
|
249
|
+
| <body>
|
|
250
|
+
| <a>
|
|
251
|
+
| 8="
|
|
252
|
+
"
|