I have now finished porting at least backwards synchronization to the new version of zathura. Patch attached.

Usage is as I described in the earlier mail:
-s: enables synctex support
-x <command>: sets the synctex editor (optional, see man synctex)

When synctex is enabled, ctrl-leftclick on the page will run "synctex edit" with appropriate parameters, also forwarding the -x paratemer if one was supplied to zathura. The synctex output goes to stdout/stderr of zathura (but it's probably better to use the -x parameter to let synctex automatically run the editor command instead of generating output).

When synctex is not enabled, ctrl-leftclick behaves just like normal leftclick (same as without the patch).


I have tested this on Arch Linux with the default texlive installation and the normal zathura packages installed (for the plugins).

I placed the new zathura binary in ~/bin and put the following lines in .latexmkrc: $pdf_previewer = "start ~/bin/zathura -s -x 'gvim --servername SYNCTEX --remote +%{line} %{input}' %S"; $ps_previewer = "start ~/bin/zathura -s -x 'gvim --servername SYNCTEX --remote +%{line} %{input}' %S";
---
 page-widget.c | 44 +++++++++++++++++++++++++++-----------------
 synctex.c     | 38 ++++++++++++++++++++++++++++++++++++++
 synctex.h     |  8 ++++++++
 zathura.c     | 12 ++++++++++--
 zathura.h     |  6 ++++++
 5 files changed, 89 insertions(+), 19 deletions(-)
 create mode 100644 synctex.c
 create mode 100644 synctex.h

diff --git a/page-widget.c b/page-widget.c
index 4734ff8..861d114 100644
--- a/page-widget.c
+++ b/page-widget.c
@@ -13,6 +13,7 @@
 #include "render.h"
 #include "utils.h"
 #include "shortcuts.h"
+#include "synctex.h"
 
 G_DEFINE_TYPE(ZathuraPage, zathura_page_widget, GTK_TYPE_DRAWING_AREA)
 
@@ -610,29 +611,38 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b
     }
   } else {
     redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection);
-    zathura_rectangle_t tmp = priv->mouse.selection;
 
-    double scale = zathura_document_get_scale(document);
-    tmp.x1 /= scale;
-    tmp.x2 /= scale;
-    tmp.y1 /= scale;
-    tmp.y2 /= scale;
+    if (priv->zathura->synctex.enabled && button->state & GDK_CONTROL_MASK) {
+      /* synctex backwards sync */
+      double scale = zathura_document_get_scale(document);
+      int x = button->x / scale, y = button->y / scale;
 
-    char* text = zathura_page_get_text(priv->page, tmp, NULL);
-    if (text != NULL) {
-      if (strlen(text) > 0) {
-        /* copy to clipboard */
-        gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, -1);
+      synctex_edit(priv->zathura, priv->page, x, y);
+    } else {
+      zathura_rectangle_t tmp = priv->mouse.selection;
+
+      double scale = zathura_document_get_scale(document);
+      tmp.x1 /= scale;
+      tmp.x2 /= scale;
+      tmp.y1 /= scale;
+      tmp.y2 /= scale;
+
+      char* text = zathura_page_get_text(priv->page, tmp, NULL);
+      if (text != NULL) {
+        if (strlen(text) > 0) {
+          /* copy to clipboard */
+          gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, -1);
 
 
-        if (priv->page != NULL && document != NULL && priv->zathura != NULL) {
-          char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' ');
-          girara_notify(priv->zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipboard: %s"), stripped_text);
-          g_free(stripped_text);
+          if (priv->page != NULL && document != NULL && priv->zathura != NULL) {
+            char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' ');
+            girara_notify(priv->zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipboard: %s"), stripped_text);
+            g_free(stripped_text);
+          }
         }
-      }
 
-      g_free(text);
+        g_free(text);
+      }
     }
   }
 
