int find_line_width(int mode, char *curr, unsigned len)
{
    int size   = 0;
    int width  = 0;
    int lwidth = 0;
    bool done = false;
    int tok;

    do
    {
        tok = find_token_length(mode, curr, len, &size, &width);

        switch (tok)
        {
        case TOK_DONE:
        case TOK_PARA:
        case TOK_NL:
        case TOK_FF:
            done = true;
            break;

        case TOK_XONLINE:
        case TOK_XDOC:
        case TOK_CENTER:
            curr += size;
            len -= size;
            break;

        default:   /* TOK_SPACE, TOK_LINK or TOK_WORD */
            lwidth += width;
            curr += size;
            len -= size;
            break;
        }
    }
    while (!done);

    return (lwidth);
}
Example #2
0
static void display_parse_text(char far *text, unsigned len, int start_margin, int *num_link, LINK far *link)
   {
   char far  *curr;
   int        row, col;
   int        tok;
   int        size,
              width;

   textcbase = SCREEN_INDENT;
   textrbase = TEXT_START_ROW;

   curr = text;
   row = 0;
   col = 0;

   size = width = 0;

   if (start_margin >= 0)
      tok = TOK_PARA;
   else
      tok = -1;

   for(;;)
      {
      switch ( tok )
         {
         case TOK_PARA:
            {
            int indent,
                margin;

            if (size > 0)
               {
               ++curr;
               indent = *curr++;
               margin = *curr++;
               len  -= 3;
               }
            else
               {
               indent = start_margin;
               margin = start_margin;
               }

            col = indent;

            for(;;)
               {
               tok = find_token_length(ONLINE, curr, len, &size, &width);

               if (tok == TOK_DONE || tok == TOK_NL || tok == TOK_FF )
                  break;

               if (tok == TOK_PARA)
                  {
                  col = 0;   /* fake a new-line */
                  row++;
                  break;
                  }

               if (tok == TOK_XONLINE || tok == TOK_XDOC)
                  {
                  curr += size;
                  len  -= size;
                  continue;
                  }

               /* now tok is TOK_SPACE or TOK_LINK or TOK_WORD */

               if (col+width > SCREEN_WIDTH)
                  {          /* go to next line... */
                  col = margin;
                  ++row;

                  if ( tok == TOK_SPACE )
                     width = 0;   /* skip spaces at start of a line */
                  }

               if (tok == TOK_LINK)
                  {
                  display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
                  if (num_link != NULL)
                     {
                     link[*num_link].r         = (BYTE)row;
                     link[*num_link].c         = (BYTE)col;
                     link[*num_link].topic_num = getint(curr+1);
                     link[*num_link].topic_off = getint(curr+1+sizeof(int));
                     link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
                     link[*num_link].width     = width;
                     ++(*num_link);
                     }
                  }
               else if (tok == TOK_WORD )
		  display_text(row, col, C_HELP_BODY, curr, width);

               col += width;
               curr += size;
               len -= size;
               }

            width = size = 0;
            break;
            }

         case TOK_CENTER:
            col = find_line_width(ONLINE, curr, len);
            col = (SCREEN_WIDTH-col)/2;
            if (col < 0)
               col = 0;
            break;

         case TOK_NL:
            col = 0;
            ++row;
            break;

         case TOK_LINK:
            display_text(row, col, C_HELP_LINK, curr+1+3*sizeof(int), width);
            if (num_link != NULL)
               {
               link[*num_link].r         = (BYTE)row;
               link[*num_link].c         = (BYTE)col;
               link[*num_link].topic_num = getint(curr+1);
               link[*num_link].topic_off = getint(curr+1+sizeof(int));
               link[*num_link].offset    = (unsigned) ((curr+1+3*sizeof(int)) - text);
               link[*num_link].width     = width;
               ++(*num_link);
               }
            break;

         case TOK_XONLINE:  /* skip */
         case TOK_FF:       /* ignore */
         case TOK_XDOC:     /* ignore */
         case TOK_DONE:
         case TOK_SPACE:
            break;

         case TOK_WORD:
            display_text(row, col, C_HELP_BODY, curr, width);
            break;
         } /* switch */

      curr += size;
      len  -= size;
      col  += width;

      if (len == 0)
         break;

      tok = find_token_length(ONLINE, curr, len, &size, &width);
      } /* for(;;) */

   textcbase = 0;
   textrbase = 0;
   }
