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); }
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; }