From 30fb3a721dfb11730db220bac9be11a38aac6f8b Mon Sep 17 00:00:00 2001 From: Shaun McCance Date: Thu, 9 Apr 2009 04:10:29 +0000 Subject: - Removing old files * src/info2html/Makefile.am: * src/info2html/html.c: * src/info2html/html.h: * src/info2html/main.c: * src/info2html/utils.c: * src/info2html/utils.h: * src/man2html/Makefile.am: * src/man2html/README: * src/test-pager.c: * src/yelp-db-pager.c: * src/yelp-db-pager.h: * src/yelp-db-print-pager.c: * src/yelp-db-print-pager.h: * src/yelp-info-pager.c: * src/yelp-info-pager.h: * src/yelp-man-pager.c: * src/yelp-man-pager.h: * src/yelp-pager.c: * src/yelp-pager.h: * src/yelp-search-pager.c: * src/yelp-search-pager.h: * src/yelp-toc-pager.c: * src/yelp-toc-pager.h: * src/yelp-xslt-pager.c: * src/yelp-xslt-pager.h: - Removing old files svn path=/trunk/; revision=3245 --- ChangeLog | 29 + src/info2html/Makefile.am | 9 - src/info2html/html.c | 925 ----------------- src/info2html/html.h | 27 - src/info2html/main.c | 325 ------ src/info2html/utils.c | 398 -------- src/info2html/utils.h | 21 - src/man2html/Makefile.am | 16 - src/man2html/README | 284 ------ src/test-pager.c | 149 --- src/yelp-db-pager.c | 605 ----------- src/yelp-db-pager.h | 55 - src/yelp-db-print-pager.c | 287 ------ src/yelp-db-print-pager.h | 55 - src/yelp-info-pager.c | 304 ------ src/yelp-info-pager.h | 55 - src/yelp-man-pager.c | 476 --------- src/yelp-man-pager.h | 55 - src/yelp-pager.c | 449 -------- src/yelp-pager.h | 121 --- src/yelp-search-pager.c | 2044 ------------------------------------- src/yelp-search-pager.h | 56 - src/yelp-toc-pager.c | 2473 --------------------------------------------- src/yelp-toc-pager.h | 59 -- src/yelp-xslt-pager.c | 575 ----------- src/yelp-xslt-pager.h | 59 -- 26 files changed, 29 insertions(+), 9882 deletions(-) delete mode 100644 src/info2html/Makefile.am delete mode 100644 src/info2html/html.c delete mode 100644 src/info2html/html.h delete mode 100644 src/info2html/main.c delete mode 100644 src/info2html/utils.c delete mode 100644 src/info2html/utils.h delete mode 100644 src/man2html/Makefile.am delete mode 100644 src/man2html/README delete mode 100644 src/test-pager.c delete mode 100644 src/yelp-db-pager.c delete mode 100644 src/yelp-db-pager.h delete mode 100644 src/yelp-db-print-pager.c delete mode 100644 src/yelp-db-print-pager.h delete mode 100644 src/yelp-info-pager.c delete mode 100644 src/yelp-info-pager.h delete mode 100644 src/yelp-man-pager.c delete mode 100644 src/yelp-man-pager.h delete mode 100644 src/yelp-pager.c delete mode 100644 src/yelp-pager.h delete mode 100644 src/yelp-search-pager.c delete mode 100644 src/yelp-search-pager.h delete mode 100644 src/yelp-toc-pager.c delete mode 100644 src/yelp-toc-pager.h delete mode 100644 src/yelp-xslt-pager.c delete mode 100644 src/yelp-xslt-pager.h diff --git a/ChangeLog b/ChangeLog index a212a22a..e928cd1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2009-04-08 Shaun McCance + + * src/info2html/Makefile.am: + * src/info2html/html.c: + * src/info2html/html.h: + * src/info2html/main.c: + * src/info2html/utils.c: + * src/info2html/utils.h: + * src/man2html/Makefile.am: + * src/man2html/README: + * src/test-pager.c: + * src/yelp-db-pager.c: + * src/yelp-db-pager.h: + * src/yelp-db-print-pager.c: + * src/yelp-db-print-pager.h: + * src/yelp-info-pager.c: + * src/yelp-info-pager.h: + * src/yelp-man-pager.c: + * src/yelp-man-pager.h: + * src/yelp-pager.c: + * src/yelp-pager.h: + * src/yelp-search-pager.c: + * src/yelp-search-pager.h: + * src/yelp-toc-pager.c: + * src/yelp-toc-pager.h: + * src/yelp-xslt-pager.c: + * src/yelp-xslt-pager.h: + - Removing old files + 2009-04-08 Pedro Fragoso * src/gtkentryaction.c: diff --git a/src/info2html/Makefile.am b/src/info2html/Makefile.am deleted file mode 100644 index 090bd889..00000000 --- a/src/info2html/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -INCLUDES = @YELP_CFLAGS@ - -libexec_PROGRAMS = yelp-info2html - -yelp_info2html_SOURCES = main.c parse.c utils.c html.c data.h html.h parse.h utils.h version.h - -yelp_info2html_LDADD = @YELP_LIBS@ $(Z_LIBS) $(BZ_LIBS) diff --git a/src/info2html/html.c b/src/info2html/html.c deleted file mode 100644 index b076010b..00000000 --- a/src/info2html/html.c +++ /dev/null @@ -1,925 +0,0 @@ -/* handles all html operations */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "data.h" -#include "html.h" -#include "parse.h" -#include "utils.h" - -#define USE_FILE_URLS - -int inTable=0; - -char *BaseFilename=NULL; -char *OverrideBaseFilename=NULL; - -int galeon_mode=0; - -/* prototypes */ -char *form_info_tag_href( char *nodefile, char *nodename ); -int make_Top_link( char *destdir, char *destfile ); -int make_info_dir( char *destdir ); -void write_node_link_html( FILE *f, char *nodefile, char *refname, char *ref ); -void start_html_content( FILE *f ); -void make_nav_links( FILE *f, NODE *node ); -void html_error( char *s, char *p, char *q ); - - -/* print out the url for a info file */ -char *form_info_tag_href( char *nodefile, char *nodename ) -{ - char tmp[1024]; - char *escaped_nodename; - char *filename; - - escaped_nodename = escape_html_chars( nodename ); - if (!strcmp(BaseFilename, nodefile)) - { - if (OverrideBaseFilename) - filename = OverrideBaseFilename; - else - filename = BaseFilename; - } - else - filename = nodefile; - - if (galeon_mode) - g_snprintf (tmp, sizeof (tmp), "HREF=\"info:%s?%s\"", filename, escaped_nodename); - /*else - g_snprintf (tmp, sizeof (tmp), "HREF=\"#%s\"", escaped_nodename); */ - /* make the default mode output links of the form "info:filename?section" */ - else - g_snprintf (tmp, sizeof (tmp), "HREF=\"info:%s?%s\"", filename, escaped_nodename); - if (escaped_nodename) - g_free(escaped_nodename); - return g_strdup(tmp); -} - - -/* returns zero if success making link from destfile -> index.html in */ -/* specified directory. If it already exists, just returns with success */ -int make_Top_link( char *destdir, char *destfile ) -{ - struct stat filestat; - char *indexlink; - - indexlink = (char *) g_malloc( strlen(destdir) + 20); - strcpy(indexlink, destdir); - strcat(indexlink, "/index.html"); - - if (lstat(indexlink, &filestat)) - { - if (errno == ENOENT) - { - if (symlink(destfile, indexlink)) - { - fprintf(stderr,"Error creating link to %s\n",indexlink); - perror("Error was"); - exit(1); - } - } - else - { - fprintf(stderr,"Error stat'ing file %s\n",indexlink); - perror("Error was"); - exit(1); - } - } - else if (!S_ISLNK(filestat.st_mode)) - { - fprintf(stderr, "file %s exists and isnt a link\n",indexlink); - fprintf(stderr, "FIX ME!!!\n"); - g_free(indexlink); - return -1; - } - return 0; -} - -/* return non-zero if error with making directory */ -int make_info_dir( char *destdir ) -{ - struct stat filestat; - - if (stat(destdir, &filestat)) - { - if (errno == ENOENT) - { - if (mkdir(destdir, 01777)) - { - fprintf(stderr,"Error creating directory %s\n",destdir); - perror("Error was"); - exit(1); - } - } - else - { - fprintf(stderr,"Error stat'ing directory %s\n",destdir); - perror("Error was"); - exit(1); - } - } - else if (!S_ISDIR(filestat.st_mode)) - { - fprintf(stderr, "Info dir %s exists and isnt a directory!\n",destdir); - fprintf(stderr, "FIX ME!!!\n"); - return -1; - } - return 0; -} - -/* write a link to another document */ -void write_node_link_html( FILE *f, char *nodefile, char *refname, char *ref ) -{ - char *converted_nodename; - char *href; - - if (ref) { - if (g_strcasecmp(ref, "(dir)")) { - converted_nodename = g_strdup( ref ); - map_spaces_to_underscores( converted_nodename ); - href = form_info_tag_href(nodefile, converted_nodename); - fprintf(f,"%s%s\n", href, refname, ref); - g_free(href); - g_free(converted_nodename); - } else { - href = form_info_tag_href("dir", "Top"); - fprintf(f,"%s(dir)\n",href, refname); - g_free(href); - - } - } -} - -/* write out top of a new html file */ -void write_html_header( FILE *f, char *filename, char *nodename) -{ - fprintf(f,"\n"); - fprintf(f,"\n"); - fprintf(f,"\n"); - fprintf(f,"Info Node: (%s)%s\n",filename,nodename); - fprintf(f,"\n"); - fprintf(f,"\n"); - fprintf(f,"\n",work_filename, work_node); -} - -/* start of everything after html header */ -void start_html_content( FILE *f ) -{ - fprintf(f,"\n"); -} - -/* we want to put links to next, prev, and up nodes */ -void make_nav_links( FILE *f, NODE *node ) -{ -#if 0 - fprintf(f,"
\n");
-  write_node_link_html( f, node->filename, "Next:", node->next );
-  write_node_link_html( f, node->filename, "Prev:", node->prev );
-  write_node_link_html( f, node->filename, "Up:", node->up );
-  fprintf(f,"
\n"); -#else - fprintf(f,"\n"); - fprintf(f,"\n"); - fprintf(f,"\t\n"); - fprintf(f,"\t\n"); - fprintf(f,"\t\n"); - fprintf(f,"\n
\n\t"); - write_node_link_html( f, node->filename, "Next:", node->next ); - fprintf(f,"\t\n\t"); - write_node_link_html( f, node->filename, "Prev:", node->prev ); - fprintf(f,"\t\n\t"); - write_node_link_html( f, node->filename, "Up:", node->up ); - fprintf(f,"\t
\n"); -#endif - -} - -/* s is error message */ -/* p is start of offending line */ -/* q is end of offending line */ -void html_error( char *s, char *p, char *q ) -{ - fprintf(stderr, "%s:%s\n",work_filename, work_node); - fprintf(stderr, "\t%s\n",s); - fprintf(stderr, "\tOffending line is:\n\t|"); - fwrite(p, 1, q-p, stderr); - fprintf(stderr, "|\n"); -} - -/******************************************************************** - * here is what we expect in contents of a node: - * - * headers: These are identified as a line of text - * followed by a row of '---' or '###' normally. - * These get mapped to

for now. - * - * body text: Format this between
 
statements. - * Catch any *Note and *note and make into - * links to other documents. Also try to catch - * URLs as well. - * - * menus: Starts with a '* Menu' line. Goes until the - * end of the node, or until the next line which - * starts with something other than a '* ' or '\n'. - * - * end of node: The INFO_FF and INFO_COOKIE mark the end of a node. - * Hitting EOF also marks the end of a node. - ********************************************************************/ - -void dump_html_for_node( NODE *node ) -{ -/* char *destdir; */ -/* char *destfile; */ - char *escaped_nodename; -/* char *converted_nodename; */ - char *contents_start, *contents_end; - char *header_name; - char *p, *q, *r, *skippnt; - char *end_menu_entry; - - - int menu_open, body_open; - - int seen_menu; - - int prev_was_blank, next_is_blank, current_is_blank; - - int seen_first_header; - - int last_output_was_header; - - int nskip; - - int we_are_in_dir_node; - - int i; - - FILE *f; - -/* msf - used to write each node to a separate file - now we're going */ -/* to just output HTML to stdout. */ -/* Each node will just be concantentated to previous */ -#if 0 - destdir = (char *) g_malloc ( strlen(node->filename) + - strlen(HTML_ROOT) + - strlen(node->filename) + 2); - strcpy(destdir, HTML_ROOT); - strcat(destdir, "/"); - strcat(destdir, node->filename); - strcat(destdir, "/"); - - /* check that the dir for info file exists */ - make_info_dir( destdir ); - - /* ok, we made the dir, lets go */ - destfile = (char *) g_malloc( strlen(destdir) + strlen(node->nodename) + 10); - strcpy(destfile, destdir); - converted_nodename = g_strdup( node->nodename ); - map_spaces_to_underscores( converted_nodename ); - strcat(destfile, converted_nodename); - strcat(destfile, ".html"); - g_free(converted_nodename); - - if (!(f=fopen(destfile, "w"))) - { - fprintf(f,"Couldnt create node html file %s\n",destfile); - perror("Error was"); - exit(1); - } -#endif - - /* hack - just dump to stdout for now */ - f = stdout; - - /* see if this is THE dir node */ - we_are_in_dir_node = !strcmp("Top", node->nodename) && !strcmp("dir", node->filename); - -#if 0 - /* try and make a link between 'index.html' and 'Top.html' */ - if (!strcmp("Top", node->nodename)) - make_Top_link( destdir, destfile ); -#endif - -#if 0 - /* do the html header first */ - write_html_header( f, node->filename, node->nodename ); -#endif - -#if 0 - /* now for the body */ - start_html_content( f ); -#endif - - /* make an anchor */ - escaped_nodename = escape_html_chars( node->nodename ); - map_spaces_to_underscores( escaped_nodename ); - fprintf(f, " \n",escaped_nodename); - g_free(escaped_nodename); - - /* links to other immediate nodes */ - make_nav_links( f, node ); - - /* setup pointers to textual content of current node */ - contents_start = node->contents; - contents_end = node->contents+node->contlen; - - /* scan through all of contents and generate html on the fly */ - /* p points at start of current line */ - /* q points at the end of current line (at '\n' actually) */ - /* r points at the start of next line */ - /* we do this to catch headers */ - /* scan for a header at the top of the contents */ - /* if we see a '\n***'3 '*' in a row i */ - /* then take previous line as a header */ - header_name = NULL; - p = contents_start = node->contents; - q = memchr(p, '\n', contents_end - p); - r=q+1; - - /* we have several states we could be in */ - next_is_blank = 0; - prev_was_blank = 0; - current_is_blank = 0; - seen_first_header = 0; - - seen_menu = 0; - menu_open = 0; - body_open = 0; - - last_output_was_header = 0; - for (; q && r <= contents_end; ) - { - nskip = 1; - skippnt = NULL; - next_is_blank = (*r == '\n'); - current_is_blank = (*p == '\n'); - - /* test some easy things first */ - if (!strncmp(p, MENU_START, strlen(MENU_START))) - { - if (we_are_in_dir_node && !seen_menu) - { - if (body_open) - { - close_body_text_html(f); - body_open = 0; - } - - fprintf(f,"

Main Info File Directory

\n"); - - open_body_text_html(f); - body_open = 1; - - fprintf(f,"This is the main directory of available info files.\n"); - } - - if (body_open) - { - close_body_text_html(f); - body_open = 0; - } - else if (seen_menu) - html_error("Warning:saw new menu start and already in menu!", p, q); - - if (menu_open) - close_menu_html( f ); - - if (last_output_was_header) - open_menu_html( f, "" ); - else - open_menu_html( f, "Contents" ); - - seen_menu = 1; - menu_open = 1; - last_output_was_header = 0; - } - else if (we_are_in_dir_node && !seen_menu) - { - /* do nothing */ - } - else if (seen_menu) - { - /* if current line is blank ignore it */ - if (current_is_blank) - { - /* do nothing */ - } - /* first see if its a menu line */ - else if (!strncmp(p, MENU_ENTRY, strlen(MENU_ENTRY))) - { - if (!seen_menu) - html_error("Have seen menu start and hit a menu line!", p, q); - else - { - if (body_open) - { - if (menu_open) - html_error("Hit a menu line, and body and menu are opened!", p, q); - close_body_text_html( f ); - body_open = 0; - open_menu_html( f, "" ); - menu_open = 1; - } - if (!menu_open) - { - open_menu_html( f, "" ); - menu_open = 1; - } - write_menu_entry_html( f, p, node->filename, &end_menu_entry ); - if (end_menu_entry != NULL) - skippnt = end_menu_entry; - last_output_was_header = 0; - } - } - /* maybe its a header line */ - /* man this is getting ridiculous, its like teaching a child */ - /* to read! */ - else if (is_a_hdr_line(r) || - (*p != '*' && *r == '*' && *(r+1) == ' ') || - (*p != '*' && seen_menu && (*p != ' ' && *(p+1) != ' ') && - !current_is_blank && prev_was_blank && next_is_blank)) - { - header_name = (char *) g_malloc( q-p+2 ); - memcpy(header_name, p, q-p); - *(header_name + (q - p) ) = '\000'; - - /* if we were writing a particular component, close it */ - if (menu_open) - { - close_menu_html( f ); - menu_open = 0; - } - - if (body_open) - { - close_body_text_html( f ); - body_open = 0; - } - - if (seen_first_header) - write_header_html( f, header_name, HEADER_SIZE_2 ); - else - { - seen_first_header = 1; - write_header_html( f, header_name, HEADER_SIZE_1 ); - } - - g_free(header_name); - - /* jump ahead another line */ - if (!(*r == '*' && *(r+1) == ' ') && !next_is_blank) - nskip++; - - last_output_was_header = 1; - } - /* well, has to be body text then */ - else - { - if (menu_open) - { - close_menu_html( f ); - menu_open = 0; - - write_html_horiz_rule ( f ); - } - - if (!body_open) - { - open_body_text_html( f ); - body_open = 1; - } - - if (*p != '\n' && !last_output_was_header) - { - skippnt=write_body_text_html( f, p, q, node->filename ); - last_output_was_header = 0; - } - } - } - /* otherwise, no menu seen so things are easier */ - else - { - if (is_a_hdr_line(r)) - { - header_name = (char *) g_malloc( q-p+2 ); - memcpy(header_name, p, q-p); - *(header_name + (q - p) ) = '\000'; - - /* if we were writing a particular component, close it */ - if (body_open) - { - close_body_text_html( f ); - body_open = 0; - } - - if (seen_first_header) - write_header_html( f, header_name, HEADER_SIZE_2 ); - else - { - seen_first_header = 1; - write_header_html( f, header_name, HEADER_SIZE_1 ); - } - - g_free(header_name); - - /* jump ahead another line */ - if (!(*r == '*' && *(r+1) == ' ') && !next_is_blank) - nskip++; - - last_output_was_header = 1; - } - /* well, has to be body text then */ - else - { - if (!body_open) - { - open_body_text_html( f ); - body_open = 1; - } - - if (!(*p == '\n' && last_output_was_header)) - { - skippnt=write_body_text_html( f, p, q, node->filename ); - last_output_was_header = 0; - } - } - } - - /* end of cases, move to next line in contents */ - prev_was_blank = (*p == '\n'); - if (skippnt) - { - p = skippnt; - q = memchr(p, '\n', contents_end - p); - r = q+1; - skippnt = NULL; - } - else - for (i=0; i< nskip; i++) - { - p = r; - q = memchr(p, '\n', contents_end - p); - r = q+1; - } - } - - /* thats all folks */ - if (menu_open) - close_menu_html( f ); - else if (body_open) - close_body_text_html( f ); - - /* put nav links at the bottom */ - make_nav_links(f, node); -#if 0 - fprintf(f,"\n\n"); -#endif - - /* clean up */ -#if 0 - g_free(destdir); - g_free(destfile); -#endif -} - - -void write_header_html( FILE *f, char *p, char *hdr ) -{ - fprintf(f,"<%s> %s \n",hdr,p,hdr); -} - - -void open_body_text_html( FILE *f ) -{ - fprintf(f, "
\n");
-}
-
-void close_body_text_html( FILE *f )
-{
-  fprintf(f, "
\n"); -} - -/* we have to handle '*note' and '*Note' links in body text */ -/* p is ptr to start of current line */ -/* q is ptr to '\n' at end of current line */ -char *write_body_text_html( FILE *f, char *p, char *q, char *nodefile ) -{ - int curlen; - int ref_exists; - char *tmp; - char *ptr; - char *match1; - char *note_ptr; - char *converted_nodename; - char *escaped_refname; - char *escaped_refnode; - char *escaped_seg; - char *refname, *reffile, *refnode, *end; - char *href; - - curlen = q - p; - tmp = (char *) g_malloc( curlen + 1 ); - memcpy( tmp, p, curlen ); - *(tmp+curlen) = '\000'; - - /* see if there is a reference in current line */ - /* and make sure this isnt a '*Note*' instead ! */ - ref_exists = 0; - if ((note_ptr=strstr(tmp, "*Note")) || (note_ptr=strstr(tmp, "*note"))) - if (*(note_ptr+6) != '*') - ref_exists = 1; - - if (ref_exists) - { - /* find the start of the link */ - note_ptr = (note_ptr - tmp) + p; - match1 = note_ptr + 4; - - /* not needed any more */ - g_free(tmp); - - for (; 1; ) - if (*(match1+1) == ' ' || *(match1+1) == '\n') - match1++; - else - break; - - /* find end of the link */ - if (parse_note_ref( match1, &refname, &reffile, &refnode, &end, 1)) - { - html_error( "Corrupt *Note link found!", p, q ); - return NULL; - } - - /* now we assume that parse_note_ref left control chars in ref* */ - /* if both null, we had a '::' and have to set both */ - if (reffile == NULL && refnode == NULL) - { - reffile = g_strdup(nodefile); - refnode = g_strdup(refname); - } - /* otherwise we had (file)., and we set node to 'Top' */ - else if (refnode == NULL) - refnode = g_strdup("Top"); - /* otherwise we had :nodename., and we set node to 'Top' */ - else if (reffile == NULL) - reffile = g_strdup(nodefile); - -/* Here we need to escape everything up to Note. - * One caveat: The "*Note*" itself isn't escaped. Currently we know this is - * okay ("*Note" has no characters needing escapes.) but.... - */ - curlen = note_ptr - p; - tmp = (char *) g_malloc (curlen + 1); - memcpy (tmp, p, curlen); - *(tmp + curlen) = '\000'; - escaped_seg = escape_html_chars (tmp); - g_free (tmp); - - /* write out stuff up to Note */ - fprintf(f, "%s", escaped_seg); - fprintf(f, ""); - fwrite(note_ptr, 1, match1 - note_ptr, f); - fprintf(f, " "); - - /* we need a nice nodename -> filename translation */ - /* so we convert newlines to spaces */ - converted_nodename = g_strdup( refnode ); - convert_newlines_to_spaces( converted_nodename ); - - /* we don't want two spaces in a row */ - strip_dupspaces( converted_nodename ); - map_spaces_to_underscores( converted_nodename ); - - /* escape HTML chars */ - escaped_refname = escape_html_chars( refname ); - escaped_refnode = escape_html_chars( refnode ); - - /* now output the link to html doc */ -#if 0 - fprintf(f,"", reffile, converted_nodename); -#endif - href = form_info_tag_href(reffile, converted_nodename); - fprintf(f,"", href); - for (ptr=escaped_refname; *ptr; ptr++) - if (*ptr == '\n') - { - fprintf(f,"\n"); - fprintf(f,"", href); - } - else - fprintf(f,"%c", *ptr); - - if (strcmp(refname, refnode)) - { - fprintf(f,": "); - for (ptr=escaped_refnode; *ptr; ptr++) - if (*ptr == '\n') - { - fprintf(f,"\n"); - fprintf(f,"", href); - } - else - fprintf(f,"%c", *ptr); - - fprintf(f,""); - if (end > q && !(strchr(refnode, '\n'))) - fprintf(f,"\n"); - } - else - fprintf(f,""); - - if (href) - g_free(href); - if (escaped_refnode) - g_free(escaped_refnode); - if (escaped_refname) - g_free(escaped_refname); - if (converted_nodename) - g_free(converted_nodename); - - g_free(escaped_seg); - g_free(refname); - g_free(reffile); - g_free(refnode); - - /* write out stuff at end */ - if (end < q) - { - -/* Escape up to the end of line. */ - curlen = q - (end+1); - tmp = (char *) g_malloc (curlen + 1); - memcpy (tmp, end+1, curlen); - *(tmp+curlen) = '\000'; - escaped_seg = escape_html_chars (tmp); - g_free (tmp); - - fprintf (f, "%s", escaped_seg); - fprintf (f, "\n"); - g_free (escaped_seg); - return NULL; - } - else - return end+1; - } - else - { - -/* Escape the whole thing. */ - escaped_seg = escape_html_chars (tmp); - fprintf (f, "%s", escaped_seg); - fprintf (f, "\n"); - /* not needed any more */ - g_free(tmp); - g_free (escaped_seg); - return NULL; - } -} - -void open_menu_html( FILE *f, char *p ) -{ - if (*p != '\000') - fprintf(f, "

%s

\n",p); - /* fprintf(f, "
    \n"); */ -#if 0 - fprintf(f, "
    \n"); -#else - if (inTable) - fprintf(stderr, "In a table and starting new one!\n"); - inTable = 1; - fprintf(f, "\n"); -#endif -} - -void close_menu_html( FILE *f ) -{ - /* fprintf(f, "\n"); */ -#if 0 - fprintf(f, "\n"); -#else - if (!inTable) - fprintf(stderr, "Not in a table and closing one!\n"); - inTable = 0; - fprintf(f, "
     
    \n"); -#endif -} - -/* writes menu entry contained in string p */ -/* nodename and nodefile apply to the node which menu entry is in */ -void write_menu_entry_html( FILE *f, char *p, char *nodefile, char **menu_end ) -{ - char *refname; - char *reffile; - char *refnode; - char *end; - char *realend; - char *converted_nodename; - char *escaped_refnode; - char *escaped_refname; - char *href; - - int i, done; - - /* skip over the '* ' at the start of the line */ - if (parse_menu_line( p+2, &refname, &reffile, &refnode, &end, 0 )) - { - html_error("Error parsing menu", p, memchr(p, '\n', 80)); - return; - } - - /* if both null, we had a '::' and have to set both */ - if (reffile == NULL && refnode == NULL) - { - reffile = g_strdup(nodefile); - refnode = g_strdup(refname); - } - /* otherwise we had (file)., and we set node to 'Top' */ - else if (refnode == NULL) - refnode = g_strdup("Top"); - else if (reffile == NULL) - reffile = g_strdup(nodefile); - - /* now find the end of the right hand text for this menu line */ - /* it can continue for several lines */ - done = 0; - for (realend = end+1; !done; realend++) - { - if (*realend == '\n') - { - if (*(realend+1) == '\n') - { - done = 1; - continue; - } - - for (i=1; i<4; i++) - if (!isspace((guchar)*(realend+i)) && *(realend+i) != '\n') - { - done = 1; - break; - } - } - } - *menu_end = realend; - - - converted_nodename = g_strdup( refnode ); - map_spaces_to_underscores( converted_nodename ); - - escaped_refnode = escape_html_chars( refnode ); - escaped_refname = escape_html_chars( refname ); - -#if 0 - fprintf(f,"
    %s\n", - reffile, converted_nodename, escaped_refname); -#endif - - href = form_info_tag_href( reffile, converted_nodename ); -#if 0 - fprintf(f,"
    %s\n", href, escaped_refname ); - fprintf(f,"
    "); - if (*end == '.' && *(end+1) == '\n') - fprintf(f,"%s.\n",escaped_refnode); - else - fwrite(end+1, 1, *menu_end - end - 1, f); -#else - fprintf(f,"\n\t\n\t\t%s\n\t\n" - "\t\n\t\t", - href, escaped_refname ); - if (*end == '.' && *(end+1) == '\n') - fprintf(f,"%s.\n",escaped_refnode); - else - fwrite(end+1, 1, *menu_end - end - 1, f); - fprintf(f,"\n\t\n\n"); -#endif - - if (href) - g_free(href); - if (escaped_refname) - g_free(escaped_refname); - if (escaped_refnode) - g_free(escaped_refnode); - if (converted_nodename) - g_free(converted_nodename); - g_free(refname); - g_free(reffile); - g_free(refnode); -} - -void write_html_horiz_rule( FILE *f ) -{ - fprintf(f, "
    \n"); -} diff --git a/src/info2html/html.h b/src/info2html/html.h deleted file mode 100644 index 0c73bad4..00000000 --- a/src/info2html/html.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HTML_H -#define HTML_H - -#define HTML_ROOT "./htmltest" - -#define HEADER_SIZE_1 "H1" -#define HEADER_SIZE_2 "H2" - -extern char *BaseFilename; -extern char *OverrideBaseFilename; - -extern int galeon_mode; - -void dump_html_for_node( NODE *node ); - -void open_body_text_html( FILE *f ); -void close_body_text_html( FILE *f ); -char *write_body_text_html( FILE *f, char *p, char *q, char *nodefile ); - -void open_menu_html( FILE *f, char *p ); -void close_menu_html( FILE *f ); -void write_menu_entry_html( FILE *f, char *p, char *nodefile,char **menu_end ); - -void write_header_html( FILE *f, char *p, char *hdr ); - -void write_html_horiz_rule( FILE *f ); -#endif diff --git a/src/info2html/main.c b/src/info2html/main.c deleted file mode 100644 index 30d4ceb0..00000000 --- a/src/info2html/main.c +++ /dev/null @@ -1,325 +0,0 @@ -/* little test main() to see how we're doing */ - -/* modifications to support : - 1. command-line of the form filename?section for yelp support - 2. outputs only "Top" section of document if no node / section is specified - 3. links modified to be of the form "info://filename?section" - - - Patanjali -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "data.h" -#include "html.h" -#include "parse.h" -#include "utils.h" -#include "version.h" - -/* be quiet or not? */ -static int be_quiet=1; - -char top_string [] = "Top"; - -/* line_number we're on */ -static int work_line_number; - -static char *requested_nodename=NULL; -static char *requested_section=NULL; -static struct poptOption options[] = { - {NULL, 'a', POPT_ARG_STRING, &requested_nodename}, - {NULL, 'b', POPT_ARG_STRING, &OverrideBaseFilename}, - {NULL, 'g', POPT_ARG_NONE, &galeon_mode}, - {NULL} -}; - -static int -file_exists(const char *fn) -{ - struct stat sbuf; - - if (g_file_test(fn, G_FILE_TEST_IS_DIR)) { - return FALSE; - } - - if (g_file_test(fn, G_FILE_TEST_IS_DIR)) { - return FALSE; - } - - return (stat(fn, &sbuf) == 0); -} - -int -main(int argc, const char **argv) -{ - ReadBuf *f=NULL; - char line[250]; - poptContext ctx; - int result; - int foundit=0; - int i, n; - char *cptr; - gboolean no_info = FALSE; - - char convanc[1024]; - NODE *node; - - const char **args; - char *fixup_args[512]; - int curarg; - - if (!be_quiet) - printf("info2html Version %s\n",INFO2HTML_VERSION); - - ctx = poptGetContext("gnome-info2html2", argc, argv, options, 0); - - while(poptGetNextOpt(ctx) >= 0) - /**/ ; - - args = poptGetArgs(ctx); - curarg = 0; - if(!args) - return 1; - - for(n = 0; args[n]; n++) /* */; - - /* hack to convert the first argument to the form : - filename?section instead of passing it in with the - -a option */ - for (cptr = (char *)args [0]; *cptr != '\0'; cptr++) { - if (*cptr == '?') { - *cptr++ = '\0'; - requested_section = g_strdup (cptr); - break; - } - - } - /* requested_section now contains the requested section, if at all ... */ - if(n == 1 && !file_exists(args[0])) { - /* As strtok destroys the string it parses and g_getenv returns a pointer to - the actually env var, we have to duplicate the var before parsing it. */ - char *ctmp, *infopath = g_strdup(g_getenv("INFOPATH")); - char *dirs[64], *ext = NULL; - int ndirs; - char *buf; - - /* First, find the directory that the info file is in. */ - dirs[0] = "/usr/info"; - dirs[1] = "/usr/share/info"; - /* We now have at least one directory to look in. This is - * necessary because we may not have an 'INFOPATH' set */ - ndirs = 2; - if(infopath) { - for (ndirs = 2, ctmp = strtok(infopath, ":"); ndirs < 64 && ctmp; ndirs++, ctmp = strtok(NULL, ":")) { - dirs[ndirs] = strdup(ctmp); - } - } - - for(i = 0; i < ndirs; i++) { - ext = ""; - buf = g_strdup_printf ("%s/%s.info", dirs[i], args[0]); - if(file_exists(buf)) - break; - g_free (buf); - buf = g_strdup_printf ("%s/%s", dirs[i], args[0]); - if(file_exists(buf)) { - no_info = TRUE; - break; - } - g_free (buf); - - ext = ".gz"; - buf = g_strdup_printf ("%s/%s.info.gz", dirs[i], args[0]); - if(file_exists(buf)) - break; - g_free (buf); - buf = g_strdup_printf ("%s/%s.gz", dirs[i], args[0]); - if(file_exists(buf)) { - no_info = TRUE; - break; - } - g_free (buf); -#ifdef HAVE_LIBBZ2 - ext = ".bz2"; - buf = g_strdup_printf ("%s/%s.info.bz2", dirs[i], args[0]); - if(file_exists(buf)) - break; - - g_free (buf); - buf = g_strdup_printf ("%s/%s.bz2", dirs[i], args[0]); - if(file_exists(buf)) { - no_info = TRUE; - break; - } - g_free (buf); -#endif - } - if(i >= ndirs) { - printf ("Document not found\n" - "The info document \"%s\" could not be found. It may have been removed from your system.\n" - "\n", args[0]); - return 2; - } - - n = i; - - for(i = 0; ; i++) { - gchar *path; - - if (no_info) { - path = g_strdup_printf ("%s/%s", - dirs[n], args[0]); - } else { - path = g_strdup_printf ("%s/%s.info", - dirs[n], args[0]); - } - - if(i) { - g_free (buf); - buf = g_strdup_printf ("%s-%d%s", path, i, ext); - } else { - g_free (buf); - buf = g_strdup_printf ("%s%s", path, ext); - } - - if(!file_exists(buf)) { - fixup_args[i] = NULL; - break; - } - - fixup_args[i] = strdup(buf); - } - g_free (buf); - args = (const char **)fixup_args; - } - - if(requested_nodename) { - char *s, *t; - int len; - /* strip off quotes */ - for (s=requested_nodename; *s == '\"'; ) { - len = strlen( s ); - memmove(s, s+1, len); - } - - t = s + strlen(s) - 1; - while (*t == '\"') { - t--; - } - - *(t+1) = '\0'; - - /* convert anchor so matching works */ - map_spaces_to_underscores(requested_nodename); - } else { - /* since no node has been asked for, it might have been passed in - as filename?section. In that case, set requested_nodename - to what is in requested_section, if that is NULL, set requested_nodename - to "Top" to display only the "Top" Node */ - if (requested_section) { - requested_nodename = requested_section; - } else { - requested_nodename = top_string; - } - } - work_line_number = 0; - - /* hack, just send to stdout for now */ - g_print("Info page for \"%s\"\n", argv[1]); - - /* big loop to identify sections of info files */ - /* NEW PLAN - format on the fly */ - /* No need to store all nodes, etc since we let web server */ - /* handle resolving tags! */ - for (;1 || !foundit || !requested_nodename;) { - if(!f) { - if(args && args[curarg]) { - f = readbuf_open (args[curarg++]); - if(!f) { - break; - } - num_files_left = args[curarg]?1:0; - for (work_line_number = 0, readbuf_gets(f,line,sizeof(line)); *line != INFO_COOKIE; - readbuf_gets(f,line,sizeof(line)), work_line_number++) - /**/ ; - } else { - break; - } - } - if(!readbuf_gets(f,line,sizeof(line))) { - readbuf_close(f); - f = NULL; - continue; - } - - work_line_number++; - - /* found a node definition line */ - if (!strncmp(line, "File:", 5)) { - node = alloc_node(); - result=read_node( f, line, node ); - if ( result == READ_ERR ) { - fprintf(stderr, "Error reading the node " - "contents\n"); - fprintf(stderr, "line was |%s|\n",line); - continue; - } - - /* see if this is the requested node name */ - strncpy(convanc, node->nodename, sizeof(convanc)); - map_spaces_to_underscores(convanc); - if (requested_nodename && - strcmp(requested_nodename, convanc)) { -#ifdef DEBUG - fprintf(stderr, "skipping ->%s<-\n", - node->nodename); -#endif - - continue; - } - - foundit = 1; - strcpy(work_node,node->nodename); - - BaseFilename = node->filename; -#ifdef DEBUG - printf("NEW NODE\n"); - printf("\tFile:|%s|\n\tNode:|%s|\n\tNext:|%s|\n", - node->filename, node->nodename,node->next); - printf("\tPrev:|%s|\n\tUp:|%s|\n\n", - node->prev, node->up); - printf("-------------------------------------------" - "-----------\n"); -#endif - /* now lets make some html */ - dump_html_for_node( node ); - - if (node) { - if ( node->contents ) - free(node->contents); - - g_free(node); - BaseFilename = NULL; - } - } else { - continue; - } - } - - if (!foundit && requested_nodename) { - fprintf(stderr, "Requested node %s not found\n", - requested_nodename); - exit(1); - } - - fprintf(stdout, "\n"); - return 0; -} diff --git a/src/info2html/utils.c b/src/info2html/utils.c deleted file mode 100644 index fcee4bf5..00000000 --- a/src/info2html/utils.c +++ /dev/null @@ -1,398 +0,0 @@ -/* various utility functions */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_LIBBZ2 -#include -#endif -#include - -#include "data.h" -#include "utils.h" - -void strip_spaces( char *str ) -{ - int len; - - len = strlen( str ); - if (len < 1) - return; - - while (*str == ' ') - { - len = strlen( str ); - memmove(str, str+1, len); - } - - len = strlen( str ); - while (*(str+len) == '\n') - { - *(str+len) = '\000'; - len = strlen( str ); - } - -#if 0 - q = str + strlen( str ); - for (p=str; *p == ' ' || *p == '\t'; p++); - for (r=q-1; *r == ' ' || *r == '\t'; r--); - len = r - p + 1; - memmove( str, p, len ); - *(str+len)='\000'; -#endif -} - -void strip_newlines( char *str ) -{ - char *p; - int len; - - len = strlen( str ); - if (len < 2) - return; - - for (p=str; len > 0; len--) - if ( *p == '\n' ) - { - if (len > 1) - memmove(p , p+1, len ); - else - *p = '\000'; - } - else - p++; -} - -void strip_dupspaces( char *str ) -{ - char *p; - int len; - - len = strlen( str ) - 1; - if (len < 2) - return; - - for (p=str+1; len > 0; len--) - if ( *p == ' ' && *(p-1) == ' ') - { - if (len > 1) - memmove(p , p+1, len ); - else - *p = '\000'; - } - else - p++; -} - -void convert_newlines_to_spaces( char *str ) -{ - char *p; - int len; - - /* trim head and trailing newlines */ - while (*str == '\n') - { - len = strlen( str ); - memmove(str, str+1, len); - } - - len = strlen( str ); - while (*(str+len) == '\n') - { - *(str+len) = '\000'; - len = strlen( str ); - } - - len = strlen( str ); - for (p=str; len > 0; len--, p++) - if ( *p == '\n' ) - *p = ' '; -} - -char * escape_html_chars( char *str ) -{ - char *p; - char *q; - char tmp[2]; - int len; - - if (!str) - return NULL; - - len = strlen( str ); -#if 0 - if (len <2) - fprintf(stderr,"escaped less < 2 chars= |%s|\n",str); - -#endif - - q = (char *) g_malloc( len * 5 + 4); - *q = '\000'; - *(tmp+1) = '\000'; - for (p=str; *p; p++) - if ( *p == '>' ) - strcat(q, ">"); - else if ( *p == '<' ) - strcat(q, "<"); - else if ( *p == '&' ) - strcat(q, "&"); - else - { - *tmp = *p; - strcat(q, tmp); - } - return q; -} - - -char *get_line_from_contents( char *ptr, int size ) -{ - char *eoln; - char *line; - int linelen; - - eoln = memchr(ptr, '\n', size); - if (eoln == NULL) - return NULL; - - linelen = (eoln-ptr); - line = (char *) g_malloc( linelen+1 ); - memcpy(line, ptr, linelen); - *(line+linelen) = '\000'; - return line; -} - -/* copies from string str up to any character in chr */ -/* if chr doesn't exist, return NULL */ -/* otherwise return location of match */ -/* allocates a new string if anything copied */ -char *copy_to_anychar( char *str, char *chr, char **copy ) -{ - int len; - char *match; - - match = strpbrk(str, chr); - if (!match) - return NULL; - - len = match - str; - *copy = (char *) g_malloc( len+1 ); - *(*copy+len) = '\000'; - memcpy(*copy, str, len ); - return match; -} - -/* allocates a new node */ -NODE *alloc_node() -{ - NODE * tmp; - - tmp = (NODE *) g_malloc( sizeof(NODE) ); - - if (tmp) - { - tmp->nodename=NULL; - tmp->filename=NULL; - tmp->contents=NULL; - tmp->contlen=0; - tmp->next=NULL; - tmp->prev=NULL; - tmp->up=NULL; - tmp->menu=NULL; - tmp->menu_start=NULL; - } - return tmp; -} - -/* deallocates a new node */ -void free_node(NODE *tmp) -{ - if (tmp) - { - if (tmp->nodename) - g_free(tmp->nodename); - if (tmp->filename) - g_free(tmp->filename); - if (tmp->contents) - g_free(tmp->contents); - } - g_free(tmp); -} - -#if 0 -void map_spaces_to_underscores( char *str ) -{ - char *p; - - for (p=str; *p; p++) - if (*p == ' ') - *p = '_'; -} -#endif - -void map_spaces_to_underscores( char *str ) -{ - char *p; - - for (p=str; *p; p++) - switch (*p) - { - case ' ': - case '\n': - case '\t': - case '`': - case '\'': - case '/': - case '\\': - case '"': - case '.': - case '!': - *p = '_'; - break; - } -} - - - -/* reduce infofile filename to basename alone */ -void fixup_info_filename( char *file ) -{ - char *ptr1; - char tail[] = ".info"; - - if (strlen(file) < 6) - return; - - ptr1 = strrchr( file, '.' ); - if (!ptr1) - return; - - if (!strncmp(ptr1, tail, strlen(tail))) - *ptr1 = '\000'; - -} - -ReadBuf * readbuf_open(const char *name) { - ReadBuf *f; - -#ifdef HAVE_LIBBZ2 - if (strlen(name) > 4 && strcmp(name+strlen(name)-4,".bz2") == 0) { - f = g_new0 (ReadBuf, 1); - f->buffer = g_malloc(READ_BUF_SIZE); - f->bzfile = bzopen(name, "r"); - if(!f->bzfile) { - free(f); - return NULL; - } - - f->type = BZIP2; - f->eof = FALSE; - } - else -#endif - { - f = g_new0 (ReadBuf, 1); - f->buffer = g_malloc(READ_BUF_SIZE); - f->gzfile = gzopen(name, "r"); - if (f->gzfile == NULL) { - free(f); - return NULL; - } - else { - f->type = GZIP; - f->eof = FALSE; - } - } - return f; -} - -void readbuf_close(ReadBuf *f) -{ - switch (f->type) { - case GZIP: - gzclose(f->gzfile); - break; -#ifdef HAVE_LIBBZ2 - case BZIP2: - bzclose(f->bzfile); - break; -#endif - } - g_free (f->buffer); - g_free (f); - } - -int readbuf_eof(ReadBuf *f) -{ - return f->eof; -} - -static int -readbuf_getc (ReadBuf *rb) -{ - if (rb->eof) - return EOF; - - if (rb->size == 0 || - rb->pos == rb->size) { - int bytes_read; - - switch (rb->type) { - case GZIP: - bytes_read = gzread(rb->gzfile,rb->buffer,READ_BUF_SIZE); - break; -#ifdef HAVE_LIBBZ2 - case BZIP2: - bytes_read = bzread(rb->bzfile,rb->buffer,READ_BUF_SIZE); - break; -#endif - } - - if (bytes_read == 0) { - rb->eof = TRUE; - return EOF; - } - - rb->size = bytes_read; - rb->pos = 0; - - } - - return (guchar) rb->buffer[rb->pos++]; -} - -char * -readbuf_gets (ReadBuf *rb, char *buf, gsize bufsize) -{ - int c; - gsize pos; - - g_return_val_if_fail (buf != NULL, NULL); - g_return_val_if_fail (rb != NULL, NULL); - - pos = 0; - buf[0] = '\0'; - - do { - c = readbuf_getc (rb); - if (c == EOF || c == '\n') - break; - buf[pos++] = c; - } while (pos < bufsize-1); - - if (c == EOF && pos == 0) - return NULL; - - if (c == '\n') - buf[pos++] = '\n'; - - buf[pos++] = '\0'; - - return buf; -} - diff --git a/src/info2html/utils.h b/src/info2html/utils.h deleted file mode 100644 index 7f77aa4d..00000000 --- a/src/info2html/utils.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H - -#include "data.h" - -void strip_spaces( char *str ); -void strip_newlines( char *str ); -void strip_dupspaces( char *str ); -void convert_newlines_to_spaces( char *str ); -char *get_line_from_contents( char *ptr, int size ); -char *copy_to_anychar( char *str, char *chr, char **copy ); -NODE *alloc_node( void ); -void free_node( NODE * ); -void map_spaces_to_underscores( char *str ); -void fixup_info_filename( char *file ); -char *escape_html_chars( char *str ); -ReadBuf * readbuf_open (const char *name); -int readbuf_eof (ReadBuf *rb); -char * readbuf_gets (ReadBuf *rb, char *buf, gsize bufsize); -void readbuf_close (ReadBuf *rb); -#endif diff --git a/src/man2html/Makefile.am b/src/man2html/Makefile.am deleted file mode 100644 index f3d08b11..00000000 --- a/src/man2html/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -## Process this file with automake to produce Makefile.in. - -INCLUDES = \ - -I$(top_srcdir) \ - @YELP_CFLAGS@ - - -libexec_PROGRAMS = yelp-man2html - -yelp_man2html_SOURCES = yelp-man2html.c - -yelp_man2html_LDADD = \ - @YELP_LIBS@ $(Z_LIBS) $(BZ_LIBS) - -#CFLAGS += -Wall - diff --git a/src/man2html/README b/src/man2html/README deleted file mode 100644 index e3b79ac5..00000000 --- a/src/man2html/README +++ /dev/null @@ -1,284 +0,0 @@ -gnome-man2html2 --------------- - -Modified version of gnome-man2html2 by Elliot Lee -- slight changes made to the man: URL's output, but otherwise it works -perfectly. - -Modified version of VH-Man2html by Michael Fulbright - -Please do not contact the individuals below if you have problems with -gnome-man2html2, instead send me an email and I'll try to help. - -The README for the original program lies below... - - -VH-Man2html - Modified Verhoeven-man2html ------------------------------------------ -Michael Hamilton -http://www.actrix.gen.nz/users/michael - -vh = Richard Verhoeven's (rcb5@win.tue.nl) Man2html as modified and -packaged by Michael Hamilton. - -Featues: - - Translate man pages to html from tbl/troff source. - - Look up a page by name and section or via full path name. - - Links generated html to other pages, include files, email addresses, - and http refs. - - Name-title index built from man whatis info. - - Name only index built from inspecting the man directories. - - Full text search via glimpse (glimpse obtainable separately). - - Works from man and BSD mandoc source files. - - Fast troff to HTML translator written in C. - - Copes with compressed (gzip etc) source. - -New in version 1.5: - - fix to mansec for compressed pages. - - make now configures ALL scripts, html files, and man pages. - - includes section 9. - -New in version 1.4: - - Uses /etc/man.config to obtain the man path. - - Man2html.c now uses decompression filters specified in /etc/man.config. - - Glimpse now uses decompression filters (see glimpse_filters file). - (Generating indexes will be be slower for compressed hierarchies.) - - Safer - more secure from memory overuns. Man2html now checks for - excessively long input parameters. - - All configuration can now be done by editing the Makefile and the - glimpse_filters file. - - By default (in version 1.4 and above) -M only allows the user to select - what part of the hierarchy to search first - they cannot specify a path - outside of the official hierarchy. Previously the -M option could be - used to retrieve any man/mandoc source file that had "man" in it's - path-name/file-name (a compile time switch can restore the previous - behaviour). - - Fixed more bugs. - -QUICK START INSTRUCTIONS ------------------------- - -To use these cgi scripts all you have to do is install the rpm and -then point your web browser at - - http://localhost/cgi-bin/man2html - -You can either save this location as a bookmark or use an editor to -insert the following lines into an appropriate place in -/usr/doc/HTML/calderadoc/caldera.html (or somewhere like -/home/httpd/index.html if you are using RedHat's http server) - -

    - Linux Manual Pages

    - -For some of the indexes to work you must generate the necessary -databases... - -Vh-man2html's manwhatis CGI-script uses the /usr/man/whatis file to build -a man page index. Caldera 1.0 normally builds the /usr/man/whatis every -morning at 3:21am. If this job has never been run (perhaps because -you turn your machine off at night), you can build it by becoming the -root user and entering: - - /usr/sbin/makewhatis /usr/man /usr/X11R6/man /usr/local/man - -WARNING: makewhatis in Caldera 1.0 takes about 30 minutes on my -486DX66. I have a modified version of makewhatis so that it does -exactly the same job in only 1.5 minutes. My modified version is now -available as part of man-1.4g (man-1.4g.tar.gz) and above: - - ftp://sunsite.unc.edu/pub/Linux/system/Manual-pagers - -To use the Glimpse full text searching, you will need to install -glimpse in /usr/bin. Redhat rpm users can get glimpse from - - ftp://ftp.redhat.com/pub/non-free/glimpse-3.0-1.i386.rpm - -The glimpse home ftp site is cs.arizona.edu. N.B. glimpse is not -freely redistributable for commercial use, I'd be very interested in a -more liberal alternative. Having installed glimpse, you will need to -build a glimpse index in /var/man2html. This doesn't take too long - -about 3 minutes on my 486DX2/66 16MB machine. As root do: - - /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man* /usr/X11R6/man/man* \ - /usr/local/man/man* /opt/man/man* - chmod ugo+r /var/man2html/.glimpse* - -The -z option causes glimpse to apply any filters (for decompression etc) -specified in /var/man2html/.glimpse_filters. - -This could be set up as a cron job in /etc/crontab, e.g. (the following -must be all on one line): - - 21 04 * * 1 root /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man* - /usr/X11R6/man/man* /usr/local/man/man* /opt/man/man* ; - chmod +r /var/man2html/.glimpse* - -If you don't want to use glimpse you can edit the man.html file that -the package installs in /home/http/html/man.html, and remove the -references to full text searches and glimpse. This file can also be -edited to include any local instructions you might wish to include. - -The scripts may generate errors to the httpd error log -/var/log/httpd/error_log. The man binary (used to obtain the man-path -by some of the scripts) seems to always think it's talking to a tty, -and tries to obtain the screen size, resulting in the following error -log entries: - - TIOCGWINSZ - failed : Bad file number - -To serve man pages to remote hosts, all that is required is a httpd -daemon that sets the environment variable SERVER_NAME correctly. - -END OF QUICK START INSTRUCTIONS -------------------------------- - -Vh-man2html was was written by Richard Verhoeven (NL:5482ZX35) at -the Eindhoven University of Technology (Email: rcb5@win.tue.nl). The -original source is available from his web page at: - - http://wsinwp01.win.tue.nl:1234/maninfo.html - -There are other man2html programs around - Richard's page has links to -several of them. Richard's man2html has some useful features for -Caldera/RedHat Linux - - - Works from the troff/nroff source pages. - With linux we almost always have the man source. - Doesn't have to run man+tbl+eqn+nroff to generate output. - Because man isn't run, no catman pages are generated. - Accurate - doesn't have to guess from the man output. - Does tables (eg man ascii) (but doesn't do eqn - few pages use eqn). - Written in C - efficient speed/memory usage. - Fast enough not to need a cache. - Intelligent - Makes good guesses on where to find pages. - Creates links for man pages and include files. - -Richard's original program copes with pages formatted with the man -macros. I've enhanced it by adding translations for the mandoc macros -used in the BSD man pages. BSD mandoc pages in Caldera/Redhat -include Mail, ftp, telnet, rlogin, and lpr and other printer man -pages - so they're pretty important. - -I don't have any documentation on the mandoc macros, so I've had to -guess what they intend, by looking at man source, man output and the -gnroff macro definitions. I've tested it on all the BSD mandoc pages -in Section 1 that I could find. It works reasonable well. There are -still minor formatting glitches to do with punctuation placement. -I checked the BSD mandoc with weblint, e.g. in tcsh/csh - - foreach i ( `egrep -l '^\.Bl' /usr/man/man1/* /usr/man/man8/*` ) - /home/httpd/cgi-bin/man2html $i > tmp/`basename $i` - end - weblint tmp/* - -For broader testing: - - find /usr/man/man* -name '*.[0-9]' \ - -printf "echo %p; /home/httpd/cgi-bin/man2html %p |weblint -x netscape -\n" \ - | sh \ - |& tee weblint.log - -If you want to sample the spectrum of mandoc translation, look at -any of the pages the above grep locates, telnet, lpc, and mail -are good examples. - -For full details of my modifications to man2html.c see the patch -included in the source archive. - -Here's a summary of the rpm's components: - - 1) man.html - Main page or access to man2html and man indexes. - 2) man2html - CGI binary that converts man pages to html. - 3) manwhatis - CGI script for a name and synopsis index organised - by manual section - 4) mansec - CGI script for a name only index for each section. - 5) mansearch - Glimpse full text searching. - 6) mansearch.html - Main page or access to man2html and man indexes. - 7) netscape-man - Front end that starts, or talks to, a running netscape. - 8) /var/ma2html - Cache directory for indexes and glimpse indexes. - -All my scripts are written in awk. In detail... - -The manwhatis script creates section contents html files by looking -for whatis files along the man path. Each whatis entry is translated -to a man2html link. Manwhatis caches it's output in -/var/man2html/whatis-[0-9].html. The cache will be regenerated if any -whatis file in the man path is updated (eg touch /usr/man/whatis). - -The mansec script lists the names of all manual pages for a given -section by using find on the man path. It caches its output in -/var/man2html/manindex-[0-9].html. The cache will be regenerated if -any associated man[0-9] directory in the man path is updated. - -The mansearch script uses glimpse to get back a list of files and -matches which it links back to the actual man pages. The mansearch -script is not pure awk. It's starts out as a shell script to ensure -that the parameters are safely passed to awk. I think it's secure, -but I'm not a cgi script expert. - -To build and install man2html, the scripts, and man.html from the -source archive - edit the Makefile and then: - - make install - -To build binary and source rpms, placing them under /usr/src/... - - make rpm - -SECURITY --------- - -I've modified the man2html C code so that it checks all client input -parameters for length and characters that need escaping. - -Man2html will only return man or mandoc files resident in the man -hierarchy defined in /etc/man.config. - -When man2html generates references to include files they are in the -form file: on the CLIENT host, not the server. - -The parameters to the decompression programs are checked for any -nasties. - -It is still possible for the contents of a man page to over-run -man2html's memory - so I guess a hacker might try to get you to -install a bogus man page in order to get man2html to do something -nasty. - -The scripts check their parameters for anything suspicious. - -The scripts and program write suspicious requests to stderr - so they -can be found in web server log files. - -CREDITS -------- - -See the man page man2html.8 for credits. - ---------------- - -My modifications, packaging and scripts are copyright (c) 1996 -Michael Hamilton (michael@actrix.gen.nz). All rights reserved. - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that the -above copyright notice and the following two paragraphs appear in all -copies of this software. - -IN NO EVENT SHALL MICHAEL HAMILTON BE LIABLE TO ANY PARTY FOR DIRECT, -INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF -THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF MICHAEL -HAMILTON HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -MICHAEL HAMILTON SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND MICHAEL HAMILTON HAS NO OBLIGATION TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -Michael diff --git a/src/test-pager.c b/src/test-pager.c deleted file mode 100644 index 9a6c7b48..00000000 --- a/src/test-pager.c +++ /dev/null @@ -1,149 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2002 Shaun McCance - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA. - * - * Author: Shaun McCance - */ - -#include -#include - -#include -#include - -#include "config.h" -#include "yelp-pager.h" -#include "yelp-db-pager.h" -#include "yelp-man-pager.h" -#include "yelp-settings.c" -#include "yelp-toc-pager.h" -#include "yelp-utils.h" - -static void pager_parse_cb (YelpPager *pager); -static void pager_start_cb (YelpPager *pager); -static void pager_page_cb (YelpPager *pager, - gchar *page_id); -static void pager_finish_cb (YelpPager *pager); -static void pager_cancel_cb (YelpPager *pager); -static void pager_error_cb (YelpPager *pager); - -gboolean main_running = TRUE; - -gint -main (gint argc, gchar **argv) -{ - YelpDocInfo *doc_info; - YelpPager *pager; - - if (argc < 2) { - g_error ("Usage: test-pager file\n"); - return 1; - } - - gnome_program_init (PACKAGE, VERSION, - LIBGNOMEUI_MODULE, argc, argv, - GNOME_PROGRAM_STANDARD_PROPERTIES, - NULL); - yelp_toc_pager_init (); - yelp_settings_init (); - - doc_info = yelp_doc_info_get (argv[1], FALSE); - - if (!doc_info) { - printf ("Failed to load URI: %s\n", argv[1]); - return -1; - } - - switch (yelp_doc_info_get_type (doc_info)) { - case YELP_DOC_TYPE_DOCBOOK_XML: - pager = yelp_db_pager_new (doc_info); - break; - case YELP_DOC_TYPE_MAN: - pager = yelp_man_pager_new (doc_info); - break; - default: - printf ("No pager type exists for this URI.\n"); - return 1; - } - - g_signal_connect (pager, "parse", G_CALLBACK (pager_parse_cb), NULL); - g_signal_connect (pager, "start", G_CALLBACK (pager_start_cb), NULL); - g_signal_connect (pager, "page", G_CALLBACK (pager_page_cb), NULL); - g_signal_connect (pager, "finish", G_CALLBACK (pager_finish_cb), NULL); - g_signal_connect (pager, "cancel", G_CALLBACK (pager_cancel_cb), NULL); - g_signal_connect (pager, "error", G_CALLBACK (pager_error_cb), NULL); - - yelp_pager_start (pager); - - gtk_main (); - - return 0; -} - -static void -pager_parse_cb (YelpPager *pager) -{ - printf ("pager_parse_cb\n"); -} - -static void -pager_start_cb (YelpPager *pager) -{ - printf ("pager_start_cb\n"); -} - -static void -pager_page_cb (YelpPager *pager, - gchar *page_id) -{ - const YelpPage *page = yelp_pager_get_page (pager, page_id); - - printf ("pager_page_cb:\n" - " id: %s\n" - " title: %s\n" - " strlen: %d\n", - page->page_id, - page->title, - strlen (page->contents)); -} - -static void -pager_finish_cb (YelpPager *pager) -{ - printf ("pager_finish_cb\n"); - gtk_main_quit (); -} - -static void -pager_cancel_cb (YelpPager *pager) -{ - printf ("pager_cancel_cb\n"); - gtk_main_quit (); -} - -static void -pager_error_cb (YelpPager *pager) -{ - GError *error = yelp_pager_get_error (pager); - - if (!error) - printf ("pager_error_cb: NO ERROR\n"); - else - printf ("pager_error_cb: %s\n", error->message); - - gtk_main_quit (); -} diff --git a/src/yelp-db-pager.c b/src/yelp-db-pager.c deleted file mode 100644 index 800ff5f0..00000000 --- a/src/yelp-db-pager.c +++ /dev/null @@ -1,605 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-error.h" -#include "yelp-db-pager.h" -#include "yelp-toc-pager.h" -#include "yelp-settings.h" -#include "yelp-debug.h" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define DB_STYLESHEET STYLESHEET_PATH"db2html.xsl" - -#define BOOK_CHUNK_DEPTH 2 -#define ARTICLE_CHUNK_DEPTH 1 - -#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration (); -#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done; - -extern gboolean main_running; - -#define YELP_DB_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_DB_PAGER, YelpDBPagerPriv)) - -struct _YelpDBPagerPriv { - GtkTreeModel *sects; - GHashTable *frags_hash; - - gint max_depth; - gchar *root_id; -}; - -typedef struct _DBWalker DBWalker; -struct _DBWalker { - YelpDBPager *pager; - gchar *page_id; - - xmlDocPtr doc; - xmlNodePtr cur; - - GtkTreeIter *iter; - - gint depth; - gint max_depth; - -}; - -static void db_pager_class_init (YelpDBPagerClass *klass); -static void db_pager_init (YelpDBPager *pager); -static void db_pager_dispose (GObject *gobject); - -static void db_pager_cancel (YelpPager *pager); -static xmlDocPtr db_pager_parse (YelpPager *pager); -static gchar ** db_pager_params (YelpPager *pager); - -static const gchar * db_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -static GtkTreeModel * db_pager_get_sections (YelpPager *pager); - -static void walker_walk_xml (DBWalker *walker); - -static gboolean node_is_chunk (DBWalker *walker); -static gboolean node_is_division (DBWalker *walker); -static gchar * node_get_title (DBWalker *walker, - gchar *type); - -xmlNodePtr node_find_child (xmlNodePtr parent, - gchar *child_name); - -static YelpPagerClass *parent_class; - -GType -yelp_db_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpDBPagerClass), - NULL, - NULL, - (GClassInitFunc) db_pager_class_init, - NULL, - NULL, - sizeof (YelpDBPager), - 0, - (GInstanceInitFunc) db_pager_init, - }; - type = g_type_register_static (YELP_TYPE_XSLT_PAGER, - "YelpDBPager", - &info, 0); - } - return type; -} - -static void -db_pager_class_init (YelpDBPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = db_pager_dispose; - - pager_class->cancel = db_pager_cancel; - - pager_class->resolve_frag = db_pager_resolve_frag; - pager_class->get_sections = db_pager_get_sections; - - xslt_class->parse = db_pager_parse; - xslt_class->params = db_pager_params; - - xslt_class->stylesheet = DB_STYLESHEET; - - g_type_class_add_private (klass, sizeof (YelpDBPagerPriv)); -} - -static void -db_pager_init (YelpDBPager *pager) -{ - pager->priv = YELP_DB_PAGER_GET_PRIVATE (pager); - - pager->priv->sects = NULL; - - pager->priv->frags_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - pager->priv->root_id = NULL; -} - -static void -db_pager_dispose (GObject *object) -{ - YelpDBPager *pager = YELP_DB_PAGER (object); - - g_object_unref (pager->priv->sects); - g_hash_table_destroy (pager->priv->frags_hash); - - g_free (pager->priv->root_id); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -YelpPager * -yelp_db_pager_new (YelpDocInfo *doc_info) -{ - YelpDBPager *pager; - - g_return_val_if_fail (doc_info != NULL, NULL); - - pager = (YelpDBPager *) g_object_new (YELP_TYPE_DB_PAGER, - "document-info", doc_info, - NULL); - - g_hash_table_insert (pager->priv->frags_hash, - g_strdup ("x-yelp-titlepage"), - g_strdup ("x-yelp-titlepage")); - - if (!pager->priv->sects) - pager->priv->sects = - GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_STRING)); - - return (YelpPager *) pager; -} - -static xmlDocPtr -db_pager_parse (YelpPager *pager) -{ - YelpDBPagerPriv *priv; - YelpDocInfo *doc_info; - gchar *filename = NULL; - - xmlParserCtxtPtr parserCtxt = NULL; - xmlDocPtr doc = NULL; - - DBWalker *walker = NULL; - xmlChar *id; - GError *error = NULL; - - debug_print (DB_FUNCTION, "entering\n"); - - doc_info = yelp_pager_get_doc_info (pager); - - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL); - priv = YELP_DB_PAGER (pager)->priv; - - g_object_ref (pager); - - if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) - goto done; - - filename = yelp_doc_info_get_filename (doc_info); - - parserCtxt = xmlNewParserCtxt (); - doc = xmlCtxtReadFile (parserCtxt, - (const char *) filename, NULL, - XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NONET ); - if (doc == NULL) { - g_set_error (&error, YELP_GERROR, YELP_ERROR_NO_DOC, - _("The file ‘%s’ could not be parsed. Either the file " - "does not exist, or it is not well-formed XML."), - filename); - yelp_pager_error (pager, error); - goto done; - } - - xmlXIncludeProcessFlags (doc, - XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NONET ); - - walker = g_new0 (DBWalker, 1); - walker->pager = YELP_DB_PAGER (pager); - walker->doc = doc; - walker->cur = xmlDocGetRootElement (walker->doc); - - if (!xmlStrcmp (xmlDocGetRootElement (doc)->name, BAD_CAST "book")) - priv->max_depth = walker->max_depth = BOOK_CHUNK_DEPTH; - else - priv->max_depth = walker->max_depth = ARTICLE_CHUNK_DEPTH; - - id = xmlGetProp (walker->cur, BAD_CAST "id"); - if (id) - priv->root_id = g_strdup ((gchar *) id); - else { - priv->root_id = g_strdup ("index"); - /* add the id attribute to the root element with value "index" - * so when we try to load the document later, it doesn't fail */ - xmlNewProp (walker->cur, BAD_CAST "id", BAD_CAST "index"); - } - - EVENTS_PENDING; - CANCEL_CHECK; - - walker_walk_xml (walker); - - done: - g_free (walker); - - g_free (filename); - - if (parserCtxt) - xmlFreeParserCtxt (parserCtxt); - - g_object_unref (pager); - - return doc; -} - -static gchar ** -db_pager_params (YelpPager *pager) -{ - YelpDBPagerPriv *priv; - gchar **params; - gint params_i = 0; - gint params_max = 20; - - debug_print (DB_FUNCTION, "entering\n"); - - g_return_val_if_fail (pager != NULL, FALSE); - g_return_val_if_fail (YELP_IS_DB_PAGER (pager), FALSE); - priv = YELP_DB_PAGER (pager)->priv; - - if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) - return NULL; - - params = g_new0 (gchar *, params_max); - - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 20; - params = g_renew (gchar *, params, params_max); - } - params[params_i++] = "db.chunk.extension"; - params[params_i++] = g_strdup ("\"\""); - params[params_i++] = "db.chunk.info_basename"; - params[params_i++] = g_strdup ("\"x-yelp-titlepage\""); - params[params_i++] = "db.chunk.max_depth"; - params[params_i++] = g_strdup_printf ("%i", priv->max_depth); - params[params_i++] = "yelp.javascript"; - params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js"); - - params[params_i] = NULL; - - return params; -} - -static void -db_pager_cancel (YelpPager *pager) -{ - YelpDBPagerPriv *priv = YELP_DB_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - gtk_tree_store_clear (GTK_TREE_STORE (priv->sects)); - g_hash_table_foreach_remove (priv->frags_hash, (GHRFunc) gtk_true, NULL); - - g_free (priv->root_id); - priv->root_id = NULL; - - YELP_PAGER_CLASS (parent_class)->cancel (pager); -} - -static const gchar * -db_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - YelpDBPager *db_pager; - gchar *page_id = NULL; - - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL); - - db_pager = YELP_DB_PAGER (pager); - - if (frag_id) - page_id = g_hash_table_lookup (db_pager->priv->frags_hash, - frag_id); - else - page_id = db_pager->priv->root_id; - - return (const gchar *) page_id; -} - -static GtkTreeModel * -db_pager_get_sections (YelpPager *pager) -{ - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_DB_PAGER (pager), NULL); - - return YELP_DB_PAGER (pager)->priv->sects; -} - -/******************************************************************************/ - -static void -walker_walk_xml (DBWalker *walker) -{ - static gint autoid = 0; - gchar autoidstr[20]; - xmlChar *id = NULL; - xmlChar *title = NULL; - gchar *old_id = NULL; - xmlNodePtr cur; - xmlNodePtr old_cur; - GtkTreeIter iter; - GtkTreeIter *old_iter = NULL; - YelpDBPagerPriv *priv = walker->pager->priv; - - /* check for the yelp:chunk-depth processing instruction and set - * the max chunk depth accordingly */ - if (walker->depth == 0) { - cur = walker->cur; - for ( ; cur; cur = cur->prev) - if (cur->type == XML_PI_NODE) - if (!xmlStrcmp (cur->name, - (const xmlChar *) "yelp:chunk-depth")) { - gint max = atoi ((gchar *) cur->content); - if (max) - priv->max_depth = walker->max_depth = max; - break; - } - } - - id = xmlGetProp (walker->cur, BAD_CAST "id"); - if (!id && walker->cur->parent->type == XML_DOCUMENT_NODE) { - id = xmlStrdup (BAD_CAST "__yelp_toc"); - } - - if (node_is_chunk (walker)) { - title = BAD_CAST node_get_title (walker, "titleabbrev"); - if (!title) - title = BAD_CAST node_get_title (walker, "title"); - - /* if id attribute is not present, autogenerate a - * unique value, and insert it into the in-memory tree */ - if (!id) { - g_snprintf (autoidstr, 20, "_auto-gen-id-%d", ++autoid); - xmlNewProp (walker->cur, BAD_CAST "id", BAD_CAST autoidstr); - id = xmlGetProp (walker->cur, BAD_CAST "id"); - } - - if (id) { - gtk_tree_store_append (GTK_TREE_STORE (priv->sects), - &iter, walker->iter); - - gtk_tree_store_set (GTK_TREE_STORE (priv->sects), - &iter, - YELP_PAGER_COLUMN_ID, id, - YELP_PAGER_COLUMN_TITLE, title, - -1); - - old_id = walker->page_id; - walker->page_id = (gchar *) id; - - old_iter = walker->iter; - - if (walker->cur->parent->type != XML_DOCUMENT_NODE) - walker->iter = &iter; - } - } - - while (gtk_events_pending ()) - gtk_main_iteration (); - /* FIXME : check for cancel */ - - old_cur = walker->cur; - walker->depth++; - - if (id) { - g_hash_table_insert (priv->frags_hash, - g_strdup ((gchar *) id), - g_strdup (walker->page_id)); - } - - cur = walker->cur->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE) { - walker->cur = cur; - walker_walk_xml (walker); - } - cur = cur->next; - } - - walker->depth--; - walker->cur = old_cur; - - if (node_is_chunk (walker) && id) { - walker->iter = old_iter; - - walker->page_id = old_id; - } - - if (id != NULL) - xmlFree (id); - if (title != NULL) - xmlFree (title); -} - -xmlNodePtr -node_find_child (xmlNodePtr parent, gchar *child_name) -{ - xmlNodePtr child = (xmlNodePtr) parent->children; - - while (child) { - if (!xmlStrcmp (child->name, BAD_CAST child_name)) - break; - child = child->next; - } - return child; -} - - -static gchar * -node_get_title (DBWalker *walker, gchar *type) -{ - gchar *title = NULL; - xmlChar *node_name = (xmlChar *) walker->cur->name; - xmlNodePtr child = NULL; - xmlNodePtr title_node = NULL; - - if (xmlStrcmp (node_name, BAD_CAST "refentry")) { - /*refentry is special cased below */ - title_node = node_find_child (walker->cur, type); - if (!title_node) { - /* Gotta look for some other way of getting the title */ - gchar *looking_for = g_strdup_printf ("%sinfo", node_name); - - child = node_find_child (walker->cur, looking_for); - g_free (looking_for); - - if (child) - title_node = node_find_child (child, type); - } - } else { - /* Refentry */ - xmlNodePtr refentry = NULL; - xmlNodePtr refmeta = NULL; - xmlNodePtr refnamediv = NULL; - xmlNodePtr child = walker->cur->children; - - while (child) { - if (!xmlStrcmp (child->name, BAD_CAST "refmeta")) - refmeta = child; - else if (!xmlStrcmp (child->name, BAD_CAST "refentryinfo")) - refentry = child; - else if (!xmlStrcmp (child->name, BAD_CAST "refnamediv")) - refnamediv = child; - else if (!xmlStrncmp (child->name, BAD_CAST "refsect", 7)) - break; - child = child->next; - - } - if (refmeta) { - xmlNodePtr tmp = node_find_child (refmeta, "refentrytitle"); - title_node = node_find_child (tmp, type); - } - if (!title_node && refentry) { - title_node = node_find_child (refentry, type); - } - if (!title_node) { - title_node = node_find_child (refnamediv, "refname"); - } - - } - /* Something pretty seriously screwy happened - * Try the fallback options - */ - if (!title_node) { - xmlNodePtr block = node_find_child (walker->cur, "blockinfo"); - if (block) { - title_node = node_find_child (block, type); - } - if (!title_node) { - xmlNodePtr obj = node_find_child (walker->cur, "objectinfo"); - if (obj) - title_node = node_find_child (obj, type); - } - } - - title = (gchar *) xmlNodeGetContent (title_node); - - return title; -} - -static gboolean -node_is_chunk (DBWalker *walker) -{ - if (walker->depth <= walker->max_depth) { - if (node_is_division (walker)) - return TRUE; - } - return FALSE; -} - -static gboolean -node_is_division (DBWalker *walker) -{ - xmlNodePtr node = walker->cur; - return (!xmlStrcmp (node->name, (const xmlChar *) "appendix") || - !xmlStrcmp (node->name, (const xmlChar *) "article") || - !xmlStrcmp (node->name, (const xmlChar *) "book") || - !xmlStrcmp (node->name, (const xmlChar *) "bibliography") || - !xmlStrcmp (node->name, (const xmlChar *) "chapter") || - !xmlStrcmp (node->name, (const xmlChar *) "colophon") || - !xmlStrcmp (node->name, (const xmlChar *) "glossary") || - !xmlStrcmp (node->name, (const xmlChar *) "index") || - !xmlStrcmp (node->name, (const xmlChar *) "part") || - !xmlStrcmp (node->name, (const xmlChar *) "preface") || - !xmlStrcmp (node->name, (const xmlChar *) "reference") || - !xmlStrcmp (node->name, (const xmlChar *) "refentry") || - !xmlStrcmp (node->name, (const xmlChar *) "refsect1") || - !xmlStrcmp (node->name, (const xmlChar *) "refsect2") || - !xmlStrcmp (node->name, (const xmlChar *) "refsect3") || - !xmlStrcmp (node->name, (const xmlChar *) "refsection") || - !xmlStrcmp (node->name, (const xmlChar *) "sect1") || - !xmlStrcmp (node->name, (const xmlChar *) "sect2") || - !xmlStrcmp (node->name, (const xmlChar *) "sect3") || - !xmlStrcmp (node->name, (const xmlChar *) "sect4") || - !xmlStrcmp (node->name, (const xmlChar *) "sect5") || - !xmlStrcmp (node->name, (const xmlChar *) "section") || - !xmlStrcmp (node->name, (const xmlChar *) "set") || - !xmlStrcmp (node->name, (const xmlChar *) "setindex") || - !xmlStrcmp (node->name, (const xmlChar *) "simplesect") ); -} diff --git a/src/yelp-db-pager.h b/src/yelp-db-pager.h deleted file mode 100644 index 40381278..00000000 --- a/src/yelp-db-pager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_DB_PAGER_H__ -#define __YELP_DB_PAGER_H__ - -#include - -#include "yelp-pager.h" -#include "yelp-xslt-pager.h" - -#define YELP_TYPE_DB_PAGER (yelp_db_pager_get_type ()) -#define YELP_DB_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DB_PAGER, YelpDBPager)) -#define YELP_DB_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_DB_PAGER, YelpDBPagerClass)) -#define YELP_IS_DB_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_DB_PAGER)) -#define YELP_IS_DB_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_DB_PAGER)) -#define YELP_DB_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_DB_PAGER, YelpDBPagerClass)) - -typedef struct _YelpDBPager YelpDBPager; -typedef struct _YelpDBPagerClass YelpDBPagerClass; -typedef struct _YelpDBPagerPriv YelpDBPagerPriv; - -struct _YelpDBPager { - YelpXsltPager parent; - - YelpDBPagerPriv *priv; -}; - -struct _YelpDBPagerClass { - YelpXsltPagerClass parent_class; -}; - -GType yelp_db_pager_get_type (void); -YelpPager * yelp_db_pager_new (YelpDocInfo *doc_info); - -#endif /* __YELP_DB_PAGER_H__ */ diff --git a/src/yelp-db-print-pager.c b/src/yelp-db-print-pager.c deleted file mode 100644 index 8e184004..00000000 --- a/src/yelp-db-print-pager.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-error.h" -#include "yelp-db-print-pager.h" -#include "yelp-toc-pager.h" -#include "yelp-settings.h" -#include "yelp-debug.h" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define DB_STYLESHEET STYLESHEET_PATH"db2html.xsl" -#define DB_TITLE STYLESHEET_PATH"db-title.xsl" - -#define BOOK_CHUNK_DEPTH 2 -#define ARTICLE_CHUNK_DEPTH 1 - -#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration (); -#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done; - -extern gboolean main_running; - -#define YELP_DB_PRINT_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerPriv)) - -struct _YelpDBPrintPagerPriv { - gchar *root_id; -}; - -static void db_print_pager_class_init (YelpDBPrintPagerClass *klass); -static void db_print_pager_init (YelpDBPrintPager *pager); -static void db_print_pager_dispose (GObject *gobject); - -static void db_print_pager_cancel (YelpPager *pager); -static xmlDocPtr db_print_pager_parse (YelpPager *pager); -static gchar ** db_print_pager_params (YelpPager *pager); - -static const gchar * db_print_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -/*static GtkTreeModel * db_print_pager_get_sections (YelpPager *pager);*/ - -static YelpPagerClass *parent_class; - -GType -yelp_db_print_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpDBPrintPagerClass), - NULL, - NULL, - (GClassInitFunc) db_print_pager_class_init, - NULL, - NULL, - sizeof (YelpDBPrintPager), - 0, - (GInstanceInitFunc) db_print_pager_init, - }; - type = g_type_register_static (YELP_TYPE_XSLT_PAGER, - "YelpDBPrintPager", - &info, 0); - } - return type; -} - -static void -db_print_pager_class_init (YelpDBPrintPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = db_print_pager_dispose; - - pager_class->cancel = db_print_pager_cancel; - - pager_class->resolve_frag = db_print_pager_resolve_frag; - - xslt_class->parse = db_print_pager_parse; - xslt_class->params = db_print_pager_params; - - xslt_class->stylesheet = DB_STYLESHEET; - - g_type_class_add_private (klass, sizeof (YelpDBPrintPagerPriv)); -} - -static void -db_print_pager_init (YelpDBPrintPager *pager) -{ - YelpDBPrintPagerPriv *priv; - - pager->priv = priv = YELP_DB_PRINT_PAGER_GET_PRIVATE (pager); - - pager->priv->root_id = NULL; -} - -static void -db_print_pager_dispose (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -YelpPager * -yelp_db_print_pager_new (YelpDocInfo *doc_info) -{ - YelpDBPrintPager *pager; - - g_return_val_if_fail (doc_info != NULL, NULL); - - pager = (YelpDBPrintPager *) g_object_new (YELP_TYPE_DB_PRINT_PAGER, - "document-info", doc_info, - NULL); - - return (YelpPager *) pager; -} - -static xmlDocPtr -db_print_pager_parse (YelpPager *pager) -{ - YelpDBPrintPagerPriv *priv; - YelpDocInfo *doc_info; - gchar *filename = NULL; - - xmlParserCtxtPtr parserCtxt = NULL; - xmlDocPtr doc = NULL; - - GError *error = NULL; - - debug_print (DB_FUNCTION, "entering\n"); - - doc_info = yelp_pager_get_doc_info (pager); - - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL); - priv = YELP_DB_PRINT_PAGER (pager)->priv; - - g_object_ref (pager); - - if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) - goto done; - - filename = yelp_doc_info_get_filename (doc_info); - - parserCtxt = xmlNewParserCtxt (); - doc = xmlCtxtReadFile (parserCtxt, - (const char *) filename, NULL, - XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NONET ); - if (doc == NULL) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC, - _("The file ‘%s’ could not be parsed. Either the file " - "does not exist, or it is not well-formed XML."), - filename); - yelp_pager_error (pager, error); - goto done; - } - - xmlXIncludeProcessFlags (doc, - XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NONET ); - - - priv->root_id = g_strdup ("index"); - - EVENTS_PENDING; - CANCEL_CHECK; - - done: - g_free (filename); - - if (parserCtxt) - xmlFreeParserCtxt (parserCtxt); - - g_object_unref (pager); - - return doc; -} - -static gchar ** -db_print_pager_params (YelpPager *pager) -{ - YelpDBPrintPagerPriv *priv; - YelpDocInfo *doc_info; - gchar **params; - gint params_i = 0; - gint params_max = 20; - - debug_print (DB_FUNCTION, "entering\n"); - - doc_info = yelp_pager_get_doc_info (pager); - - g_return_val_if_fail (pager != NULL, FALSE); - g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), FALSE); - priv = YELP_DB_PRINT_PAGER (pager)->priv; - - if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) - return NULL; - - params = g_new0 (gchar *, params_max); - - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 20; - params = g_renew (gchar *, params, params_max); - } - params[params_i++] = "db.chunk.extension"; - params[params_i++] = g_strdup ("\"\""); - params[params_i++] = "db.chunk.info_basename"; - params[params_i++] = g_strdup ("\"index\""); - params[params_i++] = "db.chunk.max_depth"; - params[params_i++] = g_strdup_printf ("0"); - params[params_i++] = "yelp.javascript"; - params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js"); - - params[params_i] = NULL; - - return params; -} - -static void -db_print_pager_cancel (YelpPager *pager) -{ - YelpDBPrintPagerPriv *priv = YELP_DB_PRINT_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - g_free (priv->root_id); - priv->root_id = NULL; - - YELP_PAGER_CLASS (parent_class)->cancel (pager); -} - -static const gchar * -db_print_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - YelpDBPrintPager *db_print_pager; - - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL); - - db_print_pager = YELP_DB_PRINT_PAGER (pager); - - return frag_id; -} - diff --git a/src/yelp-db-print-pager.h b/src/yelp-db-print-pager.h deleted file mode 100644 index 013e8af5..00000000 --- a/src/yelp-db-print-pager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_DB_PRINT_PAGER_H__ -#define __YELP_DB_PRINT_PAGER_H__ - -#include - -#include "yelp-pager.h" -#include "yelp-xslt-pager.h" - -#define YELP_TYPE_DB_PRINT_PAGER (yelp_db_print_pager_get_type ()) -#define YELP_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPager)) -#define YELP_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass)) -#define YELP_IS_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_DB_PRINT_PAGER)) -#define YELP_IS_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_DB_PRINT_PAGER)) -#define YELP_DB_PRINT_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass)) - -typedef struct _YelpDBPrintPager YelpDBPrintPager; -typedef struct _YelpDBPrintPagerClass YelpDBPrintPagerClass; -typedef struct _YelpDBPrintPagerPriv YelpDBPrintPagerPriv; - -struct _YelpDBPrintPager { - YelpXsltPager parent; - - YelpDBPrintPagerPriv *priv; -}; - -struct _YelpDBPrintPagerClass { - YelpXsltPagerClass parent_class; -}; - -GType yelp_db_print_pager_get_type (void); -YelpPager * yelp_db_print_pager_new (YelpDocInfo *doc_info); - -#endif /* __YELP_DB_PRINT_PAGER_H__ */ diff --git a/src/yelp-info-pager.c b/src/yelp-info-pager.c deleted file mode 100644 index 2c674c22..00000000 --- a/src/yelp-info-pager.c +++ /dev/null @@ -1,304 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - * Davyd Madeley - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-error.h" -#include "yelp-info-pager.h" -#include "yelp-info-parser.h" -#include "yelp-settings.h" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define INFO_STYLESHEET STYLESHEET_PATH"info2html.xsl" - -#define YELP_INFO_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_INFO_PAGER, YelpInfoPagerPriv)) - -struct _YelpInfoPagerPriv { - GtkTreeStore *tree; - GHashTable *frags_hash; -}; - -typedef struct { - gchar *frag_id; - gchar *frag_name; -} hash_lookup; - -static void info_pager_class_init (YelpInfoPagerClass *klass); -static void info_pager_init (YelpInfoPager *pager); -static void info_pager_dispose (GObject *gobject); - -static xmlDocPtr info_pager_parse (YelpPager *pager); -static gchar ** info_pager_params (YelpPager *pager); - -static const gchar * info_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -static GtkTreeModel * info_pager_get_sections (YelpPager *pager); - -static gboolean tree_hash_id (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - YelpInfoPager *pager); -static gboolean tree_find_id (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - hash_lookup *hash); - -static YelpPagerClass *parent_class; - -GType -yelp_info_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpInfoPagerClass), - NULL, - NULL, - (GClassInitFunc) info_pager_class_init, - NULL, - NULL, - sizeof (YelpInfoPager), - 0, - (GInstanceInitFunc) info_pager_init, - }; - type = g_type_register_static (YELP_TYPE_XSLT_PAGER, - "YelpInfoPager", - &info, 0); - } - return type; -} - -static void -info_pager_class_init (YelpInfoPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = info_pager_dispose; - - pager_class->resolve_frag = info_pager_resolve_frag; - pager_class->get_sections = info_pager_get_sections; - - xslt_class->parse = info_pager_parse; - xslt_class->params = info_pager_params; - - xslt_class->stylesheet = INFO_STYLESHEET; - - g_type_class_add_private (klass, sizeof (YelpInfoPagerPriv)); -} - -static void -info_pager_init (YelpInfoPager *pager) -{ - YelpInfoPagerPriv *priv; - - pager->priv = priv = YELP_INFO_PAGER_GET_PRIVATE (pager); - - /* In this hash, key == value */ - priv->frags_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); -} - -static void -info_pager_dispose (GObject *object) -{ - YelpInfoPager *pager = YELP_INFO_PAGER (object); - - g_object_unref (pager->priv->tree); - g_hash_table_destroy (pager->priv->frags_hash); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -YelpPager * -yelp_info_pager_new (YelpDocInfo *doc_info) -{ - YelpInfoPager *pager; - - g_return_val_if_fail (doc_info != NULL, NULL); - - pager = (YelpInfoPager *) g_object_new (YELP_TYPE_INFO_PAGER, - "document-info", doc_info, - NULL); - - return (YelpPager *) pager; -} - -static xmlDocPtr -info_pager_parse (YelpPager *pager) -{ - YelpDocInfo *doc_info; - gchar *filename; - xmlDocPtr doc = NULL; - GError *error = NULL; - YelpInfoPagerPriv *priv; - - g_return_val_if_fail (YELP_IS_INFO_PAGER (pager), FALSE); - priv = YELP_INFO_PAGER (pager)->priv; - - doc_info = yelp_pager_get_doc_info (pager); - filename = yelp_doc_info_get_filename (doc_info); - - g_object_ref (pager); - - /* DO STUFF HERE */ - /* parse into a GtkTreeStore */ - priv->tree = yelp_info_parser_parse_file (filename); - - if (!priv->tree) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC, - _("The file ‘%s’ could not be parsed. Either the file " - "does not exist, or it is not a well-formed info page."), - filename); - yelp_pager_error (pager, error); - - } else { - - /* create the XML file */ - doc = yelp_info_parser_parse_tree (priv->tree); - - gtk_tree_model_foreach (GTK_TREE_MODEL (priv->tree), - (GtkTreeModelForeachFunc) tree_hash_id, - pager); - } - - g_object_unref (pager); - g_free (filename); - - return doc; -} - -static gchar ** -info_pager_params (YelpPager *pager) -{ - gchar **params; - gint params_i = 0; - gint params_max = 10; - - params = g_new0 (gchar *, params_max); - - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 20; - params = g_renew (gchar *, params, params_max); - } - - params[params_i++] = "stylesheet_path"; - params[params_i++] = g_strdup_printf ("\"file://%s\"", STYLESHEET_PATH); - - params[params_i] = NULL; - - return params; -} - -static const gchar * -info_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - g_return_val_if_fail (YELP_IS_INFO_PAGER (pager), NULL); - if (frag_id) { - gchar *id = g_hash_table_lookup (YELP_INFO_PAGER (pager)->priv->frags_hash, - frag_id); - if (!id) { - hash_lookup *l = g_new0 (hash_lookup, 1); - - l->frag_name = g_strdup (frag_id); - - gtk_tree_model_foreach (GTK_TREE_MODEL (YELP_INFO_PAGER (pager)->priv->tree), - (GtkTreeModelForeachFunc) tree_find_id, - l); - if (l->frag_id) - id = g_hash_table_lookup (YELP_INFO_PAGER (pager)->priv->frags_hash, - l->frag_id); - g_free (l->frag_name); - g_free (l->frag_id); - g_free (l); - } - return id; - } else - return g_hash_table_lookup (YELP_INFO_PAGER (pager)->priv->frags_hash, "1"); -} - -static GtkTreeModel * -info_pager_get_sections (YelpPager *pager) -{ - g_return_val_if_fail (YELP_IS_INFO_PAGER (pager), NULL); - - return GTK_TREE_MODEL (YELP_INFO_PAGER (pager)->priv->tree); -} - -static gboolean -tree_hash_id (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - YelpInfoPager *pager) -{ - YelpInfoPagerPriv *priv; - gchar *id; - - priv = pager->priv; - - gtk_tree_model_get (model, iter, - YELP_PAGER_COLUMN_ID, &id, - -1); - if (id) - g_hash_table_replace (priv->frags_hash, id, id); - - return FALSE; -} - -static gboolean -tree_find_id (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, - hash_lookup *hash) -{ - gchar *title; - gchar *id; - gtk_tree_model_get (model, iter, - YELP_PAGER_COLUMN_ID, &id, - YELP_PAGER_COLUMN_TITLE, &title, - -1); - if (g_str_equal (title, hash->frag_name)) { - hash->frag_id = g_strdup (id); - return TRUE; - } - return FALSE; - -} diff --git a/src/yelp-info-pager.h b/src/yelp-info-pager.h deleted file mode 100644 index 227d1f92..00000000 --- a/src/yelp-info-pager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_INFO_PAGER_H__ -#define __YELP_INFO_PAGER_H__ - -#include - -#include "yelp-pager.h" -#include "yelp-xslt-pager.h" - -#define YELP_TYPE_INFO_PAGER (yelp_info_pager_get_type ()) -#define YELP_INFO_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_INFO_PAGER, YelpInfoPager)) -#define YELP_INFO_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_INFO_PAGER, YelpInfoPagerClass)) -#define YELP_IS_INFO_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_INFO_PAGER)) -#define YELP_IS_INFO_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_INFO_PAGER)) -#define YELP_INFO_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_INFO_PAGER, YelpInfoPagerClass)) - -typedef struct _YelpInfoPager YelpInfoPager; -typedef struct _YelpInfoPagerClass YelpInfoPagerClass; -typedef struct _YelpInfoPagerPriv YelpInfoPagerPriv; - -struct _YelpInfoPager { - YelpXsltPager parent; - - YelpInfoPagerPriv *priv; -}; - -struct _YelpInfoPagerClass { - YelpXsltPagerClass parent_class; -}; - -GType yelp_info_pager_get_type (void); -YelpPager * yelp_info_pager_new (YelpDocInfo *doc_info); - -#endif /* __YELP_INFO_PAGER_H__ */ diff --git a/src/yelp-man-pager.c b/src/yelp-man-pager.c deleted file mode 100644 index a7d7ba71..00000000 --- a/src/yelp-man-pager.c +++ /dev/null @@ -1,476 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-error.h" -#include "yelp-man-pager.h" -#include "yelp-man-parser.h" -#include "yelp-settings.h" -#include "yelp-debug.h" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define MAN_STYLESHEET STYLESHEET_PATH"man2html.xsl" - -#define YELP_MAN_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_MAN_PAGER, YelpManPagerPriv)) - -struct _YelpManPagerPriv { - gpointer unused; -}; - -typedef struct _YelpManSect YelpManSect; -struct _YelpManSect { - gchar *title; - gchar *id; - gchar **sects; - - YelpManSect *parent; - YelpManSect *child; - YelpManSect *prev; - YelpManSect *next; -}; - -static YelpManSect *man_section = NULL; -static GHashTable *man_secthash = NULL; - -static void man_pager_class_init (YelpManPagerClass *klass); -static void man_pager_init (YelpManPager *pager); -static void man_pager_dispose (GObject *gobject); - -static xmlDocPtr man_pager_parse (YelpPager *pager); -static gchar ** man_pager_params (YelpPager *pager); - -static const gchar * man_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -static GtkTreeModel * man_pager_get_sections (YelpPager *pager); -static void man_sections_init (void); -static YelpManSect * man_section_process (xmlNodePtr node, - YelpManSect *parent, - YelpManSect *previous); - -static YelpPagerClass *parent_class; - -typedef struct _YelpLangEncodings YelpLangEncodings; - -struct _YelpLangEncodings { - gchar *language; - gchar *encoding; -}; - -/* http://www.w3.org/International/O-charset-lang.html */ -static const YelpLangEncodings langmap[] = { - { "C", "ISO-8859-1" }, - { "af", "ISO-8859-1" }, - { "ar", "ISO-8859-6" }, - { "bg", "ISO-8859-5" }, - { "be", "ISO-8859-5" }, - { "ca", "ISO-8859-1" }, - { "cs", "ISO-8859-2" }, - { "da", "ISO-8859-1" }, - { "de", "ISO-8859-1" }, - { "el", "ISO-8859-7" }, - { "en", "ISO-8859-1" }, - { "eo", "ISO-8859-3" }, - { "es", "ISO-8859-1" }, - { "et", "ISO-8859-15" }, - { "eu", "ISO-8859-1" }, - { "fi", "ISO-8859-1" }, - { "fo", "ISO-8859-1" }, - { "fr", "ISO-8859-1" }, - { "ga", "ISO-8859-1" }, - { "gd", "ISO-8859-1" }, - { "gl", "ISO-8859-1" }, - { "hu", "ISO-8859-2" }, - { "id", "ISO-8859-1" }, /* is this right */ - { "mt", "ISO-8859-3" }, - { "is", "ISO-8859-1" }, - { "it", "ISO-8859-1" }, - { "iw", "ISO-8859-8" }, - { "ja", "EUC-JP" }, - { "ko", "EUC-KR" }, - { "lt", "ISO-8859-13" }, - { "lv", "ISO-8859-13" }, - { "mk", "ISO-8859-5" }, - { "mt", "ISO-8859-3" }, - { "no", "ISO-8859-1" }, - { "pl", "ISO-8859-2" }, - { "pt_BR", "ISO-8859-1" }, - { "ro", "ISO-8859-2" }, - { "ru", "KOI8-R" }, - { "sl", "ISO-8859-2" }, - { "sr", "ISO-8859-2" }, /* Latin, not cyrillic */ - { "sk", "ISO-8859-2" }, - { "sv", "ISO-8859-1" }, - { "tr", "ISO-8859-9" }, - { "uk", "ISO-8859-5" }, - { "zh_CN", "BIG5" }, - { "zh_TW", "BIG5" }, - { NULL, NULL }, -}; - - -GType -yelp_man_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpManPagerClass), - NULL, - NULL, - (GClassInitFunc) man_pager_class_init, - NULL, - NULL, - sizeof (YelpManPager), - 0, - (GInstanceInitFunc) man_pager_init, - }; - type = g_type_register_static (YELP_TYPE_XSLT_PAGER, - "YelpManPager", - &info, 0); - } - return type; -} - -static void -man_pager_class_init (YelpManPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = man_pager_dispose; - - pager_class->resolve_frag = man_pager_resolve_frag; - pager_class->get_sections = man_pager_get_sections; - - xslt_class->parse = man_pager_parse; - xslt_class->params = man_pager_params; - - xslt_class->stylesheet = MAN_STYLESHEET; - - g_type_class_add_private (klass, sizeof (YelpManPagerPriv)); -} - -static void -man_pager_init (YelpManPager *pager) -{ - pager->priv = YELP_MAN_PAGER_GET_PRIVATE (pager); -} - -static void -man_pager_dispose (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -YelpPager * -yelp_man_pager_new (YelpDocInfo *doc_info) -{ - YelpManPager *pager; - - g_return_val_if_fail (doc_info != NULL, NULL); - - pager = (YelpManPager *) g_object_new (YELP_TYPE_MAN_PAGER, - "document-info", doc_info, - NULL); - - return (YelpPager *) pager; -} - -static xmlDocPtr -man_pager_parse (YelpPager *pager) -{ - YelpDocInfo *doc_info; - gchar *filename; - const gchar *language; - const gchar *encoding; - YelpManParser *parser; - xmlDocPtr doc; - GError *error = NULL; - gint i; - - g_return_val_if_fail (YELP_IS_MAN_PAGER (pager), FALSE); - - doc_info = yelp_pager_get_doc_info (pager); - filename = yelp_doc_info_get_filename (doc_info); - - g_object_ref (pager); - - /* We use the language to determine which encoding the manual - * page is in */ - language = yelp_doc_info_get_language (doc_info); - debug_print (DB_INFO, "The language of the man page is %s\n", language); - - /* default encoding if the language doesn't match below */ - encoding = g_getenv("MAN_ENCODING"); - if (encoding == NULL) - encoding = "ISO-8859-1"; - - if (language != NULL) { - for (i=0; langmap[i].language != NULL; i++) { - if (g_str_equal (language, langmap[i].language)) { - encoding = langmap[i].encoding; - break; - } - } - } - - parser = yelp_man_parser_new (); - doc = yelp_man_parser_parse_file (parser, filename, encoding); - yelp_man_parser_free (parser); - - if (doc == NULL) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC, - _("The file ‘%s’ could not be parsed. Either the file " - "does not exist, or it is formatted incorrectly."), - filename); - yelp_pager_error (pager, error); - } - - g_object_unref (pager); - - return doc; -} - -static gchar ** -man_pager_params (YelpPager *pager) -{ - YelpDocInfo *doc_info; - gchar **params; - gint params_i = 0; - gint params_max = 20; - - gchar *uri, *file; - gchar *c1 = NULL, *c2 = NULL, *mansect = NULL; - - gchar *linktrail = NULL; - - if (man_section == NULL) - man_sections_init (); - - doc_info = yelp_pager_get_doc_info (pager); - uri = yelp_doc_info_get_uri (doc_info, NULL, YELP_URI_TYPE_MAN); - file = strrchr (uri, '/'); - if (file) - file++; - else - file = uri; - c1 = g_strrstr (file, ".bz2"); - if (c1 && strlen (c1) != 4) - c1 = NULL; - - if (!c1) { - c1 = g_strrstr (file, ".gz"); - if (c1 && strlen (c1) != 3) - c1 = NULL; - } - - if (c1) - c2 = g_strrstr_len (file, c1 - file, "."); - else - c2 = g_strrstr (file, "."); - - if (c2) { - if (c1) - mansect = g_strndup (c2 + 1, c1 - c2 - 1); - else - mansect = g_strdup (c2 + 1); - } - - if (mansect != NULL) { - YelpManSect *sectdata = g_hash_table_lookup (man_secthash, mansect); - while (sectdata != NULL) { - if (linktrail) { - gchar *new = g_strdup_printf ("%s|%s|%s", - sectdata->id, - sectdata->title, - linktrail); - g_free (linktrail); - linktrail = new; - } else { - linktrail = g_strdup_printf ("%s|%s", - sectdata->id, - sectdata->title); - } - sectdata = sectdata->parent; - } - } - g_free (mansect); - g_free (uri); - - params = g_new0 (gchar *, params_max); - - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 10; - params = g_renew (gchar *, params, params_max); - } - - if (linktrail) { - params[params_i++] = "linktrail"; - params[params_i++] = g_strdup_printf ("\"%s\"", linktrail); - g_free (linktrail); - } - - params[params_i++] = "yelp.javascript"; - params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js"); - params[params_i++] = "stylesheet_path"; - params[params_i++] = g_strdup_printf ("\"file://%s\"", STYLESHEET_PATH); - - params[params_i] = NULL; - - return params; -} - -static const gchar * -man_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - return "index"; -} - -static GtkTreeModel * -man_pager_get_sections (YelpPager *pager) -{ - return NULL; -} - -static void -man_sections_init (void) -{ - xmlParserCtxtPtr parser; - xmlDocPtr doc; - - man_secthash = g_hash_table_new (g_str_hash, g_str_equal); - - parser = xmlNewParserCtxt (); - doc = xmlCtxtReadFile (parser, DATADIR "/yelp/man.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - man_section = man_section_process (xmlDocGetRootElement (doc), NULL, NULL); - - xmlFreeParserCtxt (parser); - xmlFreeDoc (doc); -} - -static YelpManSect * -man_section_process (xmlNodePtr node, - YelpManSect *parent, - YelpManSect *previous) -{ - YelpManSect *this_sect, *psect; - xmlNodePtr cur, title_node; - xmlChar *title_lang, *title; - int i, j, title_pri; - xmlChar *sect; - - const gchar * const * langs = g_get_language_names (); - - title_node = NULL; - title_lang = NULL; - title_pri = INT_MAX; - for (cur = node->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, BAD_CAST "title")) { - xmlChar *cur_lang = NULL; - int cur_pri = INT_MAX; - cur_lang = xmlNodeGetLang (cur); - if (cur_lang) { - for (j = 0; langs[j]; j++) { - if (g_str_equal (cur_lang, langs[j])) { - cur_pri = j; - break; - } - } - } else { - cur_pri = INT_MAX - 1; - } - if (cur_pri <= title_pri) { - if (title_lang) - xmlFree (title_lang); - title_lang = cur_lang; - title_pri = cur_pri; - title_node = cur; - } else { - if (cur_lang) - xmlFree (cur_lang); - } - } - } - title = xmlNodeGetContent (title_node); - - this_sect = g_new0 (YelpManSect, 1); - this_sect->title = g_strdup ((gchar *) title); - - this_sect->parent = parent; - if (previous != NULL) { - this_sect->prev = previous; - previous->next = this_sect; - } else if (parent != NULL) { - parent->child = this_sect; - } - - this_sect->id = g_strdup ((gchar *) xmlGetProp (node, BAD_CAST "id")); - - sect = xmlGetProp (node, BAD_CAST "sect"); - if (sect) { - this_sect->sects = g_strsplit ((gchar *) sect, " ", 0); - if (this_sect->sects) { - for (i=0; this_sect->sects[i] != NULL; i++) - g_hash_table_insert (man_secthash, this_sect->sects[i], this_sect); - } - } - - psect = NULL; - for (cur = node->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, BAD_CAST "toc")) { - psect = man_section_process (cur, this_sect, psect); - } - } - - if (title_lang) - xmlFree (title_lang); - xmlFree (title); - - return this_sect; -} diff --git a/src/yelp-man-pager.h b/src/yelp-man-pager.h deleted file mode 100644 index 7fa8a655..00000000 --- a/src/yelp-man-pager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_MAN_PAGER_H__ -#define __YELP_MAN_PAGER_H__ - -#include - -#include "yelp-pager.h" -#include "yelp-xslt-pager.h" - -#define YELP_TYPE_MAN_PAGER (yelp_man_pager_get_type ()) -#define YELP_MAN_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_MAN_PAGER, YelpManPager)) -#define YELP_MAN_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_MAN_PAGER, YelpManPagerClass)) -#define YELP_IS_MAN_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_MAN_PAGER)) -#define YELP_IS_MAN_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_MAN_PAGER)) -#define YELP_MAN_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_MAN_PAGER, YelpManPagerClass)) - -typedef struct _YelpManPager YelpManPager; -typedef struct _YelpManPagerClass YelpManPagerClass; -typedef struct _YelpManPagerPriv YelpManPagerPriv; - -struct _YelpManPager { - YelpXsltPager parent; - - YelpManPagerPriv *priv; -}; - -struct _YelpManPagerClass { - YelpXsltPagerClass parent_class; -}; - -GType yelp_man_pager_get_type (void); -YelpPager * yelp_man_pager_new (YelpDocInfo *doc_info); - -#endif /* __YELP_MAN_PAGER_H__ */ diff --git a/src/yelp-pager.c b/src/yelp-pager.c deleted file mode 100644 index ec9eceb7..00000000 --- a/src/yelp-pager.c +++ /dev/null @@ -1,449 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "yelp-pager.h" -#include "yelp-marshal.h" -#include "yelp-debug.h" - -#define YELP_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_PAGER, YelpPagerPriv)) - -struct _YelpPagerPriv { - YelpDocInfo *doc_info; - YelpPagerState state; - - GError *error; - - GHashTable *page_hash; - guint process_id; -}; - -enum { - PROP_0, - PROP_DOCINFO -}; - -enum { - PARSE, - RUN, - PAGE, - FINISH, - CANCEL, - ERROR, - LAST_SIGNAL -}; - -static void pager_class_init (YelpPagerClass *klass); -static void pager_init (YelpPager *pager); -static void pager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void pager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void pager_dispose (GObject *object); - - -static GObjectClass *parent_class; -static gint signals[LAST_SIGNAL] = { 0 }; - -GType -yelp_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpPagerClass), - NULL, - NULL, - (GClassInitFunc) pager_class_init, - NULL, - NULL, - sizeof (YelpPager), - 0, - (GInstanceInitFunc) pager_init, - }; - type = g_type_register_static (G_TYPE_OBJECT, - "YelpPager", - &info, 0); - } - return type; -} - -static void -pager_class_init (YelpPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->set_property = pager_set_property; - object_class->get_property = pager_get_property; - object_class->dispose = pager_dispose; - - g_object_class_install_property - (object_class, - PROP_DOCINFO, - g_param_spec_pointer ("document-info", - _("Document Information"), - _("The YelpDocInfo struct of the document"), - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); - - signals[PARSE] = g_signal_new - ("parse", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, 0, - NULL, NULL, - yelp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[RUN] = g_signal_new - ("start", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, 0, - NULL, NULL, - yelp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[PAGE] = g_signal_new - ("page", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, 0, - NULL, NULL, - yelp_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - signals[FINISH] = g_signal_new - ("finish", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (YelpPagerClass, finish), - NULL, NULL, - yelp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CANCEL] = g_signal_new - ("cancel", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (YelpPagerClass, cancel), - NULL, NULL, - yelp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[ERROR] = g_signal_new - ("error", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (YelpPagerClass, error), - NULL, NULL, - yelp_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_type_class_add_private (klass, sizeof (YelpPagerPriv)); -} - -static void -pager_init (YelpPager *pager) -{ - YelpPagerPriv *priv; - - pager->priv = priv = YELP_PAGER_GET_PRIVATE (pager); - - priv->doc_info = NULL; - priv->state = YELP_PAGER_STATE_NEW; - priv->process_id = 0; - - priv->error = NULL; - priv->page_hash = - g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, /* Use page->page_id directly */ - (GDestroyNotify) yelp_page_free); -} - -static void -pager_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - YelpPager *pager = YELP_PAGER (object); - YelpPagerPriv *priv = pager->priv; - - switch (prop_id) { - case PROP_DOCINFO: - if (priv->doc_info) - yelp_doc_info_unref (priv->doc_info); - priv->doc_info = (YelpDocInfo *) g_value_get_pointer (value); - yelp_doc_info_ref (priv->doc_info); - break; - default: - break; - } -} - -static void -pager_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - YelpPager *pager = YELP_PAGER (object); - - switch (prop_id) { - case PROP_DOCINFO: - g_value_set_pointer (value, pager->priv->doc_info); - break; - default: - break; - } -} - -static void -pager_dispose (GObject *object) -{ - YelpPager *pager = YELP_PAGER (object); - YelpPagerPriv *priv = pager->priv; - - if (priv->doc_info) { - yelp_doc_info_unref (priv->doc_info); - priv->doc_info = NULL; - } - - if (priv->error) { - g_error_free (priv->error); - priv->error = NULL; - } - - if (priv->process_id != 0) { - g_source_remove (priv->process_id); - priv->process_id = 0; - } - - if (priv->page_hash) { - g_hash_table_destroy (priv->page_hash); - priv->page_hash = NULL; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -static gboolean -process_cb (YelpPager *pager) -{ - YelpPagerPriv *priv = pager->priv; - YelpPagerClass *klass = YELP_PAGER_GET_CLASS (pager); - gboolean retval; - - retval = klass->process (pager); - - if (!retval) { - priv->process_id = 0; - } - - return retval; -} - -gboolean -yelp_pager_start (YelpPager *pager) -{ - YelpPagerPriv *priv; - - g_return_val_if_fail (pager != NULL, FALSE); - g_return_val_if_fail (YELP_IS_PAGER (pager), FALSE); - - priv = pager->priv; - g_return_val_if_fail (priv->state == YELP_PAGER_STATE_NEW || - priv->state == YELP_PAGER_STATE_INVALID, - FALSE); - - priv->state = YELP_PAGER_STATE_STARTED; - priv->process_id = gtk_idle_add ((GSourceFunc) process_cb, pager); - - return TRUE; -} - -void -yelp_pager_cancel (YelpPager *pager) -{ - YelpPagerPriv *priv; - - g_return_if_fail (pager != NULL); - g_return_if_fail (YELP_IS_PAGER (pager)); - priv = pager->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - if (priv->process_id != 0) { - g_source_remove (priv->process_id); - priv->process_id = 0; - } - - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - g_signal_emit (pager, signals[CANCEL], 0); -} - -YelpDocInfo * -yelp_pager_get_doc_info (YelpPager *pager) -{ - g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); - - return pager->priv->doc_info; -} - -YelpPagerState -yelp_pager_get_state (YelpPager *pager) -{ - g_return_val_if_fail (pager != NULL, 0); - g_return_val_if_fail (YELP_IS_PAGER (pager), 0); - - return pager->priv->state; -} - -void -yelp_pager_set_state (YelpPager *pager, YelpPagerState state) -{ - g_return_if_fail (pager != NULL); - g_return_if_fail (YELP_IS_PAGER (pager)); - - pager->priv->state = state; -} - -GError * -yelp_pager_get_error (YelpPager *pager) -{ - GError *error; - - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); - - if (pager->priv->error) - error = g_error_copy (pager->priv->error); - else - error = NULL; - - return error; -} - -void -yelp_pager_error (YelpPager *pager, GError *error) -{ - debug_print (DB_FUNCTION, "entering\n"); - - if (pager->priv->error) - g_error_free (pager->priv->error); - pager->priv->error = error; - - yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); - - g_signal_emit (pager, signals[ERROR], 0); -} - -GtkTreeModel * -yelp_pager_get_sections (YelpPager *pager) -{ - g_return_val_if_fail (pager != NULL, NULL); - g_return_val_if_fail (YELP_IS_PAGER (pager), NULL); - - return YELP_PAGER_GET_CLASS (pager)->get_sections (pager); -} - -const gchar * -yelp_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - return YELP_PAGER_GET_CLASS (pager)->resolve_frag (pager, frag_id); -} - -gboolean -yelp_pager_page_contains_frag (YelpPager *pager, - const gchar *page_id, - const gchar *frag_id) -{ - const gchar *frag_page_id = - YELP_PAGER_GET_CLASS (pager)->resolve_frag (pager, frag_id); - - return !strcmp (frag_page_id, page_id); -} - -const YelpPage * -yelp_pager_get_page_from_id (YelpPager *pager, const gchar *page_id) -{ - if (page_id == NULL) - return NULL; - - return (const YelpPage *) g_hash_table_lookup (pager->priv->page_hash, page_id); -} - -const YelpPage * -yelp_pager_get_page (YelpPager *pager, const gchar *frag_id) -{ - YelpPage *page; - const gchar *page_id = - YELP_PAGER_GET_CLASS (pager)->resolve_frag (pager, frag_id); - - if (page_id == NULL) - return NULL; - - page = (YelpPage *) g_hash_table_lookup (pager->priv->page_hash, page_id); - - return (const YelpPage *) page; -} - -void -yelp_pager_add_page (YelpPager *pager, - YelpPage *page) -{ - g_return_if_fail (pager != NULL); - g_return_if_fail (YELP_IS_PAGER (pager)); - - g_return_if_fail (page->page_id != NULL); - - g_hash_table_replace (pager->priv->page_hash, page->page_id, page); -} - -void -yelp_page_free (YelpPage *page) -{ - g_return_if_fail (page != NULL); - - g_free (page->page_id); - g_free (page->title); - g_free (page->contents); - - g_free (page->prev_id); - g_free (page->next_id); - g_free (page->toc_id); - - g_free (page); -} diff --git a/src/yelp-pager.h b/src/yelp-pager.h deleted file mode 100644 index 088270a2..00000000 --- a/src/yelp-pager.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_PAGER_H__ -#define __YELP_PAGER_H__ - -#include -#include - -#define YELP_TYPE_PAGER (yelp_pager_get_type ()) -#define YELP_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_PAGER, YelpPager)) -#define YELP_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_PAGER, YelpPagerClass)) -#define YELP_IS_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_PAGER)) -#define YELP_IS_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_PAGER)) -#define YELP_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_PAGER, YelpPagerClass)) - -typedef struct _YelpPager YelpPager; -typedef struct _YelpPagerClass YelpPagerClass; -typedef struct _YelpPagerPriv YelpPagerPriv; -typedef struct _YelpPage YelpPage; - -typedef enum { - YELP_PAGER_STATE_NEW, - YELP_PAGER_STATE_STARTED, - YELP_PAGER_STATE_PARSING, - YELP_PAGER_STATE_RUNNING, - - YELP_PAGER_STATE_ERROR, - YELP_PAGER_STATE_INVALID, - YELP_PAGER_STATE_FINISHED, - YELP_PAGER_NUM_STATES -} YelpPagerState; - -enum { - YELP_PAGER_COLUMN_ID = 0, - YELP_PAGER_COLUMN_TITLE, - YELP_PAGER_NUM_COLUMNS -}; - -#include "yelp-utils.h" - -struct _YelpPager { - GObject parent; - - YelpPagerPriv *priv; -}; - -struct _YelpPagerClass { - GObjectClass parent_class; - - void (*error) (YelpPager *pager); - void (*cancel) (YelpPager *pager); - void (*finish) (YelpPager *pager); - - /* Virtual Functions */ - gboolean (*process) (YelpPager *pager); - const gchar * (*resolve_frag) (YelpPager *pager, - const gchar *frag_id); - GtkTreeModel * (*get_sections) (YelpPager *pager); -}; - -struct _YelpPage { - gchar *page_id; - gchar *title; - gchar *contents; - - gchar *prev_id; - gchar *next_id; - gchar *toc_id; -}; - -GType yelp_pager_get_type (void); - -gboolean yelp_pager_start (YelpPager *pager); -void yelp_pager_cancel (YelpPager *pager); - -YelpDocInfo * yelp_pager_get_doc_info (YelpPager *pager); - -YelpPagerState yelp_pager_get_state (YelpPager *pager); -void yelp_pager_set_state (YelpPager *pager, - YelpPagerState state); - -GError * yelp_pager_get_error (YelpPager *pager); -void yelp_pager_error (YelpPager *pager, - GError *error); - -GtkTreeModel * yelp_pager_get_sections (YelpPager *pager); - -const gchar * yelp_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -gboolean yelp_pager_page_contains_frag (YelpPager *pager, - const gchar *page_id, - const gchar *frag_id); -const YelpPage * yelp_pager_get_page_from_id (YelpPager *pager, - const gchar *page_id); -const YelpPage * yelp_pager_get_page (YelpPager *pager, - const gchar *frag_id); -void yelp_pager_add_page (YelpPager *pager, - YelpPage *page); -void yelp_page_free (YelpPage *page); - -#endif /* __YELP_PAGER_H__ */ diff --git a/src/yelp-search-pager.c b/src/yelp-search-pager.c deleted file mode 100644 index afa9fd51..00000000 --- a/src/yelp-search-pager.c +++ /dev/null @@ -1,2044 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef ENABLE_BEAGLE -#include -#endif /* ENABLE_BEAGLE */ - -#include "yelp-error.h" -#include "yelp-settings.h" -#include "yelp-search-pager.h" -#include "yelp-utils.h" -#include "yelp-debug.h" - -#define DESKTOP_ENTRY_GROUP "Desktop Entry" -#define KDE_DESKTOP_ENTRY_GROUP "KDE Desktop Entry" - -#define YELP_NAMESPACE "http://www.gnome.org/yelp/ns" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define SEARCH_STYLESHEET STYLESHEET_PATH"search2html.xsl" - -typedef gboolean (*ProcessFunction) (YelpSearchPager *pager); - -typedef struct _SearchContainer SearchContainer; - -#define YELP_SEARCH_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerPriv)) - -#define ONLINE_URL "http://api.gnome.org/yelp/forums?query=%s" - -#define ONLINE_NAME N_("the GNOME Support Forums") - -struct _YelpSearchPagerPriv { - xmlDocPtr search_doc; - xmlNodePtr root; - - xmlParserCtxtPtr parser; - - gboolean cancel; - - xsltStylesheetPtr stylesheet; - xsltTransformContextPtr transformContext; - char *search_terms; - GPtrArray *hits; - int snippet_request_count; - GSList * pending_searches; - - guint search_process_id; - guint slow_search_setup_process_id; - guint slow_search_process_id; - guint xslt_process_id; -}; - -enum { - NOT_SEARCHING = 0, - SEARCH_1, - SEARCH_CHILD, - SEARCH_DOC = 99 -}; - -struct _SearchContainer { - gchar * current_subsection; - gchar * result_subsection; - gchar * doc_title; - gchar * base_path; - gchar * base_filename; - gchar * snippet; - GSList * components; - GHashTable *entities; - gchar ** search_term; - gint required_words; - gint * dup_of; - gboolean * found_terms; - gboolean * stop_word; - gfloat * score_per_word; - gchar * top_element; - gint search_status; - gchar * elem_type; - GSList * elem_stack; - gfloat score; - gfloat snippet_score; - gboolean html; - gchar * sect_name; - gboolean grab_text; - gchar * default_snippet; -}; - -static void search_pager_class_init (YelpSearchPagerClass *klass); -static void search_pager_init (YelpSearchPager *pager); -static void search_pager_dispose (GObject *gobject); - -static void search_pager_error (YelpPager *pager); -static void search_pager_cancel (YelpPager *pager); -static void search_pager_finish (YelpPager *pager); - -gboolean search_pager_process (YelpPager *pager); -void search_pager_cancel (YelpPager *pager); -const gchar * search_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -GtkTreeModel * search_pager_get_sections (YelpPager *pager); - -static gboolean process_xslt (YelpSearchPager *pager); - -static void xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp); -static gboolean search_pager_process_idle (YelpSearchPager *pager); - -static YelpPagerClass *parent_class; - -static void s_startElement (void *data, - const xmlChar *name, - const xmlChar **attrs); -static void s_endElement (void *data, - const xmlChar *name); -static void s_characters (void *data, - const xmlChar *ch, - int len); -static void s_declEntity (void *data, - const xmlChar *name, - int type, - const xmlChar *pID, - const xmlChar *sID, - xmlChar *content); -static xmlEntityPtr s_getEntity (void *data, - const xmlChar *name); -static gboolean slow_search_setup (YelpSearchPager *pager); -static gboolean slow_search_process (YelpSearchPager *pager); -static void search_parse_result (YelpSearchPager *pager, - SearchContainer *c); -static gchar * search_clean_snippet (gchar *snippet, - gchar **terms); -static void search_process_man (YelpSearchPager *pager, - gchar **terms); -static void search_process_info (YelpSearchPager *pager, - gchar **terms); -static void process_man_result (YelpSearchPager *pager, - gchar *result, - gchar **terms); -void process_info_result (YelpSearchPager *pager, - gchar *result, - gchar **terms); -gchar * string_append (gchar *current, - gchar *new, - gchar *suffix); - - -#ifdef ENABLE_BEAGLE -static BeagleClient *beagle_client; -#endif /* ENABLE_BEAGLE */ -static char const * const * langs; - - -GType -yelp_search_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpSearchPagerClass), - NULL, - NULL, - (GClassInitFunc) search_pager_class_init, - NULL, - NULL, - sizeof (YelpSearchPager), - 0, - (GInstanceInitFunc) search_pager_init, - }; - type = g_type_register_static (YELP_TYPE_PAGER, - "YelpSearchPager", - &info, 0); - } - return type; -} - -static void -search_pager_class_init (YelpSearchPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - -#ifdef ENABLE_BEAGLE - if (beagle_util_daemon_is_running()) { - beagle_client = beagle_client_new (NULL); - debug_print (DB_DEBUG, "client: %p\n", beagle_client); - } else { - beagle_client = NULL; - } -#endif /* ENABLE_BEAGLE */ - - langs = g_get_language_names (); - - object_class->dispose = search_pager_dispose; - - pager_class->error = search_pager_error; - pager_class->cancel = search_pager_cancel; - pager_class->finish = search_pager_finish; - - pager_class->process = search_pager_process; - pager_class->cancel = search_pager_cancel; - pager_class->resolve_frag = search_pager_resolve_frag; - pager_class->get_sections = search_pager_get_sections; - - g_type_class_add_private (klass, sizeof (YelpSearchPagerPriv)); -} - -static void -search_pager_init (YelpSearchPager *pager) -{ - YelpSearchPagerPriv *priv; - - pager->priv = priv = YELP_SEARCH_PAGER_GET_PRIVATE (pager); - - priv->parser = xmlNewParserCtxt (); - - priv->cancel = 0; - priv->search_terms = NULL; - priv->hits = NULL; - priv->snippet_request_count = 0; - priv->search_process_id = 0; - priv->slow_search_setup_process_id = 0; - priv->slow_search_process_id = 0; - priv->xslt_process_id = 0; - -} - -static void -search_pager_dispose (GObject *object) -{ - YelpSearchPager *pager = YELP_SEARCH_PAGER (object); - YelpSearchPagerPriv *priv = pager->priv; - - if (priv->search_process_id != 0) { - g_source_remove (priv->search_process_id); - priv->search_process_id = 0; - } - - if (priv->xslt_process_id != 0) { - g_source_remove (priv->xslt_process_id); - priv->xslt_process_id = 0; - } - - if (priv->slow_search_process_id != 0) { - g_source_remove (priv->slow_search_process_id); - priv->slow_search_process_id = 0; - } - - if (priv->slow_search_setup_process_id != 0) { - g_source_remove (priv->slow_search_setup_process_id); - priv->slow_search_setup_process_id = 0; - } - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -static gboolean -check_hex (char check) -{ - if (check >= '0' && check <= '9') - return TRUE; - if (check >= 'a' && check <= 'f') - return TRUE; - if (check >= 'A' && check <= 'F') - return TRUE; - return FALSE; -} - -static int -conv_hex (char conv) -{ - if (conv >= '0' && conv <= '9') - return conv - '0'; - if (conv >= 'a' && conv <= 'f') - return conv - 'a' + 10; - if (conv >= 'A' && conv <= 'F') - return conv - 'A' + 10; - return 0; -} - -static char * -decode_uri (const char *uri) -{ - char *decoded = g_strdup (uri); - char *iterator; - - for (iterator = decoded; *iterator; iterator ++) { - if (*iterator == '%' && check_hex (iterator[1]) && check_hex(iterator[2])) { - *iterator = conv_hex (iterator[1]) * 16 + conv_hex (iterator[2]); - memmove (iterator + 1, iterator + 3, strlen (iterator + 3)); - } - } - - return decoded; -} - -YelpSearchPager * -yelp_search_pager_get (YelpDocInfo *doc_info) -{ - static GHashTable *search_hash; - YelpSearchPager *search_pager; - char *uri; - char *search_terms; - - if (search_hash == NULL) { - search_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, g_object_unref); - } - - uri = yelp_doc_info_get_uri (doc_info, NULL, YELP_URI_TYPE_SEARCH); - search_terms = decode_uri (uri + strlen ("x-yelp-search:")); - g_free (uri); - - search_pager = g_hash_table_lookup (search_hash, search_terms); - - if (search_pager == NULL) { - search_pager = (YelpSearchPager *) g_object_new (YELP_TYPE_SEARCH_PAGER, - "document-info", doc_info, - NULL); - search_pager->priv->search_terms = search_terms; - g_hash_table_insert (search_hash, search_terms, search_pager); - yelp_pager_start (YELP_PAGER (search_pager)); - } else { - g_free (search_terms); - } - - g_object_ref (search_pager); - return search_pager; -} - -/******************************************************************************/ - -static void -search_pager_error (YelpPager *pager) -{ - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); -} - -static void -search_pager_cancel (YelpPager *pager) -{ - YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - priv->cancel = TRUE; -} - -static void -search_pager_finish (YelpPager *pager) -{ - YelpSearchPager *spager = YELP_SEARCH_PAGER (pager); - YelpSearchPagerPriv *priv = spager->priv; - - g_return_if_fail (priv->search_process_id == 0); - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISHED); -} - -gboolean -search_pager_process (YelpPager *pager) -{ - YelpSearchPagerPriv *priv = (YELP_SEARCH_PAGER (pager))->priv; - debug_print (DB_FUNCTION, "entering\n"); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_PARSING); - g_signal_emit_by_name (pager, "parse"); - - /* Set it running */ - yelp_pager_set_state (pager, YELP_PAGER_STATE_RUNNING); - g_signal_emit_by_name (pager, "start"); - - priv->search_process_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) search_pager_process_idle, - pager, NULL); - return FALSE; -} - -const gchar * -search_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - if (!frag_id) - return "results"; - else - return frag_id; -} - -GtkTreeModel * -search_pager_get_sections (YelpPager *pager) -{ - return NULL; -} - -/******************************************************************************/ -#ifdef ENABLE_BEAGLE -static void -check_finished (YelpSearchPager *pager) -{ - YelpSearchPagerPriv *priv = pager->priv; - - if (priv->snippet_request_count == 0 && - priv->xslt_process_id == 0) { - priv->xslt_process_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) process_xslt, - pager, NULL); - } -} - -typedef struct -{ - YelpSearchPager *pager; - xmlNode *node; -} SnippetLocation; - -static void snippet_closed (BeagleSnippetRequest *request, - SnippetLocation *snippet_location); -static void snippet_response (BeagleSnippetRequest *request, - BeagleSnippetResponse *response, - SnippetLocation *snippet_location); -static void snippet_error (BeagleSnippetRequest *request, - GError *error, - SnippetLocation *snippet_location); - -static void -snippet_closed (BeagleSnippetRequest *request, SnippetLocation *snippet_location) -{ - YelpSearchPager *pager = snippet_location->pager; - - debug_print (DB_FUNCTION, "entering\n"); - - pager->priv->snippet_request_count --; - check_finished (pager); - - g_signal_handlers_disconnect_by_func (request, - G_CALLBACK (snippet_response), - snippet_location); - g_signal_handlers_disconnect_by_func (request, - G_CALLBACK (snippet_error), - snippet_location); - g_signal_handlers_disconnect_by_func (request, - G_CALLBACK (snippet_closed), - snippet_location); - - g_free (snippet_location); - g_object_unref (request); -} - -static void -snippet_response (BeagleSnippetRequest *request, BeagleSnippetResponse *response, SnippetLocation *snippet_location) -{ - xmlDoc *snippet_doc; - xmlNode *node; - char *xmldoc; - - const char *xml = beagle_snippet_response_get_snippet (response); - - if (xml == NULL) { - debug_print (DB_DEBUG, "snippet_response empty\n"); - return; - } - debug_print (DB_DEBUG, "snippet_response: %s\n", xml); - - xmldoc = g_strdup_printf ("%s", xml); - snippet_doc = xmlParseDoc (BAD_CAST xmldoc); - g_free (xmldoc); - if (!snippet_doc) - return; - node = xmlDocGetRootElement (snippet_doc); - xmlUnlinkNode (node); - xmlAddChild (snippet_location->node, node); - xmlFreeDoc (snippet_doc); -} - -static void -snippet_error (BeagleSnippetRequest *request, GError *error, SnippetLocation *snippet_location) -{ - debug_print (DB_FUNCTION, "entering\n"); -} - - -static void -hits_added_cb (BeagleQuery *query, BeagleHitsAddedResponse *response, YelpSearchPager *pager) -{ - YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv; - - GSList *hits, *l; - - debug_print (DB_FUNCTION, "hits_added\n"); - - hits = beagle_hits_added_response_get_hits (response); - - for (l = hits; l; l = l->next) { - BeagleHit *hit = l->data; - beagle_hit_ref (hit); - debug_print (DB_DEBUG, "%f\n", beagle_hit_get_score (hit)); - g_ptr_array_add (priv->hits, hit); - } -} - -static gboolean -check_lang (const char *lang) { - int i; - for (i = 0; langs[i]; i++) { - if (!strncmp (lang, langs[i], 2)) { - debug_print (DB_DEBUG, "%s preferred\n", lang); - return TRUE; - } - } - debug_print (DB_DEBUG, "%s not preferred\n", lang); - return FALSE; -} - -static gint -compare_hits (gconstpointer a, - gconstpointer b) -{ - BeagleHit **hita = (BeagleHit **) a; - BeagleHit **hitb = (BeagleHit **) b; - const char *langa, *langb; - gboolean a_preferred = TRUE, b_preferred = TRUE; - - if (beagle_hit_get_one_property (*hita, "fixme:language", &langa)) - a_preferred = check_lang(langa); - if (beagle_hit_get_one_property (*hitb, "fixme:language", &langb)) - b_preferred = check_lang(langb); - - if (a_preferred != b_preferred) { - if (a_preferred) - return -1; - if (b_preferred) - return 1; - } - - double scorea = beagle_hit_get_score (*hita); - double scoreb = beagle_hit_get_score (*hitb); - - /* The values here are inverted so that it's a descending sort. */ - if (scorea < scoreb) - return 1; - if (scoreb < scorea) - return -1; - return 0; -} - -static void -finished_cb (BeagleQuery *query, - BeagleFinishedResponse *response, - YelpSearchPager *pager) -{ - int i; - YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - g_ptr_array_sort (priv->hits, compare_hits); - - for (i = 0; i < 10 && i < priv->hits->len; i++) { - BeagleHit *hit = g_ptr_array_index (priv->hits, i); - xmlNode *child; - /* static float score_fake = 0; */ - char *score; - const char *property; - BeagleSnippetRequest *request; - SnippetLocation *snippet_location; - - child = xmlNewTextChild (priv->root, NULL, BAD_CAST "result", NULL); - xmlSetProp (child, BAD_CAST "uri", BAD_CAST beagle_hit_get_uri (hit)); - xmlSetProp (child, BAD_CAST "parent_uri", - BAD_CAST beagle_hit_get_parent_uri (hit)); - if (beagle_hit_get_one_property (hit, "dc:title", &property)) - xmlSetProp (child, BAD_CAST "title", BAD_CAST property); - if (beagle_hit_get_one_property (hit, "fixme:base_title", &property)) - xmlSetProp (child, BAD_CAST "base_title", BAD_CAST property); - - score = g_strdup_printf ("%f", beagle_hit_get_score (hit)); - debug_print (DB_DEBUG, "%f\n", beagle_hit_get_score (hit)); - /*xmlSetProp (child, BAD_CAST "score", BAD_CAST score);*/ - g_free (score); - - priv->snippet_request_count ++; - - snippet_location = g_new (SnippetLocation, 1); - - snippet_location->pager = pager; - snippet_location->node = child; - - request = beagle_snippet_request_new (); - beagle_snippet_request_set_hit (request, hit); - beagle_snippet_request_set_query (request, query); - - g_signal_connect (request, "response", - G_CALLBACK (snippet_response), snippet_location); - g_signal_connect (request, "error", - G_CALLBACK (snippet_error), snippet_location); - g_signal_connect (request, "closed", - G_CALLBACK (snippet_closed), snippet_location); - - debug_print (DB_DEBUG, "Requesting snippet\n"); - beagle_client_send_request_async (beagle_client, BEAGLE_REQUEST (request), - NULL); - } - - g_signal_handlers_disconnect_by_func (query, - G_CALLBACK (hits_added_cb), - pager); - g_signal_handlers_disconnect_by_func (query, - G_CALLBACK (finished_cb), - pager); - g_object_unref (query); - - g_ptr_array_foreach (priv->hits, (GFunc) beagle_hit_unref, NULL); - g_ptr_array_free (priv->hits, TRUE); - priv->hits = NULL; - - check_finished (pager); -} -#endif /* ENABLE_BEAGLE */ - -static gboolean -search_pager_process_idle (YelpSearchPager *pager) -{ -#ifdef ENABLE_BEAGLE - BeagleQuery *query; - GError *error = NULL; -#endif /* ENABLE_BEAGLE */ - YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv; - - priv->search_doc = xmlNewDoc (BAD_CAST "1.0"); - priv->root = xmlNewNode (NULL, BAD_CAST "search"); - xmlSetProp (priv->root, BAD_CAST "title", BAD_CAST priv->search_terms); - xmlDocSetRootElement (priv->search_doc, priv->root); - -#ifdef ENABLE_BEAGLE - if (beagle_client != NULL) { - query = beagle_query_new (); - - beagle_query_set_max_hits (query, 10000); - beagle_query_add_text (query, priv->search_terms); - beagle_query_add_source (query, "documentation"); - - priv->hits = g_ptr_array_new (); - - g_signal_connect (query, "hits-added", - G_CALLBACK (hits_added_cb), - pager); - - g_signal_connect (query, "finished", - G_CALLBACK (finished_cb), - pager); - - beagle_client_send_request_async (beagle_client, BEAGLE_REQUEST (query), &error); - - if (error) { - debug_print (DB_DEBUG, "error: %s\n", error->message); - } - - g_clear_error (&error); - } else { - g_warning ("beagled not running, using basic search support."); - } -#endif /* ENABLE_BEAGLE */ - -#ifdef ENABLE_BEAGLE - if (beagle_client == NULL) { -#endif - g_return_val_if_fail (priv->slow_search_setup_process_id == 0, FALSE); - - priv->slow_search_setup_process_id = - g_idle_add ((GSourceFunc) slow_search_setup, - pager); -#ifdef ENABLE_BEAGLE - } -#endif - - /* returning false removes this idle function from the main loop; - * we also set our search process id to zero */ - priv->search_process_id = 0; - return FALSE; -} - -static gboolean -process_xslt (YelpSearchPager *pager) -{ - GError *error = NULL; - xmlDocPtr outdoc = NULL; - YelpSearchPagerPriv *priv = pager->priv; - gchar **params; - gint params_i = 0; - gint params_max = 12; - GtkIconInfo *info; - GtkIconTheme *theme = (GtkIconTheme *) yelp_settings_get_icon_theme (); - xmlXPathContextPtr results_xpath_ctx = NULL; - xmlXPathObjectPtr results_xpath = NULL; - int number_of_results; - gchar *title = NULL, *text = NULL; - gchar *tmp = NULL, *check = NULL; - gchar **split = NULL; - xmlNodePtr online = NULL; - - d (xmlDocFormatDump(stdout, priv->search_doc, 1)); - - priv->stylesheet = xsltParseStylesheetFile (BAD_CAST SEARCH_STYLESHEET); - if (!priv->stylesheet) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC, - _("Your search could not be processed. The " - "file ‘%s’ is either missing or is not a valid XSLT " - "stylesheet."), - SEARCH_STYLESHEET); - yelp_pager_error (YELP_PAGER (pager), error); - goto done; - } - - priv->transformContext = xsltNewTransformContext (priv->stylesheet, - priv->search_doc); - priv->transformContext->_private = pager; - xsltRegisterExtElement (priv->transformContext, - BAD_CAST "document", - BAD_CAST YELP_NAMESPACE, - (xsltTransformFunction) xslt_yelp_document); - - params = g_new0 (gchar *, params_max); - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 14) >= params_max - 1) { - params_max += 14; - params = g_renew (gchar *, params, params_max); - } - - info = gtk_icon_theme_lookup_icon (theme, "yelp-icon-big", 192, 0); - if (info) { - params[params_i++] = "help_icon"; - params[params_i++] = g_strdup_printf ("\"%s\"", - gtk_icon_info_get_filename (info)); - params[params_i++] = "help_icon_size"; - params[params_i++] = g_strdup_printf ("%i", - gtk_icon_info_get_base_size (info)); - gtk_icon_info_free (info); - } - - params[params_i++] = "yelp.javascript"; - params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js"); - params[params_i++] = "yelp.topimage"; - params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/icons/help-title.png"); - - params[params_i++] = NULL; - - results_xpath_ctx = xmlXPathNewContext(priv->search_doc); - results_xpath = xmlXPathEvalExpression(BAD_CAST "/search/result", results_xpath_ctx); - if (results_xpath && results_xpath->nodesetval && results_xpath->nodesetval->nodeNr) { - number_of_results = results_xpath->nodesetval->nodeNr; - } else { - number_of_results = 0; - } - xmlXPathFreeObject(results_xpath); - xmlXPathFreeContext(results_xpath_ctx); - if (number_of_results == 0) { - title = g_strdup_printf( _("No results for \"%s\""), priv->search_terms); - text = g_strdup(_("Try using different words to describe the problem " - "you're having or the topic you want help with.")); - } else { - title = g_strdup_printf( _("Search results for \"%s\""), priv->search_terms); - } - xmlNewTextChild (priv->root, NULL, BAD_CAST "title", BAD_CAST title); - g_free(title); - - if (text) { - xmlNewTextChild (priv->root, NULL, BAD_CAST "text", BAD_CAST text); - g_free(text); - } - - check = g_strdup_printf (ONLINE_URL, priv->search_terms); - - /* TRANSLATORS: Please don't do anything funny with the - * format arguement. It isn't really going through a printf - * The %s is used to indicate where the name of the site (linked) - * should be. This is done in the XSLT - */ - tmp = g_strdup (_("Repeat the search online at %s")); - split = g_strsplit (tmp, "%s", 2); - - online = xmlNewTextChild (priv->root, NULL, BAD_CAST "online", BAD_CAST split[0]); - g_free (tmp); - xmlNewProp (online, BAD_CAST "name", - BAD_CAST ONLINE_NAME); - xmlNewProp (online, BAD_CAST "href", - BAD_CAST check); - g_free (check); - xmlNewTextChild (priv->root, NULL, BAD_CAST "online1", BAD_CAST split[1]); - - outdoc = xsltApplyStylesheetUser (priv->stylesheet, - priv->search_doc, - (const gchar **)params, NULL, NULL, - priv->transformContext); - /* Don't do this */ - /* g_signal_emit_by_name (pager, "finish");*/ - - done: - for (params_i = 0; params[params_i] != NULL; params_i++) - if (params_i % 2 == 1) - g_free ((gchar *) params[params_i]); - if (outdoc) - xmlFreeDoc (outdoc); - if (priv->search_doc) { - xmlFreeDoc (priv->search_doc); - priv->search_doc = NULL; - } - if (priv->stylesheet) { - xsltFreeStylesheet (priv->stylesheet); - priv->stylesheet = NULL; - } - if (priv->transformContext) { - xsltFreeTransformContext (priv->transformContext); - priv->transformContext = NULL; - } - - g_signal_emit_by_name (pager, "finish"); - - /* returning false removes this idle function from the main loop; - * we also set our xslt process id to zero to indicate it has been - * removed */ - priv->xslt_process_id = 0; - return FALSE; -} - -static void -xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp) -{ - GError *error = NULL; - YelpPage *page; - xmlChar *page_id = NULL; - xmlChar *page_title = NULL; - xmlChar *page_buf; - gint buf_size; - YelpPager *pager; - xsltStylesheetPtr style = NULL; - const char *old_outfile; - xmlDocPtr new_doc = NULL; - xmlDocPtr old_doc; - xmlNodePtr old_insert; - xmlNodePtr cur; - - if (!ctxt || !node || !inst || !comp) - return; - - pager = (YelpPager *) ctxt->_private; - - page_id = xsltEvalAttrValueTemplate (ctxt, inst, - (const xmlChar *) "href", - NULL); - if (page_id == NULL) { - xsltTransformError (ctxt, NULL, inst, - _("No href attribute found on yelp:document")); - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - - old_outfile = ctxt->outputFile; - old_doc = ctxt->output; - old_insert = ctxt->insert; - ctxt->outputFile = (const char *) page_id; - - style = xsltNewStylesheet (); - if (style == NULL) { - xsltTransformError (ctxt, NULL, inst, - _("Out of memory")); - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - - style->omitXmlDeclaration = TRUE; - - new_doc = xmlNewDoc (BAD_CAST "1.0"); - new_doc->charset = XML_CHAR_ENCODING_UTF8; - new_doc->dict = ctxt->dict; - xmlDictReference (new_doc->dict); - - ctxt->output = new_doc; - ctxt->insert = (xmlNodePtr) new_doc; - - xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL); - - xsltSaveResultToString (&page_buf, &buf_size, new_doc, style); - - ctxt->outputFile = old_outfile; - ctxt->output = old_doc; - ctxt->insert = old_insert; - - for (cur = node->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, BAD_CAST "title")) { - page_title = xmlNodeGetContent (cur); - break; - } - } - - page = g_new0 (YelpPage, 1); - - if (page_id) { - page->page_id = g_strdup ((gchar *) page_id); - xmlFree (page_id); - } - if (page_title) { - page->title = g_strdup ((gchar *) page_title); - xmlFree (page_title); - } else { - page->title = g_strdup (_("Help Contents")); - } - page->contents = (gchar *) page_buf; - - cur = xmlDocGetRootElement (new_doc); - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "head")) { - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "link")) { - xmlChar *rel = xmlGetProp (cur, BAD_CAST "rel"); - - if (!xmlStrcmp (rel, (xmlChar *) "Previous")) - page->prev_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "Next")) - page->next_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "Top")) - page->toc_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - - xmlFree (rel); - } - } - break; - } - } - - yelp_pager_add_page (pager, page); - g_signal_emit_by_name (pager, "page", page->page_id); - - done: - if (new_doc) - xmlFreeDoc (new_doc); - if (style) - xsltFreeStylesheet (style); -} - -static gboolean sk_docomf = FALSE; -static GSList *omf_pending = NULL; - -static void -sk_startElement (void *empty, const xmlChar *name, - const xmlChar **attrs) -{ - if (xmlStrEqual((const xmlChar*) name, BAD_CAST "docomf")) - sk_docomf = TRUE; -} - -static void -sk_endElement (void *empty, const xmlChar *name) -{ - if (xmlStrEqual((const xmlChar*) name, BAD_CAST "docomf")) - sk_docomf = FALSE; -} - -static void -sk_characters (void *empty, const xmlChar *ch, - int len) -{ - gchar *omf; - - if (sk_docomf) { - omf = g_strndup ((gchar *) ch, len); - omf_pending = g_slist_prepend (omf_pending, omf); - } -} - -void s_startElement(void *data, - const xmlChar * name, - const xmlChar ** attrs) -{ - SearchContainer *c = (SearchContainer *) data; - - if (g_str_equal (name, "xi:include") || g_str_equal (name, "include")) { - gint i=0; - while (attrs[i]) { - if (g_str_equal (attrs[i], "href")) { - - c->components = g_slist_append (c->components, - g_strconcat (c->base_path, - "/", - attrs[i+1], - NULL)); - break; - } - i+=2; - } - } - - if (attrs) { - gint i=0; - while (attrs[i]) { - if (g_str_equal (attrs[i], "id")) { - g_free (c->current_subsection); - c->current_subsection = g_strdup ((gchar *) attrs[i+1]); - } - i+=2; - } - } - /* Do we need to grab the title of the document? - * used in snippets when displaying results from an indexterm etc. - */ - if (c->search_status != NOT_SEARCHING && g_str_equal (name, "title")) { - c->grab_text = TRUE; - } - - /* Are we allowed to search this element? */ - if (c->search_status == NOT_SEARCHING) { - if (c->html && g_str_equal (name, "html")) { - c->search_status = SEARCH_DOC; - return; - } - - if (g_str_equal (name, "title")) { - c->search_status = SEARCH_1; - } - else if (g_str_equal (name, "indexterm")) - c->search_status = SEARCH_1; - else if (g_str_equal (name, "sect1") || - g_str_equal (name, "section") || - g_str_equal (name, "chapter") || - g_str_equal (name, "body")) - c->search_status = SEARCH_DOC; - } else if (c->search_status == SEARCH_1) { - c->search_status = SEARCH_CHILD; - } - - if (c->elem_type) { - c->elem_stack = g_slist_prepend (c->elem_stack, - g_strdup (c->elem_type)); - g_free (c->elem_type); - } - - c->elem_type = g_strdup ((gchar *) name); - - return; -} - -void s_endElement(void * data, - const xmlChar * name) -{ - SearchContainer *c = (SearchContainer *) data; - - if (c->search_status == SEARCH_CHILD) { - c->search_status = SEARCH_1; - } else if (c->search_status == SEARCH_1) { - c->search_status = NOT_SEARCHING; - } - - g_free (c->elem_type); - c->elem_type = NULL; - - if (c->elem_stack) { - GSList *top = c->elem_stack; - c->elem_type = g_strdup ((gchar *) top->data); - c->elem_stack = g_slist_delete_link (c->elem_stack, top); - } - c->grab_text = FALSE; - return; -} - -void s_characters(void * data, - const xmlChar * ch, - int len) -{ - SearchContainer *c = (SearchContainer *) data; - if (c->grab_text) { - g_free (c->sect_name); - c->sect_name = g_strndup ((gchar *) ch, len); - } - - /* Sometimes html docs don't trigger the "startElement" method - * I don't know why. Instead, we just search the entire - * html file, hoping to find something. - */ - if (c->html && c->search_status != SEARCH_DOC) - c->search_status = SEARCH_DOC; - if (c->search_status != NOT_SEARCHING) { - gchar *tmp = g_utf8_casefold ((gchar *) ch, len); - gint i = 0; - gchar *s_term = c->search_term[i]; - while (s_term && c->score_per_word[i] < 1.0) { - if (c->stop_word[i] || c->score_per_word[c->dup_of[i]] == 1.0) { - i++; - s_term = c->search_term[i]; - continue; - } - - gchar *location = strstr (tmp, s_term); - if (location) { - gchar before = *(location-1); - gchar after = *(location+strlen(s_term)); - gfloat local_score = 0.0; - gboolean use_text = TRUE; - if (location == tmp) - before = ' '; - if (strlen(location) == strlen(s_term)) - after = ' '; - - if ((g_ascii_ispunct (before) || g_ascii_isspace (before)) - && (g_ascii_ispunct (after) || g_ascii_isspace (after))) { - if (!c->elem_type) { - /* Stupid HTML. Treat like its a normal tag */ - local_score = 0.1; - } else if (g_str_equal(c->elem_type, "primary")) { - local_score = 1.0; - use_text = FALSE; - } else if (g_str_equal (c->elem_type, "secondary")) { - local_score = 0.9; - use_text = FALSE; - } else if (g_str_equal (c->elem_type, "title") || - g_str_equal (c->elem_type, "titleabbrev")) { - local_score = 0.8; - } else { - local_score = 0.1; - } - c->score += local_score; - c->found_terms[c->dup_of[i]] = TRUE; - if (local_score > c->snippet_score) { - g_free (c->snippet); - if (use_text) { - c->snippet = g_strndup (g_utf8_casefold ((gchar *) ch, - len), - len); - } else { - c->snippet = g_strdup (c->sect_name); - } - c->result_subsection = g_strdup (c->current_subsection); - c->snippet_score = local_score; - c->score_per_word[c->dup_of[i]] = local_score; - } - } - } - i++; - s_term = c->search_term[i]; - } - g_free (tmp); - } - return; -} - -void s_declEntity (void *data, const xmlChar *name, int type, - const xmlChar *pID, const xmlChar *sID, - xmlChar *content) -{ - SearchContainer *c = (SearchContainer *) data; - if (type == 2) { - g_hash_table_insert (c->entities, - g_strdup ((gchar *) name), - g_strdup ((gchar *) sID)); - - } - return; -} - -xmlEntityPtr s_getEntity (void *data, const xmlChar *name) -{ - SearchContainer *c = (SearchContainer *) data; - xmlEntityPtr t = xmlGetPredefinedEntity(name); - - if (!t) { - gchar * lookup = g_hash_table_lookup (c->entities, name); - if (lookup) { - c->components = g_slist_append (c->components, - g_strconcat (c->base_path, - "/", - lookup, NULL)); - } - } - - return t; - -} - - - - - -static xmlSAXHandler handlers = { - NULL, NULL, NULL, NULL, NULL, - s_getEntity, - s_declEntity, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - s_startElement, s_endElement, NULL, s_characters, - NULL, NULL, NULL, NULL, NULL, NULL -}; - - -/* Parse the omfs and build the list of files to be searched */ - -/* A common bit of code used below. Chucked in a function for easy */ -gchar * -string_append (gchar *current, gchar *new, gchar *suffix) -{ - gchar *ret; - - if (suffix) { - ret = g_strconcat (current, ":", new, suffix, NULL); - } else { - ret = g_strconcat (current, ":", new, NULL); - } - g_free (current); - return ret; -} - -static gint -build_lists (gchar *search_terms, gchar ***terms, gint **dups, - gboolean ** stops, gint *req) -{ - gchar *ignore_words, *common_prefixes, *common_suffixes; - gchar **prefixes, **suffixes, **ignore; - gchar **list_copy; - gchar **iter, **iter1 = NULL; - gchar *term_str = NULL; - gchar *dup_str = NULL; - gint n_terms = 0, i=-1; - gint orig_term = 0; - gint non_stop = 0; - - - /* Translators: Do not translate this list exactly. These are - * colon-separated words that aren't useful for choosing search - * results; they will be different for each language. Include - * pronouns, articles, very common verbs and prepositions, - * words from question structures like "tell me about" and - * "how do I", and words for functional states like "not", - * "work", and "broken". - */ - ignore_words = g_strdup (_("a:about:an:are:as:at:be:broke:broken:by" - ":can:can't:dialog:dialogue:do:doesn't" - ":doesnt:don't:dont:explain:for:from:get" - ":gets:got:make:makes:not:when:has" - ":have:help:how:i:in:is:it:item:me:my:of" - ":on:or:tell:that:the:thing:this:to:what" - ":where:who:will:with:won't:wont:why:work" - ":working:works")); - /* Translators: This is a list of common prefixes for words. - * Do not translate this directly. Instead, use a colon - * seperated list of word-starts. In English, an example - * is re-. If there is none, please use the term NULL - * If there is only one, please put a colon after. - * E.g. if the common prefix is re then the string would be - * "re:" - */ - common_prefixes = g_strdup (_("re")); - - /* Translators: This is a list of (guess what?) common suffixes - * to words. Things that may be put at ends of words to slightly - * alter their meaning (like -ing and -s in English). This is a - * colon seperated list (I like colons). If there are none, - * please use the strig NULL. If there is only 1, please - * add a colon at the end of the list - */ - common_suffixes = g_strdup (_("ers:er:ing:es:s:'s")); - - ignore = g_strsplit (ignore_words, ":", -1); - if (strchr (common_prefixes, ':')) { - prefixes = g_strsplit (common_prefixes, ":", -1); - } else { - prefixes = NULL; - } - if (strchr (common_suffixes, ':')) { - suffixes = g_strsplit (common_suffixes, ":", -1); - } else { - suffixes = NULL; - } - search_terms = g_strdelimit (search_terms, ":", ' '); - list_copy = g_strsplit (g_utf8_casefold (g_strstrip ( - search_terms), -1), - " ", -1); - - for (iter = list_copy; *iter != NULL; iter++) { - gboolean ignoring = FALSE; - if (strlen (*iter) == 0) { - continue; - } - if (g_str_has_suffix (*iter, "?")) { - gchar *tmp; - tmp = g_strndup (*iter, strlen (*iter) - 1); - g_free (*iter); - *iter = g_strdup (tmp); - g_free (tmp); - } - if (!term_str) { - term_str = g_strdup (*iter); - } else { - term_str = string_append (term_str, *iter, NULL); - } - - for (iter1 = ignore; *iter1; iter1++) { - if (g_str_equal (*iter, *iter1)) { - ignoring = TRUE; - break; - } - } - if (ignoring) { - if (!dup_str) { - dup_str = g_strdup ("I"); - } else { - dup_str = string_append (dup_str, "I", NULL); - } - continue; - } - non_stop++; - - if (!dup_str) { - dup_str = g_strdup ("O"); - } else { - dup_str = string_append (dup_str, "O", NULL); - } - (*req)++; - if (prefixes) { - for (iter1 = prefixes; *iter1; iter1++) { - if (g_str_has_prefix (*iter, *iter1)) { - term_str = string_append (term_str, - (*iter+strlen(*iter1)), NULL); - } else { - term_str = string_append (term_str, *iter, *iter1); - } - dup_str = string_append (dup_str, "D", NULL); - } - } - if (suffixes) { - for (iter1 = suffixes; *iter1; iter1++) { - if (g_str_has_suffix (*iter, *iter1)) { - gchar *tmp; - tmp = g_strndup (*iter, (strlen(*iter)-strlen(*iter1))); - term_str = string_append (term_str, tmp, NULL); - g_free (tmp); - } else { - term_str = string_append (term_str, *iter, *iter1); - } - dup_str = string_append (dup_str, "D", NULL); - } - } - } - g_strfreev (list_copy); - *terms = g_strsplit (term_str, ":", -1); - n_terms = g_strv_length (*terms); - (*dups) = g_new0 (gint, n_terms); - (*stops) = g_new0 (gboolean, n_terms); - list_copy = g_strsplit (dup_str, ":", -1); - - for (iter = *terms; *iter; iter++) { - i++; - if (g_str_equal (list_copy[i], "O")) { - orig_term = i; - } - (*dups)[i] = orig_term; - - for (iter1 = ignore; *iter1; iter1++) { - if (non_stop > 0 && g_str_equal (*iter, *iter1)) { - (*stops)[i] = TRUE; - (*dups)[i] = -2; - break; - } - } - } - - /* Clean up all those pesky strings */ - g_free (ignore_words); - g_free (common_prefixes); - g_free (common_suffixes); - g_free (term_str); - g_free (dup_str); - g_strfreev (prefixes); - g_strfreev (suffixes); - g_strfreev (ignore); - g_strfreev (list_copy); - - return n_terms; -} - - -static gboolean -slow_search_setup (YelpSearchPager *pager) -{ - YelpSearchPagerPriv *priv = pager->priv; - gchar *content_list; - gchar *stderr_str; - gchar *lang; - gchar *command; - - gchar **terms_list = NULL; - gint *dup_list = NULL; - gboolean *stop_list = NULL; - gint terms_number = 0; - gint required_no = 0; - - static xmlSAXHandler sk_sax_handler = { 0, }; - xmlParserCtxtPtr parser; - if (langs && langs[0]) - lang = (gchar *) langs[0]; - else - lang = "C"; - - if (!strcmp (pager->priv->search_terms, "")) { - pager->priv->slow_search_setup_process_id = 0; - priv->xslt_process_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) process_xslt, - pager, NULL); - return FALSE; - } - - command = g_strconcat("scrollkeeper-get-content-list ", lang, NULL); - - if (g_spawn_command_line_sync (command, &content_list, &stderr_str, NULL, NULL)) { - if (!sk_sax_handler.startElement) { - sk_sax_handler.startElement = sk_startElement; - sk_sax_handler.endElement = sk_endElement; - sk_sax_handler.characters = sk_characters; - sk_sax_handler.initialized = TRUE; - } - content_list = g_strstrip (content_list); - xmlSAXUserParseFile (&sk_sax_handler, NULL, content_list); - } - - parser = xmlNewParserCtxt (); - - g_free (content_list); - g_free (stderr_str); - g_free (command); - - - terms_number = build_lists (pager->priv->search_terms,&terms_list, - &dup_list, &stop_list, - &required_no); - - while (omf_pending) { - GSList *first = NULL; - gchar *file = NULL; - xmlDocPtr omf_doc = NULL; - xmlXPathContextPtr omf_xpath = NULL; - xmlXPathObjectPtr omf_url = NULL; - xmlXPathObjectPtr omf_title = NULL; - xmlXPathObjectPtr omf_mime = NULL; - xmlXPathObjectPtr omf_desc = NULL; - - SearchContainer *container; - gchar *ptr; - gchar *path; - gchar *fname; - gchar *realfname; - gchar *mime_type; - int i = 0; - - first = omf_pending; - omf_pending = g_slist_remove_link (omf_pending, first); - file = (gchar *) first->data; - - - omf_doc = xmlCtxtReadFile (parser, (const char *) file, NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - if (!omf_doc) { - g_warning (_("Could not load the OMF file '%s'."), file); - continue; - } - - omf_xpath = xmlXPathNewContext (omf_doc); - omf_url = - xmlXPathEvalExpression (BAD_CAST - "string(/omf/resource/identifier/@url)", - omf_xpath); - omf_title = - xmlXPathEvalExpression (BAD_CAST - "string(/omf/resource/title)", - omf_xpath); - omf_mime = - xmlXPathEvalExpression (BAD_CAST - "string(/omf/resource/format/@mime)", - omf_xpath); - omf_desc = - xmlXPathEvalExpression (BAD_CAST - "string(/omf/resource/description)", - omf_xpath); - - mime_type = g_strdup ((gchar *) omf_mime->stringval); - - fname = g_strdup ((gchar *) omf_url->stringval); - if (g_str_has_prefix (fname, "file:")) { - realfname = &fname[5]; - } else { - realfname = fname; - } - - if (!g_file_test (realfname, G_FILE_TEST_EXISTS)) { - continue; - } - - container = g_new0 (SearchContainer, 1); - - container->base_filename = g_strdup (realfname); - container->entities = g_hash_table_new (g_str_hash, g_str_equal); - container->doc_title = g_strdup ((gchar *) omf_title->stringval); - container->score=0; - container->html = FALSE; - container->default_snippet = g_strdup ((gchar *) omf_desc->stringval); - - ptr = g_strrstr (container->base_filename, "/"); - - path = g_strndup (container->base_filename, - ptr - container->base_filename); - - /* BEGIN HTML special block */ - if (g_str_equal (mime_type, "text/html")) { - GDir *dir; - gchar *filename; - container->html = TRUE; - ptr++; - - dir = g_dir_open (path, 0, NULL); - - while ((filename = (gchar *) g_dir_read_name (dir))) { - if ((g_str_has_suffix (filename, ".html") || - g_str_has_suffix (filename, ".htm")) && - !g_str_equal (filename, ptr)) { - container->components = - g_slist_append (container->components, - g_strconcat (path, "/", filename, - NULL)); - - } - } - /* END HTML special blcok */ - } - - container->base_path = g_strdup (path); - - container->required_words = required_no; - container->grab_text = FALSE; - container->sect_name = NULL; - - container->search_term = g_strdupv (terms_list); - container->stop_word = g_new0 (gboolean, terms_number); - container->dup_of = g_new0 (gint, terms_number); - container->found_terms = g_new0 (gboolean, terms_number); - container->score_per_word = g_new0 (gfloat, terms_number); - container->found_terms = g_new0 (gboolean, terms_number); - - container->search_status = NOT_SEARCHING; - container->snippet_score = 0; - - for (i=0; i< terms_number; i++) { - container->stop_word[i] = stop_list[i]; - container->dup_of[i] = dup_list[i]; - } - - pager->priv->pending_searches = - g_slist_prepend (pager->priv->pending_searches, container); - - g_free (fname); - g_free (path); - if (omf_url) - xmlXPathFreeObject (omf_url); - if (omf_title) - xmlXPathFreeObject (omf_title); - if (omf_xpath) - xmlXPathFreeContext (omf_xpath); - if (omf_doc) - xmlFreeDoc (omf_doc); - - } - g_return_val_if_fail (priv->slow_search_process_id == 0, FALSE); - priv->slow_search_process_id = - g_idle_add ((GSourceFunc) slow_search_process, pager); - - if (parser) - xmlFreeParserCtxt (parser); - - /* returning false removes this idle function from the main loop; - * we also set our slow search _setup_ process id to zero to - * indicate it has been removed */ - priv->slow_search_setup_process_id = 0; - return FALSE; - -} - -static void -search_free_container (SearchContainer *c) -{ - g_strfreev (c->search_term); - g_free (c->dup_of); - g_free (c->found_terms); - g_free (c->stop_word); - g_free (c->score_per_word); - g_free (c->top_element); - g_free (c->elem_type); - g_free (c->sect_name); - g_free (c->default_snippet); - g_free (c->current_subsection); - g_free (c->result_subsection); - g_free (c->doc_title); - g_free (c->base_path); - g_free (c->base_filename); - g_free (c->snippet); - g_hash_table_destroy (c->entities); - g_free (c); -} - - -static gboolean -slow_search_process (YelpSearchPager *pager) -{ - YelpSearchPagerPriv *priv = pager->priv; - SearchContainer *c; - GSList *first = pager->priv->pending_searches; - gint i, j=0; - - pager->priv->pending_searches = - g_slist_remove_link (pager->priv->pending_searches, first); - - if (first == NULL) { - g_return_val_if_fail (priv->xslt_process_id == 0, FALSE); - priv->xslt_process_id = - gtk_idle_add_priority (G_PRIORITY_LOW, - (GtkFunction) process_xslt, - pager); - priv->slow_search_process_id = 0; - return FALSE; - } - - c = (SearchContainer *) first->data; - - xmlSAXUserParseFile (&handlers, c, c->base_filename); - for (i=0; i< g_strv_length (c->search_term); ++i) { - if (c->found_terms[i]) { - j++; - } - } - if (j >= c->required_words) { - search_parse_result (pager, c); - } else while (c->components) { - GSList *next = c->components; - c->components = g_slist_remove_link (c->components, next); - c->search_status = NOT_SEARCHING; - xmlSAXUserParseFile (&handlers, c, (gchar *) next->data); - j = 0; - for (i=0; i< g_strv_length (c->search_term); ++i) { - if (c->found_terms[i]) - j++; - } - if (j >= c->required_words) { - search_parse_result (pager, c); - break; - } - } - - if (pager->priv->pending_searches) { - search_free_container (c); - return TRUE; - } - else { -#ifdef ENABLE_MAN - search_process_man (pager, c->search_term); -#endif -#ifdef ENABLE_INFO - search_process_info (pager, c->search_term); -#endif - search_free_container (c); - - g_return_val_if_fail (priv->xslt_process_id == 0, FALSE); - - priv->xslt_process_id = - g_idle_add_full (G_PRIORITY_LOW, - (GSourceFunc) process_xslt, - pager, NULL); - - /* returning false removes this idle function from the main loop; - * we also set our slow search process id to zero to - * indicate it has been removed */ - priv->slow_search_process_id = 0; - return FALSE; - } -} - -gchar * -search_clean_snippet (gchar *snippet, gchar **terms) -{ - /* This is probably what you want to change */ - gint len_before_term = 47; - gint len_after_term = 47; - gchar **iteration; - gboolean am_cutting = FALSE; - gchar *result = NULL; - gboolean found_terms = FALSE; - - - if (!snippet) - return NULL; - - if (strlen(snippet) > (len_before_term+len_after_term)) { - am_cutting = TRUE; - } - result = g_strdup (snippet); - - for (iteration = terms; *iteration; iteration++) { - gchar *before, *after, *tmp; - gchar *str; - gchar before_c, after_c; - gint count = 0; - - while ((str = strstr (result, (*iteration)))) { - gboolean breaking = FALSE; - gint i; - for (i=0; i< count; i++) { - str++; - str = strstr (str, (*iteration)); - if (!str) { - breaking = TRUE; - break; - } - } - count++; - if (breaking) - break; - - before_c = *(str-1); - after_c = *(str+strlen(*iteration)); - - if (g_ascii_isalpha (before_c) || g_ascii_isalpha (after_c)) { - continue; - } - - tmp = g_strndup (result, (str-result)); - /* If we have to chop the snippet down to size, here is the - * place to do it. Only the first time through though - */ - if (am_cutting && !found_terms && strlen (tmp) > len_before_term) { - gchar *tmp1; - gchar *tmp2; - gint cut_by; - - tmp1 = tmp; - cut_by = strlen(tmp) - len_before_term; - - tmp1 += cut_by; - tmp2 = g_strdup (tmp1); - g_free (tmp); - tmp = g_strconcat ("...",tmp2, NULL); - g_free (tmp2); - } - - before = g_strconcat (tmp, "", NULL); - g_free (tmp); - - str += strlen (*iteration); - - if (am_cutting && !found_terms && strlen (str) > len_after_term) { - gchar *tmp1; - - tmp1 = g_strndup (str, len_after_term); - tmp = g_strconcat (tmp1, "...", NULL); - g_free (tmp1); - } else { - tmp = g_strdup (str); - } - - after = g_strconcat ((*iteration), "", tmp, NULL); - - - - g_free (result); - result = g_strconcat (before, after, NULL); - found_terms = TRUE; - } - } - return result; -} - -void -search_parse_result (YelpSearchPager *pager, SearchContainer *c) -{ - xmlNode *child; - gchar *new_uri; - xmlDoc *snippet_doc; - xmlNode *node; - char *xmldoc; - - new_uri = g_strconcat (c->base_filename, "#", c->result_subsection, - NULL); - child = xmlNewTextChild (pager->priv->root, NULL, - BAD_CAST "result", NULL); - xmlSetProp (child, BAD_CAST "uri", BAD_CAST new_uri); - xmlSetProp (child, BAD_CAST "title", BAD_CAST g_strstrip (c->doc_title)); - xmlSetProp (child, BAD_CAST "score", - BAD_CAST g_strdup_printf ("%f", c->score)); - /* Fix up the snippet to show the break_term in bold */ - if (!c->snippet) - c->snippet = g_strdup (c->default_snippet); - xmldoc = g_strdup_printf ("%s", - search_clean_snippet (c->snippet, c->search_term)); - snippet_doc = xmlParseDoc (BAD_CAST xmldoc); - g_free (xmldoc); - - if (!snippet_doc) - return; - - node = xmlDocGetRootElement (snippet_doc); - xmlUnlinkNode (node); - xmlAddChild (child, node); - xmlFreeDoc (snippet_doc); -} - -void -process_man_result (YelpSearchPager *pager, gchar *result, gchar **terms) -{ - gchar ** split = g_strsplit (result, "\n", -1); - gint i; - - for (i=0;split[i];i++) { - gchar ** line = g_strsplit (split[i], "(", 2); - gchar *filename = NULL; - gchar *desc = NULL; - xmlNode *child; - gchar *tmp = NULL; - gchar *after = NULL; - /*gchar *before = NULL;*/ - gchar *title = NULL; - /*gint i;*/ - - if (line == NULL || line[0] == NULL || line[1] == NULL) - continue; - - title = g_strdup (g_strstrip (line[0])); - after = strstr (line[1], ")"); - - tmp = g_strndup (line[1], after-line[1]); - - filename = g_strconcat ("man:", title, "(", tmp,")", NULL); - - after++; - g_free (tmp); - - tmp = g_strdup (g_strchug (after)); - after = tmp; after++; - desc = g_strdup (g_strchug (after)); - - child = xmlNewTextChild (pager->priv->root, NULL, - BAD_CAST "result", NULL); - xmlSetProp (child, BAD_CAST "uri", BAD_CAST filename); - xmlSetProp (child, BAD_CAST "title", - BAD_CAST g_strconcat (title, - " manual page", NULL)); - - xmlNewChild (child, NULL, BAD_CAST "snippet", - BAD_CAST desc); - xmlNewChild (child, NULL, BAD_CAST "score", - BAD_CAST "0.1"); - g_free (tmp); - g_strfreev (line); - } - -} - -void -process_info_result (YelpSearchPager *pager, gchar *result, gchar **terms) -{ - gchar ** split = NULL; - gint i; - - split = g_strsplit (result, "\n", -1); - if (split == NULL) - return; - - for (i=0;split[i];i++) { - gchar ** line = NULL; - gchar *filename = NULL; - gchar *desc = NULL; - gchar *title = NULL; - xmlNode *child; - gchar *tmp; - gchar *tmp1; - gchar *file_name; - - line = g_strsplit (split[i], "--", 3); - if (g_strv_length (line) != 2) { - g_strfreev (line); - continue; - } - - /* First is the filename - * We gotta do some fiddling to get the actual filename - * we can use - */ - tmp = g_strdup (g_strchomp (line[0])); - tmp++; - tmp1 = strstr (tmp, "\""); - if (!tmp1) { - g_strfreev (line); - g_free (tmp); - continue; - } - file_name = g_strndup (tmp, tmp1-tmp); - tmp++; - tmp1 = strstr (tmp, ")"); - if (tmp1) - title = g_strndup (tmp, tmp1-tmp); - else { - title = g_strdup (++file_name); - --file_name; - } - tmp--; - tmp--; - filename = g_strconcat ("info:", file_name, NULL); - g_free (tmp); - g_free (file_name); - - /* Then the description */ - desc = g_strdup (g_strchug (line[1])); - - /* Now we add the result to the page */ - child = xmlNewTextChild (pager->priv->root, NULL, - BAD_CAST "result", NULL); - xmlSetProp (child, BAD_CAST "uri", BAD_CAST filename); - xmlSetProp (child, BAD_CAST "title", - BAD_CAST g_strconcat (title, - " info page", NULL)); - - xmlNewChild (child, NULL, BAD_CAST "snippet", - BAD_CAST desc); - xmlNewChild (child, NULL, BAD_CAST "score", - BAD_CAST "0.05"); - g_strfreev (line); - g_free (title); - } - -} - -void -search_process_man (YelpSearchPager *pager, gchar **terms) -{ - gchar *command; - gchar *stdout_str = NULL; - gint exit_code; - gchar *tmp = NULL; - gchar *search = NULL; - - tmp = g_strescape (pager->priv->search_terms, NULL); - tmp = g_strdelimit (tmp, "\'", '\''); - search = g_strconcat ("\"",tmp,"\"", NULL); - - command = g_strconcat("apropos ", search, NULL); - - if (g_spawn_command_line_sync (command, &stdout_str, NULL, - &exit_code, NULL) && exit_code == 0) { - process_man_result (pager, stdout_str, terms); - - } - g_free (tmp); - g_free (search); - g_free (stdout_str); - g_free (command); - - return; -} - -void -search_process_info (YelpSearchPager *pager, gchar **terms) -{ - gchar *command; - gchar *stdout_str = NULL; - gchar *stderr_str = NULL; - gchar *tmp; - gint exit_code; - - gchar *search = NULL; - - tmp = g_strescape (pager->priv->search_terms, NULL); - tmp = g_strdelimit (tmp, "\'", '\''); - search = g_strconcat ("\"",tmp,"\"", NULL); - command = g_strconcat("info --apropos ", search, NULL); - - if (g_spawn_command_line_sync (command, &stdout_str, &stderr_str, - &exit_code, NULL) && - stdout_str != NULL) { - process_info_result (pager, stdout_str, terms); - } - g_free (tmp); - g_free (stdout_str); - g_free (stderr_str); - g_free (command); - - return; -} diff --git a/src/yelp-search-pager.h b/src/yelp-search-pager.h deleted file mode 100644 index e6a19d4d..00000000 --- a/src/yelp-search-pager.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_SEARCH_PAGER_H__ -#define __YELP_SEARCH_PAGER_H__ - -#include - -#include "yelp-pager.h" - -#define YELP_TYPE_SEARCH_PAGER (yelp_search_pager_get_type ()) -#define YELP_SEARCH_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_SEARCH_PAGER, YelpSearchPager)) -#define YELP_SEARCH_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerClass)) -#define YELP_IS_SEARCH_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_SEARCH_PAGER)) -#define YELP_IS_SEARCH_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_SEARCH_PAGER)) -#define YELP_SEARCH_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerClass)) - -typedef struct _YelpSearchPager YelpSearchPager; -typedef struct _YelpSearchPagerClass YelpSearchPagerClass; -typedef struct _YelpSearchPagerPriv YelpSearchPagerPriv; - -struct _YelpSearchPager { - YelpPager parent; - - YelpSearchPagerPriv *priv; -}; - -struct _YelpSearchPagerClass { - YelpPagerClass parent_class; -}; - -GType yelp_search_pager_get_type (void); - -void yelp_search_pager_init (void); -YelpSearchPager *yelp_search_pager_get (YelpDocInfo *doc_info); - -#endif /* __YELP_SEARCH_PAGER_H__ */ diff --git a/src/yelp-toc-pager.c b/src/yelp-toc-pager.c deleted file mode 100644 index 7e9a132e..00000000 --- a/src/yelp-toc-pager.c +++ /dev/null @@ -1,2473 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-debug.h" -#include "yelp-error.h" -#include "yelp-settings.h" -#include "yelp-toc-pager.h" -#include "yelp-utils.h" -#include "yelp-io-channel.h" - -#define YELP_NAMESPACE "http://www.gnome.org/yelp/ns" - -#define STYLESHEET_PATH DATADIR"/yelp/xslt/" -#define TOC_STYLESHEET STYLESHEET_PATH"toc2html.xsl" - -typedef gboolean (*ProcessFunction) (YelpTocPager *pager); - -#define YELP_TOC_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_TOC_PAGER, YelpTocPagerPriv)) - -struct _YelpTocPagerPriv { - gboolean sk_docomf; - GSList *omf_pending; /* list of directories which contain omf files - * to process */ - GHashTable *omf_dirhash; /* key = directory name; - value = GSList of omf files to process */ - xmlDocPtr omfindex_xml; /* in memory cache file for omf files */ - xmlNodePtr omf_root; - xmlNodePtr omf_ins; - -#ifdef ENABLE_MAN - gint manpage_count; - xmlNodePtr root; - xmlNodePtr ins; - xmlDocPtr manindex_xml; - GSList *mandir_list; - GSList *mandir_ptr; /* ptr to current entry in mandir_list */ - GSList *mandir_langpath; /* ptr to current entry in mandir_ptr */ - GHashTable *man_secthash; - GHashTable *man_manhash; - GHashTable *man_dirlang; /* key = man page directory, value = language */ -#endif - - xmlDocPtr toc_doc; - xmlDocPtr man_doc; - xmlDocPtr info_doc; - - GHashTable *unique_hash; - GHashTable *category_hash; - - xmlParserCtxtPtr parser; - - ProcessFunction pending_func; - - gboolean cancel; - gint pause_count; - - xsltStylesheetPtr stylesheet; - xsltTransformContextPtr transformContext; - - guint process_id; -}; - -static void toc_pager_class_init (YelpTocPagerClass *klass); -static void toc_pager_init (YelpTocPager *pager); -static void toc_pager_dispose (GObject *gobject); - -static void toc_pager_error (YelpPager *pager); -static void toc_pager_finish (YelpPager *pager); - -static gboolean toc_pager_process (YelpPager *pager); -static void toc_pager_cancel (YelpPager *pager); -static const gchar * toc_pager_resolve_frag (YelpPager *pager, - const gchar *frag_id); -static GtkTreeModel * toc_pager_get_sections (YelpPager *pager); - -static gboolean toc_process_pending (YelpTocPager *pager); - - -static gboolean process_read_menu (YelpTocPager *pager); -static gboolean process_xslt (YelpTocPager *pager); -static gboolean process_read_scrollkeeper (YelpTocPager *pager, - gchar *content_list); -static gboolean process_omf_pending (YelpTocPager *pager); -#ifdef ENABLE_MAN -static gboolean process_mandir_pending (YelpTocPager *pager); -#endif -#ifdef ENABLE_INFO -static gboolean process_info_pending (YelpTocPager *pager); -#endif -static gboolean process_cleanup (YelpTocPager *pager); - -static void toc_add_doc_info (YelpTocPager *pager, - YelpDocInfo *doc_info); -static void toc_remove_doc_info (YelpTocPager *pager, - YelpDocInfo *doc_info); -static void xml_trim_titles (xmlNodePtr node, - xmlChar *nodetype); -static void xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp); - -static YelpPagerClass *parent_class; - -static YelpTocPager *toc_pager; - -GType -yelp_toc_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpTocPagerClass), - NULL, - NULL, - (GClassInitFunc) toc_pager_class_init, - NULL, - NULL, - sizeof (YelpTocPager), - 0, - (GInstanceInitFunc) toc_pager_init, - }; - type = g_type_register_static (YELP_TYPE_PAGER, - "YelpTocPager", - &info, 0); - } - return type; -} - -static void -toc_pager_class_init (YelpTocPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = toc_pager_dispose; - - pager_class->error = toc_pager_error; - pager_class->cancel = toc_pager_cancel; - pager_class->finish = toc_pager_finish; - - pager_class->process = toc_pager_process; - pager_class->cancel = toc_pager_cancel; - pager_class->resolve_frag = toc_pager_resolve_frag; - pager_class->get_sections = toc_pager_get_sections; - - g_type_class_add_private (klass, sizeof (YelpTocPagerPriv)); -} - -static void -toc_pager_init (YelpTocPager *pager) -{ - YelpTocPagerPriv *priv; - - pager->priv = priv = YELP_TOC_PAGER_GET_PRIVATE (pager); - - priv->parser = xmlNewParserCtxt (); - - priv->unique_hash = g_hash_table_new (g_str_hash, g_str_equal); - priv->category_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - priv->cancel = 0; - priv->pause_count = 0; - priv->pending_func = NULL; - priv->process_id = 0; -} - -static void -toc_pager_dispose (GObject *object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -void -yelp_toc_pager_init (void) -{ - YelpDocInfo *doc_info; - - doc_info = yelp_doc_info_get ("x-yelp-toc:", FALSE); - - toc_pager = (YelpTocPager *) g_object_new (YELP_TYPE_TOC_PAGER, - "document-info", doc_info, - NULL); - - yelp_pager_start (YELP_PAGER (toc_pager)); -} - -YelpTocPager * -yelp_toc_pager_get (void) -{ - return toc_pager; -} - -void -yelp_toc_pager_pause (YelpTocPager *pager) -{ - g_return_if_fail (pager != NULL); - - debug_print (DB_FUNCTION, "entering\n"); - debug_print (DB_ARG, " pause_count = %i\n", pager->priv->pause_count + 1); - - pager->priv->pause_count ++; - - debug_print (DB_FUNCTION, "exiting\n"); -} - -void -yelp_toc_pager_unpause (YelpTocPager *pager) -{ - g_return_if_fail (pager != NULL); - - debug_print (DB_FUNCTION, "entering\n"); - debug_print (DB_ARG, " pause_count = %i\n", pager->priv->pause_count - 1); - - pager->priv->pause_count--; - if (pager->priv->pause_count < 0) { - g_warning (_("YelpTocPager: Pause count is negative.")); - pager->priv->pause_count = 0; - } - - if (pager->priv->pause_count < 1 && - pager->priv->process_id == 0) { - pager->priv->process_id = - gtk_idle_add_priority (G_PRIORITY_LOW, - (GtkFunction) toc_process_pending, - pager); - } - - debug_print (DB_FUNCTION, "exiting\n"); -} - -/******************************************************************************/ - -static void -toc_pager_error (YelpPager *pager) -{ - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); -} - -static void -toc_pager_cancel (YelpPager *pager) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - priv->cancel = TRUE; -} - -static void -toc_pager_finish (YelpPager *pager) -{ - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISHED); -} - -static gboolean -toc_pager_process (YelpPager *pager) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_PARSING); - g_signal_emit_by_name (pager, "parse"); - - /* Set it running */ - yelp_pager_set_state (pager, YELP_PAGER_STATE_RUNNING); - g_signal_emit_by_name (pager, "start"); - - priv->pending_func = (ProcessFunction) process_read_menu; - - if (priv->process_id == 0) { - priv->process_id = - gtk_idle_add_priority (G_PRIORITY_LOW, - (GtkFunction) toc_process_pending, - pager); - } - return FALSE; -} - -/* we take advantage of the resolve_frag function to do lazy - * loading of each page the TOC. frag_id is the id attribute - * of the toc element that we want. - * - * yes, this kind of a hack */ -static const gchar * -toc_pager_resolve_frag (YelpPager *pager, const gchar *frag_id) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - YelpPage *page = NULL; - GError *error = NULL; - xmlDocPtr outdoc = NULL; - gchar **params = NULL; - gint params_i = 0; - gint params_max = 10; - GtkIconInfo *info; - GtkIconTheme *theme = (GtkIconTheme *) yelp_settings_get_icon_theme (); - - if (priv->toc_doc == NULL) - return NULL; - - debug_print (DB_FUNCTION, "entering\n"); - debug_print (DB_ARG, "frag_id = %s\n", frag_id); - - /* if frag_id is NULL, we assume we are loading the top level TOC page */ - if (frag_id == NULL) - frag_id = "index"; - - /* we use the "frag_id" as the page_id here */ - page = (YelpPage *) yelp_pager_get_page_from_id (pager, frag_id); - - /* if we found the page just return */ - if (page != NULL) { - debug_print (DB_DEBUG, "found the frag_id=%s\n", frag_id); - return frag_id; - } - - /* only create and parse the stylesheet on the first call to this function */ - if (!priv->stylesheet) { - priv->stylesheet = xsltParseStylesheetFile (BAD_CAST TOC_STYLESHEET); - } - - if (!priv->stylesheet) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC, - _("The table of contents could not be processed. The " - "file ‘%s’ is either missing or is not a valid XSLT " - "stylesheet."), - TOC_STYLESHEET); - yelp_pager_error (YELP_PAGER (pager), error); - goto done; - } - - priv->transformContext = xsltNewTransformContext (priv->stylesheet, - priv->toc_doc); - priv->transformContext->_private = pager; - xsltRegisterExtElement (priv->transformContext, - BAD_CAST "document", - BAD_CAST YELP_NAMESPACE, - (xsltTransformFunction) xslt_yelp_document); - - params = g_new0 (gchar *, params_max); - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 10; - params = g_renew (gchar *, params, params_max); - } - - info = gtk_icon_theme_lookup_icon (theme, "yelp-icon-big", 192, 0); - if (info) { - params[params_i++] = "help_icon"; - params[params_i++] = g_strdup_printf ("\"%s\"", - gtk_icon_info_get_filename (info)); - params[params_i++] = "help_icon_size"; - params[params_i++] = g_strdup_printf ("%i", - gtk_icon_info_get_base_size (info)); - gtk_icon_info_free (info); - } - - /* we specify the id attribute of the toc element that we want to process to - * the stylesheet */ - params[params_i++] = "yelp.toc.id"; - params[params_i++] = g_strdup_printf ("\'%s\'", frag_id); - - params[params_i++] = NULL; - - outdoc = xsltApplyStylesheetUser (priv->stylesheet, - priv->toc_doc, - (const gchar **)params, NULL, NULL, - priv->transformContext); - /* Don't do this */ - g_signal_emit_by_name (pager, "finish"); - - done: - if (params) { - for (params_i = 0; params[params_i] != NULL; params_i++) - if (params_i % 2 == 1) - g_free ((gchar *) params[params_i]); - } - if (outdoc) - xmlFreeDoc (outdoc); - /* with this hack (this function) we can't free the toc_doc */ - /*if (priv->toc_doc) { - xmlFreeDoc (priv->toc_doc); - priv->toc_doc = NULL; - }*/ - if (priv->transformContext) { - xsltFreeTransformContext (priv->transformContext); - priv->transformContext = NULL; - } - - return frag_id; -} - -static GtkTreeModel * -toc_pager_get_sections (YelpPager *pager) -{ - return NULL; -} - -/******************************************************************************/ - -static gboolean -toc_process_pending (YelpTocPager *pager) -{ - gboolean readd; - YelpTocPagerPriv *priv = pager->priv; - static ProcessFunction process_funcs[] = { - process_read_menu, - /*process_omf_pending,*/ -#ifdef ENABLE_MAN - process_mandir_pending, -#endif -#ifdef ENABLE_INFO - process_info_pending, -#endif - /* process_xslt, */ - process_cleanup, - NULL - }; - static gint process_i = 0; - - if (priv->cancel || !priv->pending_func) { - /* FIXME: clean stuff up. */ - priv->process_id = 0; - return FALSE; - } - - readd = priv->pending_func(pager); - - /* if the pending function returned FALSE, then we move on to - * calling the next function */ - if (!readd) - priv->pending_func = process_funcs[++process_i]; - - if (priv->pending_func == NULL) - g_signal_emit_by_name (pager, "finish"); - - if ((priv->pending_func != NULL) && (priv->pause_count < 1)) - return TRUE; - else { - priv->process_id = 0; - return FALSE; - } -} - -/** process_read_scrollkeeper *************************************************/ - -static void -sk_startElement (void *pager, - const xmlChar *name, - const xmlChar **attrs) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - if (xmlStrEqual((const xmlChar*) name, BAD_CAST "docomf")) - priv->sk_docomf = TRUE; -} - -static void -sk_endElement (void *pager, - const xmlChar *name) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - if (xmlStrEqual((const xmlChar*) name, BAD_CAST "docomf")) - priv->sk_docomf = FALSE; -} - -static void -sk_characters (void *pager, - const xmlChar *ch, - int len) -{ - gchar *omf; - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - if (priv->sk_docomf) { - GSList *filelist = NULL; - GSList *ptr = NULL; - gchar *dirname = NULL; - - omf = g_strndup ((gchar *) ch, len); - /* since the directory that the omf file is in can be in any - * order, we use a hash to aggregrate the files by directory. - * We end up with a hash whose key is the dirname, and whose - * values are GSLists of filenames. */ - if (!priv->omf_dirhash) - priv->omf_dirhash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - dirname = g_path_get_dirname (omf); - - ptr = g_hash_table_lookup (priv->omf_dirhash, dirname); - - if (!ptr) { - /* this directory is not in the hash; create an entry for it */ - filelist = g_slist_append (filelist, omf); - g_hash_table_insert (priv->omf_dirhash, dirname, filelist); - - /* add the directory name to a list so we can iterate through - * the hash later */ - priv->omf_pending = g_slist_prepend (priv->omf_pending, - g_path_get_dirname(omf)); - } else { - /* prepend to the existing file list for this directory entry */ - ptr = g_slist_prepend (ptr, omf); - /* writes over old value */ - g_hash_table_insert (priv->omf_dirhash, dirname, ptr); - } - - } -} - -static gboolean -process_read_scrollkeeper (YelpTocPager *pager, gchar *content_list) -{ - static xmlSAXHandler sk_sax_handler = { 0, }; - - if (!sk_sax_handler.startElement) { - sk_sax_handler.startElement = sk_startElement; - sk_sax_handler.endElement = sk_endElement; - sk_sax_handler.characters = sk_characters; - sk_sax_handler.initialized = TRUE; - } - - xmlSAXUserParseFile (&sk_sax_handler, pager, content_list); - - return FALSE; -} - -static gboolean -files_are_equivalent (gchar *file1, gchar *file2) -{ - FILE *f1; - FILE *f2; - guint data1; - guint data2; - - f1 = fopen (file1, "r"); - if (!f1) - return FALSE; - - f2 = fopen (file2, "r"); - if (!f2) - return FALSE; - - while (fread (&data1, sizeof (gint), 1, f1)) { - fread (&data2, sizeof (gint), 1, f2); - if (data1 != data2) - return FALSE; - } - - fclose (f1); - fclose (f2); - - return TRUE; -} - -/* returns a newly created hash table with the following keys: - * url, title, description, category, language, seriesid - * caller must free the hash table with g_hash_table_destroy() - * returns NULL on failure */ -static GHashTable * -get_omf_attributes (YelpTocPager *pager, const gchar *omffile) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - GHashTable *hash = NULL; - xmlXPathContextPtr xpath = NULL; - xmlXPathObjectPtr object = NULL; - xmlDocPtr omf_doc = NULL; - - omf_doc = xmlCtxtReadFile (priv->parser, omffile, NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - if (!omf_doc) { - g_warning (_("Could not load the OMF file '%s'."), omffile); - return NULL; - } - - hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); - xpath = xmlXPathNewContext (omf_doc); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/identifier/@url)", - xpath); - g_hash_table_insert (hash, "url", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/title)", - xpath); - g_hash_table_insert (hash, "title", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/description)", - xpath); - g_hash_table_insert (hash, "description", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/subject/@category)", - xpath); - g_hash_table_insert (hash, "category", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/language/@code)", - xpath); - g_hash_table_insert (hash, "language", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - object = - xmlXPathEvalExpression (BAD_CAST "string(/omf/resource/relation/@seriesid)", - xpath); - g_hash_table_insert (hash, "seriesid", g_strdup ((gchar *) object->stringval)); - xmlXPathFreeObject (object); - - xmlXPathFreeContext (xpath); - xmlFreeDoc (omf_doc); - - return hash; -} - -static void -create_toc_from_omf_cache_file (YelpTocPager *pager, const gchar *index_file) -{ - xmlXPathContextPtr xpath = NULL; - xmlXPathObjectPtr objfiles = NULL; - xmlDocPtr omfindex_xml = NULL; - gint i; - - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - omfindex_xml = xmlReadFile (index_file, NULL, XML_PARSE_NOCDATA | - XML_PARSE_NOERROR | XML_PARSE_NONET); - - if (omfindex_xml == NULL) { - g_warning ("Unable to parse index file \"%s\"\n" - "try deleting this file and running yelp again.\n", index_file); - return; - } - - xpath = xmlXPathNewContext (omfindex_xml); - - objfiles = xmlXPathEvalExpression (BAD_CAST "/omfindex/dir/omffile", xpath); - - for (i=0; i < objfiles->nodesetval->nodeNr; i++) { - YelpDocInfo *doc_info = NULL; - YelpDocInfo *doc_old = NULL; - xmlXPathObjectPtr objattr = NULL; - xmlNodePtr node = NULL; - xmlChar *attr = NULL; - gchar *id = NULL; - - xpath->node = objfiles->nodesetval->nodeTab[i]; - - objattr = xmlXPathEvalExpression (BAD_CAST "url", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - xmlXPathFreeObject (objattr); - - if (!attr) { - g_warning ("missing required \"url\" element in omf cache file\n"); - continue; - } - - doc_info = yelp_doc_info_get ((const gchar *) attr, TRUE); - xmlFree (attr); - - if (!doc_info) - return; - - objattr = xmlXPathEvalExpression (BAD_CAST "title", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - yelp_doc_info_set_title (doc_info, (gchar *)attr); - xmlXPathFreeObject (objattr); - xmlFree (attr); - - objattr = xmlXPathEvalExpression (BAD_CAST "description", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - yelp_doc_info_set_description (doc_info, (gchar *)attr); - xmlXPathFreeObject (objattr); - xmlFree (attr); - - objattr = xmlXPathEvalExpression (BAD_CAST "category", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - yelp_doc_info_set_category (doc_info, (gchar *)attr); - xmlXPathFreeObject (objattr); - xmlFree (attr); - - objattr = xmlXPathEvalExpression (BAD_CAST "language", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - yelp_doc_info_set_language (doc_info, (gchar *)attr); - xmlXPathFreeObject (objattr); - xmlFree (attr); - - objattr = xmlXPathEvalExpression (BAD_CAST "seriesid", xpath); - node = objattr->nodesetval->nodeTab[0]; - attr = xmlNodeListGetString (omfindex_xml, node->xmlChildrenNode, 1); - id = g_strconcat ("scrollkeeper.", (gchar *) attr, NULL); - yelp_doc_info_set_id (doc_info, (gchar *)id); - xmlXPathFreeObject (objattr); - xmlFree (attr); - - doc_old = g_hash_table_lookup (priv->unique_hash, id); - g_free (id); - - if (doc_old) { - if (yelp_doc_info_cmp_language (doc_info, doc_old) < 0) { - toc_remove_doc_info (YELP_TOC_PAGER (pager), doc_old); - toc_add_doc_info (YELP_TOC_PAGER (pager), doc_info); - } - } else - toc_add_doc_info (YELP_TOC_PAGER (pager), doc_info); - - } - - xmlXPathFreeContext (xpath); - xmlXPathFreeObject (objfiles); - xmlFreeDoc (omfindex_xml); - - return; -} - -/** process_omf_pending *******************************************************/ - -static gboolean -process_omf_pending (YelpTocPager *pager) -{ - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - YelpDocInfo *doc_info; - YelpDocInfo *doc_old; - static gboolean first_call = TRUE; - static gchar *index_file = NULL; - static gchar *content_list = NULL; - static gchar *sk_file = NULL; - GHashTable *omf_hash = NULL; - GSList *filelist = NULL; - GSList *firstfile = NULL; - GSList *first = NULL; - gchar *dir = NULL; - gchar *file = NULL; - gchar *lang = NULL; - gchar *stderr_str = NULL; - gchar *command = NULL; - FILE *newindex = NULL; - - if (!index_file) - index_file = g_build_filename (yelp_dot_dir(), "omfindex.xml", NULL); - - /* on first call to this function, we check for the existence of a - * cache file. If it exists, we get our information from there. If - * it doesn't exist, then we create a list of omf files to process - * with the process_read_scrollkeeper() function */ - if (first_call) { - first_call = FALSE; - - sk_file = g_build_filename (yelp_dot_dir(), "sk-content-list.last", NULL); - - /* get current language */ - const gchar * const * langs = g_get_language_names (); - if (langs && langs[0]) - lang = (gchar *) langs[0]; - else - lang = "C"; - - command = g_strconcat ("scrollkeeper-get-content-list ", lang, NULL); - - if (!g_spawn_command_line_sync (command, &content_list, - &stderr_str, NULL, NULL)) { - g_critical ("scrollkeeper-get-content-list failed: %s", stderr_str); - return FALSE; - } - - /* required to remove LFs and extra whitespace from the filename */ - g_strstrip (content_list); - - g_free (stderr_str); - g_free (command); - - if (g_file_test (index_file, G_FILE_TEST_IS_REGULAR) && - g_file_test (sk_file, G_FILE_TEST_IS_REGULAR)) { - /* the presence of a cache file is not enough. The cache file - * could be outdated since the scrollkeeper database could have - * been rebuilt since the last time the cache file was created. - * We solve this by copying the scrollkeeper content list file - * to ~/.gnome/yelp.d/sk-content-list.last when the - * cache file is originally created. On subsequent runs, we then - * do a byte by byte comparison between the generated content - * list and the old one at ~/.gnome2/yelp.d/ - If they are exactly - * the same, then we use the cache file; otherwise the cache file - * will get rebuilt. Of course this operates under the assumption - * that the contents list generated by scrollkeeper is always the - * same if the scrollkeeper database has not been rebuilt. If that - * ever fails to be the case then we end up rebuilding the cache - * file everytime, so there's no regression of functionality */ - - if (!files_are_equivalent (sk_file, content_list)) { - process_read_scrollkeeper (pager, content_list); - return TRUE; - } - - create_toc_from_omf_cache_file (pager, index_file); - - /* done processing, don't call this function again */ - return FALSE; - } - - process_read_scrollkeeper (pager, content_list); - - /* return true, so that this function is called again to continue - * processing */ - return TRUE; - } - - /* if we've made it to here, that means we need to regenerate the cache - * file, so allocate an in memory XML document here */ - if (!priv->omfindex_xml) { - priv->omfindex_xml = xmlNewDoc (BAD_CAST "1.0"); - priv->omf_root = xmlNewNode (NULL, BAD_CAST "omfindex"); - - xmlDocSetRootElement (priv->omfindex_xml, priv->omf_root); - - xmlAddChild (priv->omf_root, xmlNewText (BAD_CAST "\n ")); - } - - /* get the "first" directory in the GSList "omf_pending" */ - first = priv->omf_pending; - - /* if this is NULL, then we are done processing */ - /* FIXME: cleanup any leftover stuff here */ - if (!first) { - GFile *fromfile = g_file_new_for_uri (content_list); - GFile *tofile = g_file_new_for_uri (sk_file); - gboolean result = FALSE; - - /* create the new cache file */ - if (!(newindex = g_fopen (index_file, "w"))) - g_warning ("Unable to create '%s'\n", index_file); - else { - xmlDocDump (newindex, priv->omfindex_xml); - fclose (newindex); - } - - /* copy the newly created file to ~/.gnome2/yelp.d/omfindex.xml, - * overwriting the old one if necessary */ - result = g_file_copy (fromfile, tofile, G_FILE_COPY_OVERWRITE, - NULL, NULL, NULL, NULL); - - g_object_unref (fromfile); - g_object_unref (tofile); - - if (result != TRUE) - g_critical ("Unable to copy %s to %s\n", content_list, sk_file); - - if (priv->omf_dirhash) - g_hash_table_destroy (priv->omf_dirhash); - - xmlFreeDoc (priv->omfindex_xml); - - return FALSE; - } - - /* remove this "first" directory from our list */ - priv->omf_pending = g_slist_remove_link (priv->omf_pending, first); - dir = (gchar *) first->data; - - priv->omf_ins = xmlNewChild (priv->omf_root, NULL, BAD_CAST "dir", NULL); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "name", BAD_CAST dir); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - - filelist = g_hash_table_lookup (priv->omf_dirhash, dir); - - while (filelist && filelist->data) { - gchar *id = NULL; - gchar *url = NULL; - - firstfile = filelist; - filelist = g_slist_remove_link (filelist, firstfile); - - file = (gchar *) firstfile->data; - - if (!file || !g_str_has_suffix (file, ".omf")) - goto done; - - omf_hash = get_omf_attributes (pager, file); - - if (!omf_hash) - goto done; - - /* url is required, if it's not present don't even add the - * entry to the cache file */ - url = g_hash_table_lookup (omf_hash, "url"); - if (url == NULL || *url == '\0') - goto done; - - /* this add all the omf information to the xml cache file */ - priv->omf_ins = xmlNewChild (priv->omf_ins, NULL, - BAD_CAST "omffile", NULL); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "path", BAD_CAST file); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "url", - BAD_CAST g_hash_table_lookup (omf_hash, "url")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "title", - BAD_CAST g_hash_table_lookup (omf_hash, "title")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "language", - BAD_CAST g_hash_table_lookup (omf_hash, "language")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "category", - BAD_CAST g_hash_table_lookup (omf_hash, "category")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "description", - BAD_CAST g_hash_table_lookup (omf_hash, "description")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->omf_ins, NULL, BAD_CAST "seriesid", - BAD_CAST g_hash_table_lookup (omf_hash, "seriesid")); - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - priv->omf_ins = priv->omf_ins->parent; - - doc_info = - yelp_doc_info_get ((const gchar *) g_hash_table_lookup (omf_hash, "url"), - FALSE); - - if (!doc_info) - goto done; - - yelp_doc_info_set_title (doc_info, g_hash_table_lookup (omf_hash, "title")); - yelp_doc_info_set_language (doc_info, g_hash_table_lookup (omf_hash, "language")); - yelp_doc_info_set_category (doc_info, g_hash_table_lookup (omf_hash, "category")); - yelp_doc_info_set_description (doc_info, g_hash_table_lookup (omf_hash, "description")); - - id = g_strconcat ("scrollkeeper.", - (gchar *) g_hash_table_lookup (omf_hash, "seriesid"), - NULL); - - yelp_doc_info_set_id (doc_info, id); - - doc_old = g_hash_table_lookup (priv->unique_hash, id); - - if (doc_old) { - if (yelp_doc_info_cmp_language (doc_info, doc_old) < 0) { - toc_remove_doc_info (YELP_TOC_PAGER (pager), doc_old); - toc_add_doc_info (YELP_TOC_PAGER (pager), doc_info); - } - } else - toc_add_doc_info (YELP_TOC_PAGER (pager), doc_info); - -done: - if (omf_hash) - g_hash_table_destroy (omf_hash); - g_free (file); - g_slist_free_1 (firstfile); - g_free (id); - - } /* end while */ - - xmlAddChild (priv->omf_ins, xmlNewText (BAD_CAST "\n ")); - - g_free (dir); - g_slist_free_1 (first); - - /* continue processing */ - return TRUE; -} - -#ifdef ENABLE_MAN -static void -add_man_page_to_toc (YelpTocPager *pager, gchar *dirname, gchar *filename) -{ - xmlNodePtr tmp = NULL; - gchar *manname = NULL; - gchar *mansect = NULL; - gchar *manman = NULL; - gchar *c1 = NULL; - gchar *c2 = NULL; - - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - c1 = g_strrstr (filename, ".bz2"); - - if (c1 && strlen (c1) != 4) - c1 = NULL; - - if (!c1) { - c1 = g_strrstr (filename, ".gz"); - if (c1 && strlen (c1) != 3) - c1 = NULL; - } - - /* c1 points to the file extension, either .gz or .bz2 at this point - * or is NULL if the filename does not have either extension */ - if (c1) - c2 = g_strrstr_len (filename, c1 - filename, "."); - else - c2 = g_strrstr (filename, "."); - - /* c2 points to the period preceding the man page section in the - * filename at this point */ - if (c2) { - manname = g_strndup (filename, c2 - filename); - if (c1) - mansect = g_strndup (c2 + 1, c1 - c2 - 1); - else - mansect = g_strdup (c2 + 1); - } - - /* if filename has no period in it, we have no idea what man - * section to place it in. So just ignore it. */ - else return; - - manman = g_strconcat (manname, ".", mansect, NULL); - - if (g_hash_table_lookup (priv->man_manhash, manman) == NULL) { - tmp = g_hash_table_lookup (priv->man_secthash, mansect); - - if (tmp == NULL && strlen (mansect) > 1) { - gchar *mansect0 = g_strndup (mansect, 1); - tmp = g_hash_table_lookup (priv->man_secthash, mansect0); - g_free (mansect0); - } - - if (tmp) { - gchar *tooltip, *url_full, *url_short; - YelpDocInfo *info; - - url_full = g_strconcat ("man:", dirname, "/", filename, NULL); - url_short = g_strconcat ("man:", manname, ".", mansect, NULL); - info = yelp_doc_info_get (url_full, TRUE); - - if (info) { - gchar *lang = NULL; - - if (priv->man_dirlang) - lang = g_hash_table_lookup (priv->man_dirlang, dirname); - - if (lang) - yelp_doc_info_set_language (info, lang); - - yelp_doc_info_add_uri (info, url_short, YELP_URI_TYPE_MAN); - tmp = xmlNewChild (tmp, NULL, BAD_CAST "doc", NULL); - xmlNewProp (tmp, BAD_CAST "href", BAD_CAST url_full); - xmlNewChild (tmp, NULL, BAD_CAST "title", BAD_CAST manname); - tooltip = g_strdup_printf (_("Read man page for %s"), manname); - xmlNewChild (tmp, NULL, BAD_CAST "tooltip", BAD_CAST tooltip); - - g_free (tooltip); - } - - g_free (url_full); - g_free (url_short); - } else { - d (g_warning ("Could not locate section %s for %s\n", mansect, manman)); - } - - g_hash_table_insert (priv->man_manhash, g_strdup (manman), priv); - } - - g_free (manname); - g_free (mansect); - g_free (manman); -} - -static void -create_manindex_file (gchar *index_file, xmlDocPtr xmldoc) -{ - FILE *newindex = NULL; - - /* check to see if the file already exists, if so rename it */ - /* I only enable this for debugging */ -#if 0 - if (g_file_test (index_file, G_FILE_TEST_EXISTS)) { - struct stat buff; - gchar *backup_file = NULL; - - if (g_stat (index_file, &buff) < 0) - g_warning ("Unable to stat file \"%s\"\n", index_file); - - backup_file = g_strdup_printf ("%s.%d", index_file, (int) buff.st_mtime); - - if (g_rename (index_file, backup_file) < 0) - g_warning ("Unable to rename \"%s\" to \"%s\"\n", index_file, backup_file); - - g_free (backup_file); - } -#endif - - if (!(newindex = g_fopen (index_file, "w"))) - g_warning ("Unable to create '%s'\n", index_file); - else { - xmlDocDump (newindex, xmldoc); - fclose (newindex); - } -} - -/* returns 0 on error, 1 otherwise */ -static int -create_toc_from_index (YelpTocPager *pager, gchar *index_file) -{ - const gchar * const * langs = g_get_language_names (); - xmlXPathContextPtr xpath = NULL; - xmlXPathObjectPtr objsect = NULL; - xmlDocPtr manindex_xml = NULL; - xmlNodePtr root = NULL; - xmlChar *language = NULL; - gint update_flag = 0; - gint i, j; - - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - manindex_xml = xmlReadFile (index_file, NULL, XML_PARSE_NOCDATA | - XML_PARSE_NOERROR | XML_PARSE_NONET); - - if (manindex_xml == NULL) { - g_warning ("Unable to parse index file \"%s\"\n", index_file); - return 0; - } - - /* check the language that this index file was generated for */ - root = xmlDocGetRootElement (manindex_xml); - language = xmlGetProp (root, BAD_CAST "lang"); - - /* if the language is not the same as the current language (specified - * by the LANGUAGE environment variable) then return so that the index - * is recreated */ - if (language == NULL || !g_str_equal (BAD_CAST language, langs[0])) { - debug_print (DB_INFO, - "LANGUAGE and index file language do not match, " - "index file will be recreated.\n"); - xmlFreeDoc (manindex_xml); - return 0; - } - - xmlFree (language); - - xpath = xmlXPathNewContext (manindex_xml); - objsect = xmlXPathEvalExpression (BAD_CAST "/manindex/mansect", xpath); - - for (i=0; i < objsect->nodesetval->nodeNr; i++) { - xmlXPathObjectPtr objdirs; - - if (!priv->man_manhash) - priv->man_manhash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - xpath->node = objsect->nodesetval->nodeTab[i]; - objdirs = xmlXPathEvalExpression (BAD_CAST "dir", xpath); - - for (j=0; j < objdirs->nodesetval->nodeNr; j++) { - xmlNodePtr dirnode = objdirs->nodesetval->nodeTab[j]; - xmlNodePtr node = NULL; - xmlChar *dirname = NULL; - xmlChar *dirmtime = NULL; - xmlChar *lang = NULL; - time_t mtime; - struct stat buf; - - lang = xmlGetProp (dirnode, BAD_CAST "lang"); - dirmtime = xmlGetProp (dirnode, BAD_CAST "mtime"); - - if (lang == NULL) - lang = xmlStrdup (BAD_CAST "C"); - - for (node = dirnode->children; node != NULL; node = node->next) { - if (node->type == XML_ELEMENT_NODE && - g_str_equal ((gchar *)node->name, "name")) { - dirname = xmlNodeGetContent (node); - } - } - - g_hash_table_insert (priv->man_dirlang, g_strdup ((gchar *)dirname), - g_strdup ((gchar *)lang)); - - /* if we can't stat the dirname for some reason, then skip adding - * this directory to the TOC, remove the dirnode, and set the flag - * to rewrite the cache file */ - if (g_stat ((gchar *)dirname, &buf) < 0) { - g_warning ("Unable to stat dir \"%s\", removing from cache file.\n", dirname); - xmlUnlinkNode (dirnode); - xmlFreeNode (dirnode); - update_flag = 1; - continue; - } - - /* FIXME: need some error checking */ - mtime = (time_t) atoi ((gchar *)dirmtime); - - /* see if directory mtime has changed - if so recreate - * the directory node */ - if (buf.st_mtime > mtime) { - GDir *dir; - xmlNodePtr newNode = NULL; - gchar mtime_str[20]; - gchar *filename = NULL; - - /* this means we will rewrite the cache file at the end */ - update_flag = 1; - - if ((dir = g_dir_open ((gchar *)dirname, 0, NULL))) { - g_snprintf (mtime_str, 20, "%u", (guint) buf.st_mtime); - - newNode = xmlNewNode (NULL, BAD_CAST "dir"); - xmlNewProp (newNode, BAD_CAST "mtime", BAD_CAST mtime_str); - xmlAddChild (newNode, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (newNode, NULL, BAD_CAST "name", dirname); - xmlAddChild (newNode, xmlNewText (BAD_CAST "\n ")); - - while ((filename = (gchar *) g_dir_read_name (dir))) { - - xmlNewChild (newNode, NULL, BAD_CAST "page", BAD_CAST filename); - xmlAddChild (newNode, xmlNewText (BAD_CAST "\n ")); - - add_man_page_to_toc (pager, (gchar *)dirname, filename); - priv->manpage_count++; - } - - g_dir_close (dir); - } - - /* we replace the node in the tree */ - xmlReplaceNode (dirnode, newNode); - - /* otherwise just read from the index file */ - } else { - - for (node = dirnode->children; node != NULL; node = node->next) { - xmlChar *manpage = NULL; - - if (node->type == XML_ELEMENT_NODE && - g_str_equal ((gchar *)node->name, "page")) { - manpage = xmlNodeGetContent (node); - add_man_page_to_toc (pager, (gchar *)dirname, (gchar *)manpage); - priv->manpage_count++; - xmlFree (manpage); - } - } - - } - xmlFree (lang); - xmlFree (dirmtime); - xmlFree (dirname); - } - - /* cleanup */ - xmlXPathFreeObject (objdirs); - - if (priv->man_manhash) { - g_hash_table_destroy (priv->man_manhash); - priv->man_manhash = NULL; - } - } - - if (update_flag) { - create_manindex_file (index_file, manindex_xml); - } - - xmlXPathFreeContext (xpath); - xmlXPathFreeObject (objsect); - xmlFreeDoc (manindex_xml); - - return 1; -} - -static int -spoon_add_man_document (SpoonManEntry *entry, void *user_data) -{ - xmlNodePtr node = (xmlNodePtr) user_data; - xmlNodePtr new; - gchar tmp[255]; - new = xmlNewChild (node, NULL, BAD_CAST "doc", NULL); - g_sprintf (&tmp, "man:%s", entry->path); - - xmlNewNsProp (new, NULL, BAD_CAST "href", BAD_CAST tmp); - xmlNewTextChild (new, NULL, BAD_CAST "title", BAD_CAST entry->name); - if (entry->comment) - xmlNewTextChild (new, NULL, BAD_CAST "description", BAD_CAST entry->comment); - return TRUE; -} - -static gboolean -process_mandir_pending (YelpTocPager *pager) -{ - xmlNodePtr node = NULL; - xmlNodePtr cat_node = NULL; - xmlNodePtr mynode = NULL; - char **categories = NULL; - char **cat_iter = NULL; - int sectno = 0; - YelpTocPagerPriv * priv = pager->priv; - int i, j; - xmlXPathContextPtr xpath; - xmlXPathObjectPtr obj; - - priv->man_doc = xmlCtxtReadFile (priv->parser, DATADIR "/yelp/man.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - xpath = xmlXPathNewContext (priv->man_doc); - obj = xmlXPathEvalExpression (BAD_CAST "//toc", xpath); - - for (i = 0; i < obj->nodesetval->nodeNr; i++) { - xmlNodePtr node = obj->nodesetval->nodeTab[i]; - xmlChar *sect = xmlGetProp (node, BAD_CAST "sect"); - - if (sect) { - gchar **sects = g_strsplit ((gchar *)sect, " ", 0); - - cat_node = xmlNewChild (node, NULL, BAD_CAST "toc", - NULL); - for (j = 0; sects[j] != NULL; j++) - spoon_man_for_each_in_category (sects[j], spoon_add_man_document, node); - g_strfreev (sects); - } - xmlFree (sect); - xml_trim_titles (node, BAD_CAST "title"); - xml_trim_titles (node, BAD_CAST "description"); - } - xmlXPathFreeObject (obj); - xmlXPathFreeContext (xpath); - -#if 0 - static gchar *index_file = NULL; - gchar *filename = NULL; - gchar *dirname = NULL; - GDir *dir = NULL; - gint i, j, k; - - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - - if (!priv->man_doc) { - xmlXPathContextPtr xpath; - xmlXPathObjectPtr obj; - - /* NOTE: this document is free()'d at the end of the process_xslt function */ - priv->man_doc = xmlCtxtReadFile (priv->parser, DATADIR "/yelp/man.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - priv->man_secthash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - - xpath = xmlXPathNewContext (priv->man_doc); - obj = xmlXPathEvalExpression (BAD_CAST "//toc", xpath); - - for (i = 0; i < obj->nodesetval->nodeNr; i++) { - xmlNodePtr node = obj->nodesetval->nodeTab[i]; - xmlChar *sect = xmlGetProp (node, BAD_CAST "sect"); - - if (sect) { - gchar **sects = g_strsplit ((gchar *)sect, " ", 0); - - for (j = 0; sects[j] != NULL; j++) - g_hash_table_insert (priv->man_secthash, - g_strdup (sects[j]), node); - g_strfreev (sects); - } - xmlFree (sect); - xml_trim_titles (node, BAD_CAST "title"); - xml_trim_titles (node, BAD_CAST "description"); - } - xmlXPathFreeObject (obj); - xmlXPathFreeContext (xpath); - } - - if (!index_file) - index_file = g_build_filename (yelp_dot_dir(), "manindex.xml", NULL); - - /* On first call to this function, create a list of directories that we - * need to process: we actually make a linked list (mandir_list) whose - * members who are linked lists containing directories for a particular - * man directory such as "man1", "man2", etc.. We do this because we - * need a separate hash for every mandir */ - if (!priv->mandir_list) { - const gchar * const * langs = g_get_language_names (); - gchar *manpath = NULL; - gchar **manpaths = NULL; - gchar **mandirs = NULL; - - if (!priv->man_dirlang) - priv->man_dirlang = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - - /* check for the existence of the xml cache file in ~/.gnome2/yelp.d/ - * if it exists, use it as the source for man pages instead of - * searching the hard disk for them - should make startup much faster */ - if (g_file_test (index_file, G_FILE_TEST_IS_REGULAR) && - create_toc_from_index (pager, index_file)) { - xmlNodePtr mynode; - - mynode = xmlCopyNode (xmlDocGetRootElement (priv->man_doc), 1); - xmlAddChild (xmlDocGetRootElement(priv->toc_doc), mynode); - - xmlFreeDoc (priv->man_doc); - - /* we are done processing, return FALSE so we don't call this - * function again. */ - return FALSE; - } - - mandirs = yelp_get_man_paths (); - priv->manindex_xml = xmlNewDoc (BAD_CAST "1.0"); - priv->root = xmlNewNode (NULL, BAD_CAST "manindex"); - xmlNewProp (priv->root, BAD_CAST "lang", BAD_CAST langs[0]); - priv->ins = priv->root; - - xmlDocSetRootElement (priv->manindex_xml, priv->root); - - xmlAddChild (priv->root, xmlNewText (BAD_CAST "\n ")); - - if (!g_spawn_command_line_sync ("manpath", &manpath, NULL, NULL, NULL)) - manpath = g_strdup (g_getenv ("MANPATH")); - - if (!manpath) { - manpath = g_strdup ("/usr/share/man"); - } - - g_strstrip (manpath); - manpaths = g_strsplit (manpath, G_SEARCHPATH_SEPARATOR_S, -1); - g_free (manpath); - - /* order is important here, since we may encounter collisions when adding - * a man page to the hash table "man_manhash". - * - * We want the resulting list to be sorted in order of priority: - * 1) Highest priority is given to the base directory name returned - * from $MANPATH or the manpath program. So if that is - * /usr/local/share:/usr/share then the man page - * /usr/local/share/man/man1/python.1.gz would have precedence over - * /usr/share/man/man1/python.1.gz - * 2) Next highest priority is given to the language. - * 3) Lowest priority is given to the section name, i.e. "man0p" "man1" - * since a man page from one section should never conflict with a man page - * from another section (because of the .0p or .1 section in the filename) - * - * Here is an example of how it should be sorted when - * $MANPATH=/usr/local/share:/usr/share and LANGUAGE="es" - * - * Adding /usr/local/share/man/es/man0p - * Adding /usr/share/man/es/man0p - * Adding /usr/local/share/man/man0p - * Adding /usr/share/man/man0p - * Adding /usr/local/share/man/es/man1 - * Adding /usr/share/man/es/man1 - * Adding /usr/local/share/man/man1 - * Adding /usr/share/man/man1 - */ - - for (i=0; mandirs[i] != NULL; i++) { - GSList *tmplist = NULL; - - for (j=0; langs[j] != NULL; j++) { - for (k=0; manpaths[k] != NULL; k++) { - if (g_str_equal (langs[j], "C")) - dirname = g_build_filename (manpaths[k], mandirs[i], NULL); - else - dirname = g_build_filename (manpaths[k], langs[j], - mandirs[i], - NULL); - - g_hash_table_insert (priv->man_dirlang, g_strdup (dirname), - g_strdup (langs[j])); - - /* prepend to list for speed, reverse it at the end */ - tmplist = g_slist_prepend (tmplist, dirname); - } - } - tmplist = g_slist_reverse (tmplist); - - priv->mandir_list = g_slist_prepend (priv->mandir_list, tmplist); - } - priv->mandir_list = g_slist_reverse (priv->mandir_list); - -#ifdef YELP_DEBUG - /* debugging: print out lists in order */ - GSList *list1 = priv->mandir_list; - GSList *list2 = NULL; - - while (list1 != NULL) { - list2 = list1->data; - while (list2 && list2->data) { - debug_print (DB_INFO, "Dir=%s\n", (gchar *)list2->data); - list2 = g_slist_next (list2); - } - list1 = g_slist_next (list1); - } -#endif - - g_strfreev (manpaths); - - priv->mandir_ptr = priv->mandir_list; - if (priv->mandir_list && priv->mandir_list->data) { - priv->mandir_langpath = priv->mandir_list->data; - } - - /* return TRUE, so that this function is called again.*/ - return TRUE; - } - - /* iterate through our previously created linked lists and create the - * table of contents from them */ - if (priv->mandir_langpath && priv->mandir_langpath->data) { - dirname = priv->mandir_langpath->data; - - if ((dir = g_dir_open (dirname, 0, NULL))) { - struct stat buf; - gchar mtime_str[20]; - gchar *lang = NULL; - - if (g_stat (dirname, &buf) < 0) - debug_print (DB_WARN, "Unable to stat dir: \"%s\"\n", dirname); - - /* check to see if we need create a new hash table */ - if (!priv->man_manhash) { - priv->man_manhash = - g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - priv->ins = xmlNewChild (priv->root, NULL, BAD_CAST "mansect", NULL); - xmlAddChild (priv->ins, xmlNewText (BAD_CAST "\n ")); - } - - g_snprintf (mtime_str, 20, "%u", (guint) buf.st_mtime); - - lang = g_hash_table_lookup (priv->man_dirlang, dirname); - - priv->ins = xmlNewChild (priv->ins, NULL, BAD_CAST "dir", NULL); - - if (lang == NULL) { - g_print ("dir %s is null\n", dirname); - lang = "C"; - } - - xmlNewProp (priv->ins, BAD_CAST "lang", BAD_CAST lang); - - xmlNewProp (priv->ins, BAD_CAST "mtime", BAD_CAST mtime_str); - xmlAddChild (priv->ins, xmlNewText (BAD_CAST "\n ")); - xmlNewChild (priv->ins, NULL, BAD_CAST "name", BAD_CAST dirname); - xmlAddChild (priv->ins, xmlNewText (BAD_CAST "\n ")); - xmlAddChild (priv->ins->parent, xmlNewText (BAD_CAST "\n ")); - - while ((filename = (gchar *) g_dir_read_name (dir))) { - - xmlNewChild (priv->ins, NULL, BAD_CAST "page", BAD_CAST filename); - xmlAddChild (priv->ins, xmlNewText (BAD_CAST "\n ")); - - add_man_page_to_toc (pager, dirname, filename); - priv->manpage_count++; - } - - priv->ins = priv->ins->parent; - - g_dir_close (dir); - } - - priv->mandir_langpath = g_slist_next (priv->mandir_langpath); - - } else { - priv->mandir_ptr = g_slist_next (priv->mandir_ptr); - - if (priv->mandir_ptr && priv->mandir_ptr->data) { - priv->mandir_langpath = priv->mandir_ptr->data; - - if (priv->man_manhash) { - g_hash_table_destroy (priv->man_manhash); - priv->man_manhash = NULL; - } - } else { /* no more entries to prcoess, write file & cleanup */ - GSList *listptr = priv->mandir_list; - xmlNodePtr copynode; - - while (listptr && listptr->data) { - GSList *langptr = listptr->data; - - while (langptr && langptr->data) { - g_free (langptr->data); - langptr = g_slist_next (langptr); - } - - g_slist_free (listptr->data); - - listptr = g_slist_next (listptr); - } - - g_slist_free (priv->mandir_list); - - create_manindex_file (index_file, priv->manindex_xml); - - xmlFree (priv->manindex_xml); - - copynode = xmlCopyNode (xmlDocGetRootElement (priv->man_doc), 1); - xmlAddChild (xmlDocGetRootElement(priv->toc_doc), copynode); - - xmlFreeDoc (priv->man_doc); - - /* done processing */ - return FALSE; - } - } - - return TRUE; -#endif - - mynode = xmlCopyNode (xmlDocGetRootElement (priv->man_doc), 1); - xmlAddChild (xmlDocGetRootElement (priv->toc_doc), mynode); - - xmlFreeDoc (priv->man_doc); - - return FALSE; -} -#endif // ENABLE_MAN - -#ifdef ENABLE_INFO - -static int -spoon_info_add_document (SpoonInfoEntry *entry, void *user_data) -{ - xmlNodePtr node = (xmlNodePtr) user_data; - xmlNodePtr new; - gchar tmp[255]; - new = xmlNewChild (node, NULL, BAD_CAST "doc", NULL); - if (entry->section) - g_sprintf(&tmp, "info:%s#%s", entry->name, entry->section); - else - g_sprintf(&tmp, "info:%s", entry->name); - xmlNewNsProp (new, NULL, BAD_CAST "href", BAD_CAST tmp); - xmlNewTextChild (new, NULL, BAD_CAST "title", BAD_CAST entry->name); - xmlNewTextChild (new, NULL, BAD_CAST "description", BAD_CAST entry->comment); - return TRUE; - -} - - -static gboolean -process_info_pending (YelpTocPager *pager) -{ - xmlNodePtr node = NULL; - xmlNodePtr cat_node = NULL; - xmlNodePtr mynode = NULL; - char **categories = NULL; - char **cat_iter = NULL; - int sectno = 0; - YelpTocPagerPriv * priv = pager->priv; - int i; - xmlXPathContextPtr xpath; - xmlXPathObjectPtr obj; - - priv->info_doc = xmlCtxtReadFile (priv->parser, - DATADIR "/yelp/info.xml", NULL, - XML_PARSE_NOBLANKS | - XML_PARSE_NOCDATA | - XML_PARSE_NOENT | - XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - xpath = xmlXPathNewContext (priv->info_doc); - obj = xmlXPathEvalExpression (BAD_CAST "//toc", xpath); - node = obj->nodesetval->nodeTab[0]; - for (i=0; i < obj->nodesetval->nodeNr; i++) { - xmlNodePtr tmpnode = obj->nodesetval->nodeTab[i]; - xml_trim_titles (tmpnode, BAD_CAST "title"); - xml_trim_titles (tmpnode, BAD_CAST "description"); - } - xmlXPathFreeObject (obj); - xmlXPathFreeContext (xpath); - - categories = spoon_info_get_categories (); - cat_iter = categories; - - while (cat_iter && *cat_iter) { - char *tmp; - - cat_node = xmlNewChild (node, NULL, BAD_CAST "toc", - NULL); - tmp = g_strdup_printf ("%d", sectno); - xmlNewNsProp (cat_node, NULL, BAD_CAST "sect", - BAD_CAST tmp); - g_free (tmp); - tmp = g_strdup_printf ("infosect%d", sectno); - xmlNewNsProp (cat_node, NULL, BAD_CAST "id", - BAD_CAST tmp); - g_free (tmp); - sectno++; - xmlNewTextChild (cat_node, NULL, BAD_CAST "title", - BAD_CAST *cat_iter); - - spoon_info_for_each_in_category (*cat_iter, spoon_info_add_document, - cat_node); - cat_iter++; - } - - mynode = xmlCopyNode (xmlDocGetRootElement (priv->info_doc), 1); - xmlAddChild (xmlDocGetRootElement (priv->toc_doc), mynode); - - xmlFreeDoc (priv->info_doc); - - -#if 0 - gchar ** info_paths = yelp_get_info_paths (); - int i = 0; - gchar *filename = NULL; - xmlNodePtr mynode = NULL; - - GHashTable *info_parsed = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - GHashTable *categories = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - - YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - xmlNodePtr node = NULL; - printf ("Info parsing\n"); - for (i=0; info_paths[i]; i++) { - filename = g_strconcat (info_paths[i], "/dir", NULL); - - /* Search out the directory listing for info and follow that */ - if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { - g_free (filename); - continue; - } else { - GIOChannel *channel; - gchar *str = NULL; - gsize len; - gchar ** files; - gchar ** ptr; - xmlNodePtr tmp; - xmlNodePtr new_node = NULL; - gboolean menufound = FALSE; - - if (!priv->info_doc) { - xmlXPathContextPtr xpath; - xmlXPathObjectPtr obj; - priv->info_doc = xmlCtxtReadFile (priv->parser, DATADIR "/yelp/info.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - - xpath = xmlXPathNewContext (priv->info_doc); - obj = xmlXPathEvalExpression (BAD_CAST "//toc", xpath); - node = obj->nodesetval->nodeTab[0]; - for (i=0; i < obj->nodesetval->nodeNr; i++) { - xmlNodePtr tmpnode = obj->nodesetval->nodeTab[i]; - xml_trim_titles (tmpnode, BAD_CAST "title"); - xml_trim_titles (tmpnode, BAD_CAST "description"); - } - xmlXPathFreeObject (obj); - xmlXPathFreeContext (xpath); - } - - channel = yelp_io_channel_new_file (filename, NULL); - g_io_channel_read_to_end (channel, &str, &len, NULL); - g_io_channel_shutdown (channel, FALSE, NULL); - g_io_channel_unref (channel); - - files = g_strsplit (str, "\n", -1); - - for (ptr = files; *ptr != NULL; ptr++) { - if (!menufound) { - if (g_str_has_prefix (*ptr, "* Menu:")) { - menufound = TRUE; - } - } else { - if (g_str_has_prefix (*ptr, "*")) { - /* A menu item */ - gchar *tooltip = NULL; - gchar *fname = NULL; - gchar *desc = NULL; - gchar *part1 = NULL, *part2 = NULL, *part3 = NULL; - gchar *path = *ptr; - gchar **nextline = ptr; - gchar *p = NULL; - nextline++; - /* Due to braindead info stuff, we gotta manually - * split everything up... - */ - path++; - if (!path) - goto done; - part1 = strchr (path, ':'); - if (!part1) - goto done; - part2 = g_strndup (path, part1-path); - p = g_strdup (part2); - p = g_strstrip (p); - tooltip = g_strdup_printf (_("Read info page for %s"), p); - g_free (p); - path = part1+1; - part1 = strchr (path, ')'); - if (!part1) - goto done; - part1 = strchr (part1, '.'); - if (!part1) - goto done; - part3 = g_strndup (path, part1-path); - part1++; - desc = g_strdup (part1); - g_strstrip (desc); - - fname = g_strconcat ("info:", g_strstrip(part3), NULL); - - if (!g_hash_table_lookup (info_parsed, fname)) { - g_hash_table_insert (info_parsed, - g_strdup (fname), - g_strdup (part1)); - - while (*nextline && - g_ascii_isspace (**nextline)) { - gchar *newbit = g_strdup (*nextline); - gchar *olddesc = desc; - g_strstrip (newbit); - desc = g_strconcat (desc, " ",newbit, NULL); - nextline++; - g_free (newbit); - g_free (olddesc); - } - ptr = --nextline; - - tmp = xmlNewChild (new_node, NULL, BAD_CAST "doc", - NULL); - xmlNewNsProp (tmp, NULL, BAD_CAST "href", BAD_CAST fname); - - xmlNewTextChild (tmp, NULL, BAD_CAST "title", - BAD_CAST part2); - xmlNewTextChild (tmp, NULL, BAD_CAST "tooltip", - BAD_CAST tooltip); - - xmlNewTextChild (tmp, NULL, BAD_CAST "description", - BAD_CAST desc); - } - done: - g_free (part2); - g_free (part3); - g_free (tooltip); - g_free (desc); - g_free (fname); - } else if (!g_ascii_isspace (**ptr) && g_ascii_isprint(**ptr)){ - new_node = g_hash_table_lookup (categories, *ptr); - if (!new_node) { - gchar *tmp; - - /* A new section */ - static int sectno = 1; - new_node = xmlNewChild (node, NULL, BAD_CAST "toc", - NULL); - tmp = g_strdup_printf ("%d", sectno); - xmlNewNsProp (new_node, NULL, BAD_CAST "sect", - BAD_CAST tmp); - g_free (tmp); - tmp = g_strdup_printf ("infosect%d", sectno); - xmlNewNsProp (new_node, NULL, BAD_CAST "id", - BAD_CAST tmp); - g_free (tmp); - sectno++; - xmlNewTextChild (new_node, NULL, BAD_CAST "title", - BAD_CAST *ptr); - g_hash_table_insert (categories, - g_strdup (*ptr), - new_node); - } - - } - } - } - g_free (filename); - g_free (str); - g_strfreev (files); - } - } - g_hash_table_destroy (info_parsed); - g_hash_table_destroy (categories); - - mynode = xmlCopyNode (xmlDocGetRootElement (priv->info_doc), 1); - xmlAddChild (xmlDocGetRootElement (priv->toc_doc), mynode); - - xmlFreeDoc (priv->info_doc); - -#endif - return FALSE; -} -#endif /* ENABLE_INFO */ - -static int -spoon_add_document (void *reg, void * user_data) -{ - xmlNodePtr node = (xmlNodePtr) user_data; - SpoonReg *r = (SpoonReg *) reg; - xmlNodePtr new; - gchar tmp[10]; - - new = xmlNewChild (node, NULL, BAD_CAST "doc", NULL); - xmlNewNsProp (new, NULL, BAD_CAST "href", BAD_CAST r->uri); - xmlNewTextChild (new, NULL, BAD_CAST "title", BAD_CAST r->name); - xmlNewTextChild (new, NULL, BAD_CAST "description", BAD_CAST r->comment); - g_sprintf (&tmp, "%d", r->weight); - xmlNewNsProp (new, NULL, BAD_CAST "weight", BAD_CAST tmp); - return FALSE; -} - -static gboolean -process_read_menu (YelpTocPager *pager) -{ - xmlTextReaderPtr reader; - xmlXPathContextPtr xpath; - xmlXPathObjectPtr obj; - GError *error = NULL; - gint i, ret; - - YelpTocPagerPriv *priv = pager->priv; - - priv->toc_doc = xmlCtxtReadFile (priv->parser, DATADIR "/yelp/toc.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - if (!priv->toc_doc) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_TOC, - _("The table of contents could not be loaded. The file " - "‘%s’ is either missing or is not well-formed XML."), - DATADIR "/yelp/toc.xml"); - yelp_pager_error (YELP_PAGER (pager), error); - priv->cancel = TRUE; - return FALSE; - } - - xpath = xmlXPathNewContext (priv->toc_doc); - obj = xmlXPathEvalExpression (BAD_CAST "//toc", xpath); - for (i = 0; i < obj->nodesetval->nodeNr; i++) { - xmlNodePtr node = obj->nodesetval->nodeTab[i]; - xmlChar *icon = NULL; -#if 0 - xmlChar *id = NULL; - xmlNodePtr cmdhelp; - xmlNodePtr newnode; - id = xmlGetProp (node, BAD_CAST "id"); - if (!xmlStrcmp (id, BAD_CAST "index")) { - cmdhelp = xmlNewChild (node, NULL, BAD_CAST "toc", NULL); - xmlNewNsProp (cmdhelp, NULL, BAD_CAST "id", BAD_CAST "ManInfoHolder"); - xmlNewChild (cmdhelp, NULL, BAD_CAST "title", - BAD_CAST _("Command Line Help")); -#ifdef ENABLE_MAN - newnode = xmlNewChild (cmdhelp, NULL, BAD_CAST "toc", NULL); - xmlNewNsProp (newnode, NULL, BAD_CAST "id", BAD_CAST "Man"); - xmlNewChild (newnode, NULL, BAD_CAST "title", - BAD_CAST _("Manual Pages")); -#endif // ENABLE_MAN -#ifdef ENABLE_INFO - newnode = xmlNewChild (cmdhelp, NULL, BAD_CAST "toc", NULL); - xmlNewNsProp (newnode, NULL, BAD_CAST "id", BAD_CAST "Info"); - xmlNewChild (newnode, NULL, BAD_CAST "title", - BAD_CAST _("GNU Info Pages")); -#endif //ENABLE_INFO - } - xmlFree (id); -#endif //ENABLE_MAN_OR_INFO - - xml_trim_titles (node, BAD_CAST "title"); - xml_trim_titles (node, BAD_CAST "description"); - - icon = xmlGetProp (node, BAD_CAST "icon"); - if (icon) { - GtkIconInfo *info; - GtkIconTheme *theme = - (GtkIconTheme *) yelp_settings_get_icon_theme (); - info = gtk_icon_theme_lookup_icon (theme, (gchar *) icon, 48, 0); - if (info) { - xmlNodePtr new = xmlNewChild (node, NULL, BAD_CAST "icon", - NULL); - xmlNewNsProp (new, NULL, BAD_CAST "file", - BAD_CAST gtk_icon_info_get_filename (info)); - gtk_icon_info_free (info); - } - } - xmlFree (icon); - - } - xmlXPathFreeObject (obj); - - /* here we populate the category_hash structure of the YelpTocPager's - * private data. The hash key is a scrollkeeper category defined in the - * scrollkeeper.xml file and the value is a pointer to the parent node. - */ - reader = xmlReaderForFile (DATADIR "/yelp/scrollkeeper.xml", NULL, - XML_PARSE_NOBLANKS | XML_PARSE_NOCDATA | - XML_PARSE_NOENT | XML_PARSE_NOERROR | - XML_PARSE_NONET ); - ret = xmlTextReaderRead (reader); - while (ret == 1) { - if (!xmlStrcmp (xmlTextReaderConstLocalName (reader), - BAD_CAST "toc")) { - xmlChar *id = xmlTextReaderGetAttribute (reader, BAD_CAST "id"); - xmlNodePtr node; - gchar *xpath_s; - - if (!id) { - ret = xmlTextReaderRead (reader); - continue; - } - - xpath_s = g_strdup_printf ("//toc[@id = '%s']", id); - obj = xmlXPathEvalExpression (BAD_CAST xpath_s, xpath); - g_free (xpath_s); - - node = obj->nodesetval->nodeTab[0]; - xmlXPathFreeObject (obj); - - ret = xmlTextReaderRead (reader); - while (ret == 1) { - if (!xmlStrcmp (xmlTextReaderConstLocalName (reader), - BAD_CAST "subject")) { - xmlChar *cat = xmlTextReaderGetAttribute (reader, - BAD_CAST "category"); - /*g_hash_table_insert (priv->category_hash, - g_strdup ((gchar *) cat), - node);*/ - spoon_for_each_in_category (spoon_add_document, - (char *) cat, - (void *) node); - xmlFree (cat); - } - else if (!xmlStrcmp (xmlTextReaderConstLocalName (reader), - BAD_CAST "toc")) { - break; - } - ret = xmlTextReaderRead (reader); - } - - xmlFree (id); - ret = xmlTextReaderRead (reader); - } else { - ret = xmlTextReaderRead (reader); - } - } - xmlFreeTextReader (reader); - xmlXPathFreeContext (xpath); - - return FALSE; -} - -static gboolean -process_xslt (YelpTocPager *pager) -{ - GError *error = NULL; - xmlDocPtr outdoc = NULL; - YelpTocPagerPriv *priv = pager->priv; - gchar **params = NULL; - gint params_i = 0; - gint params_max = 10; - GtkIconInfo *info; - GtkIconTheme *theme = (GtkIconTheme *) yelp_settings_get_icon_theme (); - - if (!priv->toc_doc) - return FALSE; - - /* only create and parse the stylesheet on the first call to this function */ - if (!priv->stylesheet) { - priv->stylesheet = xsltParseStylesheetFile (BAD_CAST TOC_STYLESHEET); - } - - if (!priv->stylesheet) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC, - _("The table of contents could not be processed. The " - "file ‘%s’ is either missing or is not a valid XSLT " - "stylesheet."), - TOC_STYLESHEET); - yelp_pager_error (YELP_PAGER (pager), error); - goto done; - } - - priv->transformContext = xsltNewTransformContext (priv->stylesheet, - priv->toc_doc); - priv->transformContext->_private = pager; - xsltRegisterExtElement (priv->transformContext, - BAD_CAST "document", - BAD_CAST YELP_NAMESPACE, - (xsltTransformFunction) xslt_yelp_document); - - params = g_new0 (gchar *, params_max); - yelp_settings_params (¶ms, ¶ms_i, ¶ms_max); - - if ((params_i + 10) >= params_max - 1) { - params_max += 10; - params = g_renew (gchar *, params, params_max); - } - - info = gtk_icon_theme_lookup_icon (theme, "yelp-icon-big", 192, 0); - if (info) { - params[params_i++] = "help_icon"; - params[params_i++] = g_strdup_printf ("\"%s\"", - gtk_icon_info_get_filename (info)); - params[params_i++] = "help_icon_size"; - params[params_i++] = g_strdup_printf ("%i", - gtk_icon_info_get_base_size (info)); - gtk_icon_info_free (info); - } - - params[params_i++] = NULL; - - outdoc = xsltApplyStylesheetUser (priv->stylesheet, - priv->toc_doc, - (const gchar **)params, NULL, NULL, - priv->transformContext); - /* Don't do this */ - g_signal_emit_by_name (pager, "finish"); - - done: - if (params) { - for (params_i = 0; params[params_i] != NULL; params_i++) - if (params_i % 2 == 1) - g_free ((gchar *) params[params_i]); - } - if (outdoc) - xmlFreeDoc (outdoc); - if (priv->toc_doc) { - xmlFreeDoc (priv->toc_doc); - priv->toc_doc = NULL; - } - if (priv->transformContext) { - xsltFreeTransformContext (priv->transformContext); - priv->transformContext = NULL; - } - - return FALSE; -} - -static gboolean -process_cleanup (YelpTocPager *pager) -{ - YelpTocPagerPriv *priv = pager->priv; - - /* dump the toc_doc if we are debugging */ - /*d (xmlDocDump (stdout, priv->toc_doc)); */ - -#ifdef ENABLE_MAN - /* clean up the man directory language hash table */ - if (priv->man_dirlang) { - g_hash_table_destroy (priv->man_dirlang); - priv->man_dirlang = NULL; - } - - /* clean up the man page section hash table */ - if (priv->man_secthash) { - g_hash_table_destroy (priv->man_secthash); - priv->man_secthash = NULL; - } -#endif - - /* cleanup the stylesheet used to process the toc */ - if (priv->stylesheet) { - xsltFreeStylesheet (priv->stylesheet); - priv->stylesheet = NULL; - } - - /* cleanup the parser context */ - if (priv->parser) { - xmlFreeParserCtxt (priv->parser); - priv->parser = NULL; - } - - /* we only ever want to run this function once, so always return false */ - return FALSE; -} - -static void -toc_add_doc_info (YelpTocPager *pager, YelpDocInfo *doc_info) -{ - xmlNodePtr node; - xmlNodePtr new; - gchar *text; - gchar *category; - - g_return_if_fail (pager != NULL); - if (doc_info == NULL) - return; - - /* check if the document category exists, and return if it does not - * should fix 353554 */ - category = yelp_doc_info_get_category (doc_info); - if (category == NULL) { - debug_print (DB_DEBUG, "Missing category for %s\n", - yelp_doc_info_get_title (doc_info)); - return; - } - - YelpTocPagerPriv *priv = pager->priv; - - g_hash_table_insert (priv->unique_hash, - (gchar *) yelp_doc_info_get_id (doc_info), - doc_info); - - node = g_hash_table_lookup (priv->category_hash, category); - - text = yelp_doc_info_get_uri (doc_info, NULL, YELP_URI_TYPE_FILE); - new = xmlNewChild (node, NULL, BAD_CAST "doc", NULL); - xmlNewNsProp (new, NULL, BAD_CAST "href", BAD_CAST text); - g_free (text); - - text = (gchar *) yelp_doc_info_get_title (doc_info); - xmlNewTextChild (new, NULL, BAD_CAST "title", BAD_CAST text); - - text = (gchar *) yelp_doc_info_get_description (doc_info); - xmlNewTextChild (new, NULL, BAD_CAST "description", BAD_CAST text); -} - -static void -toc_remove_doc_info (YelpTocPager *pager, YelpDocInfo *doc_info) -{ -#if 0 - GSList *category; - YelpTocPagerPriv *priv = pager->priv; - - g_hash_table_remove (pager->priv->unique_hash, meta->id); - - for (category = meta->categories; category; category = category->next) { - gchar *catstr = (gchar *) category->data; - GSList *metas = - (GSList *) g_hash_table_lookup (pager->priv->category_hash, catstr); - - metas = g_slist_remove (metas, meta); - if (metas) - g_hash_table_insert (pager->priv->category_hash, - g_strdup (catstr), metas); - else - g_hash_table_remove (pager->priv->category_hash, catstr); - } - - priv->idx_pending = g_slist_remove (priv->idx_pending, meta); -#endif -} - -static void -xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp) -{ - GError *error; - YelpPage *page; - xmlChar *page_id = NULL; - xmlChar *page_title = NULL; - xmlChar *page_buf; - gint buf_size; - YelpPager *pager; - xsltStylesheetPtr style = NULL; - const char *old_outfile; - xmlDocPtr new_doc = NULL; - xmlDocPtr old_doc; - xmlNodePtr old_insert; - xmlNodePtr cur; - xmlDtdPtr dtd; - - if (!ctxt || !node || !inst || !comp) - return; - - pager = (YelpPager *) ctxt->_private; - - page_id = xsltEvalAttrValueTemplate (ctxt, inst, - (const xmlChar *) "href", - NULL); - if (page_id == NULL) { - xsltTransformError (ctxt, NULL, inst, - _("No href attribute found on yelp:document")); - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - - old_outfile = ctxt->outputFile; - old_doc = ctxt->output; - old_insert = ctxt->insert; - ctxt->outputFile = (const char *) page_id; - - style = xsltNewStylesheet (); - if (style == NULL) { - xsltTransformError (ctxt, NULL, inst, _("Out of memory")); - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - - style->omitXmlDeclaration = FALSE; - - new_doc = xmlNewDoc (BAD_CAST "1.0"); - dtd = xmlCreateIntSubset (new_doc, - BAD_CAST "html", - BAD_CAST "-//W3C//DTD XHTML 1.0 Strict//EN", - BAD_CAST "http://www.w3.org/TR/" - "xhtml1/DTD/xhtml1-strict.dtd"); - new_doc->intSubset = dtd; - new_doc->extSubset = dtd; - new_doc->charset = XML_CHAR_ENCODING_UTF8; - new_doc->encoding = xmlStrdup (BAD_CAST "utf-8"); - new_doc->dict = ctxt->dict; - xmlDictReference (new_doc->dict); - - ctxt->output = new_doc; - ctxt->insert = (xmlNodePtr) new_doc; - - xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL); - - xsltSaveResultToString (&page_buf, &buf_size, new_doc, style); - - ctxt->outputFile = old_outfile; - ctxt->output = old_doc; - ctxt->insert = old_insert; - - for (cur = node->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, BAD_CAST "title")) { - page_title = xmlNodeGetContent (cur); - break; - } - } - - page = g_new0 (YelpPage, 1); - - if (page_id) { - page->page_id = g_strdup ((gchar *) page_id); - xmlFree (page_id); - } - if (page_title) { - page->title = g_strdup ((gchar *) page_title); - xmlFree (page_title); - } else { - page->title = g_strdup (_("Help Contents")); - } - page->contents = (gchar *) page_buf; - - cur = xmlDocGetRootElement (new_doc); - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "head")) { - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "link")) { - xmlChar *rel = xmlGetProp (cur, BAD_CAST "rel"); - - if (!xmlStrcmp (rel, (xmlChar *) "Previous")) - page->prev_id = (gchar *) xmlGetProp (cur, - BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "Next")) - page->next_id = (gchar *) xmlGetProp (cur, - BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "Top")) - page->toc_id = (gchar *) xmlGetProp (cur, - BAD_CAST "href"); - - xmlFree (rel); - } - } - break; - } - } - - yelp_pager_add_page (pager, page); - g_signal_emit_by_name (pager, "page", page->page_id); - - done: - if (new_doc) - xmlFreeDoc (new_doc); - if (style) - xsltFreeStylesheet (style); -} - -static void -xml_trim_titles (xmlNodePtr node, xmlChar * nodetype) -{ - xmlNodePtr cur, keep = NULL; - xmlChar *keep_lang = NULL; - int j, keep_pri = INT_MAX; - - const gchar * const * langs = g_get_language_names (); - - for (cur = node->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, nodetype)) { - xmlChar *cur_lang = NULL; - int cur_pri = INT_MAX; - cur_lang = xmlNodeGetLang (cur); - if (cur_lang) { - for (j = 0; langs[j]; j++) { - if (g_str_equal (cur_lang, langs[j])) { - cur_pri = j; - break; - } - } - } else { - cur_pri = INT_MAX - 1; - } - if (cur_pri <= keep_pri) { - if (keep_lang) - xmlFree (keep_lang); - keep_lang = cur_lang; - keep_pri = cur_pri; - keep = cur; - } else { - if (cur_lang) - xmlFree (cur_lang); - } - } - } - cur = node->children; - while (cur) { - xmlNodePtr this = cur; - cur = cur->next; - if (!xmlStrcmp (this->name, nodetype)) { - if (this != keep) { - xmlUnlinkNode (this); - xmlFreeNode (this); - } - } - } - xmlFree (keep_lang); -} diff --git a/src/yelp-toc-pager.h b/src/yelp-toc-pager.h deleted file mode 100644 index 2bbe2b8a..00000000 --- a/src/yelp-toc-pager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_TOC_PAGER_H__ -#define __YELP_TOC_PAGER_H__ - -#include - -#include "yelp-pager.h" - -#define YELP_TYPE_TOC_PAGER (yelp_toc_pager_get_type ()) -#define YELP_TOC_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_TOC_PAGER, YelpTocPager)) -#define YELP_TOC_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_TOC_PAGER, YelpTocPagerClass)) -#define YELP_IS_TOC_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_TOC_PAGER)) -#define YELP_IS_TOC_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_TOC_PAGER)) -#define YELP_TOC_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_TOC_PAGER, YelpTocPagerClass)) - -typedef struct _YelpTocPager YelpTocPager; -typedef struct _YelpTocPagerClass YelpTocPagerClass; -typedef struct _YelpTocPagerPriv YelpTocPagerPriv; - -struct _YelpTocPager { - YelpPager parent; - - YelpTocPagerPriv *priv; -}; - -struct _YelpTocPagerClass { - YelpPagerClass parent_class; -}; - -GType yelp_toc_pager_get_type (void); - -void yelp_toc_pager_init (void); -YelpTocPager * yelp_toc_pager_get (void); - -void yelp_toc_pager_pause (YelpTocPager *pager); -void yelp_toc_pager_unpause (YelpTocPager *pager); - -#endif /* __YELP_TOC_PAGER_H__ */ diff --git a/src/yelp-xslt-pager.c b/src/yelp-xslt-pager.c deleted file mode 100644 index 0439a411..00000000 --- a/src/yelp-xslt-pager.c +++ /dev/null @@ -1,575 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "yelp-error.h" -#include "yelp-settings.h" -#include "yelp-xslt-pager.h" -#include "yelp-debug.h" - -#define YELP_NAMESPACE "http://www.gnome.org/yelp/ns" - -#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration (); -#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done; - -extern gboolean main_running; - -#define YELP_XSLT_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_XSLT_PAGER, YelpXsltPagerPriv)) - -struct _YelpXsltPagerPriv { - xmlDocPtr inputDoc; - xmlDocPtr outputDoc; - xsltStylesheetPtr stylesheet; - xsltTransformContextPtr transformContext; -}; - -static void xslt_pager_class_init (YelpXsltPagerClass *klass); -static void xslt_pager_init (YelpXsltPager *pager); -static void xslt_pager_dispose (GObject *gobject); - -static void xslt_pager_error (YelpPager *pager); -static void xslt_pager_cancel (YelpPager *pager); -static void xslt_pager_finish (YelpPager *pager); - -static gboolean xslt_pager_process (YelpPager *pager); - -static void xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp); -static void xslt_yelp_cache (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp); - -static YelpPagerClass *parent_class; - -GType -yelp_xslt_pager_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (YelpXsltPagerClass), - NULL, - NULL, - (GClassInitFunc) xslt_pager_class_init, - NULL, - NULL, - sizeof (YelpXsltPager), - 0, - (GInstanceInitFunc) xslt_pager_init, - }; - type = g_type_register_static (YELP_TYPE_PAGER, - "YelpXsltPager", - &info, 0); - } - return type; -} - -static void -xslt_pager_class_init (YelpXsltPagerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->dispose = xslt_pager_dispose; - - pager_class->error = xslt_pager_error; - pager_class->cancel = xslt_pager_cancel; - pager_class->finish = xslt_pager_finish; - - pager_class->process = xslt_pager_process; - - g_type_class_add_private (klass, sizeof (YelpXsltPagerPriv)); -} - -static void -xslt_pager_init (YelpXsltPager *pager) -{ - pager->priv = YELP_XSLT_PAGER_GET_PRIVATE (pager); -} - -static void -xslt_pager_dispose (GObject *object) -{ - YelpXsltPager *pager = YELP_XSLT_PAGER (object); - YelpXsltPagerPriv *priv = pager->priv; - - if (priv->outputDoc) - xmlFreeDoc (priv->outputDoc); - if (priv->stylesheet) - xsltFreeStylesheet (priv->stylesheet); - if (priv->transformContext) - xsltFreeTransformContext (priv->transformContext); - if (priv->inputDoc) - xmlFreeDoc (priv->inputDoc); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -/******************************************************************************/ - -static gboolean -xslt_pager_process (YelpPager *pager) -{ - YelpXsltPagerPriv *priv; - YelpXsltPagerClass *klass; - - YelpDocInfo *doc_info; - gchar *filename = NULL; - - gchar **params = NULL; - gint params_i = 0; - - GError *error = NULL; - - debug_print (DB_FUNCTION, "entering\n"); - debug_print (DB_PROFILE, "entering %s", __FUNCTION__); - - g_return_val_if_fail (pager != NULL, FALSE); - g_return_val_if_fail (YELP_IS_XSLT_PAGER (pager), FALSE); - - priv = YELP_XSLT_PAGER (pager)->priv; - klass = YELP_XSLT_PAGER_GET_CLASS (pager); - - doc_info = yelp_pager_get_doc_info (pager); - - if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) - goto done; - - filename = yelp_doc_info_get_filename (doc_info); - - g_object_ref (pager); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_PARSING); - g_signal_emit_by_name (pager, "parse"); - - priv->inputDoc = klass->parse (pager); - - if (priv->inputDoc == NULL) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC, - _("The file ‘%s’ could not be parsed. Either the file " - "does not exist, or it is improperly formatted."), - filename); - yelp_pager_error (pager, error); - goto done; - } - - EVENTS_PENDING; - CANCEL_CHECK; - - yelp_pager_set_state (pager, YELP_PAGER_STATE_RUNNING); - g_signal_emit_by_name (pager, "start"); - - EVENTS_PENDING; - CANCEL_CHECK; - - params = klass->params (pager); - - priv->stylesheet = xsltParseStylesheetFile (BAD_CAST klass->stylesheet); - if (!priv->stylesheet) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC, - _("The document ‘%s’ could not be processed. The file " - "‘%s’ is either missing, or it is not a valid XSLT " - "stylesheet."), - filename, - klass->stylesheet); - yelp_pager_error (pager, error); - goto done; - } - - priv->transformContext = xsltNewTransformContext (priv->stylesheet, - priv->inputDoc); - if (!priv->transformContext) { - g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC, - _("The document ‘%s’ could not be processed. The file " - "‘%s’ is either missing, or it is not a valid XSLT " - "stylesheet."), - filename, - klass->stylesheet); - yelp_pager_error (pager, error); - goto done; - } - - priv->transformContext->_private = pager; - xsltRegisterExtElement (priv->transformContext, - BAD_CAST "document", - BAD_CAST YELP_NAMESPACE, - (xsltTransformFunction) xslt_yelp_document); - xsltRegisterExtElement (priv->transformContext, - BAD_CAST "cache", - BAD_CAST YELP_NAMESPACE, - (xsltTransformFunction) xslt_yelp_cache); - - EVENTS_PENDING; - CANCEL_CHECK; - - priv->outputDoc = xsltApplyStylesheetUser (priv->stylesheet, - priv->inputDoc, - (const char **) params, - NULL, NULL, - priv->transformContext); - CANCEL_CHECK; - g_signal_emit_by_name (pager, "finish"); - - done: - if (params) { - for (params_i = 0; params[params_i] != NULL; params_i++) - if (params_i % 2 == 1) - g_free (params[params_i]); - g_free (params); - } - g_free (filename); - - if (priv->outputDoc) { - xmlFreeDoc (priv->outputDoc); - priv->outputDoc = NULL; - } - if (priv->stylesheet) { - xsltFreeStylesheet (priv->stylesheet); - priv->stylesheet = NULL; - } - if (priv->transformContext) { - xsltFreeTransformContext (priv->transformContext); - priv->transformContext = NULL; - } - if (priv->inputDoc) { - xmlFreeDoc (priv->inputDoc); - priv->inputDoc = NULL; - } - - g_object_unref (pager); - - debug_print (DB_PROFILE, "leaving %s", __FUNCTION__); - - return FALSE; -} - -static void -xslt_pager_error (YelpPager *pager) -{ - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); -} - -static void -xslt_pager_cancel (YelpPager *pager) -{ - YelpXsltPagerPriv *priv = YELP_XSLT_PAGER (pager)->priv; - - debug_print (DB_FUNCTION, "entering\n"); - - yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); - - if (priv->outputDoc) { - xmlFreeDoc (priv->outputDoc); - priv->outputDoc = NULL; - } - if (priv->stylesheet) { - xsltFreeStylesheet (priv->stylesheet); - priv->stylesheet = NULL; - } - if (priv->transformContext) { - xsltFreeTransformContext (priv->transformContext); - priv->transformContext = NULL; - } - if (priv->inputDoc) { - xmlFreeDoc (priv->inputDoc); - priv->inputDoc = NULL; - } -} - -static void -xslt_pager_finish (YelpPager *pager) -{ - debug_print (DB_FUNCTION, "entering\n"); - yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISHED); -} - -/** XSLT Extension Elements ***************************************************/ - -void -xslt_yelp_document (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp) -{ - GError *error; - YelpPage *page; - xmlChar *page_id = NULL; - xmlChar *page_title = NULL; - xmlChar *page_buf; - gint buf_size; - YelpPager *pager; - xsltStylesheetPtr style = NULL; - const char *old_outfile; - xmlDocPtr new_doc = NULL; - xmlDocPtr old_doc; - xmlNodePtr old_insert; - xmlNodePtr cur; - - if (!ctxt || !node || !inst || !comp) - return; - - pager = (YelpPager *) ctxt->_private; - - EVENTS_PENDING; - CANCEL_CHECK; - - debug_print (DB_FUNCTION, "entering\n"); - - page_id = xsltEvalAttrValueTemplate (ctxt, inst, - (const xmlChar *) "href", - NULL); - if (page_id == NULL) { - xsltTransformError (ctxt, NULL, inst, - _("No href attribute found on yelp:document")); - /* FIXME: put a real error here */ - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - debug_print (DB_FUNCTION, " page_id = \"%s\"\n", page_id); - - old_outfile = ctxt->outputFile; - old_doc = ctxt->output; - old_insert = ctxt->insert; - ctxt->outputFile = (const char *) page_id; - - style = xsltNewStylesheet (); - if (style == NULL) { - xsltTransformError (ctxt, NULL, inst, - _("Out of memory")); - error = NULL; - yelp_pager_error (pager, error); - goto done; - } - - style->omitXmlDeclaration = TRUE; - - new_doc = xmlNewDoc (BAD_CAST "1.0"); - new_doc->charset = XML_CHAR_ENCODING_UTF8; - new_doc->dict = ctxt->dict; - xmlDictReference (new_doc->dict); - - ctxt->output = new_doc; - ctxt->insert = (xmlNodePtr) new_doc; - - xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL); - - CANCEL_CHECK; - - xsltSaveResultToString (&page_buf, &buf_size, new_doc, style); - - ctxt->outputFile = old_outfile; - ctxt->output = old_doc; - ctxt->insert = old_insert; - - CANCEL_CHECK; - - if (!page_title) - page_title = BAD_CAST g_strdup ("FIXME"); - - page = g_new0 (YelpPage, 1); - - page->page_id = g_strdup ((gchar *) page_id); - xmlFree (page_id); - page_id = NULL; - - page->title = (gchar *) page_title; - page->contents = (gchar *) page_buf; - - cur = xmlDocGetRootElement (new_doc); - - if (cur != NULL) { - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "head")) { - for (cur = cur->children; cur; cur = cur->next) { - if (!xmlStrcmp (cur->name, (xmlChar *) "link")) { - xmlChar *rel = xmlGetProp (cur, BAD_CAST "rel"); - - if (!xmlStrcmp (rel, (xmlChar *) "previous")) - page->prev_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "next")) - page->next_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - else if (!xmlStrcmp (rel, (xmlChar *) "top")) - page->toc_id = (gchar *) xmlGetProp (cur, BAD_CAST "href"); - - xmlFree (rel); - } - } - break; - } - } - } - - CANCEL_CHECK; - - yelp_pager_add_page (pager, page); - g_signal_emit_by_name (pager, "page", page->page_id); - - EVENTS_PENDING; - CANCEL_CHECK; - - done: - if (new_doc) - xmlFreeDoc (new_doc); - if (style) - xsltFreeStylesheet (style); -} - -void -xslt_yelp_cache (xsltTransformContextPtr ctxt, - xmlNodePtr node, - xmlNodePtr inst, - xsltStylePreCompPtr comp) -{ - static GHashTable *keyhash = NULL; - xmlXPathObjectPtr nodeexpr = NULL; - xsltStylesheetPtr style = NULL; - xmlNodePtr nodeptr; - xmlNodePtr tmpnode; - xmlNodePtr tmpnode2; - xmlChar *keyprop = NULL; - xmlChar *nodeprop = NULL; - const char *old_outfile; - xmlDocPtr old_output; - xmlNodePtr old_insert; - xmlDocPtr new_doc = NULL; - gchar *key; - - if (!ctxt || !node || !inst || !comp) - return; - - keyprop = xmlGetProp (inst, BAD_CAST "key"); - if (!keyprop) - return; - - nodeprop = xmlGetProp (inst, BAD_CAST "node"); - if (!nodeprop) { - xmlFree (keyprop); - return; - } - - nodeexpr = xmlXPathEvalExpression (nodeprop, ctxt->xpathCtxt); - if (!nodeexpr) - goto done; - - /* if we haven't initialized the hash yet, do so */ - if (!keyhash) - keyhash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, xmlFree); - - if (nodeexpr->type != XPATH_NODESET) { - debug_print (DB_WARN, "node attribute [%s] did not evaluate to a nodeset\n", - nodeprop); - goto done; - } - - nodeptr = nodeexpr->nodesetval->nodeTab[0]; - if (!nodeptr) - goto done; - - debug_print (DB_DEBUG, "key=%s node=%s ptr=%p\n", - (gchar *)keyprop, (gchar *)nodeprop, (void *)nodeptr); - - key = g_strdup_printf ("%s%p", keyprop, (void *)nodeptr); - tmpnode = g_hash_table_lookup (keyhash, key); - - if (tmpnode) { - debug_print (DB_DEBUG, "found cached result\n"); - tmpnode2 = xmlDocCopyNode (tmpnode, tmpnode->doc, 1); - xmlAddChild (ctxt->insert, tmpnode2); - g_free (key); - goto done; - } - - old_outfile = ctxt->outputFile; - old_output = ctxt->output; - old_insert = ctxt->insert; - ctxt->outputFile = "test"; - - style = xsltNewStylesheet (); - if (style == NULL) { - xsltTransformError (ctxt, NULL, inst, _("Out of memory")); - g_free (key); - goto done; - } - - style->omitXmlDeclaration = TRUE; - - new_doc = xmlNewDoc (BAD_CAST "1.0"); - new_doc->charset = XML_CHAR_ENCODING_UTF8; - new_doc->dict = ctxt->dict; - xmlDictReference (new_doc->dict); - - ctxt->output = new_doc; - ctxt->insert = (xmlNodePtr) new_doc; - - xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL); - - ctxt->outputFile = old_outfile; - ctxt->output = old_output; - ctxt->insert = old_insert; - - /* this copy of the node we put in the cache */ - tmpnode = xmlCopyNode (new_doc->children, 1); - g_hash_table_insert (keyhash, key, tmpnode); - - /* this copy of the node gets attached to the result tree */ - tmpnode2 = xmlDocCopyNode (tmpnode, tmpnode->doc, 1); - xmlAddChild (ctxt->insert, tmpnode2); - - while (gtk_events_pending ()) - gtk_main_iteration (); - /* FIXME : check for cancel */ - -done: - if (keyprop) - xmlFree (keyprop); - if (nodeprop) - xmlFree (nodeprop); - if (nodeexpr) - xmlXPathFreeObject (nodeexpr); - if (new_doc) - xmlFreeDoc (new_doc); - if (style) - xsltFreeStylesheet (style); -} diff --git a/src/yelp-xslt-pager.h b/src/yelp-xslt-pager.h deleted file mode 100644 index b46cced5..00000000 --- a/src/yelp-xslt-pager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * Copyright (C) 2003 Shaun McCance - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Shaun McCance - */ - -#ifndef __YELP_XSLT_PAGER_H__ -#define __YELP_XSLT_PAGER_H__ - -#include -#include - -#include "yelp-pager.h" - -#define YELP_TYPE_XSLT_PAGER (yelp_xslt_pager_get_type ()) -#define YELP_XSLT_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_XSLT_PAGER, YelpXsltPager)) -#define YELP_XSLT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_XSLT_PAGER, YelpXsltPagerClass)) -#define YELP_IS_XSLT_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_XSLT_PAGER)) -#define YELP_IS_XSLT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_XSLT_PAGER)) -#define YELP_XSLT_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_XSLT_PAGER, YelpXsltPagerClass)) - -typedef struct _YelpXsltPager YelpXsltPager; -typedef struct _YelpXsltPagerClass YelpXsltPagerClass; -typedef struct _YelpXsltPagerPriv YelpXsltPagerPriv; - -struct _YelpXsltPager { - YelpPager parent; - - YelpXsltPagerPriv *priv; -}; - -struct _YelpXsltPagerClass { - YelpPagerClass parent_class; - - xmlDocPtr (*parse) (YelpPager *pager); - gchar ** (*params) (YelpPager *pager); - - gchar *stylesheet; -}; - -GType yelp_xslt_pager_get_type (void); - -#endif /* __YELP_XSLT_PAGER_H__ */ -- cgit v1.2.1