home *** CD-ROM | disk | FTP | other *** search
/ Fractal Creations (Second Edition) / FRACTALS_2E.iso / frasrc.exe / HELPCOM.H < prev    next >
C/C++ Source or Header  |  1992-07-10  |  17KB  |  813 lines

  1.  
  2. /*
  3.  * helpcom.h
  4.  *
  5.  *
  6.  * Common #defines, structures and code for HC.C and HELP.C
  7.  *
  8.  */
  9.  
  10. #ifndef HELPCOM_H
  11. #define HELPCOM_H
  12.  
  13. #include "port.h"
  14.  
  15. /*
  16.  * help file signature
  17.  * If you get a syntax error, remove the LU from the end of the number.
  18.  */
  19.  
  20. #define HELP_SIG       (0xAFBC1823LU)
  21.  
  22.  
  23. /*
  24.  * commands imbedded in the help text
  25.  */
  26.  
  27. #define CMD_LITERAL      1   /* next char taken literally */
  28. #define CMD_PARA      2   /* paragraph start code */
  29. #define CMD_LINK      3   /* hot-link start/end code */
  30. #define CMD_FF          4   /* force a form-feed */
  31. #define CMD_XONLINE      5   /* exclude from online help on/off */
  32. #define CMD_XDOC      6   /* exclude from printed document on/off */
  33. #define CMD_CENTER      7   /* center this line */
  34. #define CMD_SPACE      8   /* next byte is count of spaces */
  35.  
  36. #define MAX_CMD       8
  37.  
  38.  
  39. /*
  40.  * on-line help dimensions
  41.  */
  42.  
  43. #define SCREEN_WIDTH      (78)
  44. #define SCREEN_DEPTH      (22)
  45. #define SCREEN_INDENT      (1)
  46.  
  47.  
  48. /*
  49.  * printed document dimensions
  50.  */
  51.  
  52. #define PAGE_WIDTH       (72)  /* width of printed text */
  53. #define PAGE_INDENT       (2)     /* indent all text by this much */
  54. #define TITLE_INDENT       (1)     /* indent titles by this much */
  55.  
  56. #define PAGE_RDEPTH       (59)  /* the total depth (inc. heading) */
  57. #define PAGE_HEADING_DEPTH (3)     /* depth of the heading */
  58. #define PAGE_DEPTH       (PAGE_RDEPTH-PAGE_HEADING_DEPTH) /* depth of text */
  59.  
  60.  
  61. /*
  62.  * Document page-break macros.    Goto to next page if this close (or closer)
  63.  * to end of page when starting a CONTENT, TOPIC, or at a BLANK line.
  64.  */
  65.  
  66. #define CONTENT_BREAK (7)  /* start of a "DocContent" entry */
  67. #define TOPIC_BREAK   (4)  /* start of each topic under a DocContent entry */
  68. #define BLANK_BREAK   (2)  /* a blank line */
  69.  
  70.  
  71. /*
  72.  * tokens returned by find_token_length
  73.  */
  74.  
  75. #define TOK_DONE    (0)   /* len == 0          */
  76. #define TOK_SPACE   (1)   /* a run of spaces      */
  77. #define TOK_LINK    (2)   /* an entire link      */
  78. #define TOK_PARA    (3)   /* a CMD_PARA       */
  79. #define TOK_NL        (4)   /* a new-line ('\n')    */
  80. #define TOK_FF        (5)   /* a form-feed (CMD_FF) */
  81. #define TOK_WORD    (6)   /* a word          */
  82. #define TOK_XONLINE (7)   /* a CMD_XONLINE      */
  83. #define TOK_XDOC    (8)   /* a CMD_XDOC       */
  84. #define TOK_CENTER  (9)   /* a CMD_CENTER      */
  85.  
  86.  
  87. /*
  88.  * modes for find_token_length() and find_line_width()
  89.  */
  90.  
  91. #define ONLINE 1
  92. #define DOC    2
  93.  
  94.  
  95. /*
  96.  * struct PD_INFO used by process_document()
  97.  */
  98.  
  99. typedef struct
  100.    {
  101.  
  102.    /* used by process_document -- look but don't touch! */
  103.  
  104.    int         pnum,
  105.          lnum;
  106.  
  107.    /* PD_GET_TOPIC is allowed to change these */
  108.  
  109.    char far *curr;
  110.    unsigned  len;
  111.  
  112.    /* PD_GET_CONTENT is allowed to change these */
  113.  
  114.    char far *id;
  115.    char far *title;
  116.    int         new_page;
  117.  
  118.    /* general parameters */
  119.  
  120.    char far *s;
  121.    int         i;
  122.  
  123.  
  124.    } PD_INFO;
  125.  
  126.  
  127. /*
  128.  * Commands passed to (*get_info)() and (*output)() by process_document()
  129.  */
  130.  
  131. enum  PD_COMMANDS
  132.    {
  133.  
  134. /* commands sent to pd_output */
  135.  
  136.    PD_HEADING,           /* call at the top of each page */
  137.    PD_FOOTING,        /* called at the end of each page */
  138.    PD_PRINT,        /* called to send text to the printer */
  139.    PD_PRINTN,        /* called to print a char n times */
  140.    PD_PRINT_SEC,    /* called to print the section title line */
  141.    PD_START_SECTION,    /* called at the start of each section */
  142.    PD_START_TOPIC,    /* called at the start of each topic */
  143.    PD_SET_SECTION_PAGE, /* set the current sections page number */
  144.    PD_SET_TOPIC_PAGE,    /* set the current topics page number */
  145.    PD_PERIODIC,     /* called just before curr is incremented to next token */
  146.  
  147. /* commands sent to pd_get_info */
  148.  
  149.    PD_GET_CONTENT,
  150.    PD_GET_TOPIC,
  151.    PD_RELEASE_TOPIC,
  152.    PD_GET_LINK_PAGE
  153.  
  154.    } ;
  155.  
  156.  
  157. typedef int (*PD_FUNC)(int cmd, PD_INFO *pd, VOIDPTR info);
  158.  
  159.  
  160. int _find_token_length(char far *curr, unsigned len, int *size, int *width);
  161. int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width);
  162. int find_line_width(int mode, char far *curr, unsigned len);
  163. int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info);
  164.  
  165.  
  166. /*
  167.  * Code common to both HC.C and HELP.C (in Fractint).
  168.  * #include INCLUDE_COMMON once for each program
  169.  */
  170.  
  171.  
  172. #endif
  173. #ifdef INCLUDE_COMMON
  174.  
  175.  
  176. #ifndef XFRACT
  177. #define getint(ptr) (*(int far *)(ptr))
  178. #define setint(ptr,n) (*(int far *)(ptr)) = n
  179. #else
  180. /* Get an int from an unaligned pointer
  181.  * This routine is needed because this program uses unaligned 2 byte
  182.  * pointers all over the place.
  183.  */
  184. getint(ptr)
  185. char *ptr;
  186. {
  187.     int s;
  188.     bcopy(ptr,&s,sizeof(int));
  189.     return s;
  190. }
  191.  
  192. /* Set an int to an unaligned pointer */
  193. void setint(ptr, n)
  194. int n;
  195. char *ptr;
  196. {
  197.     bcopy(&n,ptr,sizeof(int));
  198. }
  199. #endif
  200.  
  201.  
  202. static int is_hyphen(char far *ptr)   /* true if ptr points to a real hyphen */
  203.    {                   /* checkes for "--" and " -" */
  204.    if ( *ptr != '-' )
  205.       return (0);    /* that was easy! */
  206.  
  207.    --ptr;
  208.  
  209.    return ( *ptr!=' ' && *ptr!='-' );
  210.    }
  211.  
  212.  
  213. int _find_token_length(register char far *curr, unsigned len, int *size, int *width)
  214.    {
  215.    register int _size  = 0;
  216.    register int _width = 0;
  217.    int tok;
  218.  
  219.    if (len == 0)
  220.       tok = TOK_DONE;
  221.  
  222.    else
  223.       {
  224.       switch ( *curr )
  225.      {
  226.      case ' ':    /* it's a run of spaces */
  227.         tok = TOK_SPACE;
  228.         while ( *curr == ' ' && _size < len )
  229.            {
  230.            ++curr;
  231.            ++_size;
  232.            ++_width;
  233.            }
  234.         break;
  235.  
  236.      case CMD_SPACE:
  237.         tok = TOK_SPACE;
  238.         ++curr;
  239.         ++_size;
  240.         _width = *curr;
  241.         ++curr;
  242.         ++_size;
  243.         break;
  244.  
  245.      case CMD_LINK:
  246.         tok = TOK_LINK;
  247.             _size += 1+3*sizeof(int); /* skip CMD_LINK + topic_num + topic_off + page_num */
  248.             curr += 1+3*sizeof(int);
  249.  
  250.         while ( *curr != CMD_LINK )
  251.            {
  252.            if ( *curr == CMD_LITERAL )
  253.           {
  254.           ++curr;
  255.           ++_size;
  256.           }
  257.            ++curr;
  258.            ++_size;
  259.            ++_width;
  260.            assert(_size < len);
  261.            }
  262.  
  263.         ++_size;   /* skip ending CMD_LINK */
  264.         break;
  265.  
  266.      case CMD_PARA:
  267.         tok = TOK_PARA;
  268.         _size += 3;     /* skip CMD_PARA + indent + margin */
  269.         break;
  270.  
  271.      case CMD_XONLINE:
  272.         tok = TOK_XONLINE;
  273.         ++_size;
  274.         break;
  275.  
  276.      case CMD_XDOC:
  277.         tok = TOK_XDOC;
  278.         ++_size;
  279.         break;
  280.  
  281.      case CMD_CENTER:
  282.         tok = TOK_CENTER;
  283.         ++_size;
  284.         break;
  285.  
  286.      case '\n':
  287.         tok = TOK_NL;
  288.         ++_size;
  289.         break;
  290.  
  291.      case CMD_FF:
  292.         tok = TOK_FF;
  293.         ++_size;
  294.         break;
  295.  
  296.      default:   /* it must be a word */
  297.         tok = TOK_WORD;
  298.         while (1)
  299.            {
  300.            if ( _size >= len )
  301.           break;
  302.  
  303.            else if ( *curr == CMD_LITERAL )
  304.           {
  305.           curr += 2;
  306.           _size += 2;
  307.           _width += 1;
  308.           }
  309.  
  310.            else if ( *curr == '\0' )
  311.           {
  312.           assert(0);
  313.           }
  314.  
  315.            else if ((unsigned)*curr <= MAX_CMD || *curr == ' ' ||
  316.             *curr == '\n')
  317.           break;
  318.  
  319.            else if ( *curr == '-' )
  320.           {
  321.           ++curr;
  322.           ++_size;
  323.           ++_width;
  324.           if ( is_hyphen(curr-1) )
  325.              break;
  326.           }
  327.  
  328.            else
  329.           {
  330.           ++curr;
  331.           ++_size;
  332.           ++_width;
  333.           }
  334.            }
  335.         break;
  336.      } /* switch */
  337.       }
  338.  
  339.    if (size  != NULL)    *size  = _size;
  340.    if (width != NULL)    *width = _width;
  341.  
  342.    return (tok);
  343.    }
  344.  
  345.  
  346. int find_token_length(int mode, char far *curr, unsigned len, int *size, int *width)
  347.    {
  348.    int tok;
  349.    int t;
  350.    int _size;
  351.  
  352.    tok = _find_token_length(curr, len, &t, width);
  353.  
  354.    if ( (tok == TOK_XONLINE && mode == ONLINE) ||
  355.     (tok == TOK_XDOC    && mode == DOC)     )
  356.       {
  357.       _size = 0;
  358.  
  359.       while (1)
  360.      {
  361.      curr  += t;
  362.      len   -= t;
  363.      _size += t;
  364.  
  365.      tok = _find_token_length(curr, len, &t, NULL);
  366.  
  367.      if ( (tok == TOK_XONLINE && mode == ONLINE) ||
  368.           (tok == TOK_XDOC      && mode == DOC)    ||
  369.           (tok == TOK_DONE)                )
  370.         break;
  371.      }
  372.  
  373.       _size += t;
  374.       }
  375.    else
  376.       _size = t;
  377.  
  378.    if (size != NULL )
  379.       *size = _size;
  380.  
  381.    return (tok);
  382.    }
  383.  
  384.  
  385. int find_line_width(int mode, char far *curr, unsigned len)
  386.    {
  387.    int size   = 0,
  388.        width  = 0,
  389.        lwidth = 0,
  390.        done   = 0,
  391.        tok;
  392.  
  393.    do
  394.       {
  395.       tok = find_token_length(mode, curr, len, &size, &width);
  396.  
  397.       switch(tok)
  398.      {
  399.      case TOK_DONE:
  400.      case TOK_PARA:
  401.      case TOK_NL:
  402.      case TOK_FF:
  403.         done = 1;
  404.         break;
  405.  
  406.      case TOK_XONLINE:
  407.      case TOK_XDOC:
  408.      case TOK_CENTER:
  409.         curr += size;
  410.         len -= size;
  411.         break;
  412.  
  413.      default:   /* TOK_SPACE, TOK_LINK or TOK_WORD */
  414.         lwidth += width;
  415.         curr += size;
  416.         len -= size;
  417.         break;
  418.      }
  419.       }
  420.    while ( !done );
  421.  
  422.    return (lwidth);
  423.    }
  424.  
  425.  
  426. #define DO_PRINTN(ch,n)  ( pd.s = &(ch), pd.i = (n), output(PD_PRINTN, &pd, info) )
  427. #define DO_PRINT(str,n)  ( pd.s = (str), pd.i = (n), output(PD_PRINT, &pd, info) )
  428.  
  429.  
  430. int process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info)
  431.    {
  432.    int         skip_blanks;
  433.    int         tok;
  434.    int         size,
  435.          width;
  436.    int         col;
  437.    char      page_text[10];
  438.    PD_INFO   pd;
  439.    char      nl = '\n',
  440.          sp = ' ';
  441.    int         first_section,
  442.          first_topic;
  443.  
  444.    pd.pnum = 1;
  445.    pd.lnum = 0;
  446.  
  447.    col = 0;
  448.  
  449.    output(PD_HEADING, &pd, info);
  450.  
  451.    first_section = 1;
  452.  
  453.    while ( get_info(PD_GET_CONTENT, &pd, info) )
  454.       {
  455.       if ( !output(PD_START_SECTION, &pd, info) )
  456.      return (0);
  457.  
  458.       if ( pd.new_page && pd.lnum != 0 )
  459.      {
  460.      if ( !output(PD_FOOTING, &pd, info) )
  461.         return (0);
  462.      ++pd.pnum;
  463.      pd.lnum = 0;
  464.      if ( !output(PD_HEADING, &pd, info) )
  465.         return (0);
  466.      }
  467.  
  468.       else
  469.      {
  470.      if ( pd.lnum+2 > PAGE_DEPTH-CONTENT_BREAK )
  471.         {
  472.         if ( !output(PD_FOOTING, &pd, info) )
  473.            return (0);
  474.         ++pd.pnum;
  475.         pd.lnum = 0;
  476.         if ( !output(PD_HEADING, &pd, info) )
  477.            return (0);
  478.         }
  479.      else if (pd.lnum > 0)
  480.         {
  481.         if ( !DO_PRINTN(nl, 2) )
  482.            return (0);
  483.         pd.lnum += 2;
  484.         }
  485.      }
  486.  
  487.       if ( !output(PD_SET_SECTION_PAGE, &pd, info) )
  488.      return (0);
  489.  
  490.       if ( !first_section )
  491.      {
  492.      if ( !output(PD_PRINT_SEC, &pd, info) )
  493.         return (0);
  494.      ++pd.lnum;
  495.      }
  496.  
  497.       col = 0;
  498.  
  499.       first_topic = 1;
  500.  
  501.       while ( get_info(PD_GET_TOPIC, &pd, info) )
  502.      {
  503.      if ( !output(PD_START_TOPIC, &pd, info) )
  504.         return (0);
  505.  
  506.      skip_blanks = 0;
  507.      col = 0;
  508.  
  509.      if ( !first_section )     /* do not skip blanks for DocContents */
  510.         {
  511.         while (pd.len > 0)
  512.            {
  513.            tok = find_token_length(DOC, pd.curr, pd.len, &size, NULL);
  514.            if (tok != TOK_XDOC && tok != TOK_XONLINE &&
  515.            tok != TOK_NL   && tok != TOK_DONE )
  516.           break;
  517.            pd.curr += size;
  518.            pd.len  -= size;
  519.            }
  520.         if ( first_topic && pd.len != 0 )
  521.            {
  522.            if ( !DO_PRINTN(nl, 1) )
  523.           return (0);
  524.            ++pd.lnum;
  525.            }
  526.         }
  527.  
  528.      if ( pd.lnum > PAGE_DEPTH-TOPIC_BREAK )
  529.         {
  530.         if ( !output(PD_FOOTING, &pd, info) )
  531.            return (0);
  532.         ++pd.pnum;
  533.         pd.lnum = 0;
  534.         if ( !output(PD_HEADING, &pd, info) )
  535.            return (0);
  536.         }
  537.      else if ( !first_topic )
  538.         {
  539.         if ( !DO_PRINTN(nl, 1) )
  540.            return (0);
  541.         pd.lnum++;
  542.         }
  543.  
  544.      if ( !output(PD_SET_TOPIC_PAGE, &pd, info) )
  545.         return (0);
  546.  
  547.      do
  548.         {
  549.         if ( !output(PD_PERIODIC, &pd, info) )
  550.            return (0);
  551.  
  552.         tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);
  553.  
  554.         switch ( tok )
  555.            {
  556.            case TOK_PARA:
  557.           {
  558.           int        indent,
  559.                 margin;
  560.           unsigned  holdlen = 0;
  561.           char far *holdcurr = 0;
  562.           int        in_link = 0;
  563.  
  564.           ++pd.curr;
  565.  
  566.           indent = *pd.curr++;
  567.           margin = *pd.curr++;
  568.  
  569.           pd.len -= 3;
  570.  
  571.           if ( !DO_PRINTN(sp, indent) )
  572.              return (0);
  573.  
  574.           col = indent;
  575.  
  576.           while (1)
  577.              {
  578.              if ( !output(PD_PERIODIC, &pd, info) )
  579.             return (0);
  580.  
  581.              tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);
  582.  
  583.              if ( tok == TOK_NL || tok == TOK_FF )
  584.             break;
  585.  
  586.              if ( tok == TOK_DONE )
  587.             {
  588.             if (in_link == 0)
  589.                {
  590.                col = 0;
  591.                ++pd.lnum;
  592.                if ( !DO_PRINTN(nl, 1) )
  593.                   return (0);
  594.                break;
  595.                }
  596.  
  597.             else if (in_link == 1)
  598.                {
  599.                tok = TOK_SPACE;
  600.                width = 1;
  601.                size = 0;
  602.                ++in_link;
  603.                }
  604.  
  605.             else if (in_link == 2)
  606.                {
  607.                tok = TOK_WORD;
  608.                width = strlen(page_text);
  609.                col += 8 - width;
  610.                size = 0;
  611.                pd.curr = page_text;
  612.                ++in_link;
  613.                }
  614.  
  615.             else if (in_link == 3)
  616.                {
  617.                pd.curr = holdcurr;
  618.                pd.len = holdlen;
  619.                in_link = 0;
  620.                continue;
  621.                }
  622.             }
  623.  
  624.              if ( tok == TOK_PARA )
  625.             {
  626.             col = 0;   /* fake a nl */
  627.             ++pd.lnum;
  628.             if ( !DO_PRINTN(nl, 1) )
  629.                return (0);
  630.             break;
  631.             }
  632.  
  633.              if (tok == TOK_XONLINE || tok == TOK_XDOC )
  634.             {
  635.             pd.curr += size;
  636.             pd.len -= size;
  637.             continue;
  638.             }
  639.  
  640.              if ( tok == TOK_LINK )
  641.             {
  642.             pd.s = pd.curr+1;
  643.             if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
  644.                {
  645.                in_link = 1;
  646.                sprintf(page_text, "(p. %d)", pd.i);
  647.                }
  648.             else
  649.                in_link = 3;
  650.             holdcurr = pd.curr + size;
  651.             holdlen = pd.len - size;
  652.                         pd.len = size - 2 - 3*sizeof(int);
  653.                         pd.curr += 1 + 3*sizeof(int);
  654.             continue;
  655.             }
  656.  
  657.              /* now tok is TOK_SPACE or TOK_WORD */
  658.  
  659.              if (col+width > PAGE_WIDTH)
  660.             {       /* go to next line... */
  661.             if ( !DO_PRINTN(nl, 1) )
  662.                return (0);
  663.             if ( ++pd.lnum >= PAGE_DEPTH )
  664.                {
  665.                if ( !output(PD_FOOTING, &pd, info) )
  666.                   return (0);
  667.                ++pd.pnum;
  668.                pd.lnum = 0;
  669.                if ( !output(PD_HEADING, &pd, info) )
  670.                   return (0);
  671.                }
  672.  
  673.             if ( tok == TOK_SPACE )
  674.                width = 0;    /* skip spaces at start of a line */
  675.  
  676.             if ( !DO_PRINTN(sp, margin) )
  677.                return (0);
  678.             col = margin;
  679.             }
  680.  
  681.              if (width > 0)
  682.             {
  683.             if (tok == TOK_SPACE)
  684.                {
  685.                if ( !DO_PRINTN(sp, width) )
  686.                   return (0);
  687.                }
  688.             else
  689.                {
  690.                if ( !DO_PRINT(pd.curr, (size==0) ? width : size) )
  691.                   return (0);
  692.                }
  693.             }
  694.  
  695.              col += width;
  696.              pd.curr += size;
  697.              pd.len -= size;
  698.              }
  699.  
  700.           skip_blanks = 0;
  701.           width = size = 0;
  702.           break;
  703.           }
  704.  
  705.            case TOK_NL:
  706.           if (skip_blanks && col == 0)
  707.              break;
  708.  
  709.           ++pd.lnum;
  710.  
  711.           if ( pd.lnum >= PAGE_DEPTH || (col == 0 && pd.lnum >= PAGE_DEPTH-BLANK_BREAK) )
  712.              {
  713.              if ( col != 0 )    /* if last wasn't a blank line... */
  714.             {
  715.             if ( !DO_PRINTN(nl, 1) )
  716.                return (0);
  717.             }
  718.              if ( !output(PD_FOOTING, &pd, info) )
  719.             return (0);
  720.              ++pd.pnum;
  721.              pd.lnum = 0;
  722.              skip_blanks = 1;
  723.              if ( !output(PD_HEADING, &pd, info) )
  724.             return (0);
  725.              }
  726.           else
  727.              {
  728.              if ( !DO_PRINTN(nl, 1) )
  729.             return (0);
  730.              }
  731.  
  732.           col = 0;
  733.           break;
  734.  
  735.            case TOK_FF:
  736.           if (skip_blanks)
  737.              break;
  738.           if ( !output(PD_FOOTING, &pd, info) )
  739.              return (0);
  740.           col = 0;
  741.           pd.lnum = 0;
  742.           ++pd.pnum;
  743.           if ( !output(PD_HEADING, &pd, info) )
  744.              return (0);
  745.           break;
  746.  
  747.            case TOK_CENTER:
  748.           width = (PAGE_WIDTH - find_line_width(DOC,pd.curr,pd.len)) / 2;
  749.           if ( !DO_PRINTN(sp, width) )
  750.              return (0);
  751.           break;
  752.  
  753.            case TOK_LINK:
  754.           skip_blanks = 0;
  755.           if ( !DO_PRINT(pd.curr+1+3*sizeof(int),
  756.               size-3*sizeof(int)-2) )
  757.              return (0);
  758.           pd.s = pd.curr+1;
  759.           if ( get_info(PD_GET_LINK_PAGE, &pd, info) )
  760.              {
  761.              width += 9;
  762.              sprintf(page_text, " (p. %d)", pd.i);
  763.              if ( !DO_PRINT(page_text, strlen(page_text)) )
  764.             return (0);
  765.              }
  766.           break;
  767.  
  768.            case TOK_WORD:
  769.           skip_blanks = 0;
  770.           if ( !DO_PRINT(pd.curr, size) )
  771.              return (0);
  772.           break;
  773.  
  774.            case TOK_SPACE:
  775.           skip_blanks = 0;
  776.           if ( !DO_PRINTN(sp, width) )
  777.              return (0);
  778.           break;
  779.  
  780.            case TOK_DONE:
  781.            case TOK_XONLINE:   /* skip */
  782.            case TOK_XDOC:       /* ignore */
  783.           break;
  784.  
  785.            } /* switch */
  786.  
  787.         pd.curr += size;
  788.         pd.len  -= size;
  789.         col     += width;
  790.         }
  791.      while (pd.len > 0);
  792.  
  793.      get_info(PD_RELEASE_TOPIC, &pd, info);
  794.  
  795.      first_topic = 0;
  796.      } /* while */
  797.  
  798.       first_section = 0;
  799.       } /* while */
  800.  
  801.    if ( !output(PD_FOOTING, &pd, info) )
  802.       return (0);
  803.  
  804.    return (1);
  805.    }
  806.  
  807. #undef DO_PRINT
  808. #undef DO_PRINTN
  809.  
  810.  
  811. #undef INCLUDE_COMMON
  812. #endif     /* #ifdef INCLUDE_COMMON */
  813.