Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ The AUTHORS/Contributors are (and/or have been):
* Edward Ross <gh: EdwardJRoss>
* Gregory Anders <gh: gpanders>
* Alex Vandiver <gh: alexmv>
* sjh9714

Maintainer:

Expand Down
7 changes: 7 additions & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Unreleased
==========
----

* Fix #425: Keep protected URLs intact during wrapping, including at hyphens.
With ``protect_links`` enabled, hyphenated words are also kept together.

2025.4.15
=========
----
Expand Down
3 changes: 2 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ simple indications of their function.
- BODY_WIDTH for wrapping long lines
- SKIP_INTERNAL_LINKS to skip #local-anchor things
- INLINE_LINKS for formatting images and links
- PROTECT_LINKS protect from line breaks
- PROTECT_LINKS protect URLs from line breaks by wrapping only at whitespace
(also keeps hyphenated words together)
- GOOGLE_LIST_INDENT no of pixels to indent nested lists
- IGNORE_ANCHORS
- IGNORE_IMAGES
Expand Down
1 change: 1 addition & 0 deletions html2text/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,7 @@ def optwrap(self, text: str) -> str:
para,
self.body_width,
break_long_words=False,
break_on_hyphens=not self.protect_links,
subsequent_indent=indent,
)
result += "\n".join(wrapped)
Expand Down
4 changes: 3 additions & 1 deletion test/protect_links.html
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<a href="http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html">foo</a>
<p><a href="http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html">foo</a></p>
<p>Before the link <a href="http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html">foo</a> The following text should wrap normally after the protected link, keeping every word in order.</p>
<p><a href="http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html?query=another-long-hyphenated-value">http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html?query=another-long-hyphenated-value</a></p>
10 changes: 8 additions & 2 deletions test/protect_links.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
[foo](<http://im-a-very-very-very-very-very-very-very-very-very-very-
long/link.html>)
[foo](<http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html>)

Before the link
[foo](<http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html>)
The following text should wrap normally after the protected link, keeping
every word in order.

<http://im-a-very-very-very-very-very-very-very-very-very-very-long/link.html?query=another-long-hyphenated-value>
13 changes: 13 additions & 0 deletions test/test_html2text.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,16 @@ def test_strong_emptied() -> None:
h.strong_mark = ""
string = "A <b>B</b> <i>C</i>."
assert h.handle(string) == "A B _C_.\n\n"


@pytest.mark.parametrize(
"protect_links,expected",
[
(False, "alpha-\nbeta-gamma\n\n"),
(True, "alpha-beta-gamma\n\n"),
],
)
def test_hyphen_wrapping_with_protect_links(protect_links, expected):
h = html2text.HTML2Text(bodywidth=10)
h.protect_links = protect_links
assert h.handle("alpha-beta-gamma") == expected