2012-07-13 15:39:16 +02:00
|
|
|
/* See LICENSE file for license and copyright information */
|
|
|
|
|
2012-09-17 17:37:36 +02:00
|
|
|
#include <glib.h>
|
2014-04-07 16:36:48 +02:00
|
|
|
#include <girara/utils.h>
|
2014-07-26 16:14:29 +02:00
|
|
|
#include <synctex/synctex_parser.h>
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2012-07-13 15:39:16 +02:00
|
|
|
#include "synctex.h"
|
|
|
|
#include "zathura.h"
|
|
|
|
#include "page.h"
|
|
|
|
#include "document.h"
|
2012-09-17 17:37:36 +02:00
|
|
|
#include "utils.h"
|
|
|
|
|
2012-07-13 15:39:16 +02:00
|
|
|
void
|
2014-07-26 16:14:29 +02:00
|
|
|
synctex_edit(const char* editor, zathura_page_t* page, int x, int y)
|
2012-07-13 15:39:16 +02:00
|
|
|
{
|
2014-07-26 16:14:29 +02:00
|
|
|
if (editor == NULL || page == NULL) {
|
2012-09-17 17:23:58 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-07-13 15:39:16 +02:00
|
|
|
|
2012-09-17 17:23:58 +02:00
|
|
|
zathura_document_t* document = zathura_page_get_document(page);
|
|
|
|
if (document == NULL) {
|
2012-07-13 15:39:16 +02:00
|
|
|
return;
|
2012-09-17 17:23:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *filename = zathura_document_get_path(document);
|
|
|
|
if (filename == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-05-30 17:07:07 +02:00
|
|
|
synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
|
|
|
|
if (scanner == NULL) {
|
|
|
|
girara_debug("Failed to create synctex scanner.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
synctex_scanner_t temp = synctex_scanner_parse(scanner);
|
|
|
|
if (temp == NULL) {
|
|
|
|
girara_debug("Failed to parse synctex file.");
|
|
|
|
synctex_scanner_free(scanner);
|
2014-01-19 16:47:08 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-05-30 17:07:07 +02:00
|
|
|
if (synctex_edit_query(scanner, zathura_page_get_index(page) + 1, x, y) > 0) {
|
|
|
|
/* Assume that a backward search returns either at most one result. */
|
|
|
|
synctex_node_t node = synctex_next_result(scanner);
|
|
|
|
if (node != NULL) {
|
|
|
|
const char* input_file = synctex_scanner_get_name(scanner, synctex_node_tag(node));
|
|
|
|
const int line = synctex_node_line(node);
|
|
|
|
const int column = synctex_node_column (node);
|
|
|
|
|
|
|
|
char* linestr = g_strdup_printf("%d", line);
|
|
|
|
char* columnstr = g_strdup_printf("%d", column);
|
|
|
|
|
|
|
|
gchar** argv = NULL;
|
|
|
|
gint argc = 0;
|
2014-07-26 16:14:29 +02:00
|
|
|
if (g_shell_parse_argv(editor, &argc, &argv, NULL) == TRUE) {
|
2014-05-30 17:07:07 +02:00
|
|
|
for (gint i = 0; i != argc; ++i) {
|
|
|
|
char* temp = girara_replace_substring(argv[i], "%{line}", linestr);
|
|
|
|
g_free(argv[i]);
|
|
|
|
argv[i] = temp;
|
|
|
|
temp = girara_replace_substring(argv[i], "%{column}", columnstr);
|
|
|
|
g_free(argv[i]);
|
|
|
|
argv[i] = temp;
|
|
|
|
temp = girara_replace_substring(argv[i], "%{input}", input_file);
|
|
|
|
g_free(argv[i]);
|
|
|
|
argv[i] = temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL);
|
|
|
|
g_strfreev(argv);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(linestr);
|
|
|
|
g_free(columnstr);
|
|
|
|
}
|
2012-07-13 15:39:16 +02:00
|
|
|
}
|
|
|
|
|
2014-05-30 17:07:07 +02:00
|
|
|
synctex_scanner_free(scanner);
|
2012-07-13 15:39:16 +02:00
|
|
|
}
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-01-11 22:04:14 +01:00
|
|
|
girara_list_t*
|
2014-05-30 16:31:19 +02:00
|
|
|
synctex_rectangles_from_position(const char* filename, const char* input_file,
|
|
|
|
int line, int column, unsigned int* page,
|
2014-01-17 16:31:01 +01:00
|
|
|
girara_list_t** secondary_rects)
|
2012-09-17 17:37:36 +02:00
|
|
|
{
|
2014-05-30 16:31:19 +02:00
|
|
|
if (filename == NULL || input_file == NULL || page == NULL) {
|
2014-01-11 22:04:14 +01:00
|
|
|
return NULL;
|
2013-12-23 15:41:44 +01:00
|
|
|
}
|
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
|
|
|
|
if (scanner == NULL) {
|
|
|
|
girara_debug("Failed to create synctex scanner.");
|
2014-01-19 16:47:08 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
synctex_scanner_t temp = synctex_scanner_parse(scanner);
|
|
|
|
if (temp == NULL) {
|
|
|
|
girara_debug("Failed to parse synctex file.");
|
|
|
|
synctex_scanner_free(scanner);
|
|
|
|
return NULL;
|
2012-09-17 17:37:36 +02:00
|
|
|
}
|
|
|
|
|
2014-01-19 19:42:54 +01:00
|
|
|
girara_list_t* hitlist = girara_list_new2(g_free);
|
2014-01-14 15:05:09 +01:00
|
|
|
girara_list_t* other_rects = girara_list_new2(g_free);
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
if (synctex_display_query(scanner, input_file, line, column) > 0) {
|
|
|
|
synctex_node_t node = NULL;
|
|
|
|
bool got_page = false;
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
while ((node = synctex_next_result (scanner)) != NULL) {
|
|
|
|
const unsigned int current_page = synctex_node_page(node) - 1;
|
|
|
|
if (got_page == false) {
|
|
|
|
got_page = true;
|
|
|
|
*page = current_page;
|
|
|
|
}
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
zathura_rectangle_t rect = { 0, 0, 0, 0 };
|
|
|
|
rect.x1 = synctex_node_box_visible_h(node);
|
|
|
|
rect.y1 = synctex_node_box_visible_v(node) - synctex_node_box_visible_height(node);
|
|
|
|
rect.x2 = rect.x1 + synctex_node_box_visible_width(node);
|
|
|
|
rect.y2 = synctex_node_box_visible_depth(node) + synctex_node_box_visible_height (node) + rect.y1;
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
if (*page == current_page) {
|
|
|
|
zathura_rectangle_t* real_rect = g_try_malloc(sizeof(zathura_rectangle_t));
|
|
|
|
if (real_rect == NULL) {
|
|
|
|
continue;
|
2012-09-17 17:37:36 +02:00
|
|
|
}
|
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
*real_rect = rect;
|
2014-01-19 19:42:54 +01:00
|
|
|
girara_list_append(hitlist, real_rect);
|
2014-05-30 16:31:19 +02:00
|
|
|
} else {
|
|
|
|
synctex_page_rect_t* page_rect = g_try_malloc(sizeof(synctex_page_rect_t));
|
|
|
|
if (page_rect == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-01-19 16:47:08 +01:00
|
|
|
page_rect->page = current_page;
|
2014-05-30 16:31:19 +02:00
|
|
|
page_rect->rect = rect;
|
|
|
|
|
2014-01-19 16:47:08 +01:00
|
|
|
girara_list_append(other_rects, page_rect);
|
|
|
|
}
|
2014-01-11 22:04:14 +01:00
|
|
|
}
|
2012-09-17 17:37:36 +02:00
|
|
|
}
|
|
|
|
|
2014-05-30 16:31:19 +02:00
|
|
|
synctex_scanner_free(scanner);
|
2012-09-17 17:37:36 +02:00
|
|
|
|
2014-01-14 15:05:09 +01:00
|
|
|
if (secondary_rects != NULL) {
|
|
|
|
*secondary_rects = other_rects;
|
|
|
|
} else {
|
|
|
|
girara_list_free(other_rects);
|
|
|
|
}
|
|
|
|
|
2014-01-11 22:04:14 +01:00
|
|
|
return hitlist;
|
2012-09-17 17:37:36 +02:00
|
|
|
}
|