From b710162ba8ab61ce85171cc025d57532d7b40881 Mon Sep 17 00:00:00 2001 From: Ray Andrew Date: Thu, 4 Dec 2025 14:57:05 -0600 Subject: [PATCH] fix the html link parsing --- bin/view-email-html | 52 +++++++++++++++++++++++++++++++++++++++++ config/neomutt/keybinds | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/bin/view-email-html b/bin/view-email-html index 00e0330..a49462b 100755 --- a/bin/view-email-html +++ b/bin/view-email-html @@ -193,8 +193,58 @@ else quotebuf = quotebuf $0 next } + function linkify(line, result, pos, url, email, before, after, linktext) { + result = line + # First: Handle email pattern - keep only one email as link + while (match(result, /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}<mailto:[^&]*>/)) { + before = substr(result, 1, RSTART-1) + # Extract just the email part (before <mailto:) + pos = index(substr(result, RSTART), "<mailto:") + email = substr(result, RSTART, pos-1) + after = substr(result, RSTART+RLENGTH) + result = before "" email "" after + } + # Second: Handle standalone <mailto:email> + while (match(result, /<mailto:[^&]+>/)) { + before = substr(result, 1, RSTART-1) + email = substr(result, RSTART+11, RLENGTH-15) + after = substr(result, RSTART+RLENGTH) + result = before "" email "" after + } + # Third: Handle text<https://url> - text becomes link text + while (match(result, /[A-Za-z0-9_-]+<https?:\/\/[^&]+>/)) { + before = substr(result, 1, RSTART-1) + full = substr(result, RSTART, RLENGTH) + # Find where < starts + pos = index(full, "<") + linktext = substr(full, 1, pos-1) + # Extract URL: after < (4 chars) until > (4 chars at end) + url = substr(full, pos+4, length(full)-pos-7) + after = substr(result, RSTART+RLENGTH) + result = before "" linktext "" after + } + # Fourth: Handle standalone <https://url> + while (match(result, /<https?:\/\/[^&]+>/)) { + before = substr(result, 1, RSTART-1) + url = substr(result, RSTART+4, RLENGTH-8) + after = substr(result, RSTART+RLENGTH) + result = before "" url "" after + } + # Fifth: Handle plain URLs (not already in href) + while (match(result, /https?:\/\/[^ &<>"\n\t]+/)) { + before = substr(result, 1, RSTART-1) + if (before ~ /href="$/) break + url = substr(result, RSTART, RLENGTH) + after = substr(result, RSTART+RLENGTH) + # Clean trailing punctuation + sub(/[.,;:!?)]+$/, "", url) + result = before "" url "" after + } + return result + } { flush_quote() + # HTML escape first gsub(//, "\\>") if (!incode) { @@ -205,6 +255,8 @@ else after = substr($0, RSTART+RLENGTH) $0 = before "" code "" after } + # Linkify URLs and emails + $0 = linkify($0) } print } diff --git a/config/neomutt/keybinds b/config/neomutt/keybinds index fbb1a2d..fed42ac 100644 --- a/config/neomutt/keybinds +++ b/config/neomutt/keybinds @@ -11,7 +11,7 @@ bind editor ^T complete # Pager bind index,pager V edit-raw-message -macro index,pager H "~/dotfiles/bin/view-email-html" "View email in browser" +macro index,pager H "~/dotfiles/bin/view-email-htmlN" "View email in browser" bind pager c imap-fetch-mail bind pager j next-line bind pager k previous-line