diff --git a/synctex.c b/synctex.c
new file mode 100644
index 0000000..3288c55
--- /dev/null
+++ b/synctex.c
@@ -0,0 +1,38 @@
+#include "synctex.h"
+
+#include "zathura.h"
+#include "page.h"
+#include "document.h"
+
+#include <sys/wait.h>
+#include <stdlib.h>
+
+void
+synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y) {
+  zathura_document_t* doc;
+  int ret, pid, status, pageIdx;
+  char buffer[1024];
+  const char *filename;
+
+  pageIdx = zathura_page_get_index(page);
+  doc = zathura_page_get_document(page);
+  filename = zathura_document_get_path(doc);
+
+  ret = snprintf(buffer, 1024, "%d:%d:%d:%s", pageIdx+1, x, y, filename);
+  if (ret >= 1024)
+    return;
+
+  pid = fork();
+  if (pid) {
+    /* parent */
+    if (pid > 0)
+      waitpid(pid, &status, 0);
+  } else {
+    /* child */
+    if (zathura->synctex.editor)
+      ret = execlp("synctex", "synctex", "edit", "-o", buffer, "-x", zathura->synctex.editor, NULL);
+    else
+      ret = execlp("synctex", "synctex", "edit", "-o", buffer, NULL);
+    exit(ret);
+  }
+}
diff --git a/synctex.h b/synctex.h
new file mode 100644
index 0000000..efe4701
--- /dev/null
+++ b/synctex.h
@@ -0,0 +1,8 @@
+#ifndef SYNCTEX_H
+#define SYNCTEX_H
+
+#include "types.h"
+
+void synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y);
+
+#endif
diff --git a/zathura.c b/zathura.c
index fd5acf0..2078350 100644
--- a/zathura.c
+++ b/zathura.c
@@ -66,8 +66,8 @@ zathura_init(int argc, char* argv[])
   Window embed = 0;
 #endif
 
-  gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL;
-  bool forkback = false;
+  gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL, *synctex_editor = NULL;
+  bool forkback = false, synctex = false;
   GOptionEntry entries[] =
   {
     { "reparent",    'e',  0, G_OPTION_ARG_INT,      &embed,       _("Reparents to window specified by xid"),       "xid"  },
@@ -76,6 +76,8 @@ zathura_init(int argc, char* argv[])
     { "plugins-dir", 'p',  0, G_OPTION_ARG_STRING,   &plugin_path, _("Path to the directories containing plugins"), "path" },
     { "fork",        '\0', 0, G_OPTION_ARG_NONE,     &forkback,    _("Fork into the background"),                   NULL },
     { "password",    'w',  0, G_OPTION_ARG_STRING,   &password,    _("Document password"),                          "password" },
+    { "synctex",     's',  0, G_OPTION_ARG_NONE,     &synctex,     _("Enable synctex support"),                     NULL },
+    { "editor-command", 'x', 0, G_OPTION_ARG_STRING, &synctex_editor, _("Synctex editor (this flag is forwarded to the synctex command)"), "cmd" },
     { "debug",       'l',  0, G_OPTION_ARG_STRING,   &loglevel,    _("Log level (debug, info, warning, error)"),    "level" },
     { NULL, '\0', 0, 0, NULL, NULL, NULL }
   };
@@ -140,6 +142,12 @@ zathura_init(int argc, char* argv[])
     g_free(path);
   }
 
+  /* synctex */
+  zathura->synctex.enabled = synctex;
+  if (synctex_editor) {
+    zathura->synctex.editor = g_strdup(synctex_editor);
+  }
+
   /* create zathura (config/data) directory */
   g_mkdir_with_parents(zathura->config.config_dir, 0771);
   g_mkdir_with_parents(zathura->config.data_dir,   0771);
diff --git a/zathura.h b/zathura.h
index 9e40dcb..cf204b7 100644
--- a/zathura.h
+++ b/zathura.h
@@ -68,6 +68,12 @@ struct zathura_s
 
   struct
   {
+    bool enabled;
+    gchar* editor;
+  } synctex;
+
+  struct
+  {
     GtkPrintSettings* settings; /**< Print settings */
     GtkPageSetup* page_setup; /**< Saved page setup */
   } print;
-- 
1.7.11.1

_______________________________________________
zathura mailing list
zathura@lists.pwmt.org
http://lists.pwmt.org/mailman/listinfo/zathura

Reply via email to