surf_linkselect.sh (1974B)
1 #!/usr/bin/env sh 2 # surf_linkselect.sh: 3 # Usage: curl somesite.com | surf_linkselect [SURFWINDOWID] [PROMPT] 4 # Deps: xmllint, dmenu 5 # Info: 6 # Designed to be used w/ surf externalpipe patch. Enables keyboard-only 7 # link selection via dmenu. Given HTML stdin, extracts links one per line 8 # Selected link is normalized based on current URI and printed to STDOUT. 9 # Pipe the result to a new surf or xprop _SURF_URI accordingly. 10 SURF_WINDOW="${1:-$(xprop -root | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* //p')}" 11 DMENU_PROMPT="${2:-Link}" 12 13 dump_links_with_titles() { 14 awk '{ 15 input = $0; 16 17 $0 = input; 18 gsub("<[^>]*>", ""); 19 gsub(/[ ]+/, " "); 20 gsub("&", "\\&"); 21 gsub("<", "<"); 22 gsub(">", ">"); 23 $1 = $1; 24 title = ($0 == "" ? "None" : $0); 25 26 $0 = input; 27 match($0, /\<[ ]*[aA][^>]* [hH][rR][eE][fF]=["]([^"]+)["]/, linkextract); 28 $0 = linkextract[1]; 29 gsub(/^[ \t]+/,""); 30 gsub(/[ \t]+$/,""); 31 gsub("[ ]", "%20"); 32 link = $0; 33 34 if (link != "") { 35 print title ": " link; 36 } 37 }' 38 } 39 40 link_normalize() { 41 URI=$1 42 awk -v uri=$URI '{ 43 gsub("&", "\\&"); 44 45 if ($0 ~ /^https?:\/\// || $0 ~ /^\/\/.+$/) { 46 print $0; 47 } else if ($0 ~/^#/) { 48 gsub(/[#?][^#?]+/, "", uri); 49 print uri $0; 50 } else if ($0 ~/^\//) { 51 split(uri, uri_parts, "/"); 52 print uri_parts[3] $0; 53 } else { 54 gsub(/[#][^#]+/, "", uri); 55 uri_parts_size = split(uri, uri_parts, "/"); 56 delete uri_parts[uri_parts_size]; 57 for (v in uri_parts) { 58 uri_pagestripped = uri_pagestripped uri_parts[v] "/" 59 } 60 print uri_pagestripped $0; 61 } 62 }' 63 } 64 65 link_select() { 66 tr '\n\r' ' ' | 67 xmllint --html --xpath "//a" - | 68 dump_links_with_titles | 69 awk '!x[$0]++' | 70 # sort | uniq 71 dmenu -p "$DMENU_PROMPT" -l 10 -i -w $SURF_WINDOW | 72 awk -F' ' '{print $NF}' | 73 link_normalize $(xprop -id $SURF_WINDOW _SURF_URI | cut -d '"' -f 2) 74 } 75 76 link_select