pyhtml2text 0.3.0__tar.gz → 0.4.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.
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/.gitignore +1 -0
- pyhtml2text-0.4.0/CHANGELOG.md +69 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/Cargo.lock +23 -105
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/Cargo.toml +7 -7
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/LICENSE +0 -1
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/PKG-INFO +17 -15
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/README.md +15 -12
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/pyproject.toml +3 -4
- pyhtml2text-0.4.0/src/dom.rs +290 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/src/lib.rs +19 -29
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/src/markdown.rs +9 -8
- pyhtml2text-0.4.0/src/table.rs +1226 -0
- pyhtml2text-0.4.0/src/text.rs +1333 -0
- pyhtml2text-0.4.0/src/url.rs +116 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/tests/test_basic.py +23 -9
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/tests/test_markdown.py +2 -0
- pyhtml2text-0.4.0/vendor/README.md +48 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tree_builder/mod.rs +95 -118
- pyhtml2text-0.4.0/vendor/html5ever/src/tree_builder/open_elems.rs +501 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tree_builder/rules.rs +124 -101
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tree_builder/tag_sets.rs +10 -0
- pyhtml2text-0.3.0/CHANGELOG.md +0 -31
- pyhtml2text-0.3.0/vendor/README.md +0 -13
- pyhtml2text-0.3.0/vendor/html5ever/src/tree_builder/open_elems.rs +0 -134
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/python/pyhtml2text/__init__.py +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/python/pyhtml2text/__init__.pyi +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/python/pyhtml2text/py.typed +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/tests/markdown_check.py +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/Cargo.toml +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/LICENSE-APACHE +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/LICENSE-MIT +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/README.md +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/driver.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/encoding.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/lib.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/macros.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/serialize/mod.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tokenizer/char_ref/mod.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tokenizer/interface.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tokenizer/mod.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tokenizer/states.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tree_builder/data.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/tree_builder/types.rs +0 -0
- {pyhtml2text-0.3.0 → pyhtml2text-0.4.0}/vendor/html5ever/src/util/str.rs +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.4.0 (2026-10-22)
|
|
4
|
+
|
|
5
|
+
- `html2text()` is rendered by this package's own code. The library it used
|
|
6
|
+
before came from a fork that can no longer be fetched, so the source
|
|
7
|
+
distribution and fresh builds of 0.3.1 fail. The new renderer is a
|
|
8
|
+
clean-room implementation: it was written from 0.3.1's output, the HTML
|
|
9
|
+
standard and RFC 3986, without reference to the old library's source.
|
|
10
|
+
- Output is the same as 0.3.1's, byte for byte, with every option set: on
|
|
11
|
+
the benchmark corpus, on 38 of 39 other real pages (the last differs at
|
|
12
|
+
width 40 only), and on 1,500 random documents without tables. With tables,
|
|
13
|
+
99.2% of 2,000 random documents match under each option set. The known
|
|
14
|
+
differences are all in unusual markup:
|
|
15
|
+
- A cell with nothing in it, beside a cell spanning rows: 0.3.1 draws the
|
|
16
|
+
span against the wrong cell, so borders and line breaks land a column
|
|
17
|
+
off. They now follow the spanning cell.
|
|
18
|
+
- A table with nothing to show whose cells span into further empty rows,
|
|
19
|
+
an empty `<pre>` or heading directly inside `<pre>`, and a table with
|
|
20
|
+
nothing to show in a paragraph: 0.3.1 writes an extra blank line.
|
|
21
|
+
- Headings, quotes and list items squeezed to fewer than three columns
|
|
22
|
+
break `**` and other markers in different places.
|
|
23
|
+
- Some emoji sequences (joined with U+200D) and Arabic lam-alef pairs, cut
|
|
24
|
+
at the end of a line in a narrow table cell.
|
|
25
|
+
- `html2text()` is 1.2–2× faster on real pages (7.0 ms against 10.8 ms for
|
|
26
|
+
a 780 KB Wikipedia article) and 2× faster on short snippets.
|
|
27
|
+
- `html2markdown()` output is unchanged.
|
|
28
|
+
- PyO3 0.30. Building from source needs maturin 1.9.4 or later.
|
|
29
|
+
|
|
30
|
+
## 0.3.1 (2026-10-19)
|
|
31
|
+
|
|
32
|
+
- The vendored html5ever now carries
|
|
33
|
+
[servo/html5ever#800](https://github.com/servo/html5ever/pull/800) by Josef
|
|
34
|
+
Guenther in place of our narrower patch. Every "in scope" check and the
|
|
35
|
+
other searches of the stack of open elements are now O(1), so unmatched
|
|
36
|
+
end tags and end tags inside SVG or MathML no longer make deeply nested
|
|
37
|
+
HTML quadratic: 32,000 nested `<span>` followed by as many unmatched
|
|
38
|
+
`</em>` went from 3.4 s to 0.02 s. Output is unchanged.
|
|
39
|
+
- About 0.4 µs more per call, and 0–2% on real pages.
|
|
40
|
+
|
|
41
|
+
## 0.3.0 (2026-10-15)
|
|
42
|
+
|
|
43
|
+
- New `html2markdown(html, *, base_url=None)`: HTML to CommonMark with
|
|
44
|
+
GitHub's tables and strikethrough. Links and images keep their URLs (made
|
|
45
|
+
absolute with `base_url`), tables become pipe tables, code blocks are
|
|
46
|
+
fenced with their language, and characters are escaped only where Markdown
|
|
47
|
+
would misread them. 3–13× faster than markdownify, html2text and
|
|
48
|
+
html-to-markdown on real pages.
|
|
49
|
+
- `html2text()` output is unchanged.
|
|
50
|
+
|
|
51
|
+
## 0.2.0 (2026-10-15)
|
|
52
|
+
|
|
53
|
+
- 1.5–1.7× faster than 0.1.0 on real web pages, and 2× faster on short
|
|
54
|
+
snippets. Output is unchanged.
|
|
55
|
+
- Wheels for Linux x86_64/aarch64, macOS and Windows x64 are built with
|
|
56
|
+
profile-guided optimisation.
|
|
57
|
+
- Uses mimalloc as the allocator (except on glibc armv7, ppc64le and s390x).
|
|
58
|
+
- Style rules are shared rather than rebuilt and copied for every call.
|
|
59
|
+
- Deeply nested HTML no longer takes quadratic time to parse: 40,000 nested
|
|
60
|
+
`<ul>` lists went from 6s to 0.14s (patched html5ever, see `vendor/`).
|
|
61
|
+
- `html` can be UTF-8 `bytes` as well as `str`.
|
|
62
|
+
- An internal error now raises `ValueError` rather than `PanicException`
|
|
63
|
+
(which `except Exception` doesn't catch).
|
|
64
|
+
- Supports free-threaded Python without re-enabling the GIL.
|
|
65
|
+
- Requires Python 3.10 or later (3.9 is end-of-life).
|
|
66
|
+
|
|
67
|
+
## 0.1.0 (2026-10-15)
|
|
68
|
+
|
|
69
|
+
- First release: `html2text()` with `base_url` support.
|
|
@@ -2,12 +2,6 @@
|
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
3
|
version = 4
|
|
4
4
|
|
|
5
|
-
[[package]]
|
|
6
|
-
name = "autocfg"
|
|
7
|
-
version = "1.5.1"
|
|
8
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
-
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
10
|
-
|
|
11
5
|
[[package]]
|
|
12
6
|
name = "bitflags"
|
|
13
7
|
version = "2.13.2"
|
|
@@ -16,9 +10,9 @@ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
|
|
|
16
10
|
|
|
17
11
|
[[package]]
|
|
18
12
|
name = "cc"
|
|
19
|
-
version = "1.
|
|
13
|
+
version = "1.9.0"
|
|
20
14
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
-
checksum = "
|
|
15
|
+
checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df"
|
|
22
16
|
dependencies = [
|
|
23
17
|
"find-msvc-tools",
|
|
24
18
|
"shlex",
|
|
@@ -38,9 +32,9 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
|
|
38
32
|
|
|
39
33
|
[[package]]
|
|
40
34
|
name = "find-msvc-tools"
|
|
41
|
-
version = "0.1.
|
|
35
|
+
version = "0.1.15"
|
|
42
36
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
43
|
-
checksum = "
|
|
37
|
+
checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48"
|
|
44
38
|
|
|
45
39
|
[[package]]
|
|
46
40
|
name = "heck"
|
|
@@ -48,17 +42,6 @@ version = "0.5.0"
|
|
|
48
42
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
49
43
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
50
44
|
|
|
51
|
-
[[package]]
|
|
52
|
-
name = "html2text"
|
|
53
|
-
version = "0.17.1"
|
|
54
|
-
source = "git+https://github.com/jaredlynskey/rust-html2text?rev=b42930f8e6688ea121daf392e27a7d9812e6192d#b42930f8e6688ea121daf392e27a7d9812e6192d"
|
|
55
|
-
dependencies = [
|
|
56
|
-
"html5ever",
|
|
57
|
-
"tendril",
|
|
58
|
-
"thiserror",
|
|
59
|
-
"unicode-width",
|
|
60
|
-
]
|
|
61
|
-
|
|
62
45
|
[[package]]
|
|
63
46
|
name = "html5ever"
|
|
64
47
|
version = "0.39.0"
|
|
@@ -67,20 +50,11 @@ dependencies = [
|
|
|
67
50
|
"markup5ever",
|
|
68
51
|
]
|
|
69
52
|
|
|
70
|
-
[[package]]
|
|
71
|
-
name = "indoc"
|
|
72
|
-
version = "2.0.8"
|
|
73
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
74
|
-
checksum = "a37b2691796cffeb8a8cd305ac66e65841559f147f4e63231d0eafa4db5384d1"
|
|
75
|
-
dependencies = [
|
|
76
|
-
"rustversion",
|
|
77
|
-
]
|
|
78
|
-
|
|
79
53
|
[[package]]
|
|
80
54
|
name = "libc"
|
|
81
|
-
version = "0.2.
|
|
55
|
+
version = "0.2.191"
|
|
82
56
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
83
|
-
checksum = "
|
|
57
|
+
checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
|
|
84
58
|
|
|
85
59
|
[[package]]
|
|
86
60
|
name = "libmimalloc-sys"
|
|
@@ -123,15 +97,6 @@ version = "2.8.3"
|
|
|
123
97
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
124
98
|
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
125
99
|
|
|
126
|
-
[[package]]
|
|
127
|
-
name = "memoffset"
|
|
128
|
-
version = "0.9.1"
|
|
129
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
130
|
-
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
131
|
-
dependencies = [
|
|
132
|
-
"autocfg",
|
|
133
|
-
]
|
|
134
|
-
|
|
135
100
|
[[package]]
|
|
136
101
|
name = "mimalloc"
|
|
137
102
|
version = "0.1.52"
|
|
@@ -238,9 +203,9 @@ dependencies = [
|
|
|
238
203
|
|
|
239
204
|
[[package]]
|
|
240
205
|
name = "pulldown-cmark"
|
|
241
|
-
version = "0.13.
|
|
206
|
+
version = "0.13.5"
|
|
242
207
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
243
|
-
checksum = "
|
|
208
|
+
checksum = "278e9268c93b9e498a2da46c34d90ba93a3255eb99009646398f34bc73ab36eb"
|
|
244
209
|
dependencies = [
|
|
245
210
|
"bitflags",
|
|
246
211
|
"memchr",
|
|
@@ -249,46 +214,43 @@ dependencies = [
|
|
|
249
214
|
|
|
250
215
|
[[package]]
|
|
251
216
|
name = "pyhtml2text"
|
|
252
|
-
version = "0.
|
|
217
|
+
version = "0.4.0"
|
|
253
218
|
dependencies = [
|
|
254
|
-
"html2text",
|
|
255
219
|
"html5ever",
|
|
256
220
|
"mimalloc",
|
|
257
221
|
"pulldown-cmark",
|
|
258
222
|
"pyo3",
|
|
223
|
+
"unicode-width",
|
|
259
224
|
]
|
|
260
225
|
|
|
261
226
|
[[package]]
|
|
262
227
|
name = "pyo3"
|
|
263
|
-
version = "0.
|
|
228
|
+
version = "0.30.1"
|
|
264
229
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
265
|
-
checksum = "
|
|
230
|
+
checksum = "229ca13b8a15bb0d1487b81ab975bfcd97513416499a8312011b6036e42e0de4"
|
|
266
231
|
dependencies = [
|
|
267
|
-
"indoc",
|
|
268
232
|
"libc",
|
|
269
|
-
"memoffset",
|
|
270
233
|
"once_cell",
|
|
271
234
|
"portable-atomic",
|
|
272
235
|
"pyo3-build-config",
|
|
273
236
|
"pyo3-ffi",
|
|
274
237
|
"pyo3-macros",
|
|
275
|
-
"unindent",
|
|
276
238
|
]
|
|
277
239
|
|
|
278
240
|
[[package]]
|
|
279
241
|
name = "pyo3-build-config"
|
|
280
|
-
version = "0.
|
|
242
|
+
version = "0.30.1"
|
|
281
243
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
282
|
-
checksum = "
|
|
244
|
+
checksum = "70130e2b6dd1ee589a8788026a429561ca5c40fa7a2fa7914c2282eddae24700"
|
|
283
245
|
dependencies = [
|
|
284
246
|
"target-lexicon",
|
|
285
247
|
]
|
|
286
248
|
|
|
287
249
|
[[package]]
|
|
288
250
|
name = "pyo3-ffi"
|
|
289
|
-
version = "0.
|
|
251
|
+
version = "0.30.1"
|
|
290
252
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
291
|
-
checksum = "
|
|
253
|
+
checksum = "5e7ff73c555c286d212d4ce7e5fbda845a973c4f61bd5f160f5f2c3c2a04d1c4"
|
|
292
254
|
dependencies = [
|
|
293
255
|
"libc",
|
|
294
256
|
"pyo3-build-config",
|
|
@@ -296,27 +258,26 @@ dependencies = [
|
|
|
296
258
|
|
|
297
259
|
[[package]]
|
|
298
260
|
name = "pyo3-macros"
|
|
299
|
-
version = "0.
|
|
261
|
+
version = "0.30.1"
|
|
300
262
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
301
|
-
checksum = "
|
|
263
|
+
checksum = "c46d2e5862c7bb8207e3b639f713dda3c499933444784154c11d013c5a691b60"
|
|
302
264
|
dependencies = [
|
|
303
265
|
"proc-macro2",
|
|
304
266
|
"pyo3-macros-backend",
|
|
305
267
|
"quote",
|
|
306
|
-
"syn
|
|
268
|
+
"syn",
|
|
307
269
|
]
|
|
308
270
|
|
|
309
271
|
[[package]]
|
|
310
272
|
name = "pyo3-macros-backend"
|
|
311
|
-
version = "0.
|
|
273
|
+
version = "0.30.1"
|
|
312
274
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
313
|
-
checksum = "
|
|
275
|
+
checksum = "38b89f066f2ae72a2aef52d1537ca2fcd104440ebfadee06e97aa90738a25b9b"
|
|
314
276
|
dependencies = [
|
|
315
277
|
"heck",
|
|
316
278
|
"proc-macro2",
|
|
317
|
-
"pyo3-build-config",
|
|
318
279
|
"quote",
|
|
319
|
-
"syn
|
|
280
|
+
"syn",
|
|
320
281
|
]
|
|
321
282
|
|
|
322
283
|
[[package]]
|
|
@@ -337,12 +298,6 @@ dependencies = [
|
|
|
337
298
|
"bitflags",
|
|
338
299
|
]
|
|
339
300
|
|
|
340
|
-
[[package]]
|
|
341
|
-
name = "rustversion"
|
|
342
|
-
version = "1.0.23"
|
|
343
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
344
|
-
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
345
|
-
|
|
346
301
|
[[package]]
|
|
347
302
|
name = "scopeguard"
|
|
348
303
|
version = "1.2.0"
|
|
@@ -375,7 +330,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
|
375
330
|
dependencies = [
|
|
376
331
|
"proc-macro2",
|
|
377
332
|
"quote",
|
|
378
|
-
"syn
|
|
333
|
+
"syn",
|
|
379
334
|
]
|
|
380
335
|
|
|
381
336
|
[[package]]
|
|
@@ -420,17 +375,6 @@ dependencies = [
|
|
|
420
375
|
"quote",
|
|
421
376
|
]
|
|
422
377
|
|
|
423
|
-
[[package]]
|
|
424
|
-
name = "syn"
|
|
425
|
-
version = "2.0.119"
|
|
426
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
427
|
-
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
428
|
-
dependencies = [
|
|
429
|
-
"proc-macro2",
|
|
430
|
-
"quote",
|
|
431
|
-
"unicode-ident",
|
|
432
|
-
]
|
|
433
|
-
|
|
434
378
|
[[package]]
|
|
435
379
|
name = "syn"
|
|
436
380
|
version = "3.0.9"
|
|
@@ -457,26 +401,6 @@ dependencies = [
|
|
|
457
401
|
"new_debug_unreachable",
|
|
458
402
|
]
|
|
459
403
|
|
|
460
|
-
[[package]]
|
|
461
|
-
name = "thiserror"
|
|
462
|
-
version = "2.0.21"
|
|
463
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
464
|
-
checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e"
|
|
465
|
-
dependencies = [
|
|
466
|
-
"thiserror-impl",
|
|
467
|
-
]
|
|
468
|
-
|
|
469
|
-
[[package]]
|
|
470
|
-
name = "thiserror-impl"
|
|
471
|
-
version = "2.0.21"
|
|
472
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
473
|
-
checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524"
|
|
474
|
-
dependencies = [
|
|
475
|
-
"proc-macro2",
|
|
476
|
-
"quote",
|
|
477
|
-
"syn 3.0.9",
|
|
478
|
-
]
|
|
479
|
-
|
|
480
404
|
[[package]]
|
|
481
405
|
name = "unicase"
|
|
482
406
|
version = "2.10.0"
|
|
@@ -495,12 +419,6 @@ version = "0.2.2"
|
|
|
495
419
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
496
420
|
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
|
497
421
|
|
|
498
|
-
[[package]]
|
|
499
|
-
name = "unindent"
|
|
500
|
-
version = "0.2.4"
|
|
501
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
502
|
-
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
503
|
-
|
|
504
422
|
[[package]]
|
|
505
423
|
name = "web_atoms"
|
|
506
424
|
version = "0.2.6"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "pyhtml2text"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
publish = false
|
|
@@ -11,16 +11,16 @@ name = "_pyhtml2text"
|
|
|
11
11
|
crate-type = ["cdylib"]
|
|
12
12
|
|
|
13
13
|
[dependencies]
|
|
14
|
-
pyo3 = { version = "0.
|
|
15
|
-
#
|
|
16
|
-
# changes and the DOM exports the Markdown output uses (branch pyhtml2text-perf).
|
|
17
|
-
html2text = { git = "https://github.com/jaredlynskey/rust-html2text", rev = "b42930f8e6688ea121daf392e27a7d9812e6192d" }
|
|
18
|
-
# The parser html2text uses; patched below. Used directly to read element attributes.
|
|
14
|
+
pyo3 = { version = "0.30", features = ["abi3-py310"] }
|
|
15
|
+
# The HTML parser; patched below.
|
|
19
16
|
html5ever = "0.39"
|
|
17
|
+
# Display width of characters, for wrapping.
|
|
18
|
+
unicode-width = "=0.2.2"
|
|
20
19
|
# Reads the Markdown back to check that emphasis parses as intended.
|
|
21
20
|
pulldown-cmark = { version = "0.13", default-features = false }
|
|
22
21
|
|
|
23
|
-
# Much faster than the system allocators for
|
|
22
|
+
# Much faster than the system allocators for the many small allocations of
|
|
23
|
+
# parsing and rendering.
|
|
24
24
|
# Not on glibc armv7/ppc64le/s390x: their manylinux2014 cross compilers are too
|
|
25
25
|
# old to build it (keep in sync with the cfg in src/lib.rs).
|
|
26
26
|
[target.'cfg(not(all(target_env = "gnu", any(target_arch = "arm", target_arch = "powerpc64", target_arch = "s390x"))))'.dependencies]
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 Jared Lynskey
|
|
4
|
-
Copyright (c) 2016 Chris Emerson (rust-html2text, which this package embeds)
|
|
5
4
|
|
|
6
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhtml2text
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Topic :: Text Processing :: Markup :: HTML
|
|
7
7
|
License-File: LICENSE
|
|
8
|
-
Summary: Fast HTML to plain text, with relative link resolution
|
|
8
|
+
Summary: Fast HTML to plain text and Markdown, with relative link resolution
|
|
9
9
|
Keywords: html,text,markdown,html2text
|
|
10
10
|
Author-email: Jared Lynskey <jared@lynskey.co.nz>
|
|
11
11
|
License-Expression: MIT
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
14
14
|
Project-URL: Source, https://github.com/jaredlynskey/pyhtml2text
|
|
15
|
-
Project-URL: Upstream, https://github.com/jugglerchris/rust-html2text
|
|
16
15
|
|
|
17
16
|
# pyhtml2text
|
|
18
17
|
|
|
19
|
-
Fast HTML to plain text and to Markdown for Python,
|
|
20
|
-
[rust-html2text](https://github.com/jugglerchris/rust-html2text).
|
|
18
|
+
Fast HTML to plain text and to Markdown for Python, written in Rust.
|
|
21
19
|
|
|
22
20
|
Relative links can be resolved against the page's URL, so the output's links
|
|
23
21
|
work on their own.
|
|
@@ -114,7 +112,7 @@ To plain text:
|
|
|
114
112
|
|---|---|---|
|
|
115
113
|
| [html2text](https://pypi.org/project/html2text/) (pure Python) | 71.5 ms | 14.9 ms |
|
|
116
114
|
| [html2text-rs](https://pypi.org/project/html2text-rs/) | 15.2 ms | 2.5 ms |
|
|
117
|
-
| **pyhtml2text** | **
|
|
115
|
+
| **pyhtml2text** | **7.0 ms** | **1.3 ms** |
|
|
118
116
|
|
|
119
117
|
- The GIL is released while converting, so threads scale across cores. On
|
|
120
118
|
free-threaded Python (3.14t) the module runs without re-enabling the GIL.
|
|
@@ -122,16 +120,20 @@ To plain text:
|
|
|
122
120
|
profile-guided optimisation, which makes them about 25% faster. Other
|
|
123
121
|
platforms get the same code without it.
|
|
124
122
|
- Deeply nested HTML is parsed in linear time, so hostile input can't stall a
|
|
125
|
-
worker: 40,000 nested lists take 0.14 s, against 6 s with stock html5ever
|
|
123
|
+
worker: 40,000 nested lists take 0.14 s, against 6 s with stock html5ever,
|
|
124
|
+
and 100,000 levels of nesting followed by unmatched end tags take under
|
|
125
|
+
0.1 s.
|
|
126
126
|
|
|
127
127
|
## Credits
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
`vendor/`).
|
|
134
|
-
[
|
|
135
|
-
|
|
136
|
-
|
|
129
|
+
HTML is parsed by a copy of [html5ever](https://github.com/servo/html5ever)
|
|
130
|
+
(MIT/Apache-2.0) with
|
|
131
|
+
[servo/html5ever#800](https://github.com/servo/html5ever/pull/800) by Josef
|
|
132
|
+
Guenther applied, which makes parsing deeply nested HTML linear (see
|
|
133
|
+
`vendor/`). Text is measured with
|
|
134
|
+
[unicode-width](https://github.com/unicode-rs/unicode-width) (MIT/Apache-2.0)
|
|
135
|
+
and Markdown output is checked with
|
|
136
|
+
[pulldown-cmark](https://github.com/raphlinus/pulldown-cmark) (MIT). This
|
|
137
|
+
package isn't affiliated with or endorsed by any of these projects, so please
|
|
138
|
+
report issues here rather than upstream.
|
|
137
139
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# pyhtml2text
|
|
2
2
|
|
|
3
|
-
Fast HTML to plain text and to Markdown for Python,
|
|
4
|
-
[rust-html2text](https://github.com/jugglerchris/rust-html2text).
|
|
3
|
+
Fast HTML to plain text and to Markdown for Python, written in Rust.
|
|
5
4
|
|
|
6
5
|
Relative links can be resolved against the page's URL, so the output's links
|
|
7
6
|
work on their own.
|
|
@@ -98,7 +97,7 @@ To plain text:
|
|
|
98
97
|
|---|---|---|
|
|
99
98
|
| [html2text](https://pypi.org/project/html2text/) (pure Python) | 71.5 ms | 14.9 ms |
|
|
100
99
|
| [html2text-rs](https://pypi.org/project/html2text-rs/) | 15.2 ms | 2.5 ms |
|
|
101
|
-
| **pyhtml2text** | **
|
|
100
|
+
| **pyhtml2text** | **7.0 ms** | **1.3 ms** |
|
|
102
101
|
|
|
103
102
|
- The GIL is released while converting, so threads scale across cores. On
|
|
104
103
|
free-threaded Python (3.14t) the module runs without re-enabling the GIL.
|
|
@@ -106,15 +105,19 @@ To plain text:
|
|
|
106
105
|
profile-guided optimisation, which makes them about 25% faster. Other
|
|
107
106
|
platforms get the same code without it.
|
|
108
107
|
- Deeply nested HTML is parsed in linear time, so hostile input can't stall a
|
|
109
|
-
worker: 40,000 nested lists take 0.14 s, against 6 s with stock html5ever
|
|
108
|
+
worker: 40,000 nested lists take 0.14 s, against 6 s with stock html5ever,
|
|
109
|
+
and 100,000 levels of nesting followed by unmatched end tags take under
|
|
110
|
+
0.1 s.
|
|
110
111
|
|
|
111
112
|
## Credits
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
`vendor/`).
|
|
118
|
-
[
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
HTML is parsed by a copy of [html5ever](https://github.com/servo/html5ever)
|
|
115
|
+
(MIT/Apache-2.0) with
|
|
116
|
+
[servo/html5ever#800](https://github.com/servo/html5ever/pull/800) by Josef
|
|
117
|
+
Guenther applied, which makes parsing deeply nested HTML linear (see
|
|
118
|
+
`vendor/`). Text is measured with
|
|
119
|
+
[unicode-width](https://github.com/unicode-rs/unicode-width) (MIT/Apache-2.0)
|
|
120
|
+
and Markdown output is checked with
|
|
121
|
+
[pulldown-cmark](https://github.com/raphlinus/pulldown-cmark) (MIT). This
|
|
122
|
+
package isn't affiliated with or endorsed by any of these projects, so please
|
|
123
|
+
report issues here rather than upstream.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["maturin>=1.
|
|
2
|
+
requires = ["maturin>=1.9.4,<2"]
|
|
3
3
|
build-backend = "maturin"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyhtml2text"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Fast HTML to plain text, with relative link resolution
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Fast HTML to plain text and Markdown, with relative link resolution"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
@@ -20,7 +20,6 @@ classifiers = [
|
|
|
20
20
|
|
|
21
21
|
[project.urls]
|
|
22
22
|
Source = "https://github.com/jaredlynskey/pyhtml2text"
|
|
23
|
-
Upstream = "https://github.com/jugglerchris/rust-html2text"
|
|
24
23
|
|
|
25
24
|
[tool.maturin]
|
|
26
25
|
python-source = "python"
|