#!/bin/bash # Convert email to HTML and open in browser with images emlfile="/tmp/neomutt-email-$$.eml" tmpdir="/tmp/neomutt-email-$$" tmpfile="$tmpdir/email-$$.html" # Save email from stdin mkdir -p "$tmpdir" cat >"$emlfile" # Extract MIME parts using ripmime if available if command -v ripmime &>/dev/null; then ripmime -i "$emlfile" -d "$tmpdir" --no-nameless 2>/dev/null elif command -v munpack &>/dev/null; then cd "$tmpdir" && munpack -q "$emlfile" 2>/dev/null fi # Check if there's an HTML part extracted html_part=$(find "$tmpdir" -maxdepth 1 -name "*.html" -o -name "*.htm" 2>/dev/null | head -1) if [[ -n $html_part && -s $html_part ]]; then # Use extracted HTML directly cp "$html_part" "$tmpfile" else # Generate HTML from text { echo "
" echo '' echo "" echo "" echo '" header ": " if (n > 1) { for (i=1; i<=n; i++) printf "" addrs[i] "" } else { printf "" value "" } print "
" } else if (tolower(header) == "subject") { print "" header ": " value "
" } else { print "" header ": " value "
" } } header = ""; value = "" } /^$/{output(); exit} /^(From|To|CC|Bcc|Reply-To|Subject|Date):/{ output() show=1 match($0, /^[^:]+/) header = substr($0, 1, RLENGTH) value = substr($0, RLENGTH+2) gsub(/^[ \t]+|[ \t]+$/, "", value) next } /^[A-Za-z0-9-]+:/ && !/^(From|To|CC|Bcc|Reply-To|Subject|Date):/{output(); show=0} show && /^[ \t]/{ gsub(/^[ \t]+/, "", $0) value = value " " $0 } END{output()}' "$emlfile" echo ""
print quotebuf
print ""; incode=1 }
next
}
/^>/ {
if (incode) { gsub(/, "\\<"); gsub(/>/, "\\>"); print; next }
gsub(/, "\\<")
gsub(/>/, "\\>")
if (quotebuf != "") quotebuf = quotebuf "\n"
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
}
# Sixth: Handle [cid:image] inline images
while (match(result, /\[cid:[^\]]+\]/)) {
before = substr(result, 1, RSTART-1)
# Extract image name from cid reference
cid = substr(result, RSTART+5, RLENGTH-6)
after = substr(result, RSTART+RLENGTH)
# Extract just the filename part (before @)
if (match(cid, /@/)) {
imgname = substr(cid, 1, RSTART-1)
} else {
imgname = cid
}
result = before "
" after
}
return result
}
{
flush_quote()
# HTML escape first
gsub(/, "\\<")
gsub(/>/, "\\>")
if (!incode) {
# Handle inline code `code`
while (match($0, /`[^`]+`/)) {
before = substr($0, 1, RSTART-1)
code = substr($0, RSTART+1, RLENGTH-2)
after = substr($0, RSTART+RLENGTH)
$0 = before "" code "" after
}
# Linkify URLs and emails
$0 = linkify($0)
}
print
}
END {
flush_quote()
if (incode) print " "
}
'
echo "