[wiki] [sites] Add surf externalpipe patch || Miles Alan
 
commit 1f0a0aceb97de4d05842610c90539bd97caad7b0
Author: Miles Alan <m_AT_milesalan.com>
Date:   Thu May 2 16:24:39 2019 -0500
    Add surf externalpipe patch
diff --git a/surf.suckless.org/patches/externalpipe/edit_screen.sh b/surf.suckless.org/patches/externalpipe/edit_screen.sh
new file mode 100755
index 00000000..33266668
--- /dev/null
+++ b/surf.suckless.org/patches/externalpipe/edit_screen.sh
_AT_@ -0,0 +1,5 @@
+#!/bin/sh
+tmpfile=$(mktemp /tmp/st-edit.XXXXXX)
+trap  'rm "$tmpfile"' 0 1 15
+cat > "$tmpfile"
+st -e "$EDITOR" "$tmpfile"
diff --git a/surf.suckless.org/patches/externalpipe/index.md b/surf.suckless.org/patches/externalpipe/index.md
new file mode 100644
index 00000000..e09c3078
--- /dev/null
+++ b/surf.suckless.org/patches/externalpipe/index.md
_AT_@ -0,0 +1,52 @@
+externalpipe
+============
+
+Description
+-----------
+
+Pipe the current page's source to an external program. This is particularly
+helpful for keyboard-based link following and also for viewing the source in an
+external editor. Works both when javascript is enabled and disabled.
+
+Example
+-------
+Install the below shell scripts into your `$PATH`:
+* [surf_linkselect.sh](surf_linkselect.sh) - extracts links via xmllint and
+  pipes to dmenu, converts selected link to valid URL.
+* [edit_screen.sh](edit_screen.sh) - open source in `$EDITOR` for copying text.
+
+
+Add to your `config.h`:
+	static char *linkselect_curwin [] = { "/bin/sh", "-c",
+		"surf_linkselect.sh $0 'Link' | xargs -r xprop -id $0 -f _SURF_GO 8s -set _SURF_GO",
+		winid, NULL
+	};
+	static char *linkselect_newwin [] = { "/bin/sh", "-c",
+		"surf_linkselect.sh $0 'Link (new window)' | xargs -r surf",
+		winid, NULL
+	};
+	static char *editscreen[] = { "/bin/sh", "-c", "edit_screen.sh", NULL };
+	...
+	static Key keys[] = {
+		{ MODKEY,                GDK_KEY_d, externalpipe, { .v = linkselect_curwin } },
+		{ GDK_SHIFT_MASK|MODKEY, GDK_KEY_d, externalpipe, { .v = linkselect_newwin } },
+		{ MODKEY,                GDK_KEY_o, externalpipe, { .v = editscreen        } },
+		...
+	}
+
+Now you have the new keybindings:
+- **Ctrl-d** - open dmenu with links, select to follow in current surf window
+- **Ctrl-Shift-d** - open dmenu with links, select to open in new surf window
+- **Ctrl-o** - view sourcecode for the current page in your editor
+
+
+Download
+--------
+
+* [surf-2.0-externalpipe.diff](surf-2.0-externalpipe.diff) (2368) (20190502)
+
+Author
+------
+
+* Miles Alan - m_AT_milesalan.com
+* Rob Pilling - robpilling_AT_gmail.com (author of st externalpipe, which pipe code is based on)
\ No newline at end of file
diff --git a/surf.suckless.org/patches/externalpipe/surf-2.0-externalpipe.diff b/surf.suckless.org/patches/externalpipe/surf-2.0-externalpipe.diff
new file mode 100644
index 00000000..ac9dd831
--- /dev/null
+++ b/surf.suckless.org/patches/externalpipe/surf-2.0-externalpipe.diff
_AT_@ -0,0 +1,93 @@
+diff --git a/surf.c b/surf.c
+index 93a1629..ba53b94 100644
+--- a/surf.c
++++ b/surf.c
+_AT_@ -217,6 +217,7 @@ static void togglefullscreen(Client *c, const Arg *a);
+ static void togglecookiepolicy(Client *c, const Arg *a);
+ static void toggleinspector(Client *c, const Arg *a);
+ static void find(Client *c, const Arg *a);
++static void externalpipe(Client *c, const Arg *a);
+ 
+ /* Buttons */
+ static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h);
+_AT_@ -241,6 +242,80 @@ char *argv0;
+ /* configuration, allows nested code to access above variables */
+ #include "config.h"
+ 
++static void
++externalpipe_execute(char* buffer, Arg *arg) {
++	int to[2];
++	void (*oldsigpipe)(int);
++
++	if (pipe(to) == -1)
++		return;
++
++	switch (fork()) {
++	case -1:
++		close(to[0]);
++		close(to[1]);
++		return;
++	case 0:
++		dup2(to[0], STDIN_FILENO); close(to[0]); close(to[1]);
++		execvp(((char **)arg->v)[0], (char **)arg->v);
++		fprintf(stderr, "st: execvp %s
", ((char **)arg->v)[0]);
++		perror("failed");
++		exit(0);
++	}
++
++	close(to[0]);
++	oldsigpipe = signal(SIGPIPE, SIG_IGN);
++	write(to[1], buffer, strlen(buffer));
++	close(to[1]);
++	signal(SIGPIPE, oldsigpipe);
++}
++
++static void
++externalpipe_resource_done(WebKitWebResource *r, GAsyncResult *s, Arg *arg)
++{
++	GError *gerr = NULL;
++	guchar *buffer = webkit_web_resource_get_data_finish(r, s, NULL, &gerr);
++	if (gerr == NULL) {
++		externalpipe_execute((char *) buffer, arg);
++	} else {
++		g_error_free(gerr);
++	}
++	g_free(buffer);
++}
++
++static void
++externalpipe_js_done(WebKitWebView *wv, GAsyncResult *s, Arg *arg)
++{
++	WebKitJavascriptResult *j = webkit_web_view_run_javascript_finish(
++		wv, s, NULL);
++	if (!j) {
++		return;
++	}
++	JSCValue *v = webkit_javascript_result_get_js_value(j);
++	if (jsc_value_is_string(v)) {
++		char *buffer = jsc_value_to_string(v);
++		externalpipe_execute(buffer, arg);
++		g_free(buffer);
++	}
++	webkit_javascript_result_unref(j);
++}
++
++void
++externalpipe(Client *c, const Arg *arg)
++{
++	if (curconfig[JavaScript].val.i) {
++		webkit_web_view_run_javascript(
++			c->view, "window.document.body.outerHTML",
++			NULL, externalpipe_js_done, arg);
++	} else {
++		WebKitWebResource *resource = webkit_web_view_get_main_resource(c->view);
++		if (resource != NULL) {
++			webkit_web_resource_get_data(
++				resource, NULL, externalpipe_resource_done, arg);
++		}
++	}
++}
++
+ void
+ usage(void)
+ {
diff --git a/surf.suckless.org/patches/externalpipe/surf_linkselect.sh b/surf.suckless.org/patches/externalpipe/surf_linkselect.sh
new file mode 100755
index 00000000..2edd5866
--- /dev/null
+++ b/surf.suckless.org/patches/externalpipe/surf_linkselect.sh
_AT_@ -0,0 +1,72 @@
+#!/usr/bin/env sh
+#
+# surf_linkselect.sh:
+#  Usage:
+#    curl somesite.com | surf_linkselect [SURFWINDOWID] [PROMPT]
+#
+#  Description:
+#    Given an HTML body as STDIN, extracts links via xmllint & provides list
+#    to dmenu with each link paired with its associated content. Selected
+#    link is then normalized based on the passed surf window's URI and the
+#    result is printed to STDOUT.
+#
+#  Dependencies:
+#    xmllint, awk, dmenu
+
+function dump_links_with_titles() {
+  awk '{
+    input = $0;
+
+    $0 = input;
+    gsub("<[^>]*>", "");
+    gsub(/[ ]+/, " ");
+    $1 = $1;
+    title = ($0 == "" ? "None" : $0);
+
+    $0 = input;
+    match($0, /\<[ ]*[aA][^>]* [hH][rR][eE][fF]=["]([^"]+)["]/, linkextract);
+    $0 = linkextract[1];
+    gsub("[ ]", "%20");
+    link = $0;
+
+    print title ": " link;
+  }'
+}
+
+function link_normalize() {
+  URI=$1
+  awk -v uri=$URI '{
+    if ($0 ~ /^https?:\/\//  || $0 ~ /^\/\/.+$/) {
+      print $0;
+    } else if ($0 ~/^#/) {
+      gsub(/[#?][^#?]+/, "", uri);
+      print uri $0;
+    } else if ($0 ~/^\//) {
+      split(uri, uri_parts, "/");
+      print uri_parts[3] $0;
+    } else {
+      gsub(/[#][^#]+/, "", uri);
+      uri_parts_size = split(uri, uri_parts, "/");
+      delete uri_parts[uri_parts_size];
+      for (v in uri_parts) {
+        uri_pagestripped = uri_pagestripped uri_parts[v] "/"
+      }
+      print uri_pagestripped $0;
+    }
+  }'
+}
+
+function link_select() {
+  SURF_WINDOW=$1
+  DMENU_PROMPT=$2
+  tr -d '
' |
+    xmllint --html --xpath "//a" - |
+    dump_links_with_titles |
+    sort |
+    uniq |
+    dmenu -p "$DMENU_PROMPT" -l 10 -i -w $SURF_WINDOW |
+    awk -F' ' '{print $NF}' |
+    link_normalize $(xprop -id $SURF_WINDOW _SURF_URI | cut -d '"' -f 2)
+}
+
+link_select "$1" "$2"
\ No newline at end of file
Received on Thu May 02 2019 - 23:27:49 CEST
This archive was generated by hypermail 2.3.0
: Thu May 02 2019 - 23:36:27 CEST