diff options
Diffstat (limited to 'src/devices/grohtml/post-html.cc')
-rw-r--r-- | src/devices/grohtml/post-html.cc | 1056 |
1 files changed, 907 insertions, 149 deletions
diff --git a/src/devices/grohtml/post-html.cc b/src/devices/grohtml/post-html.cc index 854bd372..0d442ee5 100644 --- a/src/devices/grohtml/post-html.cc +++ b/src/devices/grohtml/post-html.cc @@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cset.h" #include "html.h" #include "html-text.h" +#include "html-table.h" #include <time.h> @@ -55,10 +56,11 @@ extern "C" const char *Version_string; #define UNICODE_DESC_START 0x80 /* all character entities above this are */ /* either encoded by their glyph names or if */ /* there is no name then we use &#nnn; */ -#define INDENTATION /* #undef INDENTATION to remove .in handling */ - typedef enum {CENTERED, LEFT, RIGHT, INLINE} TAG_ALIGNMENT; +#undef DEBUG_TABLES + + /* * prototypes */ @@ -85,20 +87,18 @@ void stop () {} static int min (int a, int b) { - if (a < b) { - return( a ); - } else { - return( b ); - } + if (a < b) + return a; + else + return b; } static int max (int a, int b) { - if (a > b) { - return( a ); - } else { - return( b ); - } + if (a > b) + return a; + else + return b; } /* @@ -107,7 +107,7 @@ static int max (int a, int b) static int is_intersection (int a1, int a2, int b1, int b2) { - // again easier to prove NOT outside limits + // easier to prove NOT outside limits return( ! ((a1 > b2) || (a2 < b1)) ); } @@ -366,7 +366,25 @@ public: int is_eol (void); int is_auto_img (void); int is_br (void); + int is_br_ni (void); + int is_in (void); + int is_po (void); + int is_ti (void); + int is_ce (void); int is_eol_ce (void); + int is_col (void); + int is_tab (void); + int is_tab0 (void); + int is_ta (void); + int is_tab_ts (void); + int is_tab_te (void); + int is_nf (void); + int is_fi (void); + int get_arg (void); + int get_tab_args (char *align); + + void remember_table (html_table *t); + html_table *get_table (void); style text_style; const char *text_string; @@ -377,6 +395,7 @@ public: int is_special; // text has come via 'x X html:' int is_line; // is the command a <line>? int thickness; // the thickness of a line + html_table *tab; // table description private: text_glob (style *s, char *str, int length, @@ -396,18 +415,20 @@ text_glob::text_glob (style *s, char *str, int length, : text_style(*s), text_string(str), text_length(length), minv(min_vertical), minh(min_horizontal), maxv(max_vertical), maxh(max_horizontal), is_tag(is_troff_command), is_img_auto(is_auto_image), is_special(is_special_command), - is_line(is_a_line), thickness(line_thickness) + is_line(is_a_line), thickness(line_thickness), tab(NULL) { } text_glob::text_glob () : text_string(0), text_length(0), minv(-1), minh(-1), maxv(-1), maxh(-1), - is_tag(FALSE), is_special(FALSE), is_line(FALSE), thickness(0) + is_tag(FALSE), is_special(FALSE), is_line(FALSE), thickness(0), tab(NULL) { } text_glob::~text_glob () { + if (tab != NULL) + delete tab; } /* @@ -539,6 +560,115 @@ int text_glob::is_eol_ce (void) return( is_tag && (strcmp(text_string, "html-tag:eol.ce") == 0) ); } + +/* + * is_nf - returns TRUE if glob contains the tag .nf + */ + +int text_glob::is_nf (void) +{ + return( is_tag && (strcmp(text_string, "html-tag:.nf") == 0) ); +} + +/* + * is_fi - returns TRUE if glob contains the tag .fi + */ + +int text_glob::is_fi (void) +{ + return( is_tag && (strcmp(text_string, "html-tag:.fi") == 0) ); +} + +/* + * is_ce - returns TRUE if glob contains the tag .ce + */ + +int text_glob::is_ce (void) +{ + return( is_tag && (strcmp(text_string, "html-tag:.ce") == 0) ); +} + +/* + * is_in - returns TRUE if glob contains the tag .in + */ + +int text_glob::is_in (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:.in ", strlen("html-tag:.in ")) == 0) ); +} + +/* + * is_po - returns TRUE if glob contains the tag .po + */ + +int text_glob::is_po (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:.po ", strlen("html-tag:.po ")) == 0) ); +} + +/* + * is_ti - returns TRUE if glob contains the tag .ti + */ + +int text_glob::is_ti (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:.ti ", strlen("html-tag:.ti ")) == 0) ); +} + +/* + * is_col - returns TRUE if glob contains the tag .col + */ + +int text_glob::is_col (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:.col", strlen("html-tag:.col")) == 0) ); +} + +/* + * is_tab_ts - returns TRUE if glob contains the tag .tab_ts + */ + +int text_glob::is_tab_ts (void) +{ + return( is_tag && (strcmp(text_string, "html-tag:.tab-ts") == 0) ); +} + +/* + * is_tab_te - returns TRUE if glob contains the tag .tab_te + */ + +int text_glob::is_tab_te (void) +{ + return( is_tag && (strcmp(text_string, "html-tag:.tab-te") == 0) ); +} + +/* + * is_ta - returns TRUE if glob contains the tag .ta + */ + +int text_glob::is_ta (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:.ta ", strlen("html-tag:.ta ")) == 0) ); +} + +/* + * is_tab - returns TRUE if glob contains the tag tab + */ + +int text_glob::is_tab (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:tab ", strlen("html-tag:tab ")) == 0) ); +} + +/* + * is_tab0 - returns TRUE if glob contains the tag tab0 + */ + +int text_glob::is_tab0 (void) +{ + return( is_tag && (strncmp(text_string, "html-tag:tab0", strlen("html-tag:tab0")) == 0) ); +} + /* * is_auto_img - returns TRUE if the glob contains an automatically * generated image. @@ -551,7 +681,9 @@ int text_glob::is_auto_img (void) /* * is_br - returns TRUE if the glob is a tag containing a .br - * or an implied .br + * or an implied .br. Note that we do not include .nf or .fi + * as grohtml will place a .br after these commands if they + * should break the line. */ int text_glob::is_br (void) @@ -559,7 +691,80 @@ int text_glob::is_br (void) return( is_a_tag() && ((strcmp ("html-tag:.br", text_string) == 0) || (strncmp("html-tag:.sp", text_string, 11) == 0) || (strcmp ("html-tag:.ce", text_string) == 0) || - (strcmp ("html-tag:.nf", text_string) == 0)) ); + (strncmp ("html-tag:.in", text_string, 11) == 0)) ); +} + +/* + * is_br_ni - returns TRUE if the glob is a tag containing a .br + * or an implied .br, but not an .in + */ + +int text_glob::is_br_ni (void) +{ + return( is_a_tag() && ((strcmp ("html-tag:.br", text_string) == 0) || + (strncmp("html-tag:.sp", text_string, 11) == 0) || + (strcmp ("html-tag:.ce", text_string) == 0)) ); +} + +int text_glob::get_arg (void) +{ + if (strncmp("html-tag:", text_string, strlen("html-tag:")) == 0) { + const char *p = text_string; + + while ((*p != (char)0) && (!isspace(*p))) + p++; + while ((*p != (char)0) && (isspace(*p))) + p++; + if (*p == (char)0) + return -1; + return atoi(p); + } + return -1; +} + +/* + * get_tab_args - returns the tab position and alignment of the tab tag + */ + +int text_glob::get_tab_args (char *align) +{ + if (strncmp("html-tag:", text_string, strlen("html-tag:")) == 0) { + const char *p = text_string; + + // firstly the alignment C|R|L + while ((*p != (char)0) && (!isspace(*p))) + p++; + while ((*p != (char)0) && (isspace(*p))) + p++; + *align = *p; + // now the int value + while ((*p != (char)0) && (!isspace(*p))) + p++; + while ((*p != (char)0) && (isspace(*p))) + p++; + if (*p == (char)0) + return -1; + return atoi(p); + } + return -1; +} + +/* + * remember_table - saves table, t, in the text_glob. + */ + +void text_glob::remember_table (html_table *t) +{ + tab = t; +} + +/* + * get_table - returns the stored table description. + */ + +html_table *text_glob::get_table (void) +{ + return tab; } /* @@ -618,6 +823,8 @@ public: int is_equal_to_head (void); void start_from_head (void); void start_from_tail (void); + void insert (text_glob *in); + void move_to (text_glob *in); text_glob *move_right_get_data (void); text_glob *move_left_get_data (void); text_glob *get_data (void); @@ -685,6 +892,7 @@ void list::add (text_glob *in, int line_number, int min_vertical, int min_horizo if (head == 0) { head = t; tail = t; + ptr = t; t->left = t; t->right = t; } else { @@ -835,7 +1043,7 @@ text_glob* list::move_right_get_data (void) /* * move_left_get_data - returns the datum referenced via ptr and moves - * ptr right. + * ptr right. */ text_glob* list::move_left_get_data (void) @@ -849,6 +1057,39 @@ text_glob* list::move_left_get_data (void) } /* + * insert - inserts data after the current position. + */ + +void list::insert (text_glob *in) +{ + if (is_empty()) + fatal("list must not be empty if we are inserting data"); + else { + if (ptr == 0) + ptr = head; + + element_list *t = new element_list(in, ptr->lineno, ptr->minv, ptr->minh, ptr->maxv, ptr->maxh); + if (ptr == tail) + tail = t; + t->right = ptr->right; + ptr->right = t; + t->left = ptr; + } +} + +/* + * move_to - moves the current position to the point where data, in, exists. + * This is an expensive method and should be used sparingly. + */ + +void list::move_to (text_glob *in) +{ + ptr = head; + while (ptr != tail && ptr->datum != in) + ptr = ptr->right; +} + +/* * page class and methods */ @@ -871,6 +1112,7 @@ public: int line_number, int x1, int y1, int x2, int y2, int thickness); + void insert_tag (const string &str); void dump_page (void); // debugging method // and the data @@ -884,6 +1126,21 @@ page::page() } /* + * insert_tag - inserts a tag after the current position. + */ + +void page::insert_tag (const string &str) +{ + if (str.length() > 0) { + text_glob *g=new text_glob(); + text_glob *f=glyphs.get_data(); + g->text_glob_tag(&f->text_style, buffer.add_string(str), str.length(), + f->minv, f->minh, f->maxv, f->maxh); + glyphs.insert(g); + } +} + +/* * add - add html text to the list of glyphs. */ @@ -1020,16 +1277,29 @@ void page::add_and_encode (style *s, const string &str, void page::dump_page(void) { +#if defined(DEBUG_TABLES) + text_glob *old_pos = glyphs.get_data(); text_glob *g; + printf("\n<!--\n"); printf("\n\ndebugging start\n"); glyphs.start_from_head(); do { g = glyphs.get_data(); + if (g->is_tab_ts()) { + printf("\n\n"); + if (g->get_table() != NULL) + g->get_table()->dump_table(); + } printf("%s ", g->text_string); + if (g->is_tab_te()) + printf("\n\n"); glyphs.move_right(); } while (! glyphs.is_equal_to_head()); + glyphs.move_to(old_pos); printf("\ndebugging end\n\n"); + printf("\n-->\n"); +#endif } /* @@ -1177,17 +1447,19 @@ class html_printer : public printer { char *inside_font_style; int page_number; title_desc title; - title_desc indent; // use title class to remember $1 of .ip header_desc header; int header_indent; int supress_sub_sup; int cutoff_heading; page *page_contents; html_text *current_paragraph; + html_indent *indent; + html_table *table; int end_center; int end_tempindent; TAG_ALIGNMENT next_tag; int fill_on; + int max_linelength; int linelength; int pageoffset; int indentation; @@ -1227,6 +1499,7 @@ class html_printer : public printer { void do_center (char *arg); void do_break (void); void do_eol (void); + void do_eol_ce (void); void do_title (void); void do_fill (int on); void do_heading (char *arg); @@ -1256,6 +1529,23 @@ class html_printer : public printer { font *make_bold (font *f); int overstrike (unsigned char code, const char *name, const environment *env, int w); void do_body (void); + int next_horiz_pos (int nf); + void lookahead_for_tables (void); + void insert_tab_te (void); + text_glob *insert_tab_ts (text_glob *where); + void insert_tab0_foreach_tab (void); + void insert_tab_0 (text_glob *where); + void do_indent (int in, int pageoff, int linelen); + void shutdown_table (void); + void do_tab_ts (text_glob *g); + void do_tab_te (void); + void do_col (char *s); + void do_tab (char *s); + void do_tab0 (void); + int calc_nf (text_glob *g, int nf); + void calc_po_in (text_glob *g, int nf); + void remove_tabs (void); + void remove_courier_tabs (void); // ADD HERE public: @@ -1342,8 +1632,6 @@ void html_printer::emit_raw (text_glob *g) determine_space(g); current_paragraph->do_emittext(g->text_string, g->text_length); } else { - int in_table=current_paragraph->is_in_table(); - current_paragraph->done_para(); switch (next_tag) { @@ -1351,10 +1639,10 @@ void html_printer::emit_raw (text_glob *g) current_paragraph->do_para("align=center"); break; case LEFT: - current_paragraph->do_para("align=left"); + current_paragraph->do_para(&html, "align=left", indentation, pageoffset, linelength); break; case RIGHT: - current_paragraph->do_para("align=right"); + current_paragraph->do_para(&html, "align=right", indentation, pageoffset, linelength); break; default: fatal("unknown enumeration"); @@ -1363,13 +1651,14 @@ void html_printer::emit_raw (text_glob *g) current_paragraph->done_para(); next_tag = INLINE; supress_sub_sup = TRUE; -#if defined(INDENTATION) - if (in_table) { - current_paragraph->do_indent(NULL, 0, pageoffset, linelength); - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); + if (indentation > 0) { + /* + * restore indentation + */ + int newin = indentation; + indentation = 0; + do_indent(newin, pageoffset, linelength); } -#endif } } @@ -1380,16 +1669,16 @@ void html_printer::emit_raw (text_glob *g) void html_printer::do_center (char *arg) { int n = atoi(arg); - current_paragraph->do_break(); - current_paragraph->done_para(); - supress_sub_sup = TRUE; - + if (n > 0) { + current_paragraph->done_para(); + supress_sub_sup = TRUE; current_paragraph->do_para("align=center"); end_center += n; } else { end_center = 0; + current_paragraph->remove_para_align(); } } @@ -1569,7 +1858,6 @@ void html_printer::write_header (void) // firstly we must terminate any font and type faces current_paragraph->done_para(); - current_paragraph->done_table(); supress_sub_sup = TRUE; if (cutoff_heading+2 > header.header_level) { @@ -1631,7 +1919,7 @@ void html_printer::write_header (void) html.put_string(">").nl(); } - current_paragraph->do_para(""); + current_paragraph->do_para(&html, "", indentation, pageoffset, linelength); } } @@ -1715,22 +2003,20 @@ int html_printer::is_courier_until_eol (void) page_contents->glyphs.move_right(); do { g = page_contents->glyphs.get_data(); - if (! is_font_courier(g->text_style.f)) { + if (! g->is_a_tag() && (! is_font_courier(g->text_style.f))) result = FALSE; - } page_contents->glyphs.move_right(); - } while ((result) && + } while (result && (! page_contents->glyphs.is_equal_to_head()) && - (! g->is_eol())); + (! g->is_fi()) && (! g->is_eol())); /* * now restore our previous position. */ - while (page_contents->glyphs.get_data() != orig) { + while (page_contents->glyphs.get_data() != orig) page_contents->glyphs.move_left(); - } } - return( result ); + return result; } /* @@ -1739,13 +2025,11 @@ int html_printer::is_courier_until_eol (void) void html_printer::do_linelength (char *arg) { -#if defined(INDENTATION) - if (fill_on) { - linelength = atoi(arg); - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); - } -#endif + if (max_linelength == -1) + max_linelength = atoi(arg); + + if (fill_on) + do_indent(indentation, pageoffset, atoi(arg)); } /* @@ -1754,13 +2038,8 @@ void html_printer::do_linelength (char *arg) void html_printer::do_pageoffset (char *arg) { -#if defined(INDENTATION) - pageoffset = atoi(arg); - if (fill_on) { - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); - } -#endif + if (fill_on) + do_indent(indentation, atoi(arg), linelength); } /* @@ -1769,13 +2048,8 @@ void html_printer::do_pageoffset (char *arg) void html_printer::do_indentation (char *arg) { -#if defined(INDENTATION) - if (fill_on) { - indentation = atoi(arg); - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); - } -#endif + if (fill_on) + do_indent(atoi(arg), pageoffset, linelength); } /* @@ -1784,78 +2058,47 @@ void html_printer::do_indentation (char *arg) void html_printer::do_tempindent (char *arg) { -#if defined(INDENTATION) if (fill_on) { end_tempindent = 1; prev_indent = indentation; - indentation = atoi(arg); - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); + do_indent(atoi(arg), pageoffset, linelength); } -#endif } /* - * do_indentedparagraph - handle the .ip tag, this buffers the next line - * and passes this to text-text as the left hand - * column table entry. + * shutdown_table - shuts down the current table. */ -void html_printer::do_indentedparagraph (void) +void html_printer::shutdown_table (void) { -#if defined(INDENTATION) - text_glob *t; - int removed_from_head; - int found_indent_start = FALSE; - - indent.has_been_found = FALSE; - indent.text.clear(); + if (table != NULL) { + current_paragraph->done_para(); + table->emit_finish_table(); + // dont delete this table as it will be deleted when we destroy the text_glob + table = NULL; + } +} - if (! page_contents->glyphs.is_empty()) { - page_contents->glyphs.sub_move_right(); /* move onto next word */ - do { - t = page_contents->glyphs.get_data(); - removed_from_head = FALSE; - if (t->is_auto_img()) { - string img = generate_img_src((char *)(t->text_string + 20)); +/* + * do_indent - remember the indent parameters and if + * indent is > pageoff and indent has changed + * then we start a html table to implement the indentation. + */ - if (! img.empty()) { - if (found_indent_start) - indent.text += " "; +void html_printer::do_indent (int in, int pageoff, int linelen) +{ + if ((indentation != -1) && + (pageoffset+indentation != in+pageoff)) { + + current_paragraph->done_para(); + + indentation = in; + pageoffset = pageoff; + if (linelen <= max_linelength) + linelength = linelen; - found_indent_start = TRUE; - indent.text += img; - } - page_contents->glyphs.sub_move_right(); /* move onto next word */ - } else if (t->is_a_tag() && (strncmp(t->text_string, "html-tag:.br", 12) == 0)) { - /* end of indented para found, but move back so that we read this tag and process it - */ - page_contents->glyphs.move_left(); /* move backwards to last word */ - indent.has_been_found = TRUE; - return; - } else if (t->is_a_tag()) { - if (strncmp(t->text_string, "html-tag:.ti", 12) == 0) { - char *a = (char *)t->text_string+12; - do_tempindent(a); - } - page_contents->glyphs.sub_move_right(); /* move onto next word */ - } else if (found_indent_start) { - indent.text += " " + string(t->text_string, t->text_length); - page_contents->glyphs.sub_move_right(); /* move onto next word */ - removed_from_head = ((!page_contents->glyphs.is_empty()) && - (page_contents->glyphs.is_equal_to_head())); - } else { - indent.text += string(t->text_string, t->text_length); - found_indent_start = TRUE; - indent.has_been_found = TRUE; - page_contents->glyphs.sub_move_right(); /* move onto next word */ - removed_from_head = ((!page_contents->glyphs.is_empty()) && - (page_contents->glyphs.is_equal_to_head())); - } - } while ((! page_contents->glyphs.is_equal_to_head()) || (removed_from_head)); + current_paragraph->do_para(&html, "", indentation, pageoffset, max_linelength); } - // page_contents->glyphs.move_left(); /* move backwards to last word */ -#endif } /* @@ -1887,13 +2130,12 @@ void html_printer::do_fill (int on) supress_sub_sup = TRUE; if (fill_on != on) { - if (on) { - current_paragraph->done_pre(); - } else { + if (on) + current_paragraph->do_para(""); + else current_paragraph->do_pre(); - } + fill_on = on; } - fill_on = on; } /* @@ -1903,12 +2145,20 @@ void html_printer::do_fill (int on) void html_printer::do_eol (void) { if (! fill_on) { - if (current_paragraph->emitted_text()) { + if (current_paragraph->ever_emitted_text()) { current_paragraph->do_newline(); current_paragraph->do_break(); } } output_hpos = indentation+pageoffset; +} + +/* + * do_eol_ce - handle end of line specifically for a .ce + */ + +void html_printer::do_eol_ce (void) +{ if (end_center > 0) { if (end_center > 1) if (current_paragraph->emitted_text()) @@ -1929,7 +2179,6 @@ void html_printer::do_eol (void) void html_printer::do_flush (void) { current_paragraph->done_para(); - current_paragraph->done_table(); } /* @@ -1939,7 +2188,6 @@ void html_printer::do_flush (void) void html_printer::do_links (void) { current_paragraph->done_para(); - current_paragraph->done_table(); auto_links = FALSE; /* from now on only emit under user request */ file_list.add_new_file(xtmpfile()); html.set_file(file_list.get_file()); @@ -1953,21 +2201,108 @@ void html_printer::do_links (void) void html_printer::do_break (void) { current_paragraph->do_break(); -#if defined(INDENTATION) if (end_tempindent > 0) { end_tempindent--; - if (end_tempindent == 0) { - indentation = prev_indent; - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); - } + if (end_tempindent == 0) + do_indent(prev_indent, pageoffset, linelength); } -#endif output_hpos = indentation+pageoffset; supress_sub_sup = TRUE; } /* + * do_tab_ts - start a table, which will have already been defined. + */ + +void html_printer::do_tab_ts (text_glob *g) +{ + html_table *t = g->get_table(); + + if (t != NULL) { + int need_space = ((! current_paragraph->ever_emitted_text()) && + current_paragraph->starts_with_space()); + + current_paragraph->done_pre(); + current_paragraph->done_para(); + + html.simple_comment("TABS"); + t->set_linelength(max_linelength); + t->add_indent(pageoffset); + t->emit_table_header(need_space); + } + + table = t; +} + +/* + * do_tab_te - finish a table. + */ + +void html_printer::do_tab_te (void) +{ + if (table) { + current_paragraph->done_para(); + table->emit_finish_table(); + } + + table = NULL; + + if (indentation > 0) { + /* + * restore indentation + */ + int newin = indentation; + indentation = 0; + do_indent(newin, pageoffset, linelength); + } +} + +/* + * do_tab - handle the "html-tag:tab" tag + */ + +void html_printer::do_tab (char *s) +{ + if (table) { + while (isspace(*s)) + s++; + s++; + int col = table->find_column(atoi(s) + pageoffset + indentation); + if (col > 0) { + current_paragraph->done_para(); + table->emit_col(col); + } + } +} + +/* + * do_tab0 - handle the "html-tag:tab0" tag + */ + +void html_printer::do_tab0 (void) +{ + if (table) { + int col = table->find_column(pageoffset+indentation); + if (col > 0) { + current_paragraph->done_para(); + table->emit_col(col); + } + } +} + +/* + * do_col - start column, s. + */ + +void html_printer::do_col (char *s) +{ + if (table) { + current_paragraph->done_para(); + table->emit_col(atoi(s)); + } +} + +/* * troff_tag - processes the troff tag and manipulates the troff state machine. */ @@ -1981,9 +2316,12 @@ void html_printer::troff_tag (text_glob *g) if (g->is_eol()) { do_eol(); } else if (g->is_eol_ce()) { - do_eol(); + do_eol_ce(); } else if (strncmp(t, ".sp", 3) == 0) { - current_paragraph->do_space(); + if (g->get_arg() > 0) + current_paragraph->do_space(); + else + current_paragraph->do_break(); supress_sub_sup = TRUE; } else if (strncmp(t, ".br", 3) == 0) { do_break(); @@ -2030,12 +2368,22 @@ void html_printer::troff_tag (text_glob *g) } else if (strncmp(t, ".vs", 3) == 0) { char *a = (char *)t+3; do_verticalspacing(a); - } else if (strncmp(t, ".ip", 3) == 0) { - do_indentedparagraph(); } else if (strcmp(t, ".links") == 0) { do_links(); } else if (strcmp(t, ".no-auto-rule") == 0) { auto_rule = FALSE; + } else if (strcmp(t, ".tab-ts") == 0) { + do_tab_ts(g); + } else if (strcmp(t, ".tab-te") == 0) { + do_tab_te(); + } else if (strncmp(t, ".col ", 5) == 0) { + char *a = (char *)t+4; + do_col(a); + } else if (strncmp(t, "tab ", 4) == 0) { + char *a = (char *)t+3; + do_tab(a); + } else if (strncmp(t, "tab0", 4) == 0) { + do_tab0(); } } @@ -2061,9 +2409,8 @@ void html_printer::flush_globs (void) do { g = page_contents->glyphs.get_data(); - if (strcmp(g->text_string, "XXXXXXX") == 0) { + if (strcmp(g->text_string, "XXXXXXX") == 0) stop(); - } if (g->is_a_tag()) { troff_tag(g); @@ -2082,14 +2429,425 @@ void html_printer::flush_globs (void) } } +/* + * calc_nf - calculates the _no_ format flag, given the + * text glob, g. + */ + +int html_printer::calc_nf (text_glob *g, int nf) +{ + if (g->is_fi()) + return FALSE; + if (g->is_nf()) + return TRUE; + return nf; +} + +/* + * calc_po_in - calculates the, in, po, registers + */ + +void html_printer::calc_po_in (text_glob *g, int nf) +{ + if (g->is_in()) + indentation = g->get_arg(); + else if (g->is_po()) + pageoffset = g->get_arg(); + else if (g->is_ti()) { + prev_indent = indentation; + indentation = g->get_arg(); + end_tempindent = 1; + } else if (g->is_br() && ((end_tempindent > 0) || (nf && g->is_eol()))) { + end_tempindent = 0; + indentation = prev_indent; + } +} + +/* + * next_horiz_pos - returns the next horiz position. + * -1 is returned if it doesn't exist. + */ + +int html_printer::next_horiz_pos (int nf) +{ + int next = -1; + text_glob *g = page_contents->glyphs.get_data(); + + if (g->is_br() || (nf && g->is_eol())) + if (! page_contents->glyphs.is_empty()) { + page_contents->glyphs.move_right(); + next = g->minh; + page_contents->glyphs.move_left(); + } + return next; +} + +/* + * insert_tab_ts - inserts a tab-ts before, where. + */ + +text_glob *html_printer::insert_tab_ts (text_glob *where) +{ + text_glob *start_of_table; + text_glob *old_pos = page_contents->glyphs.get_data(); + + page_contents->glyphs.move_to(where); + page_contents->glyphs.move_left(); + page_contents->insert_tag(string("html-tag:.tab-ts")); // tab table start + page_contents->glyphs.move_right(); + start_of_table = page_contents->glyphs.get_data(); + page_contents->glyphs.move_to(old_pos); + return start_of_table; +} + +/* + * insert_tab_te - inserts a tab-te before the current position + * (it skips backwards over .sp/.br) + */ + +void html_printer::insert_tab_te (void) +{ + text_glob *g = page_contents->glyphs.get_data(); + page_contents->dump_page(); + + while (page_contents->glyphs.get_data()->is_a_tag()) + page_contents->glyphs.move_left(); + + page_contents->insert_tag(string("html-tag:.tab-te")); // tab table end + while (g != page_contents->glyphs.get_data()) + page_contents->glyphs.move_right(); + page_contents->dump_page(); +} + +/* + * insert_tab_0 - inserts a tab0 before, where. + */ + +void html_printer::insert_tab_0 (text_glob *where) +{ + text_glob *old_pos = page_contents->glyphs.get_data(); + + page_contents->glyphs.move_to(where); + page_contents->glyphs.move_left(); + page_contents->insert_tag(string("html-tag:tab0")); // tab0 start of line + page_contents->glyphs.move_right(); + page_contents->glyphs.move_to(old_pos); +} + +/* + * remove_tabs - removes the tabs tags on this line. + */ + +void html_printer::remove_tabs (void) +{ + text_glob *orig = page_contents->glyphs.get_data(); + text_glob *g; + + if (! page_contents->glyphs.is_equal_to_tail()) { + do { + g = page_contents->glyphs.get_data(); + if (g->is_tab()) { + page_contents->glyphs.sub_move_right(); + if (g == orig) + orig = page_contents->glyphs.get_data(); + } else + page_contents->glyphs.move_right(); + } while ((! page_contents->glyphs.is_equal_to_head()) && + (! g->is_eol())); + + /* + * now restore our previous position. + */ + while (page_contents->glyphs.get_data() != orig) + page_contents->glyphs.move_left(); + } +} + +void html_printer::remove_courier_tabs (void) +{ + text_glob *g; + int line_start = TRUE; + int nf = FALSE; + + if (! page_contents->glyphs.is_empty()) { + page_contents->glyphs.start_from_head(); + line_start = TRUE; + do { + g = page_contents->glyphs.get_data(); + + nf = calc_nf(g, nf); + + if (line_start) { + if (line_start && nf && is_courier_until_eol()) { + remove_tabs(); + g = page_contents->glyphs.get_data(); + } + } + + line_start = g->is_br() || g->is_nf() || g->is_fi() || (nf && g->is_eol()); + page_contents->glyphs.move_right(); + } while (! page_contents->glyphs.is_equal_to_head()); + } +} + +void html_printer::insert_tab0_foreach_tab (void) +{ + text_glob *start_of_line = NULL; + text_glob *g = NULL; + int seen_tab = FALSE; + int seen_col = FALSE; + int nf = FALSE; + + if (! page_contents->glyphs.is_empty()) { + page_contents->glyphs.start_from_head(); + start_of_line = page_contents->glyphs.get_data(); + do { + g = page_contents->glyphs.get_data(); + + nf = calc_nf(g, nf); + + if (g->is_tab()) + seen_tab = TRUE; + + if (g->is_col()) + seen_col = TRUE; + + if (g->is_br() || (nf && g->is_eol())) { + do { + page_contents->glyphs.move_right(); + g = page_contents->glyphs.get_data(); + nf = calc_nf(g, nf); + if (page_contents->glyphs.is_equal_to_head()) { + if (seen_tab && !seen_col) + insert_tab_0(start_of_line); + return; + } + } while (g->is_br() || (nf && g->is_eol()) || g->is_ta()); + // printf("\nstart_of_line is: %s\n", g->text_string); + if (seen_tab && !seen_col) { + insert_tab_0(start_of_line); + page_contents->glyphs.move_to(g); + } + + seen_tab = FALSE; + seen_col = FALSE; + start_of_line = g; + } + page_contents->glyphs.move_right(); + } while (! page_contents->glyphs.is_equal_to_head()); + if (seen_tab && !seen_col) + insert_tab_0(start_of_line); + + } +} + +/* + * lookahead_for_tables - checks for .col tags and inserts table start/end tags + */ + +void html_printer::lookahead_for_tables (void) +{ + text_glob *g; + text_glob *start_of_line = NULL; + text_glob *start_of_table = NULL; + text_glob *last = NULL; + enum {col_tag, tab_tag, tab0_tag, none} type_of_col = none; + int left = 0; + int found_col = FALSE; + int seen_text = FALSE; + int ncol = 0; + int colmin; + int colmax; + html_table *table = new html_table(&html, -1); + const char *tab_defs = NULL; + char align = 'L'; + int nf = FALSE; + + remove_courier_tabs(); + page_contents->dump_page(); + insert_tab0_foreach_tab(); + page_contents->dump_page(); + if (! page_contents->glyphs.is_empty()) { + page_contents->glyphs.start_from_head(); + g = page_contents->glyphs.get_data(); + do { +#if 0 + if (strcmp(g->text_string, "XXXXXXX") == 0) + stop(); +#endif + + nf = calc_nf(g, nf); + calc_po_in(g, nf); + if (g->is_col()) { + if (type_of_col == tab_tag && start_of_table != NULL) { + page_contents->glyphs.move_left(); + insert_tab_te(); + start_of_table->remember_table(table); + table = new html_table(&html, -1); + page_contents->insert_tag(string("*** TAB -> COL ***")); + if (tab_defs != NULL) + table->tab_stops->init(tab_defs); + start_of_table = NULL; + last = NULL; + } + type_of_col = col_tag; + found_col = TRUE; + ncol = g->get_arg(); + align = 'L'; + colmin = 0; + colmax = 0; + } else if (g->is_tab()) { + type_of_col = tab_tag; + colmin = g->get_tab_args(&align); + align = 'L'; // for now as 'C' and 'R' are broken + ncol = table->find_tab_column(colmin); + colmin += pageoffset + indentation; + colmax = table->get_tab_pos(ncol+1); + if (colmax > 0) + colmax += pageoffset + indentation; + } else if (g->is_tab0()) { + if (type_of_col == col_tag && start_of_table != NULL) { + page_contents->glyphs.move_left(); + insert_tab_te(); + start_of_table->remember_table(table); + table = new html_table(&html, -1); + page_contents->insert_tag(string("*** COL -> TAB ***")); + start_of_table = NULL; + last = NULL; + } + if (tab_defs != NULL) + table->tab_stops->init(tab_defs); + + type_of_col = tab0_tag; + ncol = 1; + colmin = 0; + colmax = table->get_tab_pos(2) + pageoffset + indentation; + } else if (! g->is_a_tag()) { + switch (type_of_col) { + + case tab_tag: + break; + case tab0_tag: + colmin = g->minh; + break; + case col_tag: + colmin = g->minh; + colmax = g->maxh; + break; + default: + break; + } + } + + if ((! g->is_a_tag()) || g->is_tab()) + seen_text = TRUE; + + if ((g->is_col() || g->is_tab() || g->is_tab0()) + && (start_of_line != NULL) && (start_of_table == NULL)) { + start_of_table = insert_tab_ts(start_of_line); + start_of_line = NULL; + seen_text = FALSE; + } else if (g->is_ce() && (start_of_table != NULL)) { + page_contents->glyphs.move_left(); + insert_tab_te(); + start_of_table->remember_table(table); + page_contents->insert_tag(string("*** CE ***")); + start_of_table = NULL; + last = NULL; + } else if (g->is_ta()) { + tab_defs = g->text_string; + if (!table->tab_stops->compatible(tab_defs)) { + if (start_of_table != NULL) { + page_contents->glyphs.move_left(); + insert_tab_te(); + start_of_table->remember_table(table); + table = new html_table(&html, -1); + page_contents->insert_tag(string("*** TABS ***")); + start_of_table = NULL; + type_of_col = none; + last = NULL; + } + table->tab_stops->init(tab_defs); + } + } + + if (((! g->is_a_tag()) || g->is_tab()) && (start_of_table != NULL)) { + // we are in a table and have a glyph + if ((ncol == 0) || (! table->add_column(ncol, colmin, colmax, align))) { + page_contents->glyphs.move_left(); + insert_tab_te(); +#if defined(DEBUG_TABLES) + if (ncol == 0) + page_contents->insert_tag(string("*** NCOL == 0 ***")); + else + page_contents->insert_tag(string("*** CROSSED COLS ***")); +#endif + start_of_table->remember_table(table); + table = new html_table(&html, -1); + start_of_table = NULL; + type_of_col = none; + last = NULL; + } + } + + /* + * move onto next glob, check whether we are starting a new line + */ + page_contents->glyphs.move_right(); + g = page_contents->glyphs.get_data(); + +#if defined(DEBUG_TABLES) + if (g->is_in() && (!seen_text)) + html.simple_comment("IGNORE .in"); + else +#endif + if (g->is_br_ni() || (nf && g->is_eol())) { + do { + page_contents->glyphs.move_right(); + g = page_contents->glyphs.get_data(); + nf = calc_nf(g, nf); + } while (g->is_br_ni() || (nf && g->is_eol())); + start_of_line = g; + seen_text = FALSE; + ncol = 0; + left = next_horiz_pos(nf); + if (found_col) + last = g; + found_col = FALSE; + } + } while (! page_contents->glyphs.is_equal_to_head()); + if (start_of_table != NULL) { + if (last != NULL) + while (last != page_contents->glyphs.get_data()) + page_contents->glyphs.move_left(); + + insert_tab_te(); + start_of_table->remember_table(table); + table = NULL; + page_contents->insert_tag(string("*** LAST ***")); + } + } + if (table != NULL) + delete table; + + // and reset the registers + pageoffset = 0; + pageoffset = 0; + indentation = 0; + prev_indent = 0; + end_tempindent = 0; +} + void html_printer::flush_page (void) { supress_sub_sup = TRUE; flush_sbuf(); - // page_contents->dump_page(); + page_contents->dump_page(); + lookahead_for_tables(); + page_contents->dump_page(); + flush_globs(); current_paragraph->done_para(); - current_paragraph->done_table(); // move onto a new page delete page_contents; @@ -2443,10 +3201,13 @@ html_printer::html_printer() header_indent(-1), supress_sub_sup(TRUE), cutoff_heading(100), + indent(NULL), + table(NULL), end_center(0), end_tempindent(0), next_tag(INLINE), fill_on(TRUE), + max_linelength(-1), linelength(0), pageoffset(0), indentation(0), @@ -2489,7 +3250,7 @@ html_printer::html_printer() void html_printer::add_to_sbuf (unsigned char code, const string &s) { - char *html_glyph; + char *html_glyph = NULL; if (s.empty()) { html_glyph = get_html_translation(sbuf_style.f, string(code)); @@ -2678,10 +3439,7 @@ void html_printer::begin_page(int n) output_vpos = -1; output_vpos_max = -1; current_paragraph = new html_text(&html); -#if defined(INDENTATION) - current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength); - indent.text.clear(); -#endif + do_indent(indentation, pageoffset, linelength); current_paragraph->do_para(""); } |