diff options
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex-rec.ch0 | 10 | ||||
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex.mk | 4 | ||||
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex_main.c | 28 | ||||
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex_parser.c | 916 | ||||
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex_parser.h | 17 | ||||
-rw-r--r-- | Build/source/texk/web2c/synctexdir/synctex_parser_local.h | 37 |
6 files changed, 683 insertions, 329 deletions
diff --git a/Build/source/texk/web2c/synctexdir/synctex-rec.ch0 b/Build/source/texk/web2c/synctexdir/synctex-rec.ch0 index e265e70a14d..e219d7af3f5 100644 --- a/Build/source/texk/web2c/synctexdir/synctex-rec.ch0 +++ b/Build/source/texk/web2c/synctexdir/synctex-rec.ch0 @@ -74,16 +74,6 @@ glue_node: begin r:=get_node(medium_node_size); add_glue_ref(glue_ptr(p)); @z @x -kern_node,math_node: begin r:=get_node(medium_node_size); - words:=medium_node_size; - end; -@y -kern_node,math_node: begin r:=get_node(medium_node_size); - words:=medium_node_size-synctex_field_size; {{\sl Sync\TeX}: do not let \TeX\ copy the {\sl Sync\TeX} information} - end; -@z - -@x @p procedure begin_file_reading; @y @p procedure begin_file_reading; diff --git a/Build/source/texk/web2c/synctexdir/synctex.mk b/Build/source/texk/web2c/synctexdir/synctex.mk index 2228bbb0d87..7e2bc039935 100644 --- a/Build/source/texk/web2c/synctexdir/synctex.mk +++ b/Build/source/texk/web2c/synctexdir/synctex.mk @@ -201,9 +201,9 @@ xetexd.h-with_synctex = if test -z "`grep __SyncTeX__ xetexd.h`";\ fi xetexd.h-without_synctex = echo "warning: SyncTeX is NOT enabled" -# the synctex tool, this is not yet implemented +# the synctex tool synctex_parser.o: $(synctex_dir)/synctex_parser.c $(synctex_dir)/synctex_parser.h - $(compile) -c -I$(synctex_dir) $(ZLIBCPPFLAGS) -o $@ $< + $(compile) -c -DSYNCTEX_USE_LOCAL_HEADER -I$(synctex_dir) $(ZLIBCPPFLAGS) -o $@ $< synctex_main.o: $(synctex_dir)/synctex_main.c $(synctex_dir)/synctex_parser.h $(compile) -c -I$(synctex_dir) $(ZLIBCPPFLAGS) -o $@ $< diff --git a/Build/source/texk/web2c/synctexdir/synctex_main.c b/Build/source/texk/web2c/synctexdir/synctex_main.c index 76d1fe8f9d7..900bbf676fe 100644 --- a/Build/source/texk/web2c/synctexdir/synctex_main.c +++ b/Build/source/texk/web2c/synctexdir/synctex_main.c @@ -46,20 +46,20 @@ This is the command line interface to the synctex_parser.c. # include <math.h> # include "synctex_parser.h" -/* The code below uses strlcat and strlcpy, which avoids security warnings with some compilers. - However, if these are not available we simply use the old, unchecked versions; - this is OK because all the uses in this code are working with a buffer that's been - allocated based on measuring the strings involved. */ -#ifndef HAVE_STRLCAT -#define strlcat(dst, src, size) strcat((dst), (src)) -#endif -#ifndef HAVE_STRLCPY -#define strlcpy(dst, src, size) strcpy((dst), (src)) -#endif -#ifndef HAVE_FMAX -#define fmax my_fmax +/* The code below uses strlcat and strlcpy, which avoids security warnings with some compilers. + However, if these are not available we simply use the old, unchecked versions; + this is OK because all the uses in this code are working with a buffer that's been + allocated based on measuring the strings involved. */ +# ifndef HAVE_STRLCAT +# define strlcat(dst, src, size) strcat((dst), (src)) +# endif +# ifndef HAVE_STRLCPY +# define strlcpy(dst, src, size) strcpy((dst), (src)) +# endif +# ifndef HAVE_FMAX +# define fmax my_fmax inline static double my_fmax(double x, double y) { return (x < y) ? y : x; } -#endif +# endif #define SYNCTEX_DEBUG 0 @@ -114,7 +114,7 @@ void synctex_usage(char * error,va_list ap) { } fprintf((error?stderr:stdout), "usage: synctex <subcommand> [options] [args]\n" - "Synchronize TeXnology command-line client, version 0.1\n\n" + "Synchronize TeXnology command-line client, version 1.0\n\n" "The Synchronization TeXnology by Jérôme Laurens is a new feature of recent TeX engines.\n" "It allows to synchronize between input and output, which means to\n" "navigate from the source document to the typeset material and vice versa.\n\n" diff --git a/Build/source/texk/web2c/synctexdir/synctex_parser.c b/Build/source/texk/web2c/synctexdir/synctex_parser.c index 187c13d25cb..22b3938929c 100644 --- a/Build/source/texk/web2c/synctexdir/synctex_parser.c +++ b/Build/source/texk/web2c/synctexdir/synctex_parser.c @@ -33,7 +33,22 @@ authorization from the copyright holder. */ -#include "web2c/c-auto.h" /* for inline && HAVE_xxx */ +/* We assume that high level application like pdf viewers will want + * to embed this code as is. We assume that they also have locale.h and setlocale. + * For other tools such as TeXLive tools, you must define SYNCTEX_USE_LOCAL_HEADER, + * when building. You also have to create and customize synctex_parser_local.h to fit your system. + * In particular, the HAVE_LOCALE_H and HAVE_SETLOCALE macros should be properly defined. + * With this design, you should not need to edit this file. */ + +# if defined(SYNCTEX_USE_LOCAL_HEADER) +# include "synctex_parser_local.h" +# else +# define HAVE_LOCALE_H 1 +# define HAVE_SETLOCALE 1 +# if defined(_MSC_VER) +# define inline __inline +# endif +# endif #include "stddef.h" #include "stdio.h" @@ -44,15 +59,22 @@ authorization from the copyright holder. #include "math.h" #include "errno.h" -#ifdef HAVE_LOCALE_H +#if defined(HAVE_LOCALE_H) #include <locale.h> #endif +void *_synctex_malloc(size_t size); + /* This custom malloc functions initializes to 0 the newly allocated memory. */ void *_synctex_malloc(size_t size) { void * ptr = malloc(size); if(ptr) { +/* In Visual C, bzero is not available */ +#ifdef _MSC_VER + memset(ptr,0, size); +#else bzero(ptr,size); +#endif } return (void *)ptr; } @@ -122,11 +144,14 @@ struct __synctex_class_t { _synctex_node_getter_t child; _synctex_node_getter_t sibling; _synctex_node_getter_t friend; + _synctex_node_getter_t next_box; _synctex_info_getter_t info; }; -# pragma mark - -# pragma mark Abstract OBJECTS and METHODS +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Abstract OBJECTS and METHODS +# endif /* These macros are shortcuts * This macro checks if a message can be sent. @@ -183,6 +208,16 @@ struct __synctex_class_t { SYNCTEX_GETTER(NODE,friend)[0]=NEW_FRIEND;\ } +/* Next box getter and setter + */ +# define SYNCTEX_NEXT_BOX(NODE) SYNCTEX_GET(NODE,next_box) +# define SYNCTEX_SET_NEXT_BOX(NODE,NEW_FRIEND) if(NODE && NEW_FRIEND){\ + SYNCTEX_GETTER(NODE,next_box)[0]=NEW_FRIEND;\ + } + +void _synctex_free_node(synctex_node_t node); +void _synctex_free_leaf(synctex_node_t node); + /* A node is meant to own its child and sibling. * It is not owned by its parent, unless it is its first child. * This destructor is for all nodes with children. @@ -212,16 +247,17 @@ void _synctex_free_leaf(synctex_node_t node) { #include <zlib.h> /* The synctex scanner is the root object. - * Is is initialized with the contents of a text file. + * Is is initialized with the contents of a text file or a gzipped file. * The buffer_? are first used to parse the text. */ struct __synctex_scanner_t { - gzFile file; /* The (compressed) file */ + gzFile file; /* The (possibly compressed) file */ unsigned char * buffer_cur; /* current location in the buffer */ unsigned char * buffer_start; /* start of the buffer */ unsigned char * buffer_end; /* end of the buffer */ char * output_fmt; /* dvi or pdf, not yet used */ char * output; /* the output name used to create the scanner */ + char * synctex; /* the .synctex or .synctex.gz name used to create the scanner */ int version; /* 1, not yet used */ int pre_magnification; /* magnification from the synctex preamble */ int pre_unit; /* unit from the synctex preamble */ @@ -235,7 +271,7 @@ struct __synctex_scanner_t { synctex_node_t input; /* The first input node, its siblings are the other input nodes */ int number_of_lists; /* The number of friend lists */ synctex_node_t * lists_of_friends;/* The friend lists */ - _synctex_class_t class[synctex_node_type_last]; /* The classes of the nodes of the scanner */ + _synctex_class_t class[synctex_node_number_of_types]; /* The classes of the nodes of the scanner */ }; /* SYNCTEX_CUR, SYNCTEX_START and SYNCTEX_END are convenient shortcuts @@ -244,15 +280,16 @@ struct __synctex_scanner_t { # define SYNCTEX_START (scanner->buffer_start) # define SYNCTEX_END (scanner->buffer_end) -# pragma mark - -# pragma mark OBJECTS, their creators and destructors. +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark OBJECTS, their creators and destructors. +# endif /* Here, we define the indices for the different informations. * They are used to declare the size of the implementation. * For example, if one object uses SYNCTEX_HORIZ_IDX is its size, * then its info will contain a tag, line, column, horiz but no width nor height nor depth */ -# define SYNCTEX_PAGE_IDX 0 /* The sheet is a first level node. * It has no parent (the parent is the scanner itself) @@ -270,16 +307,11 @@ struct __synctex_scanner_t { # define SYNCTEX_PAGE_IDX 0 # define SYNCTEX_PAGE(NODE) SYNCTEX_INFO(NODE)[SYNCTEX_PAGE_IDX].INT -typedef struct { - synctex_class_t class; - synctex_info_t implementation[2+SYNCTEX_PAGE_IDX+1];/* child, sibling - * SYNCTEX_PAGE_IDX */ -} synctex_sheet_t; - /* This macro defines implementation offsets * It is only used for pointer values */ # define SYNCTEX_MAKE_GET(SYNCTEX_GETTER,OFFSET)\ +synctex_node_t * SYNCTEX_GETTER (synctex_node_t node);\ synctex_node_t * SYNCTEX_GETTER (synctex_node_t node) {\ return node?(synctex_node_t *)((&((node)->implementation))+OFFSET):NULL;\ } @@ -288,6 +320,13 @@ SYNCTEX_MAKE_GET(_synctex_implementation_1,1) SYNCTEX_MAKE_GET(_synctex_implementation_2,2) SYNCTEX_MAKE_GET(_synctex_implementation_3,3) SYNCTEX_MAKE_GET(_synctex_implementation_4,4) +SYNCTEX_MAKE_GET(_synctex_implementation_5,5) + +typedef struct { + synctex_class_t class; + synctex_info_t implementation[3+SYNCTEX_PAGE_IDX+1];/* child, sibling, next box, + * SYNCTEX_PAGE_IDX */ +} synctex_sheet_t; synctex_node_t _synctex_new_sheet(synctex_scanner_t scanner); void _synctex_display_sheet(synctex_node_t sheet); @@ -304,7 +343,8 @@ static const _synctex_class_t synctex_class_sheet = { &_synctex_implementation_0, /* child */ &_synctex_implementation_1, /* sibling */ NULL, /* No friend */ - (_synctex_info_getter_t)&_synctex_implementation_2 /* info */ + &_synctex_implementation_2, /* Next box */ + (_synctex_info_getter_t)&_synctex_implementation_3 /* info */ }; /* sheet node creator */ @@ -340,7 +380,7 @@ synctex_node_t _synctex_new_sheet(synctex_scanner_t scanner) { typedef struct { synctex_class_t class; - synctex_info_t implementation[4+SYNCTEX_DEPTH_IDX+1]; /* parent,child,sibling,friend, + synctex_info_t implementation[5+SYNCTEX_DEPTH_IDX+1]; /* parent,child,sibling,friend,next box, * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH,SYNCTEX_HEIGHT,SYNCTEX_DEPTH */ } synctex_vert_box_node_t; @@ -362,7 +402,8 @@ static const _synctex_class_t synctex_class_vbox = { &_synctex_implementation_1, /* child */ &_synctex_implementation_2, /* sibling */ &_synctex_implementation_3, /* friend */ - (_synctex_info_getter_t)&_synctex_implementation_4 + &_synctex_implementation_4, /* next box */ + (_synctex_info_getter_t)&_synctex_implementation_5 }; /* vertical box node creator */ @@ -389,7 +430,7 @@ synctex_node_t _synctex_new_vbox(synctex_scanner_t scanner) { /* Horizontal boxes must contain visible size, because 0 width does not mean emptiness */ typedef struct { synctex_class_t class; - synctex_info_t implementation[4+SYNCTEX_DEPTH_V_IDX+1]; /*parent,child,sibling,friend, + synctex_info_t implementation[5+SYNCTEX_DEPTH_V_IDX+1]; /*parent,child,sibling,friend,next box, * SYNCTEX_TAG,SYNCTEX_LINE,SYNCTEX_COLUMN, * SYNCTEX_HORIZ,SYNCTEX_VERT,SYNCTEX_WIDTH,SYNCTEX_HEIGHT,SYNCTEX_DEPTH, * SYNCTEX_HORIZ_V,SYNCTEX_VERT_V,SYNCTEX_WIDTH_V,SYNCTEX_HEIGHT_V,SYNCTEX_DEPTH_V*/ @@ -411,7 +452,8 @@ static const _synctex_class_t synctex_class_hbox = { &_synctex_implementation_1, /* child */ &_synctex_implementation_2, /* sibling */ &_synctex_implementation_3, /* friend */ - (_synctex_info_getter_t)&_synctex_implementation_4 + &_synctex_implementation_4, /* next box */ + (_synctex_info_getter_t)&_synctex_implementation_5 }; /* horizontal box node creator */ @@ -448,6 +490,7 @@ static const _synctex_class_t synctex_class_void_vbox = { NULL, /* No child */ &_synctex_implementation_1, /* sibling */ &_synctex_implementation_2, /* friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_3 }; @@ -474,6 +517,7 @@ static const _synctex_class_t synctex_class_void_hbox = { NULL, /* No child */ &_synctex_implementation_1, /* sibling */ &_synctex_implementation_2, /* friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_3 }; @@ -509,6 +553,7 @@ static const _synctex_class_t synctex_class_math = { NULL, /* No child */ &_synctex_implementation_1, /* sibling */ &_synctex_implementation_2, /* friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_3 }; @@ -535,6 +580,7 @@ static const _synctex_class_t synctex_class_glue = { NULL, /* No child */ &_synctex_implementation_1, /* sibling */ &_synctex_implementation_2, /* friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_3 }; /* glue node creator */ @@ -560,6 +606,7 @@ static const _synctex_class_t synctex_class_kern = { NULL, /* No child */ &_synctex_implementation_1, /* sibling */ &_synctex_implementation_2, /* friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_3 }; @@ -599,6 +646,7 @@ static const _synctex_class_t synctex_class_input = { NULL, /* No child */ &_synctex_implementation_0, /* sibling */ NULL, /* No friend */ + NULL, /* No next box */ (_synctex_info_getter_t)&_synctex_implementation_1 }; @@ -616,8 +664,10 @@ void _synctex_free_input(synctex_node_t node){ free(node); } } -#pragma mark - -#pragma mark Navigation +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Navigation +# endif synctex_node_t synctex_node_parent(synctex_node_t node) { return SYNCTEX_PARENT(node); @@ -654,8 +704,10 @@ sibling: } return NULL; } -#pragma mark - -#pragma mark CLASS +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark CLASS +# endif /* Public node accessor: the type */ synctex_node_type_t synctex_node_type(synctex_node_t node) { @@ -667,13 +719,15 @@ synctex_node_type_t synctex_node_type(synctex_node_t node) { /* Public node accessor: the human readable type */ const char * synctex_node_isa(synctex_node_t node) { -static const char * isa[synctex_node_type_last] = - {"Not a node","sheet","vbox","void vbox","hbox","void hbox","kern","glue","math","input"}; +static const char * isa[synctex_node_number_of_types] = + {"Not a node","sheet","vbox","void vbox","hbox","non void hbox","void hbox","kern","glue","math","input"}; return isa[synctex_node_type(node)]; } -# pragma mark - -# pragma mark SYNCTEX_LOG +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark SYNCTEX_LOG +# endif # define SYNCTEX_LOG(NODE) SYNCTEX_MSG_SEND(NODE,log) @@ -682,6 +736,12 @@ void synctex_node_log(synctex_node_t node) { SYNCTEX_LOG(node); } +# define SYNCTEX_DISPLAY(NODE) SYNCTEX_MSG_SEND(NODE,display) + +void synctex_node_display(synctex_node_t node) { + SYNCTEX_DISPLAY(node); +} + void _synctex_log_sheet(synctex_node_t sheet) { if(sheet) { printf("%s:%i\n",synctex_node_isa(sheet),SYNCTEX_PAGE(sheet)); @@ -771,8 +831,6 @@ void _synctex_log_input(synctex_node_t node) { printf(" SYNCTEX_SIBLING:%p",SYNCTEX_SIBLING(node)); } -# define SYNCTEX_DISPLAY(NODE) SYNCTEX_MSG_SEND(NODE,display) - void _synctex_display_sheet(synctex_node_t sheet) { if(sheet) { printf("....{%i\n",SYNCTEX_PAGE(sheet)); @@ -869,8 +927,10 @@ void _synctex_display_input(synctex_node_t node) { SYNCTEX_DISPLAY(SYNCTEX_SIBLING(node)); } -# pragma mark - -# pragma mark SCANNER +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark SCANNER +# endif /* Here are gathered all the possible status that the next scanning functions will return. * All these functions return a status, and pass their result through pointers. @@ -898,7 +958,7 @@ typedef int synctex_status_t; # define SYNCTEX_FILE scanner->file /* Actually, the minimum buffer size is driven by integer and float parsing. - * ±0.123456789e123 + * ¬±0.123456789e123 */ # define SYNCTEX_BUFFER_MIN_SIZE 16 # define SYNCTEX_BUFFER_SIZE 32768 @@ -916,6 +976,98 @@ inline static int _synctex_error(char * reason,...) { return result; } +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Prototypes +# endif +void _synctex_free_node(synctex_node_t node); +void _synctex_free_leaf(synctex_node_t node); +synctex_node_t _synctex_new_sheet(synctex_scanner_t scanner); +synctex_node_t _synctex_new_vbox(synctex_scanner_t scanner); +synctex_node_t _synctex_new_hbox(synctex_scanner_t scanner); +synctex_node_t _synctex_new_void_vbox(synctex_scanner_t scanner); +synctex_node_t _synctex_new_void_hbox(synctex_scanner_t scanner); +synctex_node_t _synctex_new_math(synctex_scanner_t scanner); +synctex_node_t _synctex_new_glue(synctex_scanner_t scanner); +synctex_node_t _synctex_new_kern(synctex_scanner_t scanner); +synctex_node_t _synctex_new_input(synctex_scanner_t scanner); +void _synctex_free_input(synctex_node_t node); +synctex_node_t synctex_node_next(synctex_node_t node); +synctex_node_type_t synctex_node_type(synctex_node_t node); +const char * synctex_node_isa(synctex_node_t node); +void synctex_node_log(synctex_node_t node); +void _synctex_log_sheet(synctex_node_t sheet); +void _synctex_log_medium_node(synctex_node_t node); +void _synctex_log_void_box(synctex_node_t node); +void _synctex_log_box(synctex_node_t node); +void _synctex_log_horiz_box(synctex_node_t node); +void _synctex_log_input(synctex_node_t node); +void _synctex_display_sheet(synctex_node_t sheet); +void _synctex_display_vbox(synctex_node_t node); +void _synctex_display_hbox(synctex_node_t node); +void _synctex_display_void_vbox(synctex_node_t node); +void _synctex_display_void_hbox(synctex_node_t node); +void _synctex_display_glue(synctex_node_t node); +void _synctex_display_math(synctex_node_t node); +void _synctex_display_kern(synctex_node_t node); +void _synctex_display_input(synctex_node_t node); +inline static int _synctex_error(char * reason,...); +synctex_status_t _synctex_buffer_get_available_size(synctex_scanner_t scanner, size_t * size_ptr); +synctex_status_t _synctex_next_line(synctex_scanner_t scanner); +synctex_status_t _synctex_match_string(synctex_scanner_t scanner, const char * the_string); +synctex_status_t _synctex_decode_int(synctex_scanner_t scanner, int* value_ref); +synctex_status_t _synctex_decode_string(synctex_scanner_t scanner, char ** value_ref); +synctex_status_t _synctex_scan_input(synctex_scanner_t scanner); +synctex_status_t _synctex_scan_preamble(synctex_scanner_t scanner); +synctex_status_t _synctex_scan_float_and_dimension(synctex_scanner_t scanner, float * value_ref); +synctex_status_t _synctex_scan_post_scriptum(synctex_scanner_t scanner); +int _synctex_scan_postamble(synctex_scanner_t scanner); +synctex_status_t _synctex_setup_visible_box(synctex_node_t box); +synctex_status_t _synctex_horiz_box_setup_visible(synctex_node_t node,int h, int v); +synctex_status_t _synctex_scan_sheet(synctex_scanner_t scanner, synctex_node_t parent); +synctex_status_t _synctex_scan_content(synctex_scanner_t scanner); +void synctex_strip_last_path_extension(char * string); +synctex_scanner_t synctex_scanner_new_with_output_file(const char * output); +synctex_scanner_t synctex_scanner_new_with_contents_of_file(const char * name); +void synctex_scanner_free(synctex_scanner_t scanner); +int synctex_scanner_pre_x_offset(synctex_scanner_t scanner); +int synctex_scanner_pre_y_offset(synctex_scanner_t scanner); +int synctex_scanner_x_offset(synctex_scanner_t scanner); +int synctex_scanner_y_offset(synctex_scanner_t scanner); +float synctex_scanner_magnification(synctex_scanner_t scanner); +void synctex_scanner_display(synctex_scanner_t scanner); +const char * synctex_scanner_get_name(synctex_scanner_t scanner,int tag); +int synctex_scanner_get_tag(synctex_scanner_t scanner,const char * name); +synctex_node_t synctex_scanner_input(synctex_scanner_t scanner); +const char * synctex_scanner_get_output_fmt(synctex_scanner_t scanner); +const char * synctex_scanner_get_output(synctex_scanner_t scanner); +float synctex_node_h(synctex_node_t node); +float synctex_node_v(synctex_node_t node); +float synctex_node_width(synctex_node_t node); +float synctex_node_box_h(synctex_node_t node); +float synctex_node_box_v(synctex_node_t node); +float synctex_node_box_width(synctex_node_t node); +float synctex_node_box_height(synctex_node_t node); +float synctex_node_box_depth(synctex_node_t node); +float synctex_node_visible_h(synctex_node_t node); +float synctex_node_visible_v(synctex_node_t node); +float synctex_node_visible_width(synctex_node_t node); +float synctex_node_box_visible_h(synctex_node_t node); +float synctex_node_box_visible_v(synctex_node_t node); +float synctex_node_box_visible_width(synctex_node_t node); +float synctex_node_box_visible_height(synctex_node_t node); +float synctex_node_box_visible_depth(synctex_node_t node); +int synctex_node_page(synctex_node_t node); +int synctex_node_tag(synctex_node_t node); +int synctex_node_line(synctex_node_t node); +int synctex_node_column(synctex_node_t node); +synctex_node_t synctex_sheet_content(synctex_scanner_t scanner,int page); +int synctex_display_query(synctex_scanner_t scanner,const char * name,int line,int column); +int _synctex_node_is_box(synctex_node_t node); +int synctex_edit_query(synctex_scanner_t scanner,int page,float h,float v); +synctex_node_t synctex_next_result(synctex_scanner_t scanner); +int synctex_bail(void); + /* Try to ensure that the buffer contains at least size bytes. * Passing a huge size argument means the whole buffer length. * Passing a null size argument means return the available buffer length, without reading the file. @@ -1143,8 +1295,8 @@ return_NOT_OK: /* Used when parsing the synctex file. * Decode an integer. * First, field separators, namely ':' and ',' characters are skipped - * The returned value is -1 if there is an unrecoverable error. - * It is 0 if an integer could not be parsed, for example + * The returned value is negative if there is an unrecoverable error. + * It is SYNCTEX_STATUS_NOT_OK if an integer could not be parsed, for example * if the characters at the current cursor position are not digits or * if the end of the file has been reached. * It is SYNCTEX_STATUS_OK if an int has been successfully parsed. @@ -1342,6 +1494,8 @@ synctex_status_t _synctex_scan_input(synctex_scanner_t scanner) { typedef synctex_status_t (*synctex_decoder_t)(synctex_scanner_t,void *); +synctex_status_t _synctex_scan_named(synctex_scanner_t scanner,char * name,void * value_ref,synctex_decoder_t decoder); + /* Used when parsing the synctex file. * Read one of the settings. * On normal completion, returns SYNCTEX_STATUS_OK. @@ -1465,49 +1619,49 @@ synctex_status_t _synctex_scan_float_and_dimension(synctex_scanner_t scanner, fl } SYNCTEX_CUR = endptr; if((status = _synctex_match_string(scanner,"in")) >= SYNCTEX_STATUS_OK) { - f *= 72.27*65536; + f *= 72.27f*65536; } else if(status<SYNCTEX_STATUS_EOF) { report_unit_error: _synctex_error("problem with unit."); return status; } else if((status = _synctex_match_string(scanner,"cm")) >= SYNCTEX_STATUS_OK) { - f *= 72.27*65536/2.54; + f *= 72.27f*65536/2.54f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"mm")) >= SYNCTEX_STATUS_OK) { - f *= 72.27*65536/25.4; + f *= 72.27f*65536/25.4f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"pt")) >= SYNCTEX_STATUS_OK) { - f *= 65536.0; + f *= 65536.0f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"bp")) >= SYNCTEX_STATUS_OK) { - f *= 72.27/72*65536; + f *= 72.27f/72*65536.0f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"pc")) >= SYNCTEX_STATUS_OK) { - f *= 12.0*65536; + f *= 12.0*65536.0f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"sp")) >= SYNCTEX_STATUS_OK) { - f *= 1.0; + f *= 1.0f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"dd")) >= SYNCTEX_STATUS_OK) { - f *= 1238.0/1157*65536; + f *= 1238.0f/1157*65536.0f; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"cc")) >= SYNCTEX_STATUS_OK) { - f *= 14856.0/1157*65536; + f *= 14856.0f/1157*65536; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"nd")) >= SYNCTEX_STATUS_OK) { - f *= 685.0/642*65536; + f *= 685.0f/642*65536; } else if(status<0) { goto report_unit_error; } else if((status = _synctex_match_string(scanner,"nc")) >= SYNCTEX_STATUS_OK) { - f *= 1370.0/107*65536; + f *= 1370.0f/107*65536; } else if(status<0) { goto report_unit_error; } @@ -1640,7 +1794,10 @@ count_again: * At creation time, the visible size is set to the values of the real size. */ synctex_status_t _synctex_setup_visible_box(synctex_node_t box) { - if(NULL == box || box->class->type != synctex_node_type_hbox) { + if(NULL == box + || (box->class->type != synctex_node_type_hbox + && box->class->type != synctex_node_type_hbox_non_void + && box->class->type != synctex_node_type_vbox)) { return SYNCTEX_STATUS_BAD_ARGUMENT; } if(SYNCTEX_INFO(box) != NULL) { @@ -1659,9 +1816,12 @@ synctex_status_t _synctex_setup_visible_box(synctex_node_t box) { * With this method, one can enlarge the box to contain the given point (h,v). */ synctex_status_t _synctex_horiz_box_setup_visible(synctex_node_t node,int h, int v) { -#pragma unused(v) +# ifdef __DARWIN_UNIX03 +# pragma unused(v) +# endif int itsBtm, itsTop; - if(NULL == node || node->class->type != synctex_node_type_hbox) { + if(NULL == node || (node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void)) { return SYNCTEX_STATUS_BAD_ARGUMENT; } if(SYNCTEX_WIDTH_V(node)<0) { @@ -1695,26 +1855,29 @@ synctex_status_t _synctex_horiz_box_setup_visible(synctex_node_t node,int h, int int synctex_bail(void); /* Used when parsing the synctex file. - * The parent is a newly created sheet node that will hold the contents. + * The sheet argument is a newly created sheet node that will hold the contents. * Something is returned in case of error. */ -synctex_status_t _synctex_scan_sheet(synctex_scanner_t scanner, synctex_node_t parent) { +synctex_status_t _synctex_scan_sheet(synctex_scanner_t scanner, synctex_node_t sheet) { + synctex_node_t parent = sheet; synctex_node_t child = NULL; synctex_node_t sibling = NULL; + synctex_node_t box = sheet; int friend_index = 0; synctex_info_t * info = NULL; int curh, curv; synctex_status_t status = 0; size_t available = 0; - if((NULL == scanner) || (NULL == parent)) { + if((NULL == scanner) || (NULL == sheet)) { return SYNCTEX_STATUS_BAD_ARGUMENT; } -vertical_loop: + /* We MUST start with a box, so at this level, the unique possibility is '[', '(' or "}". */ +prepare_loop: if(SYNCTEX_CUR<SYNCTEX_END) { if(*SYNCTEX_CUR == '[') { +scan_vbox: ++SYNCTEX_CUR; - if(NULL != (child = _synctex_new_vbox(scanner)) - && NULL != (info = SYNCTEX_INFO(child))) { + if((child = _synctex_new_vbox(scanner)) && (info = SYNCTEX_INFO(child))) { # define SYNCTEX_DECODE_FAILED(WHAT) \ (_synctex_decode_int(scanner,&(info[WHAT].INT))<SYNCTEX_STATUS_OK) if(SYNCTEX_DECODE_FAILED(SYNCTEX_TAG_IDX) @@ -1726,7 +1889,8 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad vbox record."); - return SYNCTEX_STATUS_ERROR; + #define SYNCTEX_RETURN(STATUS) return STATUS; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); parent = child; @@ -1734,8 +1898,73 @@ vertical_loop: goto vertical_loop; } else { _synctex_error("Can't create vbox record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } + } else if(*SYNCTEX_CUR == '(') { +scan_hbox: + ++SYNCTEX_CUR; + if((child = _synctex_new_hbox(scanner)) && (info = SYNCTEX_INFO(child))) { + if(SYNCTEX_DECODE_FAILED(SYNCTEX_TAG_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_LINE_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_HORIZ_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_WIDTH_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_HEIGHT_IDX) + || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) + || _synctex_setup_visible_box(child)<SYNCTEX_STATUS_OK + || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { + _synctex_error("Bad hbox record."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + SYNCTEX_SET_CHILD(parent,child); + parent = child; + child = NULL; + goto vertical_loop; + } else { + _synctex_error("Can't create hbox record."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + } else if(*SYNCTEX_CUR == '}') { +scan_teehs: + ++SYNCTEX_CUR; + if(NULL == parent || parent->class->type != synctex_node_type_sheet + || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { + _synctex_error("Unexpected end of sheet."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + SYNCTEX_RETURN(SYNCTEX_STATUS_OK); + } else if(*SYNCTEX_CUR == '!') { +scan_anchor: + ++SYNCTEX_CUR; + if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { + _synctex_error("Missing anchor."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto prepare_loop; + } else { + /* _synctex_error("Ignored record %c\n",*SYNCTEX_CUR); */ + ++SYNCTEX_CUR; + if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { + _synctex_error("Unexpected end."); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } + goto prepare_loop; + } + } else { + available = 1; + status = _synctex_buffer_get_available_size(scanner,&available); + if(status<SYNCTEX_STATUS_OK && available>0){ + _synctex_error("Uncomplete sheet(0)"); + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); + } else { + goto prepare_loop; + } + } + synctex_bail(); +vertical_loop: + if(SYNCTEX_CUR<SYNCTEX_END) { + if(*SYNCTEX_CUR == '[') { + goto scan_vbox; } else if(*SYNCTEX_CUR == ']') { ++SYNCTEX_CUR; if(NULL != parent && parent->class->type == synctex_node_type_vbox) { @@ -1754,39 +1983,22 @@ vertical_loop: } if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Uncomplete sheet."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else if(*SYNCTEX_CUR == '(') { - ++SYNCTEX_CUR; - if(NULL != (child = _synctex_new_hbox(scanner)) - && NULL != (info = SYNCTEX_INFO(child))) { - if(SYNCTEX_DECODE_FAILED(SYNCTEX_TAG_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_LINE_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_HORIZ_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_WIDTH_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_HEIGHT_IDX) - || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) - || _synctex_setup_visible_box(child)<SYNCTEX_STATUS_OK - || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { - _synctex_error("Bad hbox record."); - return SYNCTEX_STATUS_ERROR; - } - SYNCTEX_SET_CHILD(parent,child); - parent = child; - child = NULL; - goto vertical_loop; - } else { - _synctex_error("Can't create hbox record."); - return SYNCTEX_STATUS_ERROR; - } + goto scan_hbox; } else if(*SYNCTEX_CUR == ')') { ++SYNCTEX_CUR; - if(NULL != parent && parent->class->type == synctex_node_type_hbox) { + if(NULL != parent && (parent->class->type == synctex_node_type_hbox + || parent->class->type == synctex_node_type_hbox_non_void)) { if(NULL == child) { SYNCTEX_UPDATE_BOX_FRIEND(parent); } + if(parent->class->type == synctex_node_type_hbox_non_void) { + SYNCTEX_SET_NEXT_BOX(box,parent); + box = parent; + } child = parent; parent = SYNCTEX_PARENT(child); } else { @@ -1794,7 +2006,7 @@ vertical_loop: } if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Uncomplete sheet."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else if(*SYNCTEX_CUR == 'v') { @@ -1810,7 +2022,7 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad void vbox record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); #define SYNCTEX_UPDATE_FRIEND(NODE)\ @@ -1821,7 +2033,7 @@ vertical_loop: goto horizontal_loop; } else { _synctex_error("Can't create vbox record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'h') { ++SYNCTEX_CUR; @@ -1836,7 +2048,7 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad void hbox record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); SYNCTEX_UPDATE_FRIEND(child); @@ -1845,7 +2057,7 @@ vertical_loop: goto horizontal_loop; } else { _synctex_error("Can't create void hbox record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'k') { ++SYNCTEX_CUR; @@ -1858,20 +2070,25 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_WIDTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad kern record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); _synctex_horiz_box_setup_visible(parent,synctex_node_h(child),synctex_node_v(child)); + #define SYNCTEX_HBOX_SET_NON_VOID(NODE)\ + if(NODE->class->type == synctex_node_type_hbox) {\ + NODE->class->type = synctex_node_type_hbox_non_void;\ + } + SYNCTEX_HBOX_SET_NON_VOID(parent); SYNCTEX_UPDATE_FRIEND(child); if(NULL == parent) { _synctex_error("Missing parent for Child"); synctex_node_log(child); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else { _synctex_error("Can't create kern record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'x') { ++SYNCTEX_CUR; @@ -1881,7 +2098,7 @@ vertical_loop: || _synctex_decode_int(scanner,&curv)<SYNCTEX_STATUS_OK || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad x record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } _synctex_horiz_box_setup_visible(parent,curh,curv); goto vertical_loop; @@ -1895,15 +2112,16 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad glue record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); + SYNCTEX_HBOX_SET_NON_VOID(parent); _synctex_horiz_box_setup_visible(parent,synctex_node_h(child),synctex_node_v(child)); SYNCTEX_UPDATE_FRIEND(child); goto horizontal_loop; } else { _synctex_error("Can't create glue record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == '$') { ++SYNCTEX_CUR; @@ -1915,37 +2133,27 @@ vertical_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad math record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_CHILD(parent,child); + SYNCTEX_HBOX_SET_NON_VOID(parent); _synctex_horiz_box_setup_visible(parent,synctex_node_h(child),synctex_node_v(child)); SYNCTEX_UPDATE_FRIEND(child); goto horizontal_loop; } else { _synctex_error("Can't create math record."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == '}') { - ++SYNCTEX_CUR; - if(NULL == parent || parent->class->type != synctex_node_type_sheet - || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { - _synctex_error("Unexpected end of sheet."); - return SYNCTEX_STATUS_ERROR; - } - return SYNCTEX_STATUS_OK; + goto scan_teehs; } else if(*SYNCTEX_CUR == '!') { - ++SYNCTEX_CUR; - if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { - _synctex_error("Missing anchor."); - return SYNCTEX_STATUS_ERROR; - } - goto vertical_loop; + goto scan_anchor; } else { /* _synctex_error("Ignored record %c\n",*SYNCTEX_CUR); */ ++SYNCTEX_CUR; if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Unexpected end."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto vertical_loop; } @@ -1954,7 +2162,7 @@ vertical_loop: status = _synctex_buffer_get_available_size(scanner,&available); if(status<SYNCTEX_STATUS_OK && available>0){ _synctex_error("Uncomplete sheet(0)"); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } else { goto vertical_loop; } @@ -1975,7 +2183,7 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad vbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); parent = sibling; @@ -1983,7 +2191,7 @@ horizontal_loop: goto vertical_loop; } else { _synctex_error("Can't create vbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == ']') { ++SYNCTEX_CUR; @@ -1998,7 +2206,7 @@ horizontal_loop: } if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Unexpected end of file (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else if(*SYNCTEX_CUR == '(') { @@ -2015,7 +2223,7 @@ horizontal_loop: || _synctex_setup_visible_box(sibling)<SYNCTEX_STATUS_OK || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad hbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); parent = sibling; @@ -2023,14 +2231,19 @@ horizontal_loop: goto vertical_loop; } else { _synctex_error("Can't create hbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == ')') { ++SYNCTEX_CUR; - if(NULL != parent && parent->class->type == synctex_node_type_hbox) { + if(NULL != parent &&(parent->class->type == synctex_node_type_hbox + ||parent->class->type == synctex_node_type_hbox_non_void)) { if(NULL == child) { SYNCTEX_UPDATE_BOX_FRIEND(parent); } + if(parent->class->type == synctex_node_type_hbox_non_void) { + SYNCTEX_SET_NEXT_BOX(box,parent); + box = parent; + } child = parent; parent = SYNCTEX_PARENT(child); } else { @@ -2038,7 +2251,7 @@ horizontal_loop: } if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Unexpected end of file (2,')')."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else if(*SYNCTEX_CUR == 'v') { @@ -2054,7 +2267,7 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad void vbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); SYNCTEX_UPDATE_FRIEND(sibling); @@ -2062,7 +2275,7 @@ horizontal_loop: goto horizontal_loop; } else { _synctex_error("can't create void vbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'h') { ++SYNCTEX_CUR; @@ -2077,7 +2290,7 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_DEPTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad void hbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); SYNCTEX_UPDATE_FRIEND(sibling); @@ -2087,7 +2300,7 @@ horizontal_loop: goto horizontal_loop; } else { _synctex_error("can't create void hbox record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'x') { ++SYNCTEX_CUR; @@ -2097,7 +2310,7 @@ horizontal_loop: || _synctex_decode_int(scanner,&curv)<SYNCTEX_STATUS_OK || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad x record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } _synctex_horiz_box_setup_visible(parent,curh,curv); goto horizontal_loop; @@ -2112,16 +2325,17 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_WIDTH_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad kern record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); SYNCTEX_UPDATE_FRIEND(sibling); child = sibling; _synctex_horiz_box_setup_visible(parent,synctex_node_h(child),synctex_node_v(child)); + SYNCTEX_HBOX_SET_NON_VOID(parent); goto horizontal_loop; } else { _synctex_error("Can't create kern record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == 'g') { ++SYNCTEX_CUR; @@ -2133,16 +2347,17 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad glue record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); SYNCTEX_UPDATE_FRIEND(sibling); child = sibling; _synctex_horiz_box_setup_visible(parent,synctex_node_h(child),synctex_node_v(child)); + SYNCTEX_HBOX_SET_NON_VOID(parent); goto horizontal_loop; } else { _synctex_error("Can't create glue record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == '$') { ++SYNCTEX_CUR; @@ -2154,37 +2369,32 @@ horizontal_loop: || SYNCTEX_DECODE_FAILED(SYNCTEX_VERT_IDX) || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { _synctex_error("Bad math record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } SYNCTEX_SET_SIBLING(child,sibling); _synctex_horiz_box_setup_visible(parent,synctex_node_h(sibling),synctex_node_v(sibling)); SYNCTEX_UPDATE_FRIEND(sibling); child = sibling; + SYNCTEX_HBOX_SET_NON_VOID(parent); goto horizontal_loop; } else { _synctex_error("Can't create math record (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } else if(*SYNCTEX_CUR == '}') { - ++SYNCTEX_CUR; - if(NULL == parent || parent->class->type != synctex_node_type_sheet - || (_synctex_next_line(scanner)<SYNCTEX_STATUS_OK)) { - _synctex_error("Unexpected end of sheet (2)."); - return SYNCTEX_STATUS_ERROR; - } - return SYNCTEX_STATUS_OK;/* This is where we exit normally */ + goto scan_teehs; } else if(*SYNCTEX_CUR == '!') { ++SYNCTEX_CUR; if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { _synctex_error("Missing anchor (2)."); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } else { ++SYNCTEX_CUR; /* _synctex_error("Ignored record %c(2)\n",*SYNCTEX_CUR); */ if(_synctex_next_line(scanner)<SYNCTEX_STATUS_OK) { - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } goto horizontal_loop; } @@ -2195,7 +2405,7 @@ horizontal_loop: goto horizontal_loop; } else { _synctex_error("Uncomplete sheet(2)"); - return SYNCTEX_STATUS_ERROR; + SYNCTEX_RETURN(SYNCTEX_STATUS_ERROR); } } # undef SYNCTEX_DECODE_FAILED @@ -2359,19 +2569,17 @@ return_on_error: goto return_on_error; } scanner = synctex_scanner_new_with_contents_of_file(synctex); - } - /* make a private copy of output for the scanner */ - if(NULL != scanner) { - if(NULL == (scanner->output = (char *)malloc(strlen(output)+1))){ - fputs("! synctex_scanner_new_with_output_file: Memory problem (2)",stderr); - goto return_on_error; - } - if(scanner->output != strcpy(scanner->output,output)) { - fprintf(stderr,"! synctex_scanner_new_with_output_file: Copy problem\n"); + if(NULL == scanner) { goto return_on_error; } } - free(synctex); + /* make a private copy of output for the scanner */ + if(NULL == (scanner->output = (char *)malloc(strlen(output)+1))){ + fputs("! synctex_scanner_new_with_output_file: Memory problem (2), scanner's output is not reliable.",stderr); + } else if(scanner->output != strcpy(scanner->output,output)) { + fputs("! synctex_scanner_new_with_output_file: Copy problem, scanner's output is not reliable.\n",stderr); + } + scanner->synctex = synctex;/* Now the scanner owns synctex */ return scanner; } @@ -2403,7 +2611,7 @@ synctex_scanner_t synctex_scanner_new_with_contents_of_file(const char * name) { scanner->pre_x_offset = scanner->pre_y_offset = 578; /* initialize the offset with a fake unprobable value, * If there is a post scriptum section, this value will be overriden by the real life value */ - scanner->x_offset = scanner->y_offset = 6.027e23; + scanner->x_offset = scanner->y_offset = 6.027e23f; scanner->class[synctex_node_type_sheet] = synctex_class_sheet; (scanner->class[synctex_node_type_sheet]).scanner = scanner; scanner->class[synctex_node_type_vbox] = synctex_class_vbox; @@ -2412,6 +2620,8 @@ synctex_scanner_t synctex_scanner_new_with_contents_of_file(const char * name) { (scanner->class[synctex_node_type_void_vbox]).scanner = scanner; scanner->class[synctex_node_type_hbox] = synctex_class_hbox; (scanner->class[synctex_node_type_hbox]).scanner = scanner; + scanner->class[synctex_node_type_hbox_non_void] = synctex_class_hbox; + (scanner->class[synctex_node_type_hbox_non_void]).scanner = scanner; scanner->class[synctex_node_type_void_hbox] = synctex_class_void_hbox; (scanner->class[synctex_node_type_void_hbox]).scanner = scanner; scanner->class[synctex_node_type_kern] = synctex_class_kern; @@ -2483,8 +2693,8 @@ bailey: scanner->y_offset = scanner->pre_y_offset * (scanner->pre_unit / 65781.76); } else { /* post offset */ - scanner->x_offset /= 65781.76; - scanner->y_offset /= 65781.76; + scanner->x_offset /= 65781.76f; + scanner->y_offset /= 65781.76f; } return scanner; #undef SYNCTEX_FILE @@ -2501,6 +2711,7 @@ void synctex_scanner_free(synctex_scanner_t scanner) { free(SYNCTEX_START); free(scanner->output_fmt); free(scanner->output); + free(scanner->synctex); free(scanner->lists_of_friends); free(scanner); } @@ -2593,8 +2804,13 @@ const char * synctex_scanner_get_output_fmt(synctex_scanner_t scanner) { const char * synctex_scanner_get_output(synctex_scanner_t scanner) { return NULL != scanner && scanner->output?scanner->output:""; } -#pragma mark - -#pragma mark Public node attributes +const char * synctex_scanner_get_synctex(synctex_scanner_t scanner) { + return NULL != scanner && scanner->synctex?scanner->synctex:""; +} +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Public node attributes +# endif float synctex_node_h(synctex_node_t node){ if(!node) { return 0; @@ -2620,6 +2836,7 @@ float synctex_node_box_h(synctex_node_t node){ if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) + && (node->class->type != synctex_node_type_hbox_non_void) && (node->class->type != synctex_node_type_void_hbox)) { node = SYNCTEX_PARENT(node); } @@ -2632,6 +2849,7 @@ float synctex_node_box_v(synctex_node_t node){ if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) + && (node->class->type != synctex_node_type_hbox_non_void) && (node->class->type != synctex_node_type_void_hbox)) { node = SYNCTEX_PARENT(node); } @@ -2644,6 +2862,7 @@ float synctex_node_box_width(synctex_node_t node){ if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) + && (node->class->type != synctex_node_type_hbox_non_void) && (node->class->type != synctex_node_type_void_hbox)) { node = SYNCTEX_PARENT(node); } @@ -2656,6 +2875,7 @@ float synctex_node_box_height(synctex_node_t node){ if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) + && (node->class->type != synctex_node_type_hbox_non_void) && (node->class->type != synctex_node_type_void_hbox)) { node = SYNCTEX_PARENT(node); } @@ -2668,13 +2888,16 @@ float synctex_node_box_depth(synctex_node_t node){ if((node->class->type != synctex_node_type_vbox) && (node->class->type != synctex_node_type_void_vbox) && (node->class->type != synctex_node_type_hbox) + && (node->class->type != synctex_node_type_hbox_non_void) && (node->class->type != synctex_node_type_void_hbox)) { node = SYNCTEX_PARENT(node); } return (node->class->type == synctex_node_type_sheet)?0:(float)(SYNCTEX_DEPTH(node)); } -#pragma mark - -#pragma mark Public node visible attributes +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Public node visible attributes +# endif float synctex_node_visible_h(synctex_node_t node){ if(!node) { return 0; @@ -2705,7 +2928,8 @@ result: (SYNCTEX_HORIZ(node)+SYNCTEX_WIDTH(node))*node->class->scanner->unit+node->class->scanner->x_offset: SYNCTEX_HORIZ(node)*node->class->scanner->unit+node->class->scanner->x_offset; } - if(node->class->type != synctex_node_type_hbox) { + if(node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void) { node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { @@ -2728,8 +2952,8 @@ float synctex_node_box_visible_v(synctex_node_t node){ result: return (float)(SYNCTEX_VERT(node))*node->class->scanner->unit+node->class->scanner->y_offset; } - if((node->class->type != synctex_node_type_vbox) - && (node->class->type != synctex_node_type_hbox)) { + if(node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void) { node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { @@ -2752,7 +2976,8 @@ result: -SYNCTEX_WIDTH(node)*node->class->scanner->unit: SYNCTEX_WIDTH(node)*node->class->scanner->unit; } - if(node->class->type != synctex_node_type_hbox) { + if(node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void) { node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { @@ -2775,7 +3000,8 @@ float synctex_node_box_visible_height(synctex_node_t node){ result: return (float)(SYNCTEX_HEIGHT(node))*node->class->scanner->unit; } - if(node->class->type != synctex_node_type_hbox) { + if(node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void) { node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { @@ -2796,7 +3022,8 @@ float synctex_node_box_visible_depth(synctex_node_t node){ result: return (float)(SYNCTEX_DEPTH(node))*node->class->scanner->unit; } - if(node->class->type != synctex_node_type_hbox) { + if(node->class->type != synctex_node_type_hbox + && node->class->type != synctex_node_type_hbox_non_void) { node = SYNCTEX_PARENT(node); } if(node->class->type == synctex_node_type_sheet) { @@ -2807,8 +3034,11 @@ result: } return SYNCTEX_INFO(node)[SYNCTEX_DEPTH_V_IDX].INT*node->class->scanner->unit; } -#pragma mark - -#pragma mark Other public node attributes +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Other public node attributes +# endif + int synctex_node_page(synctex_node_t node){ synctex_node_t parent = NULL; if(!node) { @@ -2831,11 +3061,15 @@ int synctex_node_line(synctex_node_t node) { return node?SYNCTEX_LINE(node):-1; } int synctex_node_column(synctex_node_t node) { -#pragma unused(node) +# ifdef __DARWIN_UNIX03 +# pragma unused(node) +# endif return -1; } -#pragma mark - -#pragma mark Query +# ifdef SYNCTEX_NOTHING +# pragma mark - +# pragma mark Query +# endif synctex_node_t synctex_sheet_content(synctex_scanner_t scanner,int page) { if(scanner) { @@ -2851,7 +3085,9 @@ synctex_node_t synctex_sheet_content(synctex_scanner_t scanner,int page) { } int synctex_display_query(synctex_scanner_t scanner,const char * name,int line,int column) { -#pragma unused(column) +# ifdef __DARWIN_UNIX03 +# pragma unused(column) +# endif int tag = synctex_scanner_get_tag(scanner,name); size_t size = 0; int friend_index = 0; @@ -2886,6 +3122,7 @@ int synctex_display_query(synctex_scanner_t scanner,const char * name,int line,i int _synctex_node_is_box(synctex_node_t node) { switch(synctex_node_type(node)) { case synctex_node_type_hbox: + case synctex_node_type_hbox_non_void: case synctex_node_type_void_hbox: case synctex_node_type_vbox: case synctex_node_type_void_vbox: @@ -2895,7 +3132,9 @@ int _synctex_node_is_box(synctex_node_t node) { } } -int _synctex_point_in_visible_box(float h, float v, synctex_node_t node) { +int _synctex_point_in_box(int h, int v, synctex_node_t node); +int _synctex_point_in_box(int h, int v, synctex_node_t node) { +#if 0 if(_synctex_node_is_box(node)) { v -= synctex_node_box_visible_v(node); if((v<=-synctex_node_box_visible_height(node) @@ -2909,22 +3148,92 @@ int _synctex_point_in_visible_box(float h, float v, synctex_node_t node) { } } } +#endif return 0; } +inline static synctex_node_t _synctex_inner_containing_node(synctex_node_t node,int H,int V); +inline static synctex_node_t _synctex_inner_containing_node(synctex_node_t node,int H,int V) { + if(_synctex_point_in_box(H,V,node) || (node->class->type == synctex_node_type_vbox)) { + synctex_node_t child = SYNCTEX_CHILD(node); + if(NULL != child) { + synctex_node_t result = NULL; + do { + if((result = _synctex_inner_containing_node(child,H,V)) + && (result->class->type != synctex_node_type_vbox)) { + return result; + } + } while((child = SYNCTEX_SIBLING(child))); + } + if(node->class->type != synctex_node_type_vbox) { + return node; + } + } + return NULL; +} +inline static synctex_node_t _synctex_best_child_node(synctex_node_t node,int H,int V, int * distanceRef); +inline static synctex_node_t _synctex_best_child_node(synctex_node_t node,int H,int V, int * distanceRef) { + if(NULL != distanceRef) { + synctex_node_t child = NULL; + if((child = SYNCTEX_CHILD(node))) { + synctex_node_t result = NULL; + do { + synctex_node_t candidate = NULL; + if((candidate = _synctex_best_child_node(child,H,V,distanceRef))) { + result = candidate; + } + } while((child = SYNCTEX_SIBLING(child))); + return result; + } else { + int distance,i; + switch((node->class)->type) { + default: + i = SYNCTEX_HORIZ(node); + if(H<i) { + distance = i-H; + } else { + distance = H-i; + } + i = SYNCTEX_VERT(node); + if(V<i) { + distance += i-V; + } else { + distance += V-i; + } + if(distance<*distanceRef) { + *distanceRef = distance; + return node; + } + break; + case synctex_node_type_hbox: + case synctex_node_type_void_hbox: + case synctex_node_type_hbox_non_void: + case synctex_node_type_vbox: + case synctex_node_type_void_vbox: + break; + } + } + } + return NULL; +} int synctex_edit_query(synctex_scanner_t scanner,int page,float h,float v) { synctex_node_t sheet = NULL; - synctex_node_t * start = NULL; - synctex_node_t * end = NULL; - synctex_node_t * ptr = NULL; - size_t size = 0; synctex_node_t node = NULL; - synctex_node_t next = NULL; - if(NULL == scanner) { + synctex_node_t best_node = NULL; + int H,V; + int minH,maxH,minV,maxV; + int distance; + int best_distance,best_height; + if(NULL == scanner || 0 == scanner->unit) { return 0; } + /* Convert the given point to scanner integer coordinates */ + H = (h-scanner->x_offset)/scanner->unit; + V = (v-scanner->y_offset)/scanner->unit; + /* We will store in the scanner's buffer the result of the query. */ free(SYNCTEX_START); SYNCTEX_START = SYNCTEX_END = SYNCTEX_CUR = NULL; + /* Find the proper sheet */ sheet = scanner->sheet; while(sheet != NULL && SYNCTEX_PAGE(sheet) != page) { sheet = SYNCTEX_SIBLING(sheet); @@ -2933,137 +3242,140 @@ int synctex_edit_query(synctex_scanner_t scanner,int page,float h,float v) { return -1; } /* Now sheet points to the sheet node with proper page number */ - /* Declare memory storage, a buffer to hold found nodes */ - node = SYNCTEX_CHILD(sheet); /* start with the child of the sheet */ -has_node_any_child: - if((next = SYNCTEX_CHILD(node)) != NULL) { - /* node is a non void box */ - if(_synctex_point_in_visible_box(h,v,node)) { - /* we found a non void box containing the point */ - if(ptr == end) { - /* not enough room to store the result, add 16 more node records */ - size += 16; - end = realloc(start,size*sizeof(synctex_node_t)); - if(end == NULL) { - return -1; - } - ptr += end - start; - start = end; - end = start + size; - } - *ptr = node; - /* Does an included box also contain the hit point? - * If this is the case, ptr will be overriden later - * This is why we do not increment ptr yet. - * ptr will be incremented (registered) later if - * no enclosing box contains the hit point */ + /* try to find the box closest to the hit point (H,V) */ + /* We initialize the values with the next box of the sheet. */ + node = SYNCTEX_NEXT_BOX(sheet); + if(NULL == node) { + return 0; + } + /* The distance between a point and a box is special. + * It is not the euclidian distance, nor something similar. + * We have to take into account the particular layout, + * and the box hierarchy. + * Given a box, there are 9 regions delimited by the lines of the edges of the box. + * The origin being at the top left corner of the page, + * we also give names to the vertices of the box. + * + * 1 | 2 | 3 + * ---A---B--- + * 4 | 5 | 6 + * ---C---D--- + * 7 | 8 | 9 + * + * In each region, there is a different formula. + * In the end we have a continuous distance which may not be a mathematical distance but who cares. */ + /* min? and max? are the coordinates of the box. */ + maxH = SYNCTEX_WIDTH_V(node); + if(maxH<0) { + minH = maxH; + maxH = SYNCTEX_HORIZ_V(node); + minH += maxH; + } else { + minH = SYNCTEX_HORIZ_V(node); + maxH += minH; + } + minV = SYNCTEX_VERT_V(node); + maxV = minV + SYNCTEX_DEPTH_V(node); + minV -= SYNCTEX_HEIGHT_V(node); + best_height = maxV - minV; + /* In what region is the point P=(H,V) ? */ + if(V<minV) { + if(H<minH) { + /* This is region 1. The distance to the box is the L1 distance PA. */ + best_distance = minV - V + minH - H;/* Integer overflow? probability epsilon */ + } else if(H<=maxH) { + /* This is region 2. The distance to the box is the geometrical distance to the top edge. */ + best_distance = minV - V; + } else { + /* This is region 3. The distance to the box is the L1 distance PB. */ + best_distance = minV - V + H - maxH; } - node = next; - goto has_node_any_child; - } - /* node has no child */ - if(_synctex_point_in_visible_box(h,v,node)) { - /* we found a void box containing the hit point */ - if(ptr == end) { - /* not enough room to store the result, add 16 more node records */ - size += 16; - end = realloc(start,size*sizeof(synctex_node_t)); - if(end == NULL) { - return -1; - } - ptr += end - start; - start = end; - end = start + size*sizeof(synctex_node_t); - } - *ptr = node; - /* Increment ptr to definitely register the node */ - ++ptr; - /* Ensure that it is the last node */ - *ptr = NULL; - } -next_sibling: - if((next = SYNCTEX_SIBLING(node)) != NULL) { - node = next; - goto has_node_any_child; - } - /* This is the last node at this level - * The next step is the parent's sibling */ - next = SYNCTEX_PARENT(node); - if(ptr && *ptr == next) { - /* No included box does contain the point - * next was already tagged to contain the hit point - * but was not fully registered at that time, now we can increment ptr */ - ++ptr; - *ptr = NULL; - } else if(next == sheet) { - float best; - float candidate; - synctex_node_t * best_node_ref = NULL; -we_are_done: - end = ptr; - ptr = NULL; - /* Up to now, we have found a list of boxes enclosing the hit point. */ - if(end == start) { - /* No match found */ - return 0; + } else if(V<=maxV) { + if(H<minH) { + /* This is region 4. The distance to the box is the geometrical distance to the left edge. */ + best_distance = minH - H; + } else if(H<=maxH) { + /* This is region 4. We are inside the box. */ + best_distance = 0; + } else { + /* This is region 6. The distance to the box is the geometrical distance to the right edge. */ + best_distance = H - maxH; } - /* If there are many different boxes containing the hit point, put the smallest one front. - * This is in general the expected box in LaTeX picture environment. */ - ptr = start; - node = *ptr; - best = synctex_node_box_visible_width(node); - while((node = *(++ptr)) != NULL) { - candidate = synctex_node_box_visible_width(node); - if(candidate<best) { - best = candidate; - best_node_ref = ptr; - } + } else { + if(H<minH) { + /* This is region 7. The distance to the box is the L1 distance PC. */ + best_distance = V - maxV + minH - H; + } else if(H<=maxH) { + /* This is region 8. The distance to the box is the geometrical distance to the top edge. */ + best_distance = V - maxV; + } else { + /* This is region 9. The distance to the box is the L1 distance PD. */ + best_distance = V - maxV + H - maxH; } - if(best_node_ref) { - node = *best_node_ref; - *best_node_ref = *start; - *start = node; + } + best_node = node; + /* Then browse the list of boxes until we find one with a 0 best_distance, or finish the list. */ + while(best_distance>0 && (node = SYNCTEX_NEXT_BOX(node))) { + maxH = SYNCTEX_WIDTH_V(node); + if(maxH<0) { + minH = maxH; + maxH = SYNCTEX_HORIZ_V(node); + minH += maxH; + } else { + minH = SYNCTEX_HORIZ_V(node); + maxH += minH; } - /* We do need to check children to find out the node closest to the hit point. - * Working with boxes is not very accurate because in general boxes are created asynchronously. - * The glue, kern, math are more appropriate for synchronization. */ - if((node = SYNCTEX_CHILD(*start)) != NULL) { - synctex_node_t best_node = NULL; - best = HUGE_VAL; - do { - switch((node->class)->type) { - default: - candidate = fabs(synctex_node_visible_h(node)-h); - if(candidate<best) { - best = candidate; - best_node = node; - } - case synctex_node_type_hbox: - case synctex_node_type_vbox: - break; - } - } while((node = SYNCTEX_SIBLING(node)) != NULL); - if(best_node) { - if((SYNCTEX_START = malloc(sizeof(synctex_node_t))) != NULL) { - * (synctex_node_t *)SYNCTEX_START = best_node; - SYNCTEX_END = SYNCTEX_START + sizeof(synctex_node_t); - SYNCTEX_CUR = NULL; - free(start); - return (SYNCTEX_END-SYNCTEX_START)/sizeof(synctex_node_t); - } + minV = SYNCTEX_VERT_V(node); + maxV = minV + SYNCTEX_DEPTH_V(node); + minV -= SYNCTEX_HEIGHT_V(node); + if(V<minV) { + if(H<minH) { + /* This is region 1. The distance to the box is the L1 distance PA. */ + distance = minV - V + minH - H;/* Integer overflow? probability epsilon */ + } else if(H<=maxH) { + /* This is region 2. The distance to the box is the geometrical distance to the top edge. */ + distance = minV - V; + } else { + /* This is region 3. The distance to the box is the L1 distance PB. */ + distance = minV - V + H - maxH; } + } else if(V<=maxV) { + if(H<minH) { + /* This is region 4. The distance to the box is the geometrical distance to the left edge. */ + distance = minH - H; + } else if(H<=maxH) { + /* This is region 4. We are inside the box. */ + distance = 0; + } else { + /* This is region 6. The distance to the box is the geometrical distance to the right edge. */ + distance = H - maxH; + } + } else { + if(H<minH) { + /* This is region 7. The distance to the box is the L1 distance PC. */ + distance = V - maxV + minH - H; + } else if(H<=maxH) { + /* This is region 8. The distance to the box is the geometrical distance to the top edge. */ + distance = V - maxV; + } else { + /* This is region 9. The distance to the box is the L1 distance PD. */ + distance = V - maxV + H - maxH; + } + } + if(distance<best_distance) { + best_distance = distance; + best_node = node; } - SYNCTEX_START = (unsigned char *)start; - SYNCTEX_END = (unsigned char *)end; + } + best_distance = INT_MAX; + if((best_node = _synctex_best_child_node(best_node,H,V,&best_distance)) + && (SYNCTEX_START = malloc(sizeof(synctex_node_t)))) { + * (synctex_node_t *)SYNCTEX_START = best_node; + SYNCTEX_END = SYNCTEX_START + sizeof(synctex_node_t); SYNCTEX_CUR = NULL; return (SYNCTEX_END-SYNCTEX_START)/sizeof(synctex_node_t); - } else if(NULL == next) { - /* What? a node with no parent? */ - _synctex_error("Internal inconsistency, an unexpected node with no parent"); - goto we_are_done; } - node = next; - goto next_sibling; + return 0; } synctex_node_t synctex_next_result(synctex_scanner_t scanner) { @@ -3084,7 +3396,9 @@ int synctex_bail(void) { return -1; } -#pragma mark ===== updater +# ifdef SYNCTEX_NOTHING +# pragma mark ===== updater +# endif typedef int (*synctex_fprintf_t)(void *, const char * , ...); /* print formatted to either FILE * or gzFile */ @@ -3105,6 +3419,12 @@ struct __synctex_updater_t { # define SYNCTEX_YES (-1) # define SYNCTEX_NO (0) +synctex_updater_t synctex_updater_new_with_output_file(const char * output); +void synctex_updater_append_magnification(synctex_updater_t updater, char * magnification); +void synctex_updater_append_x_offset(synctex_updater_t updater, char * x_offset); +void synctex_updater_append_y_offset(synctex_updater_t updater, char * y_offset); +void synctex_updater_free(synctex_updater_t updater); + synctex_updater_t synctex_updater_new_with_output_file(const char * output){ synctex_updater_t updater = NULL; char * synctex = NULL; diff --git a/Build/source/texk/web2c/synctexdir/synctex_parser.h b/Build/source/texk/web2c/synctexdir/synctex_parser.h index 5c1e7295af4..18a3c8a01a1 100644 --- a/Build/source/texk/web2c/synctexdir/synctex_parser.h +++ b/Build/source/texk/web2c/synctexdir/synctex_parser.h @@ -52,7 +52,7 @@ extern "C" { /* This is the designated method to create a new synctex scanner object. * name can be the tex file that originated the synctex file. * The ".tex" file extension is removed and replaced by the proper extension. - * Then the synctex_scanner_new_with_contents_of_file is called. + * Then the private method synctex_scanner_new_with_contents_of_file is called. * NULL is returned in case of an error or non existent file. */ synctex_scanner_t synctex_scanner_new_with_output_file(const char * output); @@ -83,14 +83,17 @@ float synctex_scanner_magnification(synctex_scanner_t scanner); * Finally, synctex_scanner_input is the first input node of the scanner. * To browse all the input node, use a loop like * - * while(input_node=synctex_node_sibling(input_node)) { - * blah + * if(input_node = synctex_scanner_input(scanner)){ + * do { + * blah + * } while(input_node=synctex_node_sibling(input_node)); * } */ const char * synctex_scanner_get_name(synctex_scanner_t scanner,int tag); int synctex_scanner_get_tag(synctex_scanner_t scanner,const char * name); synctex_node_t synctex_scanner_input(synctex_scanner_t scanner); const char * synctex_scanner_get_output(synctex_scanner_t scanner); +const char * synctex_scanner_get_synctex(synctex_scanner_t scanner); /* Browsing the nodes * parent, child and sibling are standard names for tree nodes. @@ -128,11 +131,12 @@ typedef enum { synctex_node_type_void_vbox, synctex_node_type_hbox, synctex_node_type_void_hbox, + synctex_node_type_hbox_non_void, synctex_node_type_kern, synctex_node_type_glue, synctex_node_type_math, synctex_node_type_input, - synctex_node_type_last + synctex_node_number_of_types } synctex_node_type_t; /* synctex_node_type gives the type of a given node, @@ -142,16 +146,19 @@ const char * synctex_node_isa(synctex_node_t node); /* This is primarily used for debugging purpose */ void synctex_node_log(synctex_node_t node); +void synctex_node_display(synctex_node_t node); /* Given a node, access to its tag, line and column. + * The line and column numbers are 1 based. * The latter is not yet fully supported. + * When the tag is known, the scanner of the node will give the name. */ int synctex_node_tag(synctex_node_t node); int synctex_node_line(synctex_node_t node); int synctex_node_column(synctex_node_t node); /* This is the page where the node appears. - * This is a 1 based indes as given by TeX. + * This is a 1 based index as given by TeX. */ int synctex_node_page(synctex_node_t node); diff --git a/Build/source/texk/web2c/synctexdir/synctex_parser_local.h b/Build/source/texk/web2c/synctexdir/synctex_parser_local.h new file mode 100644 index 00000000000..f1018cfa24b --- /dev/null +++ b/Build/source/texk/web2c/synctexdir/synctex_parser_local.h @@ -0,0 +1,37 @@ +/* +Copyright (c) 2008 jerome DOT laurens AT u-bourgogne DOT fr + +This file is part of the SyncTeX package. + +License: +-------- +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE + +Except as contained in this notice, the name of the copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in this Software without prior written +authorization from the copyright holder. + +*/ + +/* This local header file is for TEXLIVE, use your own header to fit your system */ +# include "web2c/c-auto.h" /* for inline && HAVE_xxx */ |