Exemple #1
0
void SynctexHandler::loadData(const QString &fileName)
{
	removeData();

	m_fileName = fileName;
	m_synctexScanner = synctex_scanner_new_with_output_file(m_fileName.toUtf8().data(), 0, 1);
}
int SyncTex::RebuildIndex() {
    synctex_scanner_free(this->scanner);
    this->scanner = NULL;

    ScopedMem<char> syncfname(str::conv::ToAnsi(syncfilepath));
    if (!syncfname)
        return PDFSYNCERR_OUTOFMEMORY;

    scanner = synctex_scanner_new_with_output_file(syncfname, NULL, 1);
    if (!scanner)
        return PDFSYNCERR_SYNCFILE_NOTFOUND; // cannot rebuild the index

    return Synchronizer::RebuildIndex();
}
Exemple #3
0
int SyncTex::RebuildIndex() {
    synctex_scanner_free(scanner);
    scanner = nullptr;

    OwnedData syncfname(str::conv::ToAnsi(syncfilepath));
    if (!syncfname.Get())
        return PDFSYNCERR_OUTOFMEMORY;

    scanner = synctex_scanner_new_with_output_file(syncfname.Get(), nullptr, 1);
    if (!scanner)
        return PDFSYNCERR_SYNCFILE_NOTFOUND; // cannot rebuild the index

    return Synchronizer::RebuildIndex();
}
static void
ev_document_initialize_synctex (EvDocument  *document,
                                const gchar *uri)
{
    EvDocumentPrivate *priv = document->priv;

    if (_ev_document_support_synctex (document)) {
        gchar *filename;

        filename = g_filename_from_uri (uri, NULL, NULL);
        if (filename != NULL) {
            priv->synctex_scanner =
                synctex_scanner_new_with_output_file (filename, NULL, 1);
            g_free (filename);
        }
    }
}
Exemple #5
0
bool
synctex_get_input_line_column(const char* filename, unsigned int page, int x, int y,
    char** input_file, unsigned int* line, unsigned int* column)
{
  if (filename == NULL) {
    return false;
  }

  synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
  if (scanner == NULL) {
    girara_debug("Failed to create synctex scanner.");
    return false;
  }

  synctex_scanner_t temp = synctex_scanner_parse(scanner);
  if (temp == NULL) {
    girara_debug("Failed to parse synctex file.");
    synctex_scanner_free(scanner);
    return false;
  }

  bool ret = false;

  if (synctex_edit_query(scanner, page + 1u, x, y) > 0) {
    /* Assume that a backward search returns at most one result. */
    synctex_node_t node = synctex_next_result(scanner);
    if (node != NULL) {
      if (input_file != NULL) {
        *input_file = g_strdup(synctex_scanner_get_name(scanner, synctex_node_tag(node)));
      }
      if (line != NULL) {
        *line = synctex_node_line(node);
      }
      if (column != NULL) {
        *column = synctex_node_column(node);
      }

      ret = true;
    }
  }

  synctex_scanner_free(scanner);

  return ret;
}
Exemple #6
0
/**
 * ev_document_load:
 * @document: a #EvDocument
 * @uri: the document's URI
 * @error: a #GError location to store an error, or %NULL
 *
 * Loads @document from @uri.
 * 
 * On failure, %FALSE is returned and @error is filled in.
 * If the document is encrypted, EV_DEFINE_ERROR_ENCRYPTED is returned.
 * If the backend cannot load the specific document, EV_DOCUMENT_ERROR_INVALID
 * is returned. Other errors are possible too, depending on the backend
 * used to load the document and the URI, e.g. #GIOError, #GFileError, and
 * #GConvertError.
 *
 * Returns: %TRUE on success, or %FALSE on failure.
 */
gboolean
ev_document_load (EvDocument  *document,
		  const char  *uri,
		  GError     **error)
{
	EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
	gboolean retval;
	GError *err = NULL;

	retval = klass->load (document, uri, &err);
	if (!retval) {
		if (err) {
			g_propagate_error (error, err);
		} else {
			g_warning ("%s::EvDocument::load returned FALSE but did not fill in @error; fix the backend!\n",
				   G_OBJECT_TYPE_NAME (document));

			/* So upper layers don't crash */
			g_set_error_literal (error,
					     EV_DOCUMENT_ERROR,
					     EV_DOCUMENT_ERROR_INVALID,
					     "Internal error in backend");
		}
	} else {
                EvDocumentPrivate *priv = document->priv;

                ev_document_setup_cache (document);

                priv->uri = g_strdup (uri);
                priv->info = _ev_document_get_info (document);
                if (_ev_document_support_synctex (document)) {
                        gchar *filename;

                        filename = g_filename_from_uri (uri, NULL, NULL);
                        if (filename != NULL) {
                                priv->synctex_scanner =
                                        synctex_scanner_new_with_output_file (filename, NULL, 1);
                                g_free (filename);
                        }
                }
        }

	return retval;
}
Exemple #7
0
int synctex_edit_proceed(synctex_edit_params_t * Ps) {
	synctex_scanner_t scanner = NULL;
#if SYNCTEX_DEBUG
	printf("page:%i\n",Ps->page);
	printf("x:%f\n",Ps->x);
	printf("y:%f\n",Ps->y);
	printf("almost output:%s\n",Ps->output);
	printf("editor:%s\n",Ps->editor);
	printf("offset:%i\n",Ps->offset);
	printf("context:%s\n",Ps->context);
	printf("cwd:%s\n",getcwd(NULL,0));
#endif
	scanner = synctex_scanner_new_with_output_file(Ps->output,Ps->directory,1);
	if(NULL == scanner) {
		synctex_help_edit("No SyncTeX available for %s",Ps->output);
		return -1;
	}
	if(synctex_edit_query(scanner,Ps->page,Ps->x,Ps->y)) {
		synctex_node_t node = NULL;
		const char * input = NULL;
		if(NULL != (node = synctex_next_result(scanner))
				&& NULL != (input = synctex_scanner_get_name(scanner,synctex_node_tag(node)))) {
			/* filtering the command */
			if(Ps->editor && strlen(Ps->editor)) {
				size_t size = 0;
				char * where = NULL;
				char * buffer = NULL;
				char * buffer_cur = NULL;
				int printed;
				int status;
				size = strlen(Ps->editor)+3*sizeof(int)+3*SYNCTEX_STR_SIZE;
				buffer = malloc(size+1);
				if(NULL == buffer) {
					printf("SyncTeX ERROR: No memory available\n");
					return -1;
				}
				buffer[size]='\0';
				/* Replace %{ by &{, then remove all unescaped '%'*/
				while((where = strstr(Ps->editor,"%{")) != NULL) {
					*where = '&';
				}
				where = Ps->editor;
				while(where &&(where = strstr(where,"%"))) {
					if(strlen(++where)) {
						if(*where == '%') {
							++where;
						} else {
							*(where-1)='&';
						}
					}
				}
				buffer_cur = buffer;
				/*  find the next occurrence of a format key */
				where = Ps->editor;
				while(Ps->editor && (where = strstr(Ps->editor,"&{"))) {
					#define TEST(KEY,FORMAT,WHAT)\
					if(!strncmp(where,KEY,strlen(KEY))) {\
						printed = where-Ps->editor;\
						if(buffer_cur != memcpy(buffer_cur,Ps->editor,(size_t)printed)) {\
							synctex_help_edit("Memory copy problem");\
							free(buffer);\
							return -1;\
						}\
						buffer_cur += printed;size-=printed;\
						printed = snprintf(buffer_cur,size,FORMAT,WHAT);\
						if((unsigned)printed >= (unsigned)size) {\
							synctex_help_edit("Snprintf problem");\
							free(buffer);\
							return -1;\
						}\
						buffer_cur += printed;size-=printed;\
						*buffer_cur='\0';\
						Ps->editor = where+strlen(KEY);\
						continue;\
					}
					TEST("&{output}", "%s",Ps->output);
					TEST("&{input}",  "%s",input);
					TEST("&{line}",   "%i",synctex_node_line(node));
					TEST("&{column}", "%i",-1);
					TEST("&{offset}", "%i",Ps->offset);
					TEST("&{context}","%s",Ps->context);
					#undef TEST
					break;
				}
				/* copy the rest of editor into the buffer */
				if(buffer_cur != memcpy(buffer_cur,Ps->editor,strlen(Ps->editor))) {
					fputs("!  synctex_edit: Memory copy problem",stderr);
					free(buffer);
					return -1;
				}\
				printf("SyncTeX: Executing\n%s\n",buffer);
				status = system(buffer);
				free(buffer);
				buffer = NULL;
				return status;
			} else {
				/* just print out the results */
				puts("SyncTeX result begin");
				do {
					printf(	"Output:%s\n"
							"Input:%s\n"
							"Line:%i\n"
							"Column:%i\n"
							"Offset:%i\n"
							"Context:%s\n",
							Ps->output,
							input,
							synctex_node_line(node),
							synctex_node_column(node),
							Ps->offset,
							(Ps->context?Ps->context:""));
				} while((node = synctex_next_result(scanner)) != NULL);
				puts("SyncTeX result end");
			}
		}
	}
	return 0;
}
Exemple #8
0
int synctex_view_proceed(synctex_view_params_t * Ps) {
	synctex_scanner_t scanner = NULL;
	size_t size = 0;
#if SYNCTEX_DEBUG
	printf("line:%i\n",Ps->line);
	printf("column:%i\n",Ps->column);
	printf("input:%s\n",Ps->input);
	printf("viewer:%s\n",Ps->viewer);
	printf("before:%s\n",Ps->before);
	printf("offset:%i\n",Ps->offset);
	printf("middle:%s\n",Ps->middle);
	printf("after:%s\n",Ps->after);
	printf("output:%s\n",Ps->output);
	printf("cwd:%s\n",getcwd(NULL,0));
#endif
	/*  We assume that viewer is not so big: */
#   define SYNCTEX_STR_SIZE 65536
	if(Ps->viewer && strlen(Ps->viewer)>=SYNCTEX_STR_SIZE) {
		synctex_help_view("Viewer command is too long");
		return -1;
	}
	scanner = synctex_scanner_new_with_output_file(Ps->output,Ps->directory,1);
	if(scanner && synctex_display_query(scanner,Ps->input,Ps->line,Ps->column)) {
		synctex_node_t node = NULL;
		if((node = synctex_next_result(scanner)) != NULL) {
			/* filtering the command */
			if(Ps->viewer && strlen(Ps->viewer)) {
				char * viewer = Ps->viewer;
				char * where = NULL;
				char * buffer = NULL;
				char * buffer_cur = NULL;
				int printed = 0;
				int status = 0;
				/* Preparing the buffer where everything will be printed */
				size = strlen(viewer)+3*sizeof(int)+6*sizeof(float)+4*(SYNCTEX_STR_SIZE);
				buffer = malloc(size+1);
				if(NULL == buffer) {
					synctex_help_view("No memory available");
					return -1;
				}
				/*  Properly terminate the buffer, no bad access for string related functions. */
				buffer[size] = '\0';
				/* Replace %{ by &{, then remove all unescaped '%'*/
				while((where = strstr(viewer,"%{")) != NULL) {
					*where = '&';
				}
				/* find all the unescaped '%', change to a safe character */
				where = viewer;
				while(where && (where = strstr(where,"%"))) {
					/*  Find the next occurrence of a "%",
					 *  if it is not followed by another "%",
					 *  replace it by a "&" */
					if(strlen(++where)) {
						if(*where == '%') {
							++where;
						} else {
							*(where-1)='&';
						}
					}
				}
				buffer_cur = buffer;
				/*  find the next occurrence of a format key */
				where = viewer;
				while(viewer && (where = strstr(viewer,"&{"))) {
					#define TEST(KEY,FORMAT,WHAT)\
					if(!strncmp(where,KEY,strlen(KEY))) {\
						printed = where-viewer;\
						if(buffer_cur != memcpy(buffer_cur,viewer,(size_t)printed)) {\
							synctex_help_view("Memory copy problem");\
							free(buffer);\
							return -1;\
						}\
						buffer_cur += printed;size-=printed;\
						printed = snprintf(buffer_cur,size,FORMAT,WHAT);\
						if((unsigned)printed >= (unsigned)size) {\
							synctex_help_view("Snprintf problem");\
							free(buffer);\
							return -1;\
						}\
						buffer_cur += printed;size-=printed;\
						*buffer_cur='\0';\
						viewer = where+strlen(KEY);\
						continue;\
					}
					TEST("&{output}","%s",synctex_scanner_get_output(scanner));
					TEST("&{page}",  "%i",synctex_node_page(node)-1);
					TEST("&{page+1}","%i",synctex_node_page(node));
					TEST("&{x}",     "%f",synctex_node_visible_h(node));
					TEST("&{y}",     "%f",synctex_node_visible_v(node));
					TEST("&{h}",     "%f",synctex_node_box_visible_h(node));
					TEST("&{v}",     "%f",synctex_node_box_visible_v(node)+synctex_node_box_visible_depth(node));
					TEST("&{width}", "%f",fabs(synctex_node_box_visible_width(node)));
					TEST("&{height}","%f",fmax(synctex_node_box_visible_height(node)+synctex_node_box_visible_depth(node),1));
					TEST("&{before}","%s",(Ps->before && strlen(Ps->before)<SYNCTEX_STR_SIZE?Ps->before:""));
					TEST("&{offset}","%i",Ps->offset);
					TEST("&{middle}","%s",(Ps->middle && strlen(Ps->middle)<SYNCTEX_STR_SIZE?Ps->middle:""));
					TEST("&{after}", "%s",(Ps->after && strlen(Ps->after)<SYNCTEX_STR_SIZE?Ps->after:""));
					#undef TEST
					break;
				}
				/* copy the rest of viewer into the buffer */
				if(buffer_cur != strncpy(buffer_cur,viewer,size + 1)) {
					synctex_help_view("Memory copy problem");
					free(buffer);
					return -1;
				}
				buffer_cur[size] = '\0';
				printf("SyncTeX: Executing\n%s\n",buffer);
				status = system(buffer);
				free(buffer);
				buffer = NULL;
				return status;
			} else {
				/* just print out the results */
				puts("SyncTeX result begin");
				do {
					printf(	"Output:%s\n"
							"Page:%i\n"
							"x:%f\n"
							"y:%f\n"
							"h:%f\n"
							"v:%f\n"
							"W:%f\n"
							"H:%f\n"
							"before:%s\n"
							"offset:%i\n"
							"middle:%s\n"
							"after:%s\n",
							Ps->output,
							synctex_node_page(node),
							synctex_node_visible_h(node),
							synctex_node_visible_v(node),
							synctex_node_box_visible_h(node),
							synctex_node_box_visible_v(node)+synctex_node_box_visible_depth(node),
							synctex_node_box_visible_width(node),
							synctex_node_box_visible_height(node)+synctex_node_box_visible_depth(node),
							(Ps->before?Ps->before:""),
							Ps->offset,
							(Ps->middle?Ps->middle:""),
							(Ps->after?Ps->after:""));
				} while((node = synctex_next_result(scanner)) != NULL);
				puts("SyncTeX result end");
			}
		}
	}
	return 0;
}
Exemple #9
0
girara_list_t*
synctex_rectangles_from_position(const char* filename, const char* input_file,
                                 int line, int column, unsigned int* page,
                                 girara_list_t** secondary_rects)
{
  if (filename == NULL || input_file == NULL || page == NULL) {
    return NULL;
  }

  synctex_scanner_t scanner = synctex_scanner_new_with_output_file(filename, NULL, 1);
  if (scanner == NULL) {
    girara_debug("Failed to create synctex scanner.");
    return NULL;
  }

  synctex_scanner_t temp = synctex_scanner_parse(scanner);
  if (temp == NULL) {
    girara_debug("Failed to parse synctex file.");
    synctex_scanner_free(scanner);
    return NULL;
  }

  girara_list_t* hitlist     = girara_list_new2(g_free);
  girara_list_t* other_rects = girara_list_new2(g_free);

  if (synctex_display_query(scanner, input_file, line, column) > 0) {
    synctex_node_t node        = NULL;
    bool got_page              = false;

    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;
      }

      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;

      if (*page == current_page) {
        zathura_rectangle_t* real_rect = g_try_malloc(sizeof(zathura_rectangle_t));
        if (real_rect == NULL) {
          continue;
        }

        *real_rect = rect;
        girara_list_append(hitlist, real_rect);
      } else {
        synctex_page_rect_t* page_rect = g_try_malloc(sizeof(synctex_page_rect_t));
        if (page_rect == NULL) {
          continue;
        }

        page_rect->page = current_page;
        page_rect->rect = rect;

        girara_list_append(other_rects, page_rect);
      }
    }
  }

  synctex_scanner_free(scanner);

  if (secondary_rects != NULL) {
    *secondary_rects = other_rects;
  } else {
    girara_list_free(other_rects);
  }

  return hitlist;
}
Exemple #10
0
void
synctex_edit(zathura_t* zathura, zathura_page_t* page, int x, int y)
{
  if (zathura == NULL || page == NULL || zathura->synctex.editor == NULL) {
    return;
  }

  zathura_document_t* document = zathura_page_get_document(page);
  if (document == NULL) {
    return;
  }

  const char *filename = zathura_document_get_path(document);
  if (filename == NULL) {
    return;
  }

  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);
    return;
  }

  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;
      if (g_shell_parse_argv(zathura->synctex.editor, &argc, &argv, NULL) == TRUE) {
        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);
    }
  }

  synctex_scanner_free(scanner);
}