home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gsview13 / src / gvctext.c < prev    next >
C/C++ Source or Header  |  1995-12-09  |  8KB  |  343 lines

  1. /* Copyright (C) 1993, 1994, 1995, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gvctext.c */
  19. /* Text Extract and Search module of PM and Windows GSview */
  20.  
  21. #ifdef _Windows
  22. #include "gvwin.h"
  23. #else
  24. #include "gvpm.h"
  25. #endif
  26.  
  27. /* extract text from next line of ps file */
  28. /* return count of characters written to dest */
  29. int
  30. text_extract_line(char *dest, FILE *inf)
  31. {
  32. char linebuf[PSLINELENGTH];
  33. int count = 0;
  34. char *p;
  35. char ch;
  36. int instring;
  37.     *dest = '\0';
  38.     if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
  39.         return 0;
  40.     /* skip over binary sections */
  41.     if (strncmp(linebuf, "%%BeginBinary:",14)==0) {
  42.         long count = 0;
  43.         int read;
  44.         char buf[1024];
  45.         if (sscanf(linebuf+14, "%ld", &count) != 1)
  46.         count = 0;
  47.         while (count) {
  48.         read = fread(buf, 1, min(count, sizeof(buf)), inf);
  49.         count -= read;
  50.         if (read == 0)
  51.             count = 0;
  52.         }
  53.         if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
  54.             return 0;
  55.     }
  56.     if (strncmp(linebuf, "%%BeginData:",12)==0) {
  57.         long count;
  58.         int read;
  59.         char buf[PSLINELENGTH];
  60.         if (sscanf(linebuf+12, "%ld %*s %s", &count, buf) != 2)
  61.         count = 0;
  62.         if (strncmp(buf, "Lines", 5) == 0) {
  63.         while (count) {
  64.             count--;
  65.             if (fgets(buf, sizeof(buf), inf) == (char *)NULL)
  66.             count = 0;
  67.         }
  68.         }
  69.         else {
  70.         while (count) {
  71.             read = fread(buf, 1, min(count, sizeof(buf)), inf);
  72.             count -= read;
  73.             if (read == 0)
  74.             count = 0;
  75.         }
  76.         }
  77.         if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
  78.             return 0;
  79.     }
  80.     instring = FALSE;
  81.     while ((ch = *p)!='\0') {
  82.             if (!instring && (ch=='%'))
  83.                 break;    /* comment until EOL */
  84.             if (ch == '(') {
  85.                 if (instring) {
  86.             *dest++ = ch;
  87.             count++;
  88.             }
  89.                 instring++;
  90.             }
  91.             else if (ch == ')') {
  92.                 instring--;
  93.                 if (instring) {
  94.             *dest++ = ch;
  95.             count++;
  96.             }
  97.                 else {
  98.             *dest++ = ' ';  /* may need to be changed */
  99.             count++;
  100.             }
  101.             }
  102.             else if (instring && (ch == '\\')) {
  103.                 ch = *++p;
  104.                 if (ch == '\0') {
  105.                     p--;
  106.                 }
  107.                 else {
  108.             if ((ch != '(') && (ch != ')') && (ch !='\\')) {
  109.                 *dest++ = '\\';
  110.                 count++;
  111.             }
  112.             *dest++ = ch;
  113.             count++;
  114.             }
  115.             }
  116.             else if (instring) {
  117.             *dest++ = ch;
  118.             count++;
  119.         }
  120.             p++;
  121.     }
  122.     *dest = '\0';
  123.     return count;
  124. }
  125.  
  126. void 
  127. text_extract(FILE *outf, FILE *inf, unsigned long end)
  128. {
  129. char outline[PSLINELENGTH];
  130.     while (ftell(inf) < end) {
  131.         if (text_extract_line(outline, inf)) {
  132.         fputs(outline, outf);
  133.         fputc('\n', outf);
  134.         }
  135.     }
  136. }
  137.  
  138.  
  139.  
  140. /* extract text from a range of pages */
  141. void
  142. gsview_text_extract()
  143. {
  144.     FILE *f;
  145.     static char output[MAXSTR];
  146.     int thispage = psfile.pagenum;
  147.  
  148.     if (psfile.name[0] == '\0') {
  149.         gserror(IDS_NOTOPEN, NULL, MB_ICONEXCLAMATION, SOUND_NOTOPEN);
  150.         return;
  151.     }
  152.  
  153.     load_string(IDS_TOPICTEXT, szHelpTopic, sizeof(szHelpTopic));
  154.     if ((doc != (PSDOC *)NULL) && (doc->numpages != 0))
  155.         if (!get_page(&thispage, TRUE))
  156.             return;
  157.  
  158.     if (!get_filename(output, TRUE, FILTER_TXT, 0, IDS_TOPICTEXT))
  159.         return;
  160.  
  161.     if ((f = fopen(output, "w")) == (FILE *)NULL) {
  162.         return;
  163.     }
  164.  
  165.     load_string(IDS_WAITWRITE, szWait, sizeof(szWait));
  166.     info_wait(TRUE);
  167.     if (doc == (PSDOC *)NULL) {
  168.         /* scan whole document */
  169.         unsigned long end;
  170.         if ( (psfile.file = fopen(psfile.name, "rb")) == (FILE *)NULL ) {
  171.         fclose(f);
  172.         return;
  173.         }
  174.         fseek(psfile.file, 0L, SEEK_END);
  175.         end = ftell(psfile.file);
  176.         fseek(psfile.file, 0L, SEEK_SET);
  177.         text_extract(f, psfile.file, end);
  178.         dfclose();
  179.     }
  180.     else {
  181.       if (doc->numpages != 0) {
  182.         int i;
  183.         for (i = 0; i < doc->numpages; i++) {
  184.         if (page_list.select[map_page(i)])  {
  185.                 fseek(psfile.file, doc->pages[map_page(i)].begin, SEEK_SET);
  186.                 text_extract(f, psfile.file, doc->pages[map_page(i)].end);
  187.             fputc('\f', f);
  188.             fputc('\n', f);
  189.         }
  190.         }
  191.       }
  192.       else {
  193.         fseek(psfile.file, doc->beginheader, SEEK_SET);
  194.         text_extract(f, psfile.file, doc->endtrailer);
  195.       }
  196.     }
  197.  
  198.     fclose(f);
  199.  
  200.     info_wait(FALSE);
  201.     return;
  202. }
  203.  
  204.  
  205.  
  206. char *
  207. text_find_string(char *str, char *find, int flen)
  208. {
  209. char *p, *last;
  210. int mcount = 0;
  211.     last = p = str;
  212.     while (*p) {
  213.         if (*p == ' ') {
  214.         p++;
  215.         continue;    /* ignore white space */
  216.         }
  217.         if (mcount) {
  218.             if (toupper(*p) == find[mcount])
  219.             mcount++;    /* matched one more character */
  220.         else {
  221.             mcount = 0;
  222.             p = last+1;    /* retrace to just past last partial match */
  223.         }
  224.         }
  225.         else {
  226.         if (toupper(*p) == *find) {
  227.             last = p;
  228.             mcount++;    /* start of partial match */
  229.         }
  230.         }
  231.         if (mcount == flen)
  232.         return last;
  233.         p++;
  234.     }
  235.     return (char *)NULL;
  236. }
  237.  
  238. /* if str found return malloc'd string containing match */
  239. char *
  240. text_find_section(FILE *inf, unsigned long end, char *str)
  241. {
  242. char dbuf[PSLINELENGTH+PSLINELENGTH];
  243. char sbuf[PSLINELENGTH/4];
  244. int dlength;
  245. int slength;
  246. int count;
  247.  
  248.     /* copy str to uppercase, removing spaces */
  249.     slength = 0;
  250.     for (count=0; str[count]; count++) {
  251.         if (slength > PSLINELENGTH/4)
  252.         return NULL;
  253.         if (str[count] != ' ')            /* ignore spaces */
  254.             sbuf[slength++] = (char)toupper(str[count]);    /* searches are case insensitive */
  255.     }
  256.     sbuf[slength] = '\0';
  257.     if (slength==0)
  258.         return NULL;
  259.     dlength = 0;
  260.     while (ftell(inf) < end) {
  261.         while ((ftell(inf) < end) && (dlength < PSLINELENGTH)) {
  262.         count = text_extract_line(dbuf+dlength, inf);
  263.             dlength += count;
  264.         if (count) { /* separate lines by spaces */
  265.             dbuf[dlength++] = ' ';
  266.             dbuf[dlength] = '\0';
  267.         }
  268.         }
  269.         if (text_find_string(dbuf, sbuf, slength)) {
  270.         str = malloc(dlength+1);
  271.         if (str)
  272.             strcpy(str, dbuf);
  273.         return str;
  274.         }
  275.         if (dlength > slength) {
  276.            memmove(dbuf, dbuf+dlength-slength, slength+1);
  277.            dlength = slength;
  278.         }
  279.         else 
  280.             dlength = 0;
  281.         }
  282.         return NULL;
  283. }
  284.  
  285.  
  286. void
  287. gsview_text_find()
  288. {
  289. char prompt[MAXSTR];        /* input dialog box prompt and message box string */
  290. char answer[MAXSTR];        /* input dialog box answer string */
  291. int thispage = psfile.pagenum;
  292.     if (not_dsc())
  293.         return;
  294.     if (doc->numpages == 0) {
  295.         gserror(IDS_NOPAGE, NULL, MB_ICONEXCLAMATION, SOUND_NONUMBER);
  296.         return;
  297.     }
  298.     load_string(IDS_TEXTFIND, prompt, sizeof(prompt));
  299.     strcpy(answer, szFindText);
  300.     load_string(IDS_TOPICTEXT, szHelpTopic, sizeof(szHelpTopic));
  301.     if (!get_string(prompt,answer))
  302.         return;
  303.     strcpy(szFindText, answer);
  304.     if (!get_page(&thispage, TRUE))
  305.             return;
  306.     gsview_text_findnext();
  307. }
  308.  
  309. void
  310. gsview_text_findnext()
  311. {
  312. int i;
  313. char *p;
  314.     if (not_dsc())
  315.         return;
  316.     if (strlen(szFindText)==0) {
  317.         gserror(IDS_TEXTNOTFIND, NULL, MB_ICONEXCLAMATION, 0);
  318.         return;
  319.     }
  320.     dfreopen();
  321.     load_string(IDS_WAITSEARCH, szWait, sizeof(szWait));
  322.     info_wait(TRUE);
  323.     for (i = 0; i < doc->numpages; i++) {
  324.         if (page_list.select[map_page(i)])  {
  325.         page_list.select[map_page(i)] = FALSE;
  326.             fseek(psfile.file, doc->pages[map_page(i)].begin, SEEK_SET);
  327.         p = text_find_section(psfile.file, doc->pages[map_page(i)].end, szFindText);
  328.         if (p) {    /* found it */
  329.             info_wait(FALSE);
  330.             free(p);
  331.             psfile.pagenum = i+1;
  332.             if (gs_open())
  333.                     dsc_dopage();
  334.             dfclose();
  335.             return;
  336.         }
  337.         }
  338.     }
  339.     dfclose();
  340.         info_wait(FALSE);
  341.     gserror(IDS_TEXTNOTFIND, NULL, MB_ICONEXCLAMATION, 0);
  342. }
  343.