bool process_document(PD_FUNC get_info, PD_FUNC output, VOIDPTR info)
{
    int       tok;
    int       size,
              width;
    int       col;
    char      page_text[10];
    PD_INFO   pd;
    char      nl = '\n',
              sp = ' ';
    bool first_topic;

    pd.pnum = 1;
    pd.lnum = 0;

    output(PD_HEADING, &pd, info);

    bool first_section = true;

    while (get_info(PD_GET_CONTENT, &pd, info))
    {
        if (!output(PD_START_SECTION, &pd, info))
            return false;

        if (pd.new_page && pd.lnum != 0)
        {
            if (!output(PD_FOOTING, &pd, info))
                return false;
            ++pd.pnum;
            pd.lnum = 0;
            if (!output(PD_HEADING, &pd, info))
                return false;
        }

        else
        {
            if (pd.lnum+2 > PAGE_DEPTH-CONTENT_BREAK)
            {
                if (!output(PD_FOOTING, &pd, info))
                    return false;
                ++pd.pnum;
                pd.lnum = 0;
                if (!output(PD_HEADING, &pd, info))
                    return false;
            }
            else if (pd.lnum > 0)
            {
                if (!DO_PRINTN(nl, 2))
                    return false;
                pd.lnum += 2;
            }
        }

        if (!output(PD_SET_SECTION_PAGE, &pd, info))
            return false;

        if (!first_section)
        {
            if (!output(PD_PRINT_SEC, &pd, info))
                return false;
            ++pd.lnum;
        }

        first_topic = true;

        bool skip_blanks;
        while (get_info(PD_GET_TOPIC, &pd, info))
        {
            if (!output(PD_START_TOPIC, &pd, info))
                return false;

            skip_blanks = false;
            col = 0;

            if (!first_section)     /* do not skip blanks for DocContents */
            {
                while (pd.len > 0)
                {
                    tok = find_token_length(DOC, pd.curr, pd.len, &size, nullptr);
                    if (tok != TOK_XDOC && tok != TOK_XONLINE &&
                            tok != TOK_NL   && tok != TOK_DONE)
                        break;
                    pd.curr += size;
                    pd.len  -= size;
                }
                if (first_topic && pd.len != 0)
                {
                    if (!DO_PRINTN(nl, 1))
                        return false;
                    ++pd.lnum;
                }
            }

            if (pd.lnum > PAGE_DEPTH-TOPIC_BREAK)
            {
                if (!output(PD_FOOTING, &pd, info))
                    return false;
                ++pd.pnum;
                pd.lnum = 0;
                if (!output(PD_HEADING, &pd, info))
                    return false;
            }
            else if (!first_topic)
            {
                if (!DO_PRINTN(nl, 1))
                    return false;
                pd.lnum++;
            }

            if (!output(PD_SET_TOPIC_PAGE, &pd, info))
                return false;

            do
            {
                if (!output(PD_PERIODIC, &pd, info))
                    return false;

                tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);

                switch (tok)
                {
                case TOK_PARA:
                {
                    int       indent,
                              margin;
                    unsigned  holdlen = 0;
                    char *holdcurr = 0;
                    int       in_link = 0;

                    ++pd.curr;

                    indent = *pd.curr++;
                    margin = *pd.curr++;

                    pd.len -= 3;

                    if (!DO_PRINTN(sp, indent))
                        return false;

                    col = indent;

                    while (true)
                    {
                        if (!output(PD_PERIODIC, &pd, info))
                            return false;

                        tok = find_token_length(DOC, pd.curr, pd.len, &size, &width);

                        if (tok == TOK_NL || tok == TOK_FF)
                            break;

                        if (tok == TOK_DONE)
                        {
                            if (in_link == 0)
                            {
                                col = 0;
                                ++pd.lnum;
                                if (!DO_PRINTN(nl, 1))
                                    return false;
                                break;
                            }

                            else if (in_link == 1)
                            {
                                tok = TOK_SPACE;
                                width = 1;
                                size = 0;
                                ++in_link;
                            }

                            else if (in_link == 2)
                            {
                                tok = TOK_WORD;
                                width = (int) strlen(page_text);
                                col += 8 - width;
                                size = 0;
                                pd.curr = page_text;
                                ++in_link;
                            }

                            else if (in_link == 3)
                            {
                                pd.curr = holdcurr;
                                pd.len = holdlen;
                                in_link = 0;
                                continue;
                            }
                        }

                        if (tok == TOK_PARA)
                        {
                            col = 0;   /* fake a nl */
                            ++pd.lnum;
                            if (!DO_PRINTN(nl, 1))
                                return false;
                            break;
                        }

                        if (tok == TOK_XONLINE || tok == TOK_XDOC)
                        {
                            pd.curr += size;
                            pd.len -= size;
                            continue;
                        }

                        if (tok == TOK_LINK)
                        {
                            pd.s = pd.curr+1;
                            if (get_info(PD_GET_LINK_PAGE, &pd, info))
                            {
                                in_link = 1;
                                sprintf(page_text, "(p. %d)", pd.i);
                            }
                            else
                                in_link = 3;
                            holdcurr = pd.curr + size;
                            holdlen = pd.len - size;
                            pd.len = size - 2 - 3*sizeof(int);
                            pd.curr += 1 + 3*sizeof(int);
                            continue;
                        }

                        /* now tok is TOK_SPACE or TOK_WORD */

                        if (col+width > PAGE_WIDTH)
                        {   /* go to next line... */
                            if (!DO_PRINTN(nl, 1))
                                return false;
                            if (++pd.lnum >= PAGE_DEPTH)
                            {
                                if (!output(PD_FOOTING, &pd, info))
                                    return false;
                                ++pd.pnum;
                                pd.lnum = 0;
                                if (!output(PD_HEADING, &pd, info))
                                    return false;
                            }

                            if (tok == TOK_SPACE)
                                width = 0;   /* skip spaces at start of a line */

                            if (!DO_PRINTN(sp, margin))
                                return false;
                            col = margin;
                        }

                        if (width > 0)
                        {
                            if (tok == TOK_SPACE)
                            {
                                if (!DO_PRINTN(sp, width))
                                    return false;
                            }
                            else
                            {
                                if (!DO_PRINT(pd.curr, (size == 0) ? width : size))
                                    return false;
                            }
                        }

                        col += width;
                        pd.curr += size;
                        pd.len -= size;
                    }

                    skip_blanks = false;
                    size = 0;
                    width = size;
                    break;
                }

                case TOK_NL:
                    if (skip_blanks && col == 0)
                        break;

                    ++pd.lnum;

                    if (pd.lnum >= PAGE_DEPTH || (col == 0 && pd.lnum >= PAGE_DEPTH-BLANK_BREAK))
                    {
                        if (col != 0)      /* if last wasn't a blank line... */
                        {
                            if (!DO_PRINTN(nl, 1))
                                return false;
                        }
                        if (!output(PD_FOOTING, &pd, info))
                            return false;
                        ++pd.pnum;
                        pd.lnum = 0;
                        skip_blanks = true;
                        if (!output(PD_HEADING, &pd, info))
                            return false;
                    }
                    else
                    {
                        if (!DO_PRINTN(nl, 1))
                            return false;
                    }

                    col = 0;
                    break;

                case TOK_FF:
                    if (skip_blanks)
                        break;
                    if (!output(PD_FOOTING, &pd, info))
                        return false;
                    col = 0;
                    pd.lnum = 0;
                    ++pd.pnum;
                    if (!output(PD_HEADING, &pd, info))
                        return false;
                    break;

                case TOK_CENTER:
                    width = (PAGE_WIDTH - find_line_width(DOC, pd.curr, pd.len)) / 2;
                    if (!DO_PRINTN(sp, width))
                        return false;
                    break;

                case TOK_LINK:
                    skip_blanks = false;
                    if (!DO_PRINT(pd.curr+1+3*sizeof(int),
                                  size-3*sizeof(int)-2))
                        return false;
                    pd.s = pd.curr+1;
                    if (get_info(PD_GET_LINK_PAGE, &pd, info))
                    {
                        width += 9;
                        sprintf(page_text, " (p. %d)", pd.i);
                        if (!DO_PRINT(page_text, (int) strlen(page_text)))
                            return false;
                    }
                    break;

                case TOK_WORD:
                    skip_blanks = false;
                    if (!DO_PRINT(pd.curr, size))
                        return false;
                    break;

                case TOK_SPACE:
                    skip_blanks = false;
                    if (!DO_PRINTN(sp, width))
                        return false;
                    break;

                case TOK_DONE:
                case TOK_XONLINE:   /* skip */
                case TOK_XDOC:      /* ignore */
                    break;

                } /* switch */

                pd.curr += size;
                pd.len  -= size;
                col     += width;
            }
            while (pd.len > 0);

            get_info(PD_RELEASE_TOPIC, &pd, info);

            first_topic = false;
        } /* while */

        first_section = false;
    } /* while */

    if (!output(PD_FOOTING, &pd, info))
        return false;

    return true;
}