diff options
author | wl <wl> | 2005-02-16 14:07:23 +0000 |
---|---|---|
committer | wl <wl> | 2005-02-16 14:07:23 +0000 |
commit | adb8606f04b2c267674d6309c2263f429a0b6494 (patch) | |
tree | 2e9f244087554471645c147e82da0b4c3eac7780 | |
parent | 01317f4cac00f1d64be39b706bb84c9a8fadd284 (diff) | |
download | groff-adb8606f04b2c267674d6309c2263f429a0b6494.tar.gz |
These patches modify the indentation implementation to use `<p
style=margin-left: n%>'. Many thanks to Peter and Larry for
suggesting this solution. Grohtml only uses tables for `.IP' and
related tags when the first operand has a short width.
Similarly, they modify all vertical space code. By default, grohtml
sets up a style sheet which uses no vertical space between `table',
`pre', and `p' tags. It forces spaces when it needs them using
`style="margin-top: 1em"'.
* src/devices/grohtml/html-table.cpp: Include `html-text.h'.
(html_table::emit_table_header, html_table::emit_new_row):
Rewritten.
(html_table::set_space): New function.
(html_indent::html_indent): Don't set `is_used'.
(html_indent::begin): Rewritten.
(html_indent::end): Remove code in function.
* src/devices/grohtml/html-table.h: Updated.
(html_table): Make `out' public.
* src/devices/grohtml/html-text.cpp (html_text::html_text):
Initialize `start_space' with FALSE.
(html_text::end_tag) <P_TAG, PRE_TAG>: Updated.
(html_text::issue_tag): Add argument to handle space style.
(html_text::start_tag) <P_TAG, PRE_TAG>: Updated.
(html_text::flush_text): Don't set `start_space'.
(html_text::push_para): Don't set `p->really_issued'.
(html_text::do_emittext): Updated.
(html_text::do_para): Add paremeter to handle space.
Update all callers.
(html_text::retrieve_para_space): New function.
* src/devices/grohtml/html-text.h (STYLE_VERTICAL_SPACE): New macro.
(tag_definition): Remove `really_issued'.
(html_text): Updated.
* src/devices/grohtml/post-html.cpp (html_printer): Add variables
`current_column' and `row_space'.
Update constructor.
(html_printer::emit_raw, html_printer::write_header,
html_printer::do_indent, html_printer::do_check_center,
html_printer::do_tab_ts): Handle vertical space.
(html_printer:do_tab_te, html_printer::do_end_para): Call
`remove_para_space'.
(html_printer::do_col): Rewritten.
(html_printer::flush_globs): Remove debugging code.
(html_printer::is_line_start): New function.
(html_printer::start_font): Use `is_line_start'.
(html_printer::writeHeadMetaStyle): New function.
(html_printer::do_file_components, html_printer::~html_printer):
Call `writeHeadMetaStyle'.
* tmac/www.tmac (www-handle-percent): New macro.
(MPIMG): Handle percent values for width and height parameters.
(DC): Updated.
* tmac/groff_www.man: Updated.
-rw-r--r-- | ChangeLog | 61 | ||||
-rw-r--r-- | src/devices/grohtml/html-table.cpp | 78 | ||||
-rw-r--r-- | src/devices/grohtml/html-table.h | 7 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.cpp | 135 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.h | 16 | ||||
-rw-r--r-- | src/devices/grohtml/post-html.cpp | 143 | ||||
-rw-r--r-- | tmac/groff_www.man | 18 | ||||
-rw-r--r-- | tmac/www.tmac | 111 |
8 files changed, 430 insertions, 139 deletions
@@ -1,3 +1,64 @@ +2004-02-15 Gaius Mulley <gaius@glam.ac.uk> + + These patches modify the indentation implementation to use `<p + style=margin-left: n%>'. Many thanks to Peter and Larry for + suggesting this solution. Grohtml only uses tables for `.IP' and + related tags when the first operand has a short width. + + Similarly, they modify all vertical space code. By default, grohtml + sets up a style sheet which uses no vertical space between `table', + `pre', and `p' tags. It forces spaces when it needs them using + `style="margin-top: 1em"'. + + * src/devices/grohtml/html-table.cpp: Include `html-text.h'. + (html_table::emit_table_header, html_table::emit_new_row): + Rewritten. + (html_table::set_space): New function. + (html_indent::html_indent): Don't set `is_used'. + (html_indent::begin): Rewritten. + (html_indent::end): Remove code in function. + + * src/devices/grohtml/html-table.h: Updated. + (html_table): Make `out' public. + + * src/devices/grohtml/html-text.cpp (html_text::html_text): + Initialize `start_space' with FALSE. + (html_text::end_tag) <P_TAG, PRE_TAG>: Updated. + (html_text::issue_tag): Add argument to handle space style. + (html_text::start_tag) <P_TAG, PRE_TAG>: Updated. + (html_text::flush_text): Don't set `start_space'. + (html_text::push_para): Don't set `p->really_issued'. + (html_text::do_emittext): Updated. + (html_text::do_para): Add paremeter to handle space. + Update all callers. + (html_text::retrieve_para_space): New function. + + * src/devices/grohtml/html-text.h (STYLE_VERTICAL_SPACE): New macro. + (tag_definition): Remove `really_issued'. + (html_text): Updated. + + * src/devices/grohtml/post-html.cpp (html_printer): Add variables + `current_column' and `row_space'. + Update constructor. + (html_printer::emit_raw, html_printer::write_header, + html_printer::do_indent, html_printer::do_check_center, + html_printer::do_tab_ts): Handle vertical space. + (html_printer:do_tab_te, html_printer::do_end_para): Call + `remove_para_space'. + (html_printer::do_col): Rewritten. + (html_printer::flush_globs): Remove debugging code. + (html_printer::is_line_start): New function. + (html_printer::start_font): Use `is_line_start'. + (html_printer::writeHeadMetaStyle): New function. + (html_printer::do_file_components, html_printer::~html_printer): + Call `writeHeadMetaStyle'. + + * tmac/www.tmac (www-handle-percent): New macro. + (MPIMG): Handle percent values for width and height parameters. + (DC): Updated. + + * tmac/groff_www.man: Updated. + 2004-02-14 Werner LEMBERG <wl@gnu.org> * src/utils/afmtodit/afmtodit.pl: Remove an incorrect `my' from diff --git a/src/devices/grohtml/html-table.cpp b/src/devices/grohtml/html-table.cpp index 44ac964c..c817e884 100644 --- a/src/devices/grohtml/html-table.cpp +++ b/src/devices/grohtml/html-table.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-table.cpp * @@ -32,6 +32,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "html-table.h" #include "ctype.h" #include "html.h" +#include "html-text.h" #if !defined(TRUE) # define TRUE (1==1) @@ -238,7 +239,7 @@ void tabs::dump_tabs (void) */ html_table::html_table (simple_output *op, int linelen) - : columns(NULL), out(op), linelength(linelen), last_col(NULL), start_space(FALSE) + : out(op), columns(NULL), linelength(linelen), last_col(NULL), start_space(FALSE) { tab_stops = new tabs(); } @@ -335,19 +336,18 @@ void html_table::emit_table_header (int space) out->nl(); out->nl(); -#if 0 - if (space) - out->put_string("<p>"); -#endif - - start_space = space; out->put_string("<table width=\"100%\"") .put_string(" border=0 rules=\"none\" frame=\"void\"\n") - .put_string(" cellspacing=\"0\" cellpadding=\"0\"") - .put_string(start_space ? " style=\"margin-top: 8px; margin-bottom: 8px\"" : "") - .put_string(">") + .put_string(" cellspacing=\"0\" cellpadding=\"0\""); + out->put_string(">") .nl(); - out->put_string("<tr valign=\"top\" align=\"left\">").nl(); + out->put_string("<tr valign=\"top\" align=\"left\""); + if (space) { + out->put_string(" style=\"margin-top: "); + out->put_string(STYLE_VERTICAL_SPACE); + out->put_string("\""); + } + out->put_string(">").nl(); } } @@ -365,6 +365,16 @@ int html_table::get_right (cols *c) } /* + * set_space - assigns start_space. Used to determine the + * vertical alignment when generating the next table row. + */ + +void html_table::set_space (int space) +{ + start_space = space; +} + +/* * emit_col - moves onto column, n. */ @@ -478,7 +488,15 @@ void html_table::finish_row (void) void html_table::emit_new_row (void) { finish_row(); - out->put_string("<tr valign=\"top\" align=\"left\">").nl(); + + out->put_string("<tr valign=\"top\" align=\"left\""); + if (start_space) { + out->put_string(" style=\"margin-top: "); + out->put_string(STYLE_VERTICAL_SPACE); + out->put_string("\""); + } + out->put_string(">").nl(); + start_space = FALSE; last_col = NULL; } @@ -486,10 +504,6 @@ void html_table::emit_finish_table (void) { finish_row(); out->put_string("</table>"); -#if 0 - if (start_space) - out->put_string("</p>"); -#endif } /* @@ -718,7 +732,6 @@ html_indent::html_indent (simple_output *op, int ind, int pageoffset, int linele in = ind; pg = pageoffset; ll = linelength; - is_used = FALSE; } html_indent::~html_indent (void) @@ -729,18 +742,33 @@ html_indent::~html_indent (void) void html_indent::begin (int space) { - if (! is_used) { - table->emit_table_header(space); - table->emit_col(1); - is_used = TRUE; + if (in + pg == 0) { + if (space) { + table->out->put_string(" style=\"margin-top: "); + table->out->put_string(STYLE_VERTICAL_SPACE); + table->out->put_string("\""); + } + } + else { + // + // we use exactly the same mechanism for calculating + // indentation as html_table::emit_col + // + table->out->put_string(" style=\"margin-left:") + .put_number(((in + pg) * 100 + ll/2) / ll - + (ll/2)/ll) + .put_string("%;"); + + if (space) { + table->out->put_string(" margin-top: "); + table->out->put_string(STYLE_VERTICAL_SPACE); + } + table->out->put_string("\""); } } void html_indent::end (void) { - if (is_used) - table->emit_finish_table(); - is_used = FALSE; } /* diff --git a/src/devices/grohtml/html-table.h b/src/devices/grohtml/html-table.h index 76655520..341b996d 100644 --- a/src/devices/grohtml/html-table.h +++ b/src/devices/grohtml/html-table.h @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-table.h * @@ -92,14 +92,15 @@ public: void add_indent (int indent); void finish_row (void); int get_effective_linelength (void); + void set_space (int space); tabs *tab_stops; /* tab stop positions */ + simple_output *out; private: cols *columns; /* column entries */ - simple_output *out; int linelength; cols *last_col; /* last column started */ - int start_space; /* encapsulate with <p> </p> */ + int start_space; /* have we seen a `.sp' tag? */ void remove_cols (cols *c); }; diff --git a/src/devices/grohtml/html-text.cpp b/src/devices/grohtml/html-text.cpp index ba5b03be..28f051ab 100644 --- a/src/devices/grohtml/html-text.cpp +++ b/src/devices/grohtml/html-text.cpp @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-text.cpp * @@ -41,11 +42,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "html-text.h" #undef DEBUGGING +// #define DEBUGGING html_text::html_text (simple_output *op) : stackptr(NULL), lastptr(NULL), out(op), space_emitted(TRUE), current_indentation(-1), pageoffset(-1), linelength(-1), - blank_para(TRUE), start_space(TRUE) + blank_para(TRUE), start_space(FALSE) { } @@ -146,11 +148,11 @@ void html_text::end_tag (tag_definition *t) case I_TAG: out->put_string("</i>"); break; case B_TAG: out->put_string("</b>"); break; case P_TAG: if (t->indent == NULL) { - if (t->really_issued) - out->put_string("</p>"); + out->put_string("</p>"); } else { delete t->indent; t->indent = NULL; + out->put_string("</p>"); } out->enable_newlines(FALSE); blank_para = TRUE; break; @@ -158,7 +160,11 @@ void html_text::end_tag (tag_definition *t) case SUP_TAG: out->put_string("</sup>"); break; case TT_TAG: out->put_string("</tt>"); break; case PRE_TAG: out->put_string("</pre>"); out->enable_newlines(TRUE); - blank_para = TRUE; break; + blank_para = TRUE; + if (t->indent != NULL) + delete t->indent; + t->indent = NULL; + break; case SMALL_TAG: out->put_string("</small>"); break; case BIG_TAG: out->put_string("</big>"); break; case COLOR_TAG: out->put_string("</font>"); break; @@ -170,19 +176,29 @@ void html_text::end_tag (tag_definition *t) /* * issue_tag - writes out an html tag with argument. + * space == 0 if no space is requested + * space == 1 if a space is requested + * space == 2 if tag should not have a space style */ -void html_text::issue_tag (const char *tagname, const char *arg) +void html_text::issue_tag (const char *tagname, const char *arg, + int space) { - if ((arg == 0) || (strlen(arg) == 0)) { + if ((arg == 0) || (strlen(arg) == 0)) out->put_string(tagname); - out->put_string(">"); - } else { + else { out->put_string(tagname); out->put_string(" "); out->put_string(arg); - out->put_string(">"); } + if (space == TRUE) { + out->put_string(" style=\"margin-top: "); + out->put_string(STYLE_VERTICAL_SPACE); + out->put_string("\""); + } + if (space == TRUE || space == FALSE) + out->put_string(" valign=\"top\""); + out->put_string(">"); } /* @@ -221,28 +237,26 @@ void html_text::start_tag (tag_definition *t) #if defined(DEBUGGING) out->simple_comment("INDENTATION"); #endif - t->indent->begin(FALSE); - t->really_issued = FALSE; - } else if (start_space) { + out->put_string("\n<p"); + t->indent->begin(start_space); + issue_tag("", (char *)t->arg1); + } else { out->nl(); - issue_tag("\n<p", (char *)t->arg1); - t->really_issued = TRUE; - } else - t->really_issued = FALSE; + issue_tag("\n<p", (char *)t->arg1, start_space); + } out->enable_newlines(TRUE); break; case SUB_TAG: issue_tag("<sub", (char *)t->arg1); break; case SUP_TAG: issue_tag("<sup", (char *)t->arg1); break; case TT_TAG: issue_tag("<tt", (char *)t->arg1); break; - case PRE_TAG: if (t->indent != NULL) { - out->nl(); -#if defined(DEBUGGING) - out->simple_comment("INDENTATION"); -#endif - t->indent->begin(FALSE); - } - out->enable_newlines(TRUE); - out->nl(); issue_tag("<pre", (char *)t->arg1); + case PRE_TAG: out->enable_newlines(TRUE); + out->nl(); out->put_string("<pre"); + if (t->indent == NULL) + issue_tag("", (char *)t->arg1, start_space); + else { + t->indent->begin(start_space); + issue_tag("", (char *)t->arg1); + } out->enable_newlines(FALSE); break; case SMALL_TAG: issue_tag("<small", (char *)t->arg1); break; case BIG_TAG: issue_tag("<big", (char *)t->arg1); break; @@ -273,7 +287,6 @@ void html_text::flush_text (void) free(p); } lastptr = NULL; - start_space = TRUE; } /* @@ -367,7 +380,6 @@ void html_text::push_para (HTML_TAG t, void *arg, html_indent *in) p->arg1 = arg; p->text_emitted = FALSE; p->indent = in; - p->really_issued= FALSE; if (t == PRE_TAG && is_present(PRE_TAG)) fatal("cannot have multiple PRE_TAGs"); @@ -389,7 +401,6 @@ void html_text::push_para (color *c) p->col = *c; p->text_emitted = FALSE; p->indent = NULL; - p->really_issued= FALSE; do_push(p); } @@ -633,7 +644,7 @@ void html_text::check_emit_text (tag_definition *t) void html_text::do_emittext (const char *s, int length) { if ((! is_present(P_TAG)) && (! is_present(PRE_TAG))) - do_para(""); + do_para("", FALSE); if (is_present(BREAK_TAG)) { int text = remove_break(); @@ -656,7 +667,7 @@ void html_text::do_emittext (const char *s, int length) * do_para - starts a new paragraph */ -void html_text::do_para (const char *arg, html_indent *in) +void html_text::do_para (const char *arg, html_indent *in, int space) { if (! is_present(P_TAG)) { if (is_present(PRE_TAG)) { @@ -670,17 +681,18 @@ void html_text::do_para (const char *arg, html_indent *in) } remove_sub_sup(); push_para(P_TAG, (void *)arg, in); + start_space = space; } } -void html_text::do_para (const char *arg) +void html_text::do_para (const char *arg, int space) { - do_para(arg, NULL); + do_para(arg, NULL, space); } void html_text::do_para (simple_output *op, const char *arg1, int indentation_value, int page_offset, - int line_length) + int line_length, int space) { html_indent *ind; @@ -688,7 +700,7 @@ void html_text::do_para (simple_output *op, const char *arg1, ind = NULL; else ind = new html_indent(op, indentation_value, page_offset, line_length); - do_para(arg1, ind); + do_para(arg1, ind, space); } /* @@ -723,8 +735,7 @@ html_indent *html_text::remove_indent (HTML_TAG tag) /* * remove_para_space - removes the leading space to a paragraph - * (effectively this trims off the <p> and </p> - * tags. + * (effectively this trims off a leading `.sp' tag). */ void html_text::remove_para_space (void) @@ -739,23 +750,14 @@ void html_text::remove_para_space (void) void html_text::do_space (void) { if (is_in_pre()) { -#if 0 - if (blank_para) - start_space = TRUE; - else { -#endif - do_emittext("", 0); - out->force_nl(); - space_emitted = TRUE; -#if 0 - } -#endif + do_emittext("", 0); + out->force_nl(); + space_emitted = TRUE; } else { html_indent *i = remove_indent(P_TAG); - do_para(done_para(), i); + do_para(done_para(), i, TRUE); space_emitted = TRUE; - start_space = TRUE; } } @@ -765,13 +767,11 @@ void html_text::do_space (void) void html_text::do_break (void) { - if (! is_present(PRE_TAG)) { - if (emitted_text()) { - if (! is_present(BREAK_TAG)) { + if (! is_present(PRE_TAG)) + if (emitted_text()) + if (! is_present(BREAK_TAG)) push_para(BREAK_TAG); - } - } - } + space_emitted = TRUE; } @@ -797,7 +797,8 @@ int html_text::emitted_text (void) } /* - * ever_emitted_text - returns TRUE if we have ever emitted text in this paragraph. + * ever_emitted_text - returns TRUE if we have ever emitted text in this + * paragraph. */ int html_text::ever_emitted_text (void) @@ -815,6 +816,23 @@ int html_text::starts_with_space (void) } /* + * retrieve_para_space - returns TRUE, if the paragraph starts with + * a space and text has not yet been emitted. + * If TRUE is returned, then the, start_space, + * variable is set to FALSE. + */ + +int html_text::retrieve_para_space (void) +{ + if (start_space && blank_para) { + start_space = FALSE; + return TRUE; + } + else + return FALSE; +} + +/* * emit_space - writes a space providing that text was written beforehand. */ @@ -951,7 +969,7 @@ void html_text::remove_para_align (void) if (p->type == P_TAG && p->arg1 != NULL) { html_indent *i = remove_indent(P_TAG); done_para(); - do_para("", i); + do_para("", i, space_emitted); return; } p = p->next; @@ -1021,4 +1039,3 @@ void html_text::do_sub (void) { push_para(SUB_TAG); } - diff --git a/src/devices/grohtml/html-text.h b/src/devices/grohtml/html-text.h index 79d86b17..fcfac290 100644 --- a/src/devices/grohtml/html-text.h +++ b/src/devices/grohtml/html-text.h @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-text.h * @@ -28,6 +29,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "html.h" #include "html-table.h" +#define STYLE_VERTICAL_SPACE "1em" + /* * html tags */ @@ -41,7 +44,6 @@ typedef struct tag_definition { void *arg1; int text_emitted; color col; - int really_issued; html_indent *indent; tag_definition *next; } tag_definition ; @@ -65,9 +67,10 @@ public: void do_pre (void); void do_small (void); void do_big (void); - void do_para (const char *arg); // used for no indentation + void do_para (const char *arg, int space); // used for no indentation void do_para (simple_output *op, const char *arg1, - int indentation, int pageoffset, int linelength); + int indentation, int pageoffset, int linelength, + int space); void do_sup (void); void do_sub (void); void do_space (void); @@ -88,6 +91,7 @@ public: int emitted_text (void); int ever_emitted_text (void); int starts_with_space (void); + int retrieve_para_space (void); void emit_space (void); int is_in_pre (void); int uses_indent (void); @@ -112,7 +116,7 @@ private: int is_present (HTML_TAG t); void end_tag (tag_definition *t); void start_tag (tag_definition *t); - void do_para (const char *arg, html_indent *in); + void do_para (const char *arg, html_indent *in, int space); void push_para (HTML_TAG t); void push_para (HTML_TAG t, void *arg, html_indent *in); void push_para (color *c); @@ -120,7 +124,7 @@ private: char *shutdown (HTML_TAG t); void check_emit_text (tag_definition *t); int remove_break (void); - void issue_tag (const char *tagname, const char *arg); + void issue_tag (const char *tagname, const char *arg, int space=2); void issue_color_begin (color *c); void remove_def (tag_definition *t); html_indent *remove_indent (HTML_TAG tag); diff --git a/src/devices/grohtml/post-html.cpp b/src/devices/grohtml/post-html.cpp index e4c1b4b1..0e06c436 100644 --- a/src/devices/grohtml/post-html.cpp +++ b/src/devices/grohtml/post-html.cpp @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote post-html.cpp * but it owes a huge amount of ideas and raw code from @@ -1993,6 +1994,8 @@ class html_printer : public printer { int next_center; int seen_space; int seen_break; + int current_column; + int row_space; assert_state as; void flush_sbuf (); @@ -2019,6 +2022,7 @@ class html_printer : public printer { void start_font (const char *name); void end_font (const char *name); int is_font_courier (font *f); + int is_line_start (int nf); int is_courier_until_eol (void); void start_size (int from, int to); void do_font (text_glob *g); @@ -2090,7 +2094,7 @@ class html_printer : public printer { void do_end_para (text_glob *g); int round_width (int x); void handle_tag_within_title (text_glob *g); - + void writeHeadMetaStyle (void); // ADD HERE public: @@ -2199,18 +2203,20 @@ void html_printer::emit_raw (text_glob *g) determine_space(g); current_paragraph->do_emittext(g->text_string, g->text_length); } else { + int space = current_paragraph->retrieve_para_space() || seen_space; + current_paragraph->done_para(); shutdown_table(); switch (next_tag) { case CENTERED: - current_paragraph->do_para("align=center"); + current_paragraph->do_para("align=center", space); break; case LEFT: - current_paragraph->do_para(&html, "align=left", get_troff_indent(), pageoffset, linelength); + current_paragraph->do_para(&html, "align=left", get_troff_indent(), pageoffset, linelength, space); break; case RIGHT: - current_paragraph->do_para(&html, "align=right", get_troff_indent(), pageoffset, linelength); + current_paragraph->do_para(&html, "align=right", get_troff_indent(), pageoffset, linelength, space); break; default: fatal("unknown enumeration"); @@ -2409,6 +2415,8 @@ void html_printer::do_title (void) void html_printer::write_header (void) { if (! header.header_buffer.empty()) { + int space = current_paragraph->retrieve_para_space() || seen_space; + if (header.header_level > 7) { header.header_level = 7; } @@ -2492,7 +2500,7 @@ void html_printer::write_header (void) header.no_of_headings, header.no_of_headings, header.no_of_headings, header.no_of_headings); - current_paragraph->do_para(&html, "", get_troff_indent(), pageoffset, linelength); + current_paragraph->do_para(&html, "", get_troff_indent(), pageoffset, linelength, space); } } @@ -2688,7 +2696,8 @@ void html_printer::do_indent (int in, int pageoff, int linelen) { if ((device_indent != -1) && (pageoffset+device_indent != in+pageoff)) { - + + int space = current_paragraph->retrieve_para_space() || seen_space; current_paragraph->done_para(); device_indent = in; @@ -2697,7 +2706,7 @@ void html_printer::do_indent (int in, int pageoff, int linelen) linelength = linelen; current_paragraph->do_para(&html, "", device_indent, - pageoffset, max_linelength); + pageoffset, max_linelength, space); } } @@ -2765,7 +2774,7 @@ void html_printer::do_fill (char *arg) if (fill_on != on) { if (on) - current_paragraph->do_para(""); + current_paragraph->do_para("", seen_space); fill_on = on; } } @@ -2796,9 +2805,10 @@ void html_printer::do_check_center(void) seen_center = FALSE; if (next_center > 0) { if (end_center == 0) { + int space = current_paragraph->retrieve_para_space() || seen_space; current_paragraph->done_para(); supress_sub_sup = TRUE; - current_paragraph->do_para("align=center"); + current_paragraph->do_para("align=center", space); } else if (strcmp("align=center", current_paragraph->get_alignment()) != 0) { @@ -2806,9 +2816,10 @@ void html_printer::do_check_center(void) * different alignment, so shutdown paragraph and open * a new one. */ + int space = current_paragraph->retrieve_para_space() || seen_space; current_paragraph->done_para(); supress_sub_sup = TRUE; - current_paragraph->do_para("align=center"); + current_paragraph->do_para("align=center", space); } else /* * same alignment, if we have emitted text then issue a break. @@ -2820,6 +2831,7 @@ void html_printer::do_check_center(void) * next_center == 0 */ if (end_center > 0) { + seen_space = seen_space || current_paragraph->retrieve_para_space(); current_paragraph->done_para(); supress_sub_sup = TRUE; } @@ -2956,6 +2968,11 @@ void html_printer::do_space (char *arg) seen_space = atoi(arg); as.check_sp(seen_space); +#if 0 + if (n>0 && table) + table->set_space(TRUE); +#endif + while (n>0) { current_paragraph->do_space(); n--; @@ -2972,6 +2989,7 @@ void html_printer::do_tab_ts (text_glob *g) html_table *t = g->get_table(); if (t != NULL) { + current_column = 0; current_paragraph->done_pre(); current_paragraph->done_para(); current_paragraph->remove_para_space(); @@ -2982,7 +3000,13 @@ void html_printer::do_tab_ts (text_glob *g) t->set_linelength(max_linelength); t->add_indent(pageoffset); +#if 0 + t->emit_table_header(seen_space); +#else t->emit_table_header(FALSE); + row_space = current_paragraph->retrieve_para_space() || seen_space; + seen_space = FALSE; +#endif } table = t; @@ -2996,6 +3020,7 @@ void html_printer::do_tab_te (void) { if (table) { current_paragraph->done_para(); + current_paragraph->remove_para_space(); table->emit_finish_table(); } @@ -3043,8 +3068,13 @@ void html_printer::do_tab0 (void) void html_printer::do_col (char *s) { if (table) { + if (atoi(s) < current_column) + row_space = seen_space; + + current_column = atoi(s); current_paragraph->done_para(); - table->emit_col(atoi(s)); + table->emit_col(current_column); + current_paragraph->do_para("", row_space); } } @@ -3165,9 +3195,6 @@ void html_printer::flush_globs (void) page_contents->glyphs.start_from_head(); do { g = page_contents->glyphs.get_data(); - if (strcmp(g->text_string, "Here") == 0) - stop(); - #if 0 fprintf(stderr, "[%s:%d:%d:%d:%d]", g->text_string, g->minv, g->minh, g->maxv, g->maxh) ; @@ -3731,6 +3758,37 @@ void html_printer::determine_space (text_glob *g) } /* + * is_line_start - returns TRUE if we are at the start of a line. + */ + +int html_printer::is_line_start (int nf) +{ + int line_start = FALSE; + int result = TRUE; + text_glob *orig = page_contents->glyphs.get_data(); + text_glob *g; + + if (! page_contents->glyphs.is_equal_to_head()) { + do { + page_contents->glyphs.move_left(); + g = page_contents->glyphs.get_data(); + result = !g->is_a_tag(); + if (g->is_fi()) + nf = FALSE; + else if (g->is_nf()) + nf = TRUE; + line_start = g->is_col() || g->is_br() || (nf && g->is_eol()); + } while ((!line_start) && (result)); + /* + * now restore our previous position. + */ + while (page_contents->glyphs.get_data() != orig) + page_contents->glyphs.move_right(); + } + return result; +} + +/* * is_font_courier - returns TRUE if the font, f, is courier. */ @@ -3790,24 +3848,28 @@ void html_printer::start_font (const char *fontname) current_paragraph->do_bold(); current_paragraph->do_italic(); } else if (strcmp(fontname, "CR") == 0) { - if ((! fill_on) && (is_courier_until_eol())) { + if ((! fill_on) && (is_courier_until_eol()) && + is_line_start(fill_on)) { current_paragraph->do_pre(); } current_paragraph->do_tt(); } else if (strcmp(fontname, "CI") == 0) { - if ((! fill_on) && (is_courier_until_eol())) { + if ((! fill_on) && (is_courier_until_eol()) && + is_line_start(fill_on)) { current_paragraph->do_pre(); } current_paragraph->do_tt(); current_paragraph->do_italic(); } else if (strcmp(fontname, "CB") == 0) { - if ((! fill_on) && (is_courier_until_eol())) { + if ((! fill_on) && (is_courier_until_eol()) && + is_line_start(fill_on)) { current_paragraph->do_pre(); } current_paragraph->do_tt(); current_paragraph->do_bold(); } else if (strcmp(fontname, "CBI") == 0) { - if ((! fill_on) && (is_courier_until_eol())) { + if ((! fill_on) && (is_courier_until_eol()) && + is_line_start(fill_on)) { current_paragraph->do_pre(); } current_paragraph->do_tt(); @@ -3968,6 +4030,7 @@ void html_printer::do_end_para (text_glob *g) { do_font(g); current_paragraph->done_para(); + current_paragraph->remove_para_space(); html.put_string(g->text_string+9); output_vpos = g->minv; output_hpos = g->maxh; @@ -4125,7 +4188,9 @@ html_printer::html_printer() seen_center(FALSE), next_center(0), seen_space(0), - seen_break(0) + seen_break(0), + current_column(0), + row_space(FALSE) { file_list.add_new_file(xtmpfile()); html.set_file(file_list.get_file()); @@ -4435,7 +4500,7 @@ void html_printer::begin_page(int n) output_vpos_max = -1; current_paragraph = new html_text(&html); do_indent(get_troff_indent(), pageoffset, linelength); - current_paragraph->do_para(""); + current_paragraph->do_para("", FALSE); } void html_printer::end_page(int) @@ -4557,6 +4622,7 @@ void html_printer::do_file_components (void) fflush(stdout); freopen(split_file.contents(), "w", stdout); fragment_no++; + writeHeadMetaStyle(); write_navigation(top, prev, next, current); } if (file_list.are_links_required()) @@ -4568,6 +4634,31 @@ void html_printer::do_file_components (void) write_rule(); } +/* + * writeHeadMetaStyle - emits the <head> <meta> and <style> tags and + * related information. + */ + +void html_printer::writeHeadMetaStyle (void) +{ + fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n", stdout); + fputs("\"http://www.w3.org/TR/html4/loose.dtd\">\n", stdout); + + fputs("<html>\n", stdout); + fputs("<head>\n", stdout); + fputs("<meta name=\"generator\" " + "content=\"groff -Thtml, see www.gnu.org\">\n", stdout); + fputs("<meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=US-ASCII\">\n", stdout); + fputs("<meta name=\"Content-Style\" content=\"text/css\">\n", stdout); + + fputs("<style type=\"text/css\">\n", stdout); + fputs(" p { margin-top: 0; margin-bottom: 0; }\n", stdout); + fputs(" pre { margin-top: 0; margin-bottom: 0; }\n", stdout); + fputs(" table { margin-top: 0; margin-bottom: 0; }\n", stdout); + fputs("</style>\n", stdout); +} + html_printer::~html_printer() { #ifdef LONG_FOR_TIME_T @@ -4590,16 +4681,8 @@ html_printer::~html_printer() .put_string(ctime(&t), strlen(ctime(&t))-1) .end_comment(); - fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n", stdout); - fputs("\"http://www.w3.org/TR/html4/loose.dtd\">\n", stdout); + writeHeadMetaStyle(); - fputs("<html>\n", stdout); - fputs("<head>\n", stdout); - fputs("<meta name=\"generator\" " - "content=\"groff -Thtml, see www.gnu.org\">\n", stdout); - fputs("<meta http-equiv=\"Content-Type\" " - "content=\"text/html; charset=US-ASCII\">\n", stdout); - fputs("<meta name=\"Content-Style\" content=\"text/css\">\n", stdout); write_title(TRUE); head_info += '\0'; fputs(head_info.contents(), stdout); diff --git a/tmac/groff_www.man b/tmac/groff_www.man index ce203024..4601b7af 100644 --- a/tmac/groff_www.man +++ b/tmac/groff_www.man @@ -1,5 +1,6 @@ .TH GROFF_WWW @MAN7EXT@ "@MDATE@" "Groff Version @VERSION@" -.\" Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +.\" Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 +.\" Free Software Foundation, Inc. .\" Written by Gaius Mulley (gaius@glam.ac.uk) .\" .\" This file is part of groff. @@ -329,6 +330,21 @@ Example: .ft P .fi .RE +.IP +The height and width may also be given as percentages. The PostScript +device calculates the width from the +.B .l +register and the height from the +.B .p +register. For example: +.RS +.IP +.nf +.ft B +\&.MPIMG -L -G 2c foo.png 15% +.ft P +.fi +.RE . .TP .B .HnS n diff --git a/tmac/www.tmac b/tmac/www.tmac index 1f4da764..8fa1b9bd 100644 --- a/tmac/www.tmac +++ b/tmac/www.tmac @@ -10,7 +10,7 @@ Installed position: groff's main macro directory. This file is part of groff, the GNU roff type-setting system. -Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. written by Gaius Mulley <gaius@glam.ac.uk>, with additions by Werner Lemberg <wl@gnu.org> and Bernd Warken <bwarken@mayn.de>. @@ -524,6 +524,32 @@ www functionality. It should work with any macro set. . wh \\n[www-left-ll-trap]u . nr www-left-ll-trap 0 .. +. +.\" www-handle-percent arg N1 N2 S1 +.\" arg - input string (number or number%) +.\" output parameters: +.\" N1 - name of number register 1=absolute 0=percentage +.\" N2 - number register name for absolute value +.\" S1 - string register name for percentage value +. +.de www-handle-percent +. ds www-percent \\$1\" +. substring www-percent -1 -1 +. +. ie '\\*[www-percent]'%' \{\ +. ds www-abs \\$1\" +. substring www-abs 0 -2 +. nr \\$2 0 +. nr \\$3 \\*[www-abs] +. ds \\$4 \\$1\" +. \} +. el \{\ +. nr \\$2 1 +. nr \\$3 \\$1 +. ds \\$4 none\" +. \} +.. +. .\" -------------------------------------------------------------------- .\" MPIMG [-R|-L] [-G gap] filename [width [height]] .\" @@ -531,6 +557,10 @@ www functionality. It should work with any macro set. .\" -Tps and -Thtml. The default value for WIDTH is 1i; default value .\" for HEIGHT is WIDTH; the default alignment is left (-L). .\" -G is used to insert a gap between the text and the image. +.\" The height and width can also be given as a percentage. +.\" The PostScript device converts the percentage width into an +.\" absolute value by using \\n[.l], and the height by using \\n[.p]. +.\" .\" .\" Note: This macro can only be used with the `-U' option of groff, .\" activating unsafe mode, if not used with -Thtml; the PNG image @@ -561,24 +591,74 @@ www functionality. It should work with any macro set. . \} . break . \} +. . nr www-width 1i -. if !'\\$2'' \ -. nr www-width \\$2 -. nr www-height \\n[www-width] -. if !'\\$3'' \ -. nr www-height \\$3 -. nr www-width (\\n[www-width] * 100 / 240) -. nr www-height (\\n[www-height] * 100 / 240) +. nr www-height 1i +. ds www-size-specs "width=\\n[www-width] height=\\n[www-height]\" +. ie !'\\$2'' \{\ +. nr www-is-absolute 0 +. nr www-absolute 0 +. ds www-percentage none\" +. www-handle-percent \\$2 www-is-absolute www-absolute www-percentage +. ie !\\n[www-is-absolute] \{\ +. \" percentage of linelength requested +. nr www-width (\\n[www-absolute] * \\n[.l] / 100) +. if \\n[www-html] \ +. nr www-width (\\n[www-width] * 100 / 240) +. ds www-size-specs "width=\\*[www-percentage]\" +. \} +. el \{\ +. nr www-width \\n[www-absolute] +. if \\n[www-html] \ +. nr www-width (\\n[www-width] * 100 / 240) +. ds www-size-specs "width=\\n[www-width]\" +. \} +. +. nr www-height \\n[www-width] +. ie !'\\$3'' \{\ +. nr www-is-absolute 0 +. nr www-absolute 0 +. ds www-percentage none\" +. www-handle-percent \\$3 www-is-absolute www-absolute www-percentage +. ie !\\n[www-is-absolute] \{\ +. \" percentage of pagelength requested +. nr www-height (\\n[www-absolute] * \\n[.p] / 100) +. if \\n[www-html] \ +. nr www-height (\\n[www-height] * 100 / 240) +. ds www-size-specs "\\*[www-size-specs] height=\\*[www-percentage]\" +. \} +. el \{\ +. nr www-height \\n[www-absolute] +. if \\n[www-html] \ +. nr www-height (\\n[www-height] * 100 / 240) +. ds www-size-specs "\\*[www-size-specs] height=\\*[www-height]\" +. \} +. \} +. \} +. el \{\ +. \" height not specified; use width value +. ie !\\n[www-is-absolute] \{\ +. \" percentage value +. ds www-size-specs "\\*[www-size-specs] height=\\*[www-percentage]\" +. nr www-height \\n[www-width] +. \} +. el \{\ +. ds www-size-specs "\\*[www-size-specs] height=\\*[www-width]\" +. nr www-height \\n[www-width] +. \} +. \} . . ie \\n[www-html] \{\ . ie !\\n[www-image-just] \ . HTML <img src="\\$1" alt="Image \\$1" hspace=\\n[www-htmlimage-gap] \ - align=right width=\\n[www-width] height=\\n[www-height]> + align=right \\*[www-size-specs]> . el \ . HTML <img src="\\$1" alt="Image \\$1" hspace=\\n[www-htmlimage-gap] \ - align=left width=\\n[www-width] height=\\n[www-height]> + align=left \\*[www-size-specs]> . \} . el \{\ +. tm www-width is \\n[www-width] +. tm www-height is \\n[www-height] . if !r ps4html \{\ . www-make-unique-name . sy pngtopnm \\$1 | pnmcrop -white | @PNMTOPS_NOSETPAGE@ -noturn > \\*[www-unique-name].eps @@ -589,7 +669,7 @@ www functionality. It should work with any macro set. . wh \\n[www-left-ll-trap]u . if (\\n[www-left-po-trap] > 0) \ . wh \\n[www-left-po-trap]u -. PSPIC -R \\*[www-unique-name].eps \\$2 \\$3 +. PSPIC -R \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u . sp -\\n[ps-desht]u . nr www-right-indent \\n[ps-deswid]u . \" we want to have some space between text and image, @@ -608,7 +688,7 @@ www functionality. It should work with any macro set. . \" we must now disable a possible right image trap . if (\\n[www-right-ll-trap] > 0) \ . wh \\n[www-right-ll-trap]u -. PSPIC -L \\*[www-unique-name].eps \\$2 \\$3 +. PSPIC -L \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u . sp -\\n[ps-desht]u . nr www-left-indent \\n[ps-deswid]u . \" increase offset by gap @@ -790,7 +870,8 @@ www functionality. It should work with any macro set. . ds www-dropcolor \\$3 . ie '\*(.T'html' \{\ . www-make-unique-name -. MPIMG -L \\*[www-unique-name].png "(\\n[.v] * 2u)" +. nr www-drop-width (100u * \\n[.v]u * 3u / \\n[.l]u) +. MPIMG -L \\*[www-unique-name].png "\\n[www-drop-width]%" . \} . el \{\ . ie r ps4html \{\ @@ -801,9 +882,9 @@ www functionality. It should work with any macro set. . \" glyphs overlap. . bp . ev www-DC -. vs 80p +. vs 320p . nop \O[5i\\*[www-unique-name].png]\O[1] -. nop \m[\\*[www-dropcolor]]\s[40]\O[3]\\$1\O[4] +. nop \m[\\*[www-dropcolor]]\s[160]\O[3]\\$1\O[4] . nop \O[2]\O[0] . br . ev |