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