home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / utils / rtfprsr / rtf2text.c < prev    next >
C/C++ Source or Header  |  1995-05-18  |  5KB  |  265 lines

  1. /*
  2.     rtf2text - read rtf input, write text of document (text extraction).
  3.  
  4.     This installs callbacks for the ascii and control token classes.
  5.     The control class is necessary so that special characters such as
  6.     \par, \tab, \sect, etc.  can be converted.
  7.  
  8.     It's problematic what to do with text in headers and footers, and
  9.     what to do about tables.
  10.  
  11.     This really is quite a stupid program, for instance, it could keep
  12.     track of the current leader character and dump that out when a tab
  13.     is encountered.
  14.  
  15.     04 Feb 91    Paul DuBois    dubois@primate.wisc.edu
  16.  
  17.     04 Feb 91 V1.0. Created.
  18.     27 Feb 91 V1.01. Updated for distribution 1.05.
  19. */
  20.  
  21. # include    <stdio.h>
  22. # include    "rtf.h"
  23.  
  24.  
  25. /*
  26.     structure for mapping character values >= 128 to text strings
  27.     for different character sets.
  28. */
  29.  
  30. typedef struct CharMap    CharMap;
  31.  
  32. struct CharMap
  33. {
  34.     int    charVal;
  35.     char    *charStr;
  36. };
  37.  
  38. extern CharMap    ansiCharMap[];    /* these are defined below */
  39. extern CharMap    macCharMap[];
  40. extern CharMap    pcCharMap[];
  41. extern CharMap    pcaCharMap[];
  42.  
  43. /*
  44.     Default is ANSI but I hope we don't see \ansi, since its char
  45.     map is empty...
  46. */
  47.  
  48. CharMap    *charMap = ansiCharMap;
  49.  
  50.  
  51. static void    Text ();
  52. static void    Control ();
  53. static void    CharSet ();
  54. static void    Destination ();
  55. static void    SpecialChar ();
  56.  
  57.  
  58. int main (argc, argv)
  59. int    argc;
  60. char    **argv;
  61. {
  62.     RTFInit ();
  63.  
  64.     --argc;
  65.     ++argv;
  66.  
  67.     /* not clever; only allows stdin or one named file to be read */
  68.  
  69.     if (argc > 0)
  70.     {
  71.         if (freopen (argv[0], "r", stdin) == (FILE *) NULL)
  72.         {
  73.             fprintf (stderr, "Can't open \"%s\"\n", argv[0]);
  74.             exit (1);
  75.         }
  76.     }
  77.  
  78.     /* install class callbacks and process the input stream */
  79.  
  80.     RTFSetClassCallback (rtfText, Text);
  81.     RTFSetClassCallback (rtfControl, Control);
  82.     RTFRead ();
  83.  
  84.     exit (0);
  85. }
  86.  
  87. static void Text ()
  88. {
  89.     PutChar (rtfMajor);
  90. }
  91.  
  92.  
  93. static void Control ()
  94. {
  95.     switch (rtfMajor)
  96.     {
  97.     case rtfCharSet:
  98.         CharSet ();
  99.         break;
  100.     case rtfDestination:
  101.         Destination ();
  102.         break;
  103.     case rtfSpecialChar:
  104.         SpecialChar ();
  105.         break;
  106.     }
  107. }
  108.  
  109.  
  110. static void CharSet ()
  111. {
  112.     switch (rtfMinor)
  113.     {
  114.     case rtfAnsiCharSet:
  115.         charMap = ansiCharMap;
  116.         break;
  117.     case rtfMacCharSet:
  118.         charMap = macCharMap;
  119.         break;
  120.     case rtfPcCharSet:
  121.         charMap = pcCharMap;
  122.         break;
  123.     case rtfPcaCharSet:
  124.         charMap = pcaCharMap;
  125.         break;
  126.     }
  127. }
  128.  
  129.  
  130. /*
  131.     This function notices destinations that should be ignored
  132.     and skips to their ends.  This keeps, for instance, picture
  133.     data from being considered as plain text.
  134. */
  135.  
  136. static void Destination ()
  137. {
  138.     switch (rtfMinor)
  139.     {
  140.     case rtfPict:
  141.     case rtfFNContSep:
  142.     case rtfFNContNotice:
  143.     case rtfInfo:
  144.     case rtfIndexRange:
  145.     case rtfITitle:
  146.     case rtfISubject:
  147.     case rtfIAuthor:
  148.     case rtfIOperator:
  149.     case rtfIKeywords:
  150.     case rtfIComment:
  151.     case rtfIVersion:
  152.     case rtfIDoccomm:
  153.         RTFSkipGroup ();
  154.         break;
  155.     }
  156. }
  157.  
  158.  
  159. static void SpecialChar ()
  160. {
  161.     switch (rtfMinor)
  162.     {
  163.     case rtfPage:
  164.     case rtfSect:
  165.     case rtfRow:
  166.     case rtfLine:
  167.     case rtfPar:
  168.         PutChar ('\n');
  169.         break;
  170.     case rtfCell:
  171.         PutChar (' ');    /* make sure cells are separated */
  172.         break;
  173.     case rtfNoBrkSpace:
  174.         PutChar (' ');
  175.         break;
  176.     case rtfTab:
  177.         PutChar ('\t');
  178.         break;
  179.     case rtfNoBrkHyphen:
  180.         PutChar ('-');
  181.         break;
  182.     }
  183. }
  184.  
  185.  
  186. /*
  187.     Eventually this should keep track of the destination of the
  188.     current state and only write text when in the initial state.
  189. */
  190.  
  191. PutChar (c)
  192. int    c;
  193. {
  194. CharMap    *cmp;
  195. char    *p = "X";
  196.  
  197.     if (c < 128)
  198.         putchar (c);
  199.     else
  200.     {
  201.         for (cmp = charMap; cmp->charStr != (char *) NULL; cmp++)
  202.         {
  203.             if (c == cmp->charVal)
  204.             {
  205.                 p = cmp->charStr;
  206.                 break;
  207.             }
  208.         }
  209.         fputs (p, stdout);
  210.     }
  211. }
  212.  
  213.  
  214. CharMap    ansiCharMap [] =
  215. {
  216.     0,    NULL
  217. };
  218.  
  219.  
  220. CharMap    macCharMap [] =
  221. {
  222.     0xa0,    "+",        /* dagger */
  223.     0xa1,    "deg.",        /* degree */
  224.     0xa2,    "cents",    /* cent */
  225.     0xa5,    "o",        /* bullet */
  226.     0xa7,    "B",        /* German B? */
  227.     0xa8,    "reg.",        /* registered */
  228.     0xa9,    "(c)",        /* copyright */
  229.     0xaa,    "(TM)",        /* trademark */
  230.     0xab,    "'",        /* acute accent */
  231.     0xad,    "!=",        /* not equal */
  232.     0xae,    "AE",        /* joined A-E */
  233.     0xb1,    "+/-",        /* plus or minus */
  234.     0xb2,    "<=",        /* less than or equal */
  235.     0xb3,    ">=",        /* greater than or equal */
  236.     0xb5,    "u",        /* micro */
  237.     0xb6,    "d",        /* delta */
  238.     0xbe,    "ae",        /* joined a-e */
  239.     0xc5,    "~",        /* approximately */
  240.     0xc7,    "<<",        /* alternate quote */
  241.     0xc8,    ">>",        /* alternate end-quote*/
  242.     0xc9,    "...",        /* ellipsis */
  243.     0xca,    " ",        /* unbreakable space */
  244.     0xd0,    "-",        /* short dash */
  245.     0xd1,    "--",        /* long dash */
  246.     0xd2,    "\"",        /* left curly double quote */
  247.     0xd3,    "\"",        /* right curly double quote */
  248.     0xd4,    "`",        /* left curly single quote */
  249.     0xd5,    "'",        /* right curly single quote */
  250.     0xd6,    "/",        /* divide */
  251.     0,    NULL
  252. };
  253.  
  254.  
  255. CharMap    pcCharMap [] =
  256. {
  257.     0,    NULL
  258. };
  259.  
  260.  
  261. CharMap    pcaCharMap [] =
  262. {
  263.     0,    NULL
  264. };
  265.