summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
authorwl <wl>2007-09-19 14:55:54 +0000
committerwl <wl>2007-09-19 14:55:54 +0000
commite4f206b8a3104ee734b913a2d50980bf5bdf3634 (patch)
tree814cb9652b873192c9648453480aa48f37c41271 /src/devices
parente128c4d2011e4dce3bb8db70fdeb59816f839c40 (diff)
downloadgroff-e4f206b8a3104ee734b913a2d50980bf5bdf3634.tar.gz
* doc/groff.texinfo: Document new .O register and add cross
reference entries. * NEWS: Updated. * src/devices/grohtml/grohtml.man: Document new -V and -y options. * src/devices/grohtml/html-table.cpp: Add support for XHTML 1.1. (html_table:: emit_colspan, html_table::emit_td): New methods. (html_table::emit_col): Use html_table::emit_td. (html_table::emit_table_header): Use html_table::emit_colspan if dialect xhtml is specified. (html_table::finish_row): Updated. * src/devices/grohtml/html-table.h (html_table): Declare emit_colspan, emit_td. * src/devices/grohtml/html-text.cpp: Modified tags to comply with xhtml if this dialect was requested. * src/devices/grohtml/html-text.h (html_dialect): New enumeration. (html_text): Add new variable `dialect'. * src/devices/grohtml/post-html.cpp: Modify header tags to be XHTML compliant. (valid_flag, groff_sig, dialect): New global variables. (html_printer::handle_valid_flag, html_printer::do_math, html_printer::write_html_anchor, html_printer::write_xhtml_anchor, html_printer::do_math, html_printer::handle_valid_flag): New methods. (html_printer::emit_line, html_printer::emit_raw, html_printer::do_check_center, html_printer::write_title, write_rule, html_printer::writeHeadMetaStyle, generate_img_src, html_printer::begin_page): Altered to be XHTML compliant. (html_printer::write_header): Updated. (html_printer::troff_tag): Call do_math. (html_printer::insert_split_file, html_printer::do_file_components, html_printer::write_navigation): Create XHTML file components if necessary and also produces a groff signature if requested. (~html_printer): Call writeHeadMetaStyle at appropriate places depending upon html_dialect. (html_printer::special): Handle new tags `html<?p>' and `math<?p>'. (main): Added options -x, -V, and -y. (usage): Updated. * src/preproc/eqn/box.cpp: Create a distinction between the MathML device and the XHTML device. (do_text): Issue a newline at the end of the equation if XHTML was specified. (box::top_level): Prefix the output of an equation by the .MATHML macro. (output_string): Suppress \n if XHTML was specified. * src/preproc/eqn/main.cpp (xhtml): New global flag. (inline_equation): Skip leading spaces after inline equation for XHTML device. (main): Set `xhtml' flag if `-Tmathml:xhtml' is specified. * src/preproc/eqn/eqn.h (xhtml): New external flag. * src/preproc/eqn/text.cpp (entity_table): Fix typo. * src/preproc/html/pre-html.cpp (html_dialect): New enumeration. (dialect, eqn_flag): New global variables. (html_system): Improve debugging support. (alterDeviceTo): Test for -Txhtml when altering device to the image device and reset to -Txhtml. (addZ): Renamed to... (addArg): This. Introducea a general parameter. (print_args): New debugging function. (char_buffer::run_output_filter): Use print_args and addArg rather than addZ. (char_buffer::do_html, char_buffer::do_image): Add -rxhtml=1 command line parameter as an argument to the html generation of text when xhtml is needed. Include -e on the command line if mathml is required. (scanArguments): Allow -e, -V, -y and -x options. -V, -y are handled by the back end. -e sets `eqn_flag'. -x determines HTML dialect. * src/roff/groff/groff.cpp (possible_command): New method `clear_name'. (main): Set eflag if -e is present on command line. Set is_xhtml if -Txhtml is present. Pass `-x x' to the HTML pre and post processors. Pass `-e' to the HTML pre processor if required. Pass `-Tmathml:xhtml' to eqn if XHTML is requested. * src/roff/troff/input.cpp (init_input_requests): Introduce new number register `\n[.O]'. * tmac/s.tmac: (LP): Use .nop for semantic sugar. (cov*ab-init) reformat. (@EQ): Use EQN-HTML-IMAGE and friends rather than HTML-IMAGE. (CHECK-FOOTER-AND-KEEP): Define FS, FE such that they use <cite></cite> for the html device rather than generate images for footnotes. * tmac/troffrc-end: Define EQN-HTML-IMAGE, EQN-HTML-IMAGE-END, EQN-HTML-IMAGE-RIGHT, EQN-HTML-IMAGE-LEFT, EQN-HTML-IMAGE-INLINE, EQN-HTML-DO-IMAGE, EQN-HTML-IMAGE-END as null strings. * tmac/www.tmac: (HTML<?p>): New macro. (MATH<?p>): New macro. (IMG, PIMG, MPIMG, HR): Use XHTML compliant syntax. (www-emit-ltag): New macro. (www-push-li): Updated. (ULS): Ensure that tags are balanced in order by use of www-emit-ltag. (ULE): Likewise: Use www-emit-ltag and shut down paragraphs in order. (OLS, OLE, DLS, DLE): Ditto. <global>: Define EQ and EN to EQN-HTML-IMAGE and EQN-HTML-IMAGE-END respectively. (www-li-ul, www-li-ol, www-li-dl): Updated. (EQN-HTML-IMAGE, EQN-HTML-IMAGE-RIGHT, EQN-HTML-IMAGE-LEFT, EQN-HTML-IMAGE-INLINE, EQN-HTML-DO-IMAGE, EQN-HTML-IMAGE-END, MATHML): New macros.
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/grohtml/grohtml.man54
-rw-r--r--src/devices/grohtml/html-table.cpp128
-rw-r--r--src/devices/grohtml/html-table.h6
-rw-r--r--src/devices/grohtml/html-text.cpp35
-rw-r--r--src/devices/grohtml/html-text.h11
-rw-r--r--src/devices/grohtml/post-html.cpp371
6 files changed, 496 insertions, 109 deletions
diff --git a/src/devices/grohtml/grohtml.man b/src/devices/grohtml/grohtml.man
index a4d4ece0..d1c6d28c 100644
--- a/src/devices/grohtml/grohtml.man
+++ b/src/devices/grohtml/grohtml.man
@@ -1,5 +1,5 @@
.ig
-Copyright (C) 1999-2000, 2001, 2002, 2003, 2004, 2006
+Copyright (C) 1999-2000, 2001, 2002, 2003, 2004, 2006, 2007
Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
@@ -58,6 +58,7 @@ grohtml \- html driver for groff
.OP \-o \%image-vertical-offset
.OP \-s size
.OP \-S level
+.OP \-x \%html-dialect
.RI "[\ " files\|.\|.\|. "\ ]"
.br
.ad \na
@@ -130,6 +131,24 @@ to place all image files into directory
.IR dir .
.
.TP
+.B \-e
+This option should not be directly invoked by the user as it is
+an internal option utilized by
+.B groff
+when
+.B \-Thtml
+or
+.B \-Txhtml
+is specified.
+It is used by the
+.B grohtml
+preprocessor to determine whether
+.B eqn
+should attempt to produce MathML (if
+.B \-Txhtml
+is specified).
+.
+.TP
.BI \-F dir
Prepend directory
.IB dir /dev name
@@ -241,6 +260,39 @@ split at the heading level (or higher) defined by
.B \-v
Print the version number.
.
+.TP
+.B \-V
+Create an XHTML validator button at the bottom of each page of
+the document.
+.
+.TP
+.BI \-x dialect
+Select HTML dialect.
+Currently,
+.I dialect
+should be either the digit\~\c
+.B 4
+or the letter\~\c
+.B x
+which indicates whether
+.B grohtml
+should generate HTML\~4 or XHTML, respectively.
+This option should not be directly invoked by the user as it is
+an internal option utilized by
+.B groff
+when
+.B \-Thtml
+or
+.B \-Txhtml
+is specified.
+.
+.TP
+.B \-y
+Produce a right-justified groff signature at the end of the document.
+This is only generated if the
+.B \-V
+flag is also specified.
+.
.
.SH USAGE
There are styles called
diff --git a/src/devices/grohtml/html-table.cpp b/src/devices/grohtml/html-table.cpp
index 7e5b2dc5..c752b766 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, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote html-table.cpp
*
@@ -41,6 +41,9 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
# define FALSE (1==0)
#endif
+extern html_dialect dialect;
+
+
tabs::tabs ()
: tab(NULL)
{
@@ -294,7 +297,7 @@ void html_table::set_linelength (int linelen)
}
p = c;
}
- if (p != NULL && p->right > 0)
+ if (p != NULL && p->right > 0 && linelength > p->right)
add_column(p->no+1, p->right, linelength, 'L');
}
@@ -337,10 +340,12 @@ void html_table::emit_table_header (int space)
out->nl();
out->put_string("<table width=\"100%\"")
- .put_string(" border=0 rules=\"none\" frame=\"void\"\n")
+ .put_string(" border=\"0\" rules=\"none\" frame=\"void\"\n")
.put_string(" cellspacing=\"0\" cellpadding=\"0\"");
out->put_string(">")
.nl();
+ if (dialect == xhtml)
+ emit_colspan();
out->put_string("<tr valign=\"top\" align=\"left\"");
if (space) {
out->put_string(" style=\"margin-top: ");
@@ -375,6 +380,82 @@ void html_table::set_space (int space)
}
/*
+ * emit_colspan - emits a series of colspan entries defining the
+ * table columns.
+ */
+
+void html_table::emit_colspan (void)
+{
+ cols *b = columns;
+ cols *c = columns;
+ int width = 0;
+
+ out->put_string("<colgroup>");
+ while (c != NULL) {
+ if (b != NULL && b != c && is_gap(b))
+ /*
+ * blank column for gap
+ */
+ out->put_string("<col width=\"")
+ .put_number(is_gap(b))
+ .put_string("%\" class=\"center\"></col>")
+ .nl();
+
+ width = (get_right(c)*100 + get_effective_linelength()/2)
+ / get_effective_linelength()
+ - (c->left*100 + get_effective_linelength()/2)
+ /get_effective_linelength();
+ switch (c->alignment) {
+ case 'C':
+ out->put_string("<col width=\"")
+ .put_number(width)
+ .put_string("%\" class=\"center\"></col>")
+ .nl();
+ break;
+ case 'R':
+ out->put_string("<col width=\"")
+ .put_number(width)
+ .put_string("%\" class=\"right\"></col>")
+ .nl();
+ break;
+ default:
+ out->put_string("<col width=\"")
+ .put_number(width)
+ .put_string("%\"></col>")
+ .nl();
+ }
+ b = c;
+ c = c->next;
+ }
+ out->put_string("</colgroup>").nl();
+}
+
+/*
+ * emit_td - writes out a <td> tag with a corresponding width
+ * if the dialect is html4.
+ */
+
+void html_table::emit_td (int percentage, const char *s)
+{
+ if (percentage) {
+ if (dialect == html4) {
+ out->put_string("<td width=\"")
+ .put_number(percentage)
+ .put_string("%\"");
+ if (s != NULL)
+ out->put_string(s);
+ out->nl();
+ }
+ else {
+ out->put_string("<td");
+ if (s != NULL)
+ out->put_string(s);
+ out->nl();
+ }
+ }
+}
+
+/*
* emit_col - moves onto column, n.
*/
@@ -405,11 +486,7 @@ void html_table::emit_col (int n)
// have we a gap?
if (last_col != NULL) {
- if (is_gap(b))
- out->put_string("<td width=\"")
- .put_number(is_gap(b))
- .put_string("%\"></td>")
- .nl();
+ emit_td(is_gap(b), "></td>");
b = b->next;
}
@@ -421,17 +498,9 @@ void html_table::emit_col (int n)
/ get_effective_linelength()
- (b->left*100 + get_effective_linelength()/2)
/get_effective_linelength();
- if (width)
- out->put_string("<td width=\"")
- .put_number(width)
- .put_string("%\"></td>")
- .nl();
+ emit_td(width, "></td>");
// have we a gap?
- if (is_gap(b))
- out->put_string("<td width=\"")
- .put_number(is_gap(b))
- .put_string("%\"></td>")
- .nl();
+ emit_td(is_gap(b), "></td>");
b = b->next;
}
width = (get_right(b)*100 + get_effective_linelength()/2)
@@ -440,22 +509,13 @@ void html_table::emit_col (int n)
/get_effective_linelength();
switch (b->alignment) {
case 'C':
- out->put_string("<td width=\"")
- .put_number(width)
- .put_string("%\" align=center>")
- .nl();
+ emit_td(width, " align=center>");
break;
case 'R':
- out->put_string("<td width=\"")
- .put_number(width)
- .put_string("%\" align=right>")
- .nl();
+ emit_td(width, " align=right>");
break;
default:
- out->put_string("<td width=\"")
- .put_number(width)
- .put_string("%\">")
- .nl();
+ emit_td(width);
}
// remember column, b
last_col = b;
@@ -477,7 +537,13 @@ void html_table::finish_row (void)
if (n > 0)
emit_col(n);
- out->put_string("</td>").nl();
+#if 1
+ if (last_col != NULL) {
+ out->put_string("</td>");
+ last_col = NULL;
+ }
+#endif
+ out->put_string("</tr>").nl();
}
}
diff --git a/src/devices/grohtml/html-table.h b/src/devices/grohtml/html-table.h
index dc6cebe2..5f1cfe56 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, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote html-table.h
*
@@ -93,6 +93,8 @@ public:
void finish_row (void);
int get_effective_linelength (void);
void set_space (int space);
+ void emit_colspan (void);
+ void emit_td (int percentage, const char *s = ">");
tabs *tab_stops; /* tab stop positions */
simple_output *out;
@@ -121,7 +123,7 @@ public:
// the indent is shutdown when it is deleted
private:
- void end (void);
+ void end (void);
int is_used;
int pg; // values of the registers as passed via initialization
int ll;
diff --git a/src/devices/grohtml/html-text.cpp b/src/devices/grohtml/html-text.cpp
index b58d5e4a..f2b36025 100644
--- a/src/devices/grohtml/html-text.cpp
+++ b/src/devices/grohtml/html-text.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
* Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote html-text.cpp
@@ -44,10 +44,11 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#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(FALSE)
+html_text::html_text (simple_output *op, html_dialect d) :
+ stackptr(NULL), lastptr(NULL), out(op), dialect(d),
+ space_emitted(TRUE), current_indentation(-1),
+ pageoffset(-1), linelength(-1), blank_para(TRUE),
+ start_space(FALSE)
{
}
@@ -165,8 +166,12 @@ void html_text::end_tag (tag_definition *t)
delete t->indent;
t->indent = NULL;
break;
- case SMALL_TAG: out->put_string("</small>"); break;
- case BIG_TAG: out->put_string("</big>"); break;
+ case SMALL_TAG: if (dialect != xhtml || (! is_in_pre ()))
+ out->put_string("</small>");
+ break;
+ case BIG_TAG: if (dialect != xhtml || (! is_in_pre ()))
+ out->put_string("</big>");
+ break;
case COLOR_TAG: out->put_string("</font>"); break;
default:
@@ -196,8 +201,10 @@ void html_text::issue_tag (const char *tagname, const char *arg,
out->put_string(STYLE_VERTICAL_SPACE);
out->put_string("\"");
}
+#if 0
if (space == TRUE || space == FALSE)
out->put_string(" valign=\"top\"");
+#endif
out->put_string(">");
}
@@ -258,8 +265,12 @@ void html_text::start_tag (tag_definition *t)
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;
+ case SMALL_TAG: if (dialect != xhtml || (! is_in_pre ()))
+ issue_tag("<small", (char *)t->arg1);
+ break;
+ case BIG_TAG: if (dialect != xhtml || (! is_in_pre ()))
+ issue_tag("<big", (char *)t->arg1);
+ break;
case BREAK_TAG: break;
case COLOR_TAG: issue_color_begin(&t->col); break;
@@ -652,9 +663,11 @@ void html_text::do_emittext (const char *s, int length)
int text = remove_break();
check_emit_text(stackptr);
if (text) {
- if (is_present(PRE_TAG)) {
+ if (is_present(PRE_TAG))
out->nl();
- } else
+ else if (dialect == xhtml)
+ out->put_string("<br/>").nl();
+ else
out->put_string("<br>").nl();
}
} else
diff --git a/src/devices/grohtml/html-text.h b/src/devices/grohtml/html-text.h
index e0e3cc75..d6e11cd8 100644
--- a/src/devices/grohtml/html-text.h
+++ b/src/devices/grohtml/html-text.h
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007
* Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote html-text.h
@@ -32,6 +32,12 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
#define STYLE_VERTICAL_SPACE "1em"
/*
+ * supported html dialects.
+ */
+
+typedef enum {xhtml, html4} html_dialect;
+
+/*
* html tags
*/
@@ -56,7 +62,7 @@ typedef struct tag_definition {
class html_text {
public:
- html_text (simple_output *op);
+ html_text (simple_output *op, html_dialect d);
~html_text (void);
void flush_text (void);
void do_emittext (const char *s, int length);
@@ -105,6 +111,7 @@ private:
tag_definition *stackptr; /* the current paragraph state */
tag_definition *lastptr; /* the end of the stack */
simple_output *out;
+ html_dialect dialect; /* which dialect of html? */
int space_emitted; /* just emitted a space? */
int current_indentation; /* current .in value */
int pageoffset; /* .po value */
diff --git a/src/devices/grohtml/post-html.cpp b/src/devices/grohtml/post-html.cpp
index 3d93dc72..4a6e0cbc 100644
--- a/src/devices/grohtml/post-html.cpp
+++ b/src/devices/grohtml/post-html.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
* Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote post-html.cpp
@@ -90,6 +90,10 @@ static int base_point_size = 0; /* which troff font size ma
static int split_level = 2; /* what heading level to split at? */
static string head_info; /* user supplied information to be placed */
/* into <head> </head> */
+static int valid_flag = FALSE; /* has user requested a valid flag at the */
+ /* end of each page? */
+static int groff_sig = FALSE; /* "This document was produced using" */
+html_dialect dialect = html4; /* which html dialect should grohtml output */
/*
@@ -1570,6 +1574,8 @@ void header_desc::write_headings (FILE *f, int force)
headers.start_from_head();
header_filename.start_from_head();
+ if (dialect == xhtml)
+ fputs("<p>", f);
do {
g = headers.get_data();
fputs("<a href=\"", f);
@@ -1589,12 +1595,18 @@ void header_desc::write_headings (FILE *f, int force)
h++;
fputs("\">", f);
fputs(g->text_string, f);
- fputs("</a><br>\n", f);
+ fputs("</a>", f);
+ if (dialect == xhtml)
+ fputs("<br/>\n", f);
+ else
+ fputs("<br>\n", f);
headers.move_right();
if (multiple_files && (! header_filename.is_empty()))
header_filename.move_right();
} while (! headers.is_equal_to_head());
fputs("\n", f);
+ if (dialect == xhtml)
+ fputs("</p>\n", f);
}
}
}
@@ -2091,6 +2103,10 @@ class html_printer : public printer {
int round_width (int x);
void handle_tag_within_title (text_glob *g);
void writeHeadMetaStyle (void);
+ void handle_valid_flag (void);
+ void do_math (text_glob *g);
+ void write_html_anchor (text_glob *h);
+ void write_xhtml_anchor (text_glob *h);
// ADD HERE
public:
@@ -2167,7 +2183,10 @@ void html_printer::end_of_line()
void html_printer::emit_line (text_glob *)
{
// --fixme-- needs to know the length in percentage
- html.put_string("<hr>");
+ if (dialect == xhtml)
+ html.put_string("<hr/>");
+ else
+ html.put_string("<hr>");
}
/*
@@ -2206,13 +2225,22 @@ void html_printer::emit_raw (text_glob *g)
switch (next_tag) {
case CENTERED:
- current_paragraph->do_para("align=center", space);
+ if (dialect == html4)
+ current_paragraph->do_para("align=\"center\"", space);
+ else
+ current_paragraph->do_para("class=\"center\"", space);
break;
case LEFT:
- current_paragraph->do_para(&html, "align=left", get_troff_indent(), pageoffset, linelength, space);
+ if (dialect == html4)
+ current_paragraph->do_para(&html, "align=\"left\"", get_troff_indent(), pageoffset, linelength, space);
+ else
+ current_paragraph->do_para(&html, "class=\"left\"", get_troff_indent(), pageoffset, linelength, space);
break;
case RIGHT:
- current_paragraph->do_para(&html, "align=right", get_troff_indent(), pageoffset, linelength, space);
+ if (dialect == html4)
+ current_paragraph->do_para(&html, "align=\"right\"", get_troff_indent(), pageoffset, linelength, space);
+ else
+ current_paragraph->do_para(&html, "class=\"right\"", get_troff_indent(), pageoffset, linelength, space);
break;
default:
fatal("unknown enumeration");
@@ -2308,9 +2336,12 @@ static string &generate_img_src (const char *filename)
while (filename && (filename[0] == ' ')) {
filename++;
}
- if (exists(filename))
+ if (exists(filename)) {
*s += string("<img src=\"") + filename + "\" "
+ "alt=\"Image " + filename + "\">";
+ if (dialect == xhtml)
+ *s += "</img>";
+ }
return *s;
}
@@ -2409,14 +2440,60 @@ void html_printer::do_title (void)
}
}
+/*
+ * write_html_anchor - writes out an anchor. The style of the anchor
+ * dependent upon simple_anchor.
+ */
+
+void html_printer::write_html_anchor (text_glob *h)
+{
+ if (dialect == html4) {
+ if (h != NULL) {
+ html.put_string("<a name=\"");
+ if (simple_anchors) {
+ string buffer(ANCHOR_TEMPLATE);
+
+ buffer += as_string(header.no_of_headings);
+ buffer += '\0';
+ html.put_string(buffer.contents());
+ } else
+ html.put_string(header.header_buffer);
+ html.put_string("\"></a>").nl();
+ }
+ }
+}
+
+/*
+ * write_xhtml_anchor - writes out an anchor. The style of the anchor
+ * dependent upon simple_anchor.
+ */
+
+void html_printer::write_xhtml_anchor (text_glob *h)
+{
+ if (dialect == xhtml) {
+ if (h != NULL) {
+ html.put_string(" id=\"");
+ if (simple_anchors) {
+ string buffer(ANCHOR_TEMPLATE);
+
+ buffer += as_string(header.no_of_headings);
+ buffer += '\0';
+ html.put_string(buffer.contents());
+ } else
+ html.put_string(header.header_buffer);
+ html.put_string("\"");
+ }
+ }
+}
+
void html_printer::write_header (void)
{
if (! header.header_buffer.empty()) {
+ text_glob *a = NULL;
int space = current_paragraph->retrieve_para_space() || seen_space;
- if (header.header_level > 7) {
+ if (header.header_level > 7)
header.header_level = 7;
- }
// firstly we must terminate any font and type faces
current_paragraph->done_para();
@@ -2427,33 +2504,22 @@ void html_printer::write_header (void)
header.no_of_headings++;
style st;
- text_glob *h=new text_glob();
- h->text_glob_html(&st,
+ a = new text_glob();
+ a->text_glob_html(&st,
header.headings.add_string(header.header_buffer),
header.header_buffer.length(),
header.no_of_headings, header.header_level,
header.no_of_headings, header.header_level);
- header.headers.add(h,
+ // and add this header to the header list
+ header.headers.add(a,
header.no_of_headings,
header.no_of_headings, header.no_of_headings,
- header.no_of_headings, header.no_of_headings); // and add this header to the header list
-
- // lastly we generate a tag
-
- html.nl().nl().put_string("<a name=\"");
- if (simple_anchors) {
- string buffer(ANCHOR_TEMPLATE);
-
- buffer += as_string(header.no_of_headings);
- buffer += '\0';
- html.put_string(buffer.contents());
- } else {
- html.put_string(header.header_buffer);
- }
- html.put_string("\"></a>").nl();
+ header.no_of_headings, header.no_of_headings);
}
+ html.nl().nl();
+
if (manufacture_headings) {
// line break before a header
if (!current_paragraph->emitted_text())
@@ -2462,11 +2528,14 @@ void html_printer::write_header (void)
if (header.header_level<4) {
html.put_string("<b><font size=\"+1\">");
html.put_string(header.header_buffer);
- html.put_string("</font></b>").nl();
+ html.put_string("</font>").nl();
+ write_html_anchor(a);
+ html.put_string("</b>").nl();
}
else {
html.put_string("<b>");
- html.put_string(header.header_buffer);
+ html.put_string(header.header_buffer).nl();
+ write_html_anchor(a);
html.put_string("</b>").nl();
}
}
@@ -2474,8 +2543,10 @@ void html_printer::write_header (void)
// and now we issue the real header
html.put_string("<h");
html.put_number(header.header_level);
+ write_xhtml_anchor(a);
html.put_string(">");
- html.put_string(header.header_buffer);
+ html.put_string(header.header_buffer).nl();
+ write_html_anchor(a);
html.put_string("</h");
html.put_number(header.header_level);
html.put_string(">").nl();
@@ -2810,10 +2881,15 @@ void html_printer::do_check_center(void)
int space = current_paragraph->retrieve_para_space() || seen_space;
current_paragraph->done_para();
supress_sub_sup = TRUE;
- current_paragraph->do_para("align=center", space);
+ if (dialect == html4)
+ current_paragraph->do_para("align=\"center\"", space);
+ else
+ current_paragraph->do_para("class=\"center\"", space);
} else
- if (strcmp("align=center",
- current_paragraph->get_alignment()) != 0) {
+ if ((strcmp("align=\"center\"",
+ current_paragraph->get_alignment()) != 0) &&
+ (strcmp("class=\"center\"",
+ current_paragraph->get_alignment()) != 0)) {
/*
* different alignment, so shutdown paragraph and open
* a new one.
@@ -2821,7 +2897,10 @@ void html_printer::do_check_center(void)
int space = current_paragraph->retrieve_para_space() || seen_space;
current_paragraph->done_para();
supress_sub_sup = TRUE;
- current_paragraph->do_para("align=center", space);
+ if (dialect == html4)
+ current_paragraph->do_para("align=\"center\"", space);
+ else
+ current_paragraph->do_para("class=\"center\"", space);
} else
/*
* same alignment, if we have emitted text then issue a break.
@@ -2898,7 +2977,10 @@ void html_printer::insert_split_file (void)
split_file += string("-");
split_file += as_string(header.no_of_level_one_headings);
- split_file += string(".html");
+ if (dialect == xhtml)
+ split_file += string(".xhtml");
+ else
+ split_file += string(".html");
split_file += '\0';
file_list.set_file_name(split_file);
@@ -3092,9 +3174,15 @@ void html_printer::troff_tag (text_glob *g)
* firstly skip over devtag:
*/
char *t=(char *)g->text_string+strlen("devtag:");
-
if (strncmp(g->text_string, "html</p>:", strlen("html</p>:")) == 0) {
do_end_para(g);
+ } else if (strncmp(g->text_string, "html<?p>:", strlen("html<?p>:")) == 0) {
+ if (current_paragraph->emitted_text())
+ html.put_string(g->text_string+9);
+ else
+ do_end_para(g);
+ } else if (strncmp(g->text_string, "math<?p>:", strlen("math<?p>:")) == 0) {
+ do_math(g);
} else if (g->is_eol()) {
do_eol();
} else if (g->is_eol_ce()) {
@@ -3177,6 +3265,19 @@ void html_printer::troff_tag (text_glob *g)
}
/*
+ * do_math - prints out the equation
+ */
+
+void html_printer::do_math (text_glob *g)
+{
+ do_font(g);
+ if (current_paragraph->emitted_text())
+ html.put_string(g->text_string+9);
+ else
+ do_end_para(g);
+}
+
+/*
* is_in_middle - returns TRUE if the positions left..right are in the center of the page.
*/
@@ -4720,7 +4821,10 @@ void html_printer::write_title (int in_head)
} else {
title.has_been_written = TRUE;
if (title.with_h1) {
- html.put_string("<h1 align=center>");
+ if (dialect == xhtml)
+ html.put_string("<h1>");
+ else
+ html.put_string("<h1 align=\"center\">");
html.put_string(title.text);
html.put_string("</h1>").nl().nl();
}
@@ -4737,8 +4841,12 @@ void html_printer::write_title (int in_head)
static void write_rule (void)
{
- if (auto_rule)
- fputs("<hr>\n", stdout);
+ if (auto_rule) {
+ if (dialect == xhtml)
+ fputs("<hr/>\n", stdout);
+ else
+ fputs("<hr>\n", stdout);
+ }
}
void html_printer::begin_page(int n)
@@ -4757,7 +4865,7 @@ void html_printer::begin_page(int n)
output_hpos = -1;
output_vpos = -1;
output_vpos_max = -1;
- current_paragraph = new html_text(&html);
+ current_paragraph = new html_text(&html, dialect);
do_indent(get_troff_indent(), pageoffset, linelength);
current_paragraph->do_para("", FALSE);
}
@@ -4815,7 +4923,13 @@ void html_printer::write_navigation (const string &top, const string &prev,
int need_bar = FALSE;
if (multiple_files) {
+ current_paragraph->done_para();
write_rule();
+ if (groff_sig)
+ fputs("\n\n<table width=\"100%\" border=\"0\" rules=\"none\"\n"
+ "frame=\"void\" cellspacing=\"1\" cellpadding=\"0\">\n"
+ "<colgroup><col class=\"left\"></col><col class=\"right\"></col></colgroup>\n"
+ "<tr><td class=\"left\">", stdout);
fputs("[ ", stdout);
if ((strcmp(prev.contents(), "") != 0) && prev != top && prev != current) {
emit_link(prev, "prev");
@@ -4833,6 +4947,16 @@ void html_printer::write_navigation (const string &top, const string &prev,
emit_link(top, "top");
}
fputs(" ]\n", stdout);
+ handle_valid_flag();
+
+ if (groff_sig) {
+ fputs("</td><td class=\"right\"><i><small>"
+ "This document was produced using "
+ "<a href=\"http://www.gnu.org/software/groff/\">"
+ "groff-", stdout);
+ fputs(Version_string, stdout);
+ fputs("</a>.</small></i></td></tr></table>\n", stdout);
+ }
write_rule();
}
}
@@ -4857,7 +4981,10 @@ void html_printer::do_file_components (void)
file_list.start_of_list();
top = string(job_name);
- top += string(".html");
+ if (dialect == xhtml)
+ top += string(".xhtml");
+ else
+ top += string(".html");
top += '\0';
next = file_list.next_file_name();
next += '\0';
@@ -4870,6 +4997,12 @@ void html_printer::do_file_components (void)
file_list.move_next();
if (file_list.is_new_output_file()) {
+#ifdef LONG_FOR_TIME_T
+ long t;
+#else
+ time_t t;
+#endif
+
if (fragment_no > 1)
write_navigation(top, prev, next, current);
prev = current;
@@ -4881,7 +5014,27 @@ void html_printer::do_file_components (void)
fflush(stdout);
freopen(split_file.contents(), "w", stdout);
fragment_no++;
- writeHeadMetaStyle();
+ if (dialect == xhtml)
+ writeHeadMetaStyle();
+
+ html.begin_comment("Creator : ")
+ .put_string("groff ")
+ .put_string("version ")
+ .put_string(Version_string)
+ .end_comment();
+
+ t = time(0);
+ html.begin_comment("CreationDate: ")
+ .put_string(ctime(&t), strlen(ctime(&t))-1)
+ .end_comment();
+
+ if (dialect == html4)
+ writeHeadMetaStyle();
+
+ html.put_string("<title>");
+ html.put_string(split_file.contents());
+ html.put_string("</title>").nl().nl();
+
fputs(head_info.contents(), stdout);
fputs("</head>\n", stdout);
write_navigation(top, prev, next, current);
@@ -4891,8 +5044,27 @@ void html_printer::do_file_components (void)
}
if (fragment_no > 1)
write_navigation(top, prev, next, current);
- else
+ else {
+ current_paragraph->done_para();
write_rule();
+ if (valid_flag && dialect == xhtml) {
+ if (groff_sig)
+ fputs("\n\n<table width=\"100%\" border=\"0\" rules=\"none\"\n"
+ "frame=\"void\" cellspacing=\"1\" cellpadding=\"0\">\n"
+ "<colgroup><col class=\"left\"></col><col class=\"right\"></col></colgroup>\n"
+ "<tr><td class=\"left\">", stdout);
+ handle_valid_flag();
+ if (groff_sig) {
+ fputs("</td><td class=\"right\"><i><small>"
+ "This document was produced using "
+ "<a href=\"http://www.gnu.org/software/groff/\">"
+ "groff-", stdout);
+ fputs(Version_string, stdout);
+ fputs("</a>.</small></i></td></tr></table>\n", stdout);
+ }
+ write_rule();
+ }
+ }
}
/*
@@ -4902,21 +5074,43 @@ void html_printer::do_file_components (void)
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);
+ if (dialect == html4) {
+ 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);
+ }
+ else {
+ fputs("<?xml version=\"1.0\" encoding=\"us-ascii\"?>\n", stdout);
+ fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN\"\n", stdout);
+ fputs(" \"http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd\"\n", stdout);
+ fputs(" [<!ENTITY mathml \"http://www.w3.org/1998/Math/MathML\">]>\n", stdout);
+
+ fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n",
+ stdout);
+ fputs("<head>\n", stdout);
+ fputs("<meta name=\"generator\" "
+ "content=\"groff -Txhtml, 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(" .center { text-align: center }\n", stdout);
+ fputs(" .right { text-align: right }\n", stdout);
+ }
+ fputs(" p { margin-top: 0; margin-bottom: 0; "
+ "vertical-align=\"top\" }\n", stdout);
+ fputs(" pre { margin-top: 0; margin-bottom: 0; "
+ "vertical-align=\"top\" }\n", stdout);
+ fputs(" table { margin-top: 0; margin-bottom: 0; "
+ "vertical-align=\"top\" }\n", stdout);
+ fputs(" h1 { text-align: center }\n", stdout);
fputs("</style>\n", stdout);
}
@@ -4932,6 +5126,10 @@ html_printer::~html_printer()
current_paragraph->flush_text();
html.end_line();
html.set_file(stdout);
+
+ if (dialect == xhtml)
+ writeHeadMetaStyle();
+
html.begin_comment("Creator : ")
.put_string("groff ")
.put_string("version ")
@@ -4943,7 +5141,8 @@ html_printer::~html_printer()
.put_string(ctime(&t), strlen(ctime(&t))-1)
.end_comment();
- writeHeadMetaStyle();
+ if (dialect == html4)
+ writeHeadMetaStyle();
write_title(TRUE);
head_info += '\0';
@@ -5123,9 +5322,12 @@ void html_printer::special(char *s, const environment *env, char type)
* requesting that the formatting move right by the appropriate
* amount.
*/
- } else if (strncmp(s, "html</p>:", 9) == 0) {
+ } else if ((strncmp(s, "html</p>:", 9) == 0) ||
+ (strncmp(s, "html<?p>:", 9) == 0) ||
+ (strncmp(s, "math<?p>:", 9) == 0)) {
int r=font::res; /* resolution of the device */
font *f=sbuf_style.f;
+ string t;
if (f == NULL) {
int found=FALSE;
@@ -5133,6 +5335,17 @@ void html_printer::special(char *s, const environment *env, char type)
f = font::load_font("TR", &found);
}
+ if (strncmp(s, "math<?p>:", 9) == 0) {
+ if (strncmp((char *)&s[9], "<math>", 6) == 0) {
+ s[9] = '\0';
+ t = s;
+ t += "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">";
+ t += (char *)&s[15];
+ t += '\0';
+ s = (char *)&t[0];
+ }
+ }
+
/*
* need to pass all of string through to html output during flush
*/
@@ -5148,6 +5361,7 @@ void html_printer::special(char *s, const environment *env, char type)
* requesting that the formatting move right by the appropriate
* amount.
*/
+
} else if (strncmp(s, "index:", 6) == 0) {
cutoff_heading = atoi(&s[6]);
} else if (strncmp(s, "assertion:[", 11) == 0) {
@@ -5211,6 +5425,21 @@ int html_printer::round_width(int x)
return n * r;
}
+/*
+ * handle_valid_flag - emits a valid xhtml 1.1 button, provided -V and -x
+ * were supplied on the command line.
+ */
+
+void html_printer::handle_valid_flag (void)
+{
+ if (valid_flag && dialect == xhtml)
+ fputs("<p>"
+ "<a href=\"http://validator.w3.org/check?uri=referer\"><img "
+ "src=\"http://www.w3.org/Icons/valid-xhtml11\" "
+ "alt=\"Valid XHTML 1.1 Transitional\" height=\"31\" width=\"88\" /></a>\n"
+ "</p>\n", stdout);
+}
+
int main(int argc, char **argv)
{
program_name = argv[0];
@@ -5222,7 +5451,7 @@ int main(int argc, char **argv)
{ "version", no_argument, 0, 'v' },
{ NULL, 0, 0, 0 }
};
- while ((c = getopt_long(argc, argv, "a:bdD:F:g:hi:I:j:lno:prs:S:v",
+ while ((c = getopt_long(argc, argv, "a:bdD:eF:g:hi:I:j:lno:prs:S:vVx:y",
long_options, NULL))
!= EOF)
switch(c) {
@@ -5240,6 +5469,9 @@ int main(int argc, char **argv)
case 'D':
/* handled by pre-html */
break;
+ case 'e':
+ /* handled by pre-html */
+ break;
case 'F':
font::command_line_font_dir(optarg);
break;
@@ -5285,6 +5517,21 @@ int main(int argc, char **argv)
printf("GNU post-grohtml (groff) version %s\n", Version_string);
exit(0);
break;
+ case 'V':
+ valid_flag = TRUE;
+ break;
+ case 'x':
+ if (strcmp(optarg, "x") == 0) {
+ dialect = xhtml;
+ simple_anchors = TRUE;
+ } else if (strcmp(optarg, "4") == 0)
+ dialect = html4;
+ else
+ printf("unsupported html dialect %s (defaulting to html4)\n", optarg);
+ break;
+ case 'y':
+ groff_sig = TRUE;
+ break;
case CHAR_MAX + 1: // --help
usage(stdout);
exit(0);
@@ -5307,6 +5554,6 @@ int main(int argc, char **argv)
static void usage(FILE *stream)
{
- fprintf(stream, "usage: %s [-vblnh] [-D dir] [-I image_stem] [-F dir] [files ...]\n",
+ fprintf(stream, "usage: %s [-vbelnhVy] [-D dir] [-I image_stem] [-F dir] [-x x] [files ...]\n",
program_name);
}