summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwl <wl>2005-02-16 14:07:23 +0000
committerwl <wl>2005-02-16 14:07:23 +0000
commitadb8606f04b2c267674d6309c2263f429a0b6494 (patch)
tree2e9f244087554471645c147e82da0b4c3eac7780
parent01317f4cac00f1d64be39b706bb84c9a8fadd284 (diff)
downloadgroff-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--ChangeLog61
-rw-r--r--src/devices/grohtml/html-table.cpp78
-rw-r--r--src/devices/grohtml/html-table.h7
-rw-r--r--src/devices/grohtml/html-text.cpp135
-rw-r--r--src/devices/grohtml/html-text.h16
-rw-r--r--src/devices/grohtml/post-html.cpp143
-rw-r--r--tmac/groff_www.man18
-rw-r--r--tmac/www.tmac111
8 files changed, 430 insertions, 139 deletions
diff --git a/ChangeLog b/ChangeLog
index 065ccdd1..336919ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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