groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff-commit] groff ChangeLog NEWS doc/groff.texinfo man/grof...


From: Werner LEMBERG
Subject: [Groff-commit] groff ChangeLog NEWS doc/groff.texinfo man/grof...
Date: Wed, 19 Sep 2007 14:55:57 +0000

CVSROOT:        /cvsroot/groff
Module name:    groff
Changes by:     Werner LEMBERG <wl>     07/09/19 14:55:56

Modified files:
        .              : ChangeLog NEWS 
        doc            : groff.texinfo 
        man            : groff_font.man 
        src/devices/grohtml: grohtml.man html-table.cpp html-table.h 
                             html-text.cpp html-text.h post-html.cpp 
        src/preproc/eqn: box.cpp eqn.h main.cpp text.cpp 
        src/preproc/html: pre-html.cpp 
        src/roff/groff : groff.cpp 
        src/roff/troff : input.cpp 
        tmac           : s.tmac troffrc-end www.tmac 

Log message:
        * 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.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/groff/ChangeLog?cvsroot=groff&r1=1.1100&r2=1.1101
http://cvs.savannah.gnu.org/viewcvs/groff/NEWS?cvsroot=groff&r1=1.241&r2=1.242
http://cvs.savannah.gnu.org/viewcvs/groff/doc/groff.texinfo?cvsroot=groff&r1=1.258&r2=1.259
http://cvs.savannah.gnu.org/viewcvs/groff/man/groff_font.man?cvsroot=groff&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/grohtml.man?cvsroot=groff&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/html-table.cpp?cvsroot=groff&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/html-table.h?cvsroot=groff&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/html-text.cpp?cvsroot=groff&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/html-text.h?cvsroot=groff&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/groff/src/devices/grohtml/post-html.cpp?cvsroot=groff&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/eqn/box.cpp?cvsroot=groff&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/eqn/eqn.h?cvsroot=groff&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/eqn/main.cpp?cvsroot=groff&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/eqn/text.cpp?cvsroot=groff&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/groff/src/preproc/html/pre-html.cpp?cvsroot=groff&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/groff/src/roff/groff/groff.cpp?cvsroot=groff&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/groff/src/roff/troff/input.cpp?cvsroot=groff&r1=1.45&r2=1.46
http://cvs.savannah.gnu.org/viewcvs/groff/tmac/s.tmac?cvsroot=groff&r1=1.34&r2=1.35
http://cvs.savannah.gnu.org/viewcvs/groff/tmac/troffrc-end?cvsroot=groff&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/groff/tmac/www.tmac?cvsroot=groff&r1=1.50&r2=1.51

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/groff/groff/ChangeLog,v
retrieving revision 1.1100
retrieving revision 1.1101
diff -u -b -r1.1100 -r1.1101
--- ChangeLog   15 Sep 2007 09:11:14 -0000      1.1100
+++ ChangeLog   19 Sep 2007 14:55:54 -0000      1.1101
@@ -1,3 +1,132 @@
+2007-09-19  Gaius Mulley  <address@hidden>
+
+       * 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.
+
+2007-09-17  Werner LEMBERG  <address@hidden>
+
+       * man/groff_font.man: Document `unicode' keyword.
+       * doc/groff.texinfo (DESC File Format): Synchronize with
+       groff_font.man.
+
 2007-09-15  Werner LEMBERG  <address@hidden>
 
        * man/groff.man: Document `\_'.

Index: NEWS
===================================================================
RCS file: /cvsroot/groff/groff/NEWS,v
retrieving revision 1.241
retrieving revision 1.242
diff -u -b -r1.241 -r1.242
--- NEWS        11 Jul 2007 21:10:15 -0000      1.241
+++ NEWS        19 Sep 2007 14:55:55 -0000      1.242
@@ -14,6 +14,16 @@
 Groff
 -----
 
+o XHTML support has been added to grohtml and can be specified by
+  -Txhtml.  This option also utilizes the MathML capability of
+  eqn and combine the outputs of both in the final XHTML file.
+  Users can also specify the `-P-V' option together with `-Txhtml'
+  in groff.  This has the effect of creating an XHTML' validator
+  button at the bottom of each page.
+
+Troff
+-----
+
 o Two new requests `device' and `devicem' have been added which are
   equivalents to the \X and \Y escapes, respectively.
 
@@ -64,6 +74,9 @@
   For backwards compatibility, the old set of font definition files is still
   available; for details please read the man page of `grops(1)'.
   
+o A new read-only number register `.O' is available which returns the
+  current suppression level as set by the `\O' escape.
+  
 Pic
 ---
 
@@ -79,7 +92,7 @@
 
 o Eric S. Raymond has added a new device type to eqn, MathML.  When 
   -TMathML is enabled, eqn now emits MathML formula markup rather than
-  groff commands.
+  groff commands.  The new groff -Txhtml device uses this.
 
 Chem
 ----
@@ -93,6 +106,18 @@
 o \D'p...' is now supported if the polygon consists entirely of horizontal
    and vertical lines.
 
+Grohtml
+-------
+
+o XHTML support has been added.
+
+o New command line option `-V' (to be used in XHTML mode) to produce an
+  XHTML validator button.
+
+o New command line option `-y' to produce a right-justified groff signature
+  at the end of the document (in combination with option `-V').
+
+
 Gxditview
 ---------
 

Index: doc/groff.texinfo
===================================================================
RCS file: /cvsroot/groff/groff/doc/groff.texinfo,v
retrieving revision 1.258
retrieving revision 1.259
diff -u -b -r1.258 -r1.259
--- doc/groff.texinfo   15 Sep 2007 08:10:46 -0000      1.258
+++ doc/groff.texinfo   19 Sep 2007 14:55:55 -0000      1.259
@@ -26,7 +26,8 @@
 @copying
 This manual documents GNU @code{troff} version 1.19.2.
 
-Copyright @copyright{} 1994-2000, 2001, 2002, 2003, 2004, 2005, 2006
+Copyright @copyright{} 1994-2000, 2001, 2002, 2003, 2004, 2005, 2006,
+2007
 Free Software Foundation, Inc.
 
 @quotation
@@ -472,7 +473,7 @@
 @title groff
 @subtitle The GNU implementation of @code{troff}
 @subtitle Edition 1.19.3
address@hidden Summer 2006
address@hidden Autumn 2007
 @author by Trent address@hidden
 @author and Werner Lemberg (@email{bug-groff@@gnu.org})
 
@@ -6472,6 +6473,11 @@
 @acronym{ASCII} approximation of the output, this is set address@hidden, zero
 otherwise.  @xref{Groff Options}.
 
address@hidden \n[.O]
address@hidden .O
+This read-only register is set to the suppression nesting level (see
+escapes @code{\O}).  @xref{Suppressing output}.
+
 @item \n[.P]
 @vindex .P
 This register is set address@hidden (and address@hidden otherwise) if the 
current
@@ -12854,9 +12860,13 @@
 
 @item \O3
 Begin a nesting level.  At start-up, @code{gtroff} is at outer level.
+The current level is contained within the read-only register @code{.O}.
address@hidden Registers}.
 
 @item \O4
 End a nesting level.
+The current level is contained within the read-only register @code{.O}.
address@hidden Registers}.
 
 @item address@hidden@var{filename}]
 This escape is @code{grohtml} specific.  Provided that this escape
@@ -15670,14 +15680,25 @@
 
 The @file{DESC} file can contain the following types of line.  Except
 for the @code{charset} keyword which must comes last (if at all), the
-order of the lines is not important.
+order of the lines is not important.  Later entries in the file, however,
+override previous values.
 
 @table @code
address@hidden res @var{n}
address@hidden res
address@hidden device resolution
address@hidden resolution, device
-There are @address@hidden units per inch.
address@hidden charset
address@hidden charset
+This line and everything following in the file are ignored.  It is
+allowed for the sake of backwards compatibility.
+
address@hidden family @var{fam}
address@hidden family
+The default font family is @var{fam}.
+
address@hidden fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn}
address@hidden fonts
+Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions
address@hidden, @dots{}, @address@hidden where @var{m} is the number of
+styles.  This command may extend over more than one line.  A font name
address@hidden means no font is mounted on the corresponding font position.
 
 @item hor @var{n}
 @kindex hor
@@ -15686,29 +15707,54 @@
 The horizontal resolution is @address@hidden units.  All horizontal
 quantities are rounded to be multiples of this value.
 
address@hidden vert @var{n}
address@hidden vert
address@hidden vertical resolution
address@hidden resolution, vertical
-The vertical resolution is @address@hidden units.  All vertical
-quantities are rounded to be multiples of this value.
address@hidden image_generator @var{string}
address@hidden image_generator
address@hidden PostScript, PNG image generation
address@hidden PNG image generation from PostScript
+Needed for @code{grohtml} only.  It specifies the program to generate
+PNG images from PostScript input.  Under GNU/Linux this is usually
address@hidden but under other systems (notably cygwin) it might be set to
+another name.
+
address@hidden paperlength @var{n}
address@hidden paperlength
+The physical vertical dimension of the output medium in machine units.
+This isn't used by @code{troff} itself but by output devices.
+Deprecated.  Use @code{papersize} instead.
 
address@hidden sizescale @var{n}
address@hidden sizescale
-The scale factor for point sizes.  By default this has a value address@hidden
-One scaled point is equal to one point/@var{n}.  The arguments to the
address@hidden and @code{sizes} commands are given in scaled points.
address@hidden Type Sizes}, for more information.
address@hidden papersize @var{string} @dots{}
address@hidden papersize
+Select a paper size.  Valid values for @var{string} are the ISO paper
+types @address@hidden, @address@hidden, @address@hidden,
address@hidden@code{D7}, @code{DL}, and the US paper types @code{letter},
address@hidden, @code{tabloid}, @code{ledger}, @code{statement},
address@hidden, @code{com10}, and @code{monarch}.  Case is not significant
+for @var{string} if it holds predefined paper types.  Alternatively,
address@hidden can be a file name (e.g.@: @file{/etc/papersize}); if the file
+can be opened, @code{groff} reads the first line and tests for the above
+paper sizes.  Finally, @var{string} can be a custom paper size in the format
address@hidden@var{length},@var{width}} (no spaces before and after the comma).
+Both @var{length} and @var{width} must have a unit appended; valid values
+are @samp{i} for inches, @samp{C} for centimeters, @samp{p} for points, and
address@hidden for picas.  Example: @code{12c,235p}.  An argument which starts
+with a digit is always treated as a custom paper format.  @code{papersize}
+sets both the vertical and horizontal dimension of the output medium.
 
address@hidden unitwidth @var{n}
address@hidden unitwidth
-Quantities in the font files are given in machine units for fonts whose
-point size is @address@hidden points.
+More than one argument can be specified; @code{groff} scans from left to
+right and uses the first valid paper specification.
 
address@hidden prepro @var{program}
address@hidden prepro
-Call @var{program} as a preprocessor.  Currently, this keyword is used
-by @code{groff} with option @option{-Thtml} only.
address@hidden paperwidth @var{n}
address@hidden paperwidth
+The physical horizontal dimension of the output medium in machine units.
+This isn't used by @code{troff} itself but by output devices.
+Deprecated.  Use @code{papersize} instead.
+
address@hidden pass_filenames
address@hidden pass_filenames
+Tell @code{gtroff} to emit the name of the source file currently
+being processed.  This is achieved by the intermediate output command
address@hidden  Currently, this is only used by the @acronym{HTML} output
+device.
 
 @item postpro @var{program}
 @kindex postpro
@@ -15722,10 +15768,21 @@
 in the file @file{devdvi/DESC} makes @code{groff} call @code{grodvi}
 if option @option{-Tdvi} is given (and @option{-Z} isn't used).
 
address@hidden tcommand
address@hidden tcommand
-This means that the postprocessor can handle the @samp{t} and @samp{u}
-intermediate output commands.
address@hidden prepro @var{program}
address@hidden prepro
+Call @var{program} as a preprocessor.  Currently, this keyword is used
+by @code{groff} with option @option{-Thtml} only.
+
address@hidden print @var{program}
address@hidden print
+Use @var{program} as a spooler program for printing.  If omitted,
+the @option{-l} and @option{-L} options of @code{groff} are ignored.
+
address@hidden res @var{n}
address@hidden res
address@hidden device resolution
address@hidden resolution, device
+There are @address@hidden units per inch.
 
 @item sizes @var{s1} @var{s2} @dots{} @var{sn} 0
 @kindex sizes
@@ -15734,65 +15791,59 @@
 (this is digit zero).  Each @var{si} can also be a range of sizes
 @address@hidden  The list can extend over more than one line.
 
address@hidden sizescale @var{n}
address@hidden sizescale
+The scale factor for point sizes.  By default this has a value address@hidden
+One scaled point is equal to one point/@var{n}.  The arguments to the
address@hidden and @code{sizes} commands are given in scaled points.
address@hidden Type Sizes}, for more information.
+
 @item styles @var{S1} @var{S2} @dots{} @var{Sm}
 @kindex styles
 The first @address@hidden positions are associated with styles
 @var{S1} @dots{} @var{Sm}.
 
address@hidden fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn}
address@hidden fonts
-Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions
address@hidden, @dots{}, @address@hidden where @var{m} is the number of
-styles.  This command may extend over more than one line.  A font name
address@hidden means no font is mounted on the corresponding font position.
address@hidden tcommand
address@hidden tcommand
+This means that the postprocessor can handle the @samp{t} and @samp{u}
+intermediate output commands.
 
address@hidden family @var{fam}
address@hidden family
-The default font family is @var{fam}.
address@hidden unicode
address@hidden unicode
+Indicate that the output device supports the complete Unicode
+repertoire.  Useful only for devices which produce @emph{character
+entities} instead of glyphs.
+
+If @code{unicode} is present, no @code{charset} section is required
+in the font description files since the Unicode handling built into
address@hidden is used.  However, if there are entries in a
address@hidden section, they either override the default mappings for
+those particular characters or add new mappings (normally for composite
+characters).
 
+This is used for @option{-Tutf8} and @option{-Thtml}.
+
address@hidden unitwidth @var{n}
address@hidden unitwidth
+Quantities in the font files are given in machine units for fonts whose
+point size is @address@hidden points.
+
address@hidden unscaled_charwidths
address@hidden unscaled_charwidths
+Make the font handling module always return unscaled character widths.
+Needed for the @code{grohtml} device.
 @item use_charnames_in_special
 @kindex use_charnames_in_special
 This command indicates that @code{gtroff} should encode special
 characters inside special commands.  Currently, this is only used
 by the @acronym{HTML} output device.  @xref{Postprocessor Access}.
 
address@hidden papersize @var{string} @dots{}
address@hidden papersize
-Select a paper size.  Valid values for @var{string} are the ISO paper
-types @address@hidden, @address@hidden, @address@hidden,
address@hidden@code{D7}, @code{DL}, and the US paper types @code{letter},
address@hidden, @code{tabloid}, @code{ledger}, @code{statement},
address@hidden, @code{com10}, and @code{monarch}.  Case is not significant
-for @var{string} if it holds predefined paper types.  Alternatively,
address@hidden can be a file name (e.g.@: @file{/etc/papersize}); if the file
-can be opened, @code{groff} reads the first line and tests for the above
-paper sizes.  Finally, @var{string} can be a custom paper size in the format
address@hidden@var{length},@var{width}} (no spaces before and after the comma).
-Both @var{length} and @var{width} must have a unit appended; valid values
-are @samp{i} for inches, @samp{C} for centimeters, @samp{p} for points, and
address@hidden for picas.  Example: @code{12c,235p}.  An argument which starts
-with a digit is always treated as a custom paper format.  @code{papersize}
-sets both the vertical and horizontal dimension of the output medium.
-
-More than one argument can be specified; @code{groff} scans from left to
-right and uses the first valid paper specification.
-
address@hidden pass_filenames
address@hidden pass_filenames
-Tell @code{gtroff} to emit the name of the source file currently
-being processed.  This is achieved by the intermediate output command
address@hidden  Currently, this is only used by the @acronym{HTML} output
-device.
-
address@hidden print @var{program}
address@hidden print
-Use @var{program} as a spooler program for printing.  If omitted,
-the @option{-l} and @option{-L} options of @code{groff} are ignored.
-
address@hidden charset
address@hidden charset
-This line and everything following in the file are ignored.  It is
-allowed for the sake of backwards compatibility.
address@hidden vert @var{n}
address@hidden vert
address@hidden vertical resolution
address@hidden resolution, vertical
+The vertical resolution is @address@hidden units.  All vertical
+quantities are rounded to be multiples of this value.
 @end table
 
 The @code{res}, @code{unitwidth}, @code{fonts}, and @code{sizes} lines

Index: man/groff_font.man
===================================================================
RCS file: /cvsroot/groff/groff/man/groff_font.man,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- man/groff_font.man  1 Jan 2007 13:49:55 -0000       1.25
+++ man/groff_font.man  19 Sep 2007 14:55:55 -0000      1.26
@@ -287,6 +287,37 @@
 output commands.
 .
 .TP
+.B unicode
+Indicate that the output device supports the complete Unicode
+repertoire.
+.
+Useful only for devices which produce
+.I character entities
+instead of glyphs.
+.
+.IP
+If
+.B unicode
+is present, no
+.B charset
+section is required in the font description files since the Unicode
+handling built into
+.B groff
+is used.
+.
+However, if there are entries in a
+.B charset
+section, they either override the default mappings for those
+particular characters or add new mappings (normally for composite
+characters).
+.
+.IP
+This is used for
+.B \-Tutf8
+and
+.BR \-Thtml .
+.
+.TP
 .BI unitwidth\  n
 Quantities in the font files are given in machine units
 for fonts whose point size is

Index: src/devices/grohtml/grohtml.man
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/grohtml.man,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- src/devices/grohtml/grohtml.man     31 Dec 2006 17:34:32 -0000      1.23
+++ src/devices/grohtml/grohtml.man     19 Sep 2007 14:55:55 -0000      1.24
@@ -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 @@
 .OP \-o \%image-vertical-offset
 .OP \-s size
 .OP \-S level
+.OP \-x \%html-dialect
 .RI "[\ " files\|.\|.\|. "\ ]"
 .br
 .ad \na
@@ -130,6 +131,24 @@
 .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 @@
 .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

Index: src/devices/grohtml/html-table.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/html-table.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- src/devices/grohtml/html-table.cpp  26 May 2005 21:01:58 -0000      1.6
+++ src/devices/grohtml/html-table.cpp  19 Sep 2007 14:55:55 -0000      1.7
@@ -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 (address@hidden) wrote html-table.cpp
  *
@@ -41,6 +41,9 @@
 #   define FALSE (1==0)
 #endif
 
+extern html_dialect dialect;
+
+
 tabs::tabs ()
   : tab(NULL)
 {
@@ -294,7 +297,7 @@
     }
     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 @@
     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 @@
 }
 
 /*
+ *  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 @@
     
     // 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 @@
                / 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 @@
                /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 @@
     
     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();
   }
 }
 

Index: src/devices/grohtml/html-table.h
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/html-table.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- src/devices/grohtml/html-table.h    26 May 2005 21:01:58 -0000      1.5
+++ src/devices/grohtml/html-table.h    19 Sep 2007 14:55:55 -0000      1.6
@@ -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 (address@hidden) wrote html-table.h
  *
@@ -93,6 +93,8 @@
   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;

Index: src/devices/grohtml/html-text.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/html-text.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- src/devices/grohtml/html-text.cpp   26 May 2005 21:01:58 -0000      1.9
+++ src/devices/grohtml/html-text.cpp   19 Sep 2007 14:55:55 -0000      1.10
@@ -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 (address@hidden) wrote html-text.cpp
@@ -44,10 +44,11 @@
 #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 @@
                     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 @@
     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 @@
                     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 @@
     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

Index: src/devices/grohtml/html-text.h
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/html-text.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- src/devices/grohtml/html-text.h     26 May 2005 21:01:58 -0000      1.14
+++ src/devices/grohtml/html-text.h     19 Sep 2007 14:55:55 -0000      1.15
@@ -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 (address@hidden) wrote html-text.h
@@ -32,6 +32,12 @@
 #define STYLE_VERTICAL_SPACE "1em"
 
 /*
+ *  supported html dialects.
+ */
+
+typedef enum {xhtml, html4} html_dialect;
+
+/*
  *  html tags
  */
 
@@ -56,7 +62,7 @@
 
 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 @@
   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         */

Index: src/devices/grohtml/post-html.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/devices/grohtml/post-html.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- src/devices/grohtml/post-html.cpp   5 May 2006 21:03:50 -0000       1.38
+++ src/devices/grohtml/post-html.cpp   19 Sep 2007 14:55:55 -0000      1.39
@@ -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 (address@hidden) wrote post-html.cpp
@@ -90,6 +90,10 @@
 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 @@
 
       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 @@
        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 @@
   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,6 +2183,9 @@
 void html_printer::emit_line (text_glob *)
 {
   // --fixme-- needs to know the length in percentage
+  if (dialect == xhtml)
+    html.put_string("<hr/>");
+  else
   html.put_string("<hr>");
 }
 
@@ -2206,13 +2225,22 @@
     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 @@
   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 @@
   }
 }
 
+/*
+ *  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 @@
       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 @@
       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 @@
       // 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 @@
        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 @@
          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,6 +2977,9 @@
 
     split_file += string("-");
     split_file += as_string(header.no_of_level_one_headings);
+    if (dialect == xhtml)
+      split_file += string(".xhtml");
+    else
     split_file += string(".html");
     split_file += '\0';
 
@@ -3092,9 +3174,15 @@
    *  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 @@
 }
 
 /*
+ *  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 @@
     } 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 @@
 
 static void write_rule (void)
 {
-  if (auto_rule)
+  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 @@
   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 @@
   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 @@
       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,6 +4981,9 @@
 
   file_list.start_of_list();
   top = string(job_name);
+  if (dialect == xhtml)
+    top += string(".xhtml");
+  else
   top += string(".html");
   top += '\0';
   next = file_list.next_file_name();
@@ -4870,6 +4997,12 @@
     
     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 @@
       fflush(stdout);
       freopen(split_file.contents(), "w", stdout);
       fragment_no++;
+      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 @@
   }
   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,9 +5074,9 @@
 
 void html_printer::writeHeadMetaStyle (void)
 {
+  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\" "
@@ -4912,11 +5084,33 @@
   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("       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("       .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 @@
     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,6 +5141,7 @@
     .put_string(ctime(&t), strlen(ctime(&t))-1)
     .end_comment();
 
+  if (dialect == html4)
   writeHeadMetaStyle();
 
   write_title(TRUE);
@@ -5123,9 +5322,12 @@
        * 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 @@
        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 @@
        * 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 @@
   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 @@
     { "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 @@
     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 @@
       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 @@
 
 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);
 }

Index: src/preproc/eqn/box.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/eqn/box.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- src/preproc/eqn/box.cpp     21 Mar 2007 13:30:59 -0000      1.6
+++ src/preproc/eqn/box.cpp     19 Sep 2007 14:55:56 -0000      1.7
@@ -237,7 +237,7 @@
 {
   if (output_format == troff)
     printf("\\*(" LINE_STRING "\n");
-  else if (output_format == mathml)
+  else if (output_format == mathml && !xhtml)
     putchar('\n');
 }
 
@@ -254,8 +254,11 @@
     printf(".as " LINE_STRING " \"%s\n", s);
     printf(".ec\n");
   }
-  else if (output_format == mathml)
+  else if (output_format == mathml) {
     fputs(s, stdout);
+    if (xhtml && strlen(s) > 0)
+      printf("\n");
+  }
 }
 
 void set_minimum_size(int n)
@@ -349,6 +352,8 @@
             b->uid, body_height, b->uid, body_depth);
   }
   else if (output_format == mathml) {
+    if (xhtml)
+      printf(".MATHML ");
     printf("<math>");
     b->output();
     printf("</math>");

Index: src/preproc/eqn/eqn.h
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/eqn/eqn.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- src/preproc/eqn/eqn.h       5 Feb 2007 15:24:56 -0000       1.5
+++ src/preproc/eqn/eqn.h       19 Sep 2007 14:55:56 -0000      1.6
@@ -41,6 +41,7 @@
 extern int compatible_flag;
 extern int nroff;
 extern eqnmode_t output_format;
+extern int xhtml;
 
 void init_lex(const char *str, const char *filename, int lineno);
 void lex_error(const char *message,

Index: src/preproc/eqn/main.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/eqn/main.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- src/preproc/eqn/main.cpp    5 Feb 2007 15:24:56 -0000       1.6
+++ src/preproc/eqn/main.cpp    19 Sep 2007 14:55:56 -0000      1.7
@@ -45,6 +45,7 @@
 int compatible_flag = 0;
 int no_newline_in_delim_flag = 0;
 int html = 0;
+int xhtml = 0;
 eqnmode_t output_format;
 
 int read_line(FILE *fp, string *p)
@@ -188,6 +189,13 @@
       html_end_suppress();
       printf("\n");
     }
+    if (output_format == mathml)
+      printf("\n");
+    if (xhtml) {
+      /* skip leading spaces */
+      while ((*ptr != '\0') && (*ptr == ' '))
+       ptr++;
+    }
     start = delim_search(ptr, start_delim);
     if (start == 0) {
       char *nl = strchr(ptr, '\n');
@@ -314,6 +322,12 @@
        output_format = mathml;
        load_startup_file = 0;
       }
+      else if (strcmp(device, "mathml:xhtml") == 0) {
+       device = "MathML";
+       output_format = mathml;
+       load_startup_file = 0;
+       xhtml = 1;
+      }
       break;
     case 's':
       if (!set_gsize(optarg))

Index: src/preproc/eqn/text.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/eqn/text.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- src/preproc/eqn/text.cpp    5 Feb 2007 15:24:56 -0000       1.4
+++ src/preproc/eqn/text.cpp    19 Sep 2007 14:55:56 -0000      1.5
@@ -57,7 +57,7 @@
   {"*L", "&Lambda;"},  // ISOgrk3
   {"*m", "&mu;"},      // ISOgrk3
   {"*M", "M"},
-  {"*n", "&nu"},       // ISOgrk3
+  {"*n", "&nu;"},      // ISOgrk3
   {"*N", "N"},
   {"*o", "o"},
   {"*O", "O"},

Index: src/preproc/html/pre-html.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/preproc/html/pre-html.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- src/preproc/html/pre-html.cpp       27 Jun 2006 00:52:39 -0000      1.15
+++ src/preproc/html/pre-html.cpp       19 Sep 2007 14:55:56 -0000      1.16
@@ -1,5 +1,5 @@
 // -*- C++ -*-
-/* Copyright (C) 2000, 2001, 2002, 2003, 2004
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2007
  *     Free Software Foundation, Inc.
  * Written by Gaius Mulley (address@hidden).
  *
@@ -56,6 +56,10 @@
 
 #include "nonposix.h"
 
+#if 0
+# define DEBUGGING
+#endif
+
 /* Establish some definitions to facilitate discrimination between
    differing runtime environments. */
 
@@ -162,10 +166,6 @@
 #define REGION_TEMPLATE_SHORT "rg"
 #define REGION_TEMPLATE_LONG "-regions-"
 
-#if 0
-# define DEBUGGING
-#endif
-
 #if !defined(TRUE)
 # define TRUE (1==1)
 #endif
@@ -177,6 +177,8 @@
   CENTERED, LEFT, RIGHT, INLINE
 } IMAGE_ALIGNMENT;
 
+typedef enum {xhtml, html4} html_dialect;
+
 static int postscriptRes = -1;         // postscript resolution,
                                        // dots per inch
 static int stdoutfd = 1;               // output file descriptor -
@@ -210,6 +212,7 @@
 static char *htmlFileName = NULL;      // output of pre-html output which
                                        // is sent to troff -Thtml
 #endif
+static int eqn_flag = FALSE;            // must we preprocess via eqn?
 
 static char *linebuf = NULL;           // for scanning devps/DESC
 static int linebufsize = 0;
@@ -217,6 +220,7 @@
 
 const char *const FONT_ENV_VAR = "GROFF_FONT_PATH";
 static search_path font_path(FONT_ENV_VAR, FONTPATH, 0, 0);
+static html_dialect dialect = html4;
 
 
 /*
@@ -313,6 +317,14 @@
 
 void html_system(const char *s, int redirect_stdout)
 {
+#if defined(DEBUGGING)
+  if (debug) {
+    fprintf(stderr, "executing: ");
+    fwrite(s, sizeof(char), strlen(s), stderr);
+    fflush(stderr);
+  }
+#endif
+  {
   // Redirect standard error to the null device.  This is more
   // portable than using "2> /dev/null", since it doesn't require a
   // Unixy shell.
@@ -335,6 +347,7 @@
     fprintf(stderr, "Calling `%s' returned status %d\n", s, status);
   close(save_stderr);
   close(save_stdout);
+  }
 }
 
 /*
@@ -921,12 +934,6 @@
 
   if (s == NULL)
     sys_fatal("make_message");
-#if defined(DEBUGGING)
-  if (debug) {
-    fwrite(s, sizeof(char), strlen(s), stderr);
-    fflush(stderr);
-  }
-#endif
   html_system(s, 1);
 
   s = make_message("echo showpage | "
@@ -945,12 +952,6 @@
                   psPageName);
   if (s == NULL)
     sys_fatal("make_message");
-#if defined(DEBUGGING)
-  if (debug) {
-    fwrite(s, sizeof(char), strlen(s), stderr);
-    fflush(stderr);
-  }
-#endif
   html_system(s, 1);
   free(s);
   currentPageNo = pageno;
@@ -1031,12 +1032,6 @@
       if (s == NULL)
        sys_fatal("make_message");
 
-#if defined(DEBUGGING)
-      if (debug) {
-       fprintf(stderr, s);
-       fflush(stderr);
-      }
-#endif
       html_system(s, 0);
       free(s);
     }
@@ -1201,7 +1196,8 @@
 
   if (toImage) {
     while (i < argc) {
-      if (strcmp(argv[i], "-Thtml") == 0)
+      if ((strcmp(argv[i], "-Thtml") == 0) ||
+         (strcmp(argv[i], "-Txhtml") == 0))
        argv[i] = (char *)IMAGE_DEVICE;
       i++;
     }
@@ -1210,6 +1206,9 @@
   else {
     while (i < argc) {
       if (strcmp(argv[i], IMAGE_DEVICE) == 0)
+       if (dialect == xhtml)
+         argv[i] = (char *)"-Txhtml";
+       else
        argv[i] = (char *)"-Thtml";
       i++;
     }
@@ -1218,10 +1217,10 @@
 }
 
 /*
- *  addZ - Append -Z onto the command list for groff.
+ *  addArg - Append newarg onto the command list for groff.
  */
 
-char **addZ(int argc, char *argv[])
+char **addArg(int argc, char *argv[], char *newarg)
 {
   char **new_argv = (char **)malloc((argc + 2) * sizeof(char *));
   int i = 0;
@@ -1233,7 +1232,7 @@
     new_argv[i] = argv[i];
     i++;
   }
-  new_argv[i] = (char *)"-Z";
+  new_argv[i] = newarg;
   while (i < argc) {
     new_argv[i + 1] = argv[i];
     i++;
@@ -1278,12 +1277,37 @@
   fprintf(stderr, "\n");
 }
 
-int char_buffer::run_output_filter(int filter, int /* argc */, char **argv)
+/*
+ *  print_args - print arguments as if they were issued on the command line.
+ */
+
+#if defined(DEBUGGING)
+
+void print_args(int argc, char *argv[])
+{
+  if (debug) {
+    fprintf(stderr, "executing: ");
+    for (int i = 0; i < argc; i++)
+      fprintf(stderr, "%s ", argv[i]);
+    fprintf(stderr, "\n");
+  }
+}
+
+#else
+
+void print_args(int, char **)
+{
+}
+
+#endif
+
+int char_buffer::run_output_filter(int filter, int argc, char **argv)
 {
   int pipedes[2];
   PID_T child_pid;
   int status;
 
+  print_args(argc, argv);
   if (pipe(pipedes) < 0)
     sys_fatal("pipe");
 
@@ -1441,16 +1465,25 @@
   alterDeviceTo(argc, argv, 0);
   argv += troff_arg;           // skip all arguments up to groff
   argc -= troff_arg;
-  argv = addZ(argc, argv);
+  argv = addArg(argc, argv, (char *)"-Z");
   argc++;
 
-  s = "-dwww-image-template=";
+  s = (char *)"-dwww-image-template=";
   s += macroset_template;      // do not combine these statements,
                                // otherwise they will not work
   s += '\0';                   // the trailing `\0' is ignored
   argv = addRegDef(argc, argv, s.contents());
   argc++;
 
+  if (dialect == xhtml) {
+    argv = addRegDef(argc, argv, "-rxhtml=1");
+    argc++;
+    if (eqn_flag) {
+      argv = addRegDef(argc, argv, "-e");
+      argc++;
+    }
+  }
+
 #if defined(DEBUGGING)
 # define HTML_DEBUG_STREAM  OUTPUT_STREAM(htmlFileName)
   // slight security risk so only enabled if compiled with defined(DEBUGGING)
@@ -1488,6 +1521,15 @@
   argv = addRegDef(argc, argv, "-P-pletter");
   argc++;
 
+  if (dialect == xhtml) {
+    if (eqn_flag) {
+      argv = addRegDef(argc, argv, "-rxhtml=1");
+      argc++;
+    }
+    argv = addRegDef(argc, argv, "-e");
+    argc++;
+  }
+
 #if defined(DEBUGGING)
 # define IMAGE_DEBUG_STREAM  OUTPUT_STREAM(troffFileName)
   // slight security risk so only enabled if compiled with defined(DEBUGGING)
@@ -1547,7 +1589,7 @@
     { "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) {
@@ -1570,6 +1612,9 @@
     case 'D':
       image_dir = optarg;
       break;
+    case 'e':
+      eqn_flag = TRUE;
+      break;
     case 'F':
       font_path.command_line_dir(optarg);
       break;
@@ -1617,6 +1662,21 @@
     case 'v':
       printf("GNU pre-grohtml (groff) version %s\n", Version_string);
       exit(0);
+    case 'V':
+      // handled by post-grohtml (create validator button)
+      break;
+    case 'x':
+      // html dialect
+      if (strcmp(optarg, "x") == 0)
+       dialect = xhtml;
+      else if (strcmp(optarg, "4") == 0)
+       dialect = html4;
+      else
+       printf("unsupported html dialect %s (defaulting to html4)\n", optarg);
+      break;
+    case 'y':
+      // handled by post-grohtml (create groff signature)
+      break;
     case CHAR_MAX + 1: // --help
       usage(stdout);
       exit(0);

Index: src/roff/groff/groff.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/roff/groff/groff.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- src/roff/groff/groff.cpp    3 Sep 2006 12:52:20 -0000       1.11
+++ src/roff/groff/groff.cpp    19 Sep 2007 14:55:56 -0000      1.12
@@ -1,5 +1,5 @@
 // -*- C++ -*-
-/* Copyright (C) 1989-2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Copyright (C) 1989-2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
      Written by James Clark (address@hidden)
 
@@ -74,6 +74,7 @@
 public:
   possible_command();
   ~possible_command();
+  void clear_name();
   void set_name(const char *);
   void set_name(const char *, const char *);
   const char *get_name();
@@ -119,6 +120,8 @@
   int Xflag = 0;
   int oflag = 0;
   int safer_flag = 1;
+  int is_xhtml = 0;
+  int eflag = 0;
   int opt;
   const char *command_prefix = getenv("GROFF_COMMAND_PREFIX");
   const char *encoding = getenv("GROFF_ENCODING");
@@ -173,6 +176,7 @@
       commands[GRAP_INDEX].set_name(command_prefix, "grap");
       break;
     case 'e':
+      eflag = 1;
       commands[EQN_INDEX].set_name(command_prefix, "eqn");
       break;
     case 's':
@@ -237,10 +241,21 @@
       safer_flag = 0;
       break;
     case 'T':
-      if (strcmp(optarg, "html") == 0) {
+      if (strcmp(optarg, "xhtml") == 0) {
        // force soelim to aid the html preprocessor
        commands[SOELIM_INDEX].set_name(command_prefix, "soelim");
+       Pargs += "-x";
+       Pargs += '\0';
+       Pargs += 'x';
+       Pargs += '\0';
+       is_xhtml = 1;
+       device = "html";
+       break;
       }
+      if (strcmp(optarg, "html") == 0)
+       // force soelim to aid the html preprocessor
+       commands[SOELIM_INDEX].set_name(command_prefix, "soelim");
+      
       if (strcmp(optarg, "Xps") == 0) {
        warning("-TXps option is obsolete: use -X -Tps instead");
        device = "ps";
@@ -313,6 +328,8 @@
     commands[TROFF_INDEX].set_name(predriver);
     // pass the device arguments to the predrivers as well
     commands[TROFF_INDEX].insert_args(Pargs);
+    if (eflag && is_xhtml)
+      commands[TROFF_INDEX].insert_arg("-e");
     if (vflag)
       commands[TROFF_INDEX].insert_arg("-v");
   }
@@ -371,12 +388,22 @@
     commands[SPOOL_INDEX].set_name(0);
   }
   commands[TROFF_INDEX].append_arg("-T", device);
-  // html renders equations as images via ps
   if (strcmp(device, "html") == 0) {
+    if (is_xhtml) {
+      if (oflag)
+       fatal("`-o' option is invalid with device `xhtml'");
+      if (zflag)
+       commands[EQN_INDEX].append_arg("-Tmathml:xhtml");
+      else if (eflag)
+       commands[EQN_INDEX].clear_name();
+    }
+    else {
     if (oflag)
       fatal("`-o' option is invalid with device `html'");
+      // html renders equations as images via ps
     commands[EQN_INDEX].append_arg("-Tps:html");
   }
+  }
   else
     commands[EQN_INDEX].append_arg("-T", device);
 
@@ -542,6 +569,14 @@
   name = strsave(s);
 }
 
+void possible_command::clear_name()
+{
+  a_delete name;
+  a_delete argv;
+  name = NULL;
+  argv = NULL;
+}
+
 void possible_command::set_name(const char *s1, const char *s2)
 {
   a_delete name;

Index: src/roff/troff/input.cpp
===================================================================
RCS file: /cvsroot/groff/groff/src/roff/troff/input.cpp,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -b -r1.45 -r1.46
--- src/roff/troff/input.cpp    14 Sep 2007 06:13:48 -0000      1.45
+++ src/roff/troff/input.cpp    19 Sep 2007 14:55:56 -0000      1.46
@@ -7757,6 +7757,7 @@
   number_reg_dictionary.define(".$", new nargs_reg);
   number_reg_dictionary.define(".br", new break_flag_reg);
   number_reg_dictionary.define(".C", new constant_int_reg(&compatible_flag));
+  number_reg_dictionary.define(".O", new variable_reg(&begin_level));
   number_reg_dictionary.define(".c", new lineno_reg);
   number_reg_dictionary.define(".color", new constant_int_reg(&color_flag));
   number_reg_dictionary.define(".F", new filename_reg);

Index: tmac/s.tmac
===================================================================
RCS file: /cvsroot/groff/groff/tmac/s.tmac,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -b -r1.34 -r1.35
--- tmac/s.tmac 15 Jul 2007 15:02:55 -0000      1.34
+++ tmac/s.tmac 19 Sep 2007 14:55:56 -0000      1.35
@@ -221,6 +221,7 @@
 .              ps \\n[PS]
 .\}
 ..
+.
 .de LP
 .if !'\\n[.z]'' \{\
 .      br
@@ -229,8 +230,9 @@
 .br
 .cov*ab-init
 .cov*print
-\\*[\\$0]\\
+.nop \\*[\\$0]\\
 ..
+.
 .als IP LP
 .als PP LP
 .als XP LP
@@ -241,6 +243,7 @@
 .als MC LP
 .als RT LP
 .als XS LP
+.
 .de cov*ab-init
 .als cov*ab-init @nop
 .als LP @LP
@@ -265,6 +268,7 @@
 .als AI address@hidden
 .als TL address@hidden
 ..
+.
 .de @AB
 .if !'\\n(.z'' \{\
 .      br
@@ -342,7 +346,7 @@
 .cov*tl-au-print
 .sp 3
 .if d cov*ab-div \{\
-.  if !'\*(.T'html'  . nf
+.  if !'\*(.T'html'  .nf
 .       cov*ab-div
 .\}
 .sp 3
@@ -1691,12 +1695,12 @@
 .\}
 .di eqn*div
 .in 0
-.if \\n[eqn*type]=0 .HTML-IMAGE-LEFT
+.if \\n[eqn*type]=0 .EQN-HTML-IMAGE-LEFT
 .if \\n[eqn*type]=1 \{\
 .   if '\*(.T'html' .RS
-.   HTML-IMAGE-INLINE
+.EQN-HTML-IMAGE-INLINE
 .\}
-.if \\n[eqn*type]=2 .HTML-IMAGE
+.if \\n[eqn*type]=2 .EQN-HTML-IMAGE
 .nf
 ..
 .de @div-end!eqn*div
@@ -1744,20 +1748,21 @@
 .      \}
 .      el \{
 .\" must terminate empty equations in html and ps4html as they contain
-.\" the HTML-IMAGE-END suppression nodes
+.\" the EQN-HTML-IMAGE-END suppression nodes
 .              if \\n[dl] .chop eqn*div
 .              if '\*(.T'html' \\*[eqn*div]
 .              if r ps4html    \\*[eqn*div]
 .      \}
 .       if !'\*(.T'html' .fi
-.      if \\n[eqn*type]=0 .HTML-IMAGE-END
+.      if \\n[eqn*type]=0 .EQN-HTML-IMAGE-END
 .      if \\n[eqn*type]=1 \{\
-.              HTML-IMAGE-END
+.              EQN-HTML-IMAGE-END
 .              if '\*(.T'html' .RE
 .      \}
-.      if \\n[eqn*type]=2 .HTML-IMAGE-END
+.      if \\n[eqn*type]=2 .EQN-HTML-IMAGE-END
 .\}
 ..
+.
 .\" ****************************
 .\" ******** module tbl ********
 .\" ****************************
@@ -2065,35 +2070,21 @@
 .ds ! \(r!\"                   upside down !
 ..
 .de CHECK-FOOTER-AND-KEEP
-.\" it might be better to als FS -> B1 and FE -> B2
-.\" however this produced wierd results, so I've moved back to a more reliable
-.\" but less interesting solution --fixme--
-.   if '\*(.T'html' \{\
+.if '\*(.T'html' \{\
 .      rm KF
 .      als KF KS
+.
 .      rm FS
 .      de FS
-.              br
-.              HTML-IMAGE
-\\..
-.      rm FE
-.      de FE
-.              br
-.              HTML-IMAGE-END
-\\..
-.   \}
-.   if r ps4html \{\
-.      rm FS
-.      de FS
-.              br
-.              HTML-IMAGE
+.      sp
+.      HTML-NS <cite>
 \\..
 .      rm FE
 .      de FE
-.              br
-.              HTML-IMAGE-END
+.      HTML-NS </cite>
+.      sp
 \\..
-.   \}
+.\}
 ..
 address@hidden
 .\" ****************************

Index: tmac/troffrc-end
===================================================================
RCS file: /cvsroot/groff/groff/tmac/troffrc-end,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- tmac/troffrc-end    16 Dec 2004 13:09:54 -0000      1.11
+++ tmac/troffrc-end    19 Sep 2007 14:55:56 -0000      1.12
@@ -15,5 +15,12 @@
 .do if !d HTML-IMAGE-END    .do ds HTML-IMAGE-END
 .do if !d DEVTAG            .do ds DEVTAG
 .do if !d HTML-DO-IMAGE     .do ds HTML-DO-IMAGE
+.do if !d EQN-HTML-IMAGE-END     .do ds EQN-HTML-IMAGE-END
+.do if !d EQN-HTML-IMAGE         .do ds EQN-HTML-IMAGE
+.do if !d EQN-HTML-IMAGE-RIGHT   .do ds EQN-HTML-IMAGE-RIGHT
+.do if !d EQN-HTML-IMAGE-LEFT    .do ds EQN-HTML-IMAGE-LEFT
+.do if !d EQN-HTML-IMAGE-INLINE  .do ds EQN-HTML-IMAGE-INLINE
+.do if !d EQN-HTML-DO-IMAGE      .do ds EQN-HTML-DO-IMAGE
+.do if !d EQN-HTML-IMAGE-END     .do ds EQN-HTML-IMAGE-END
 .
 .\" Don't let blank lines creep in here.

Index: tmac/www.tmac
===================================================================
RCS file: /cvsroot/groff/groff/tmac/www.tmac,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -b -r1.50 -r1.51
--- tmac/www.tmac       7 May 2006 20:52:25 -0000       1.50
+++ tmac/www.tmac       19 Sep 2007 14:55:56 -0000      1.51
@@ -301,6 +301,26 @@
 .  \}
 ..
 .
+.\"
+.\" emit an HTML tag.  If text has been written in the paragraph
+.\"                    then do not shut the paragraph down.
+.\"                    If text was not written, remove the empty
+.\"                    paragraph tag and emit the desired html tag.
+.\"
+.de HTML<?p>
+.  if \\n[www-html] .nop \&\X^html<?p>:\\$*^
+..
+.
+.\"
+.\" emit a MATH tag.  If text has been written in the paragraph
+.\"                   then do not shut the paragraph down.
+.\"                   If text was not written, remove the empty
+.\"                   paragraph tag and emit the desired math tag.
+.\"
+.de MATH<?p>
+.  if \\n[www-html] .nop \&\X^math<?p>:\\$*^
+..
+.
 .\" --------------------------------------------------------------------
 .\" HX n
 .\"
@@ -490,7 +510,8 @@
 .    if !'\\$4'' \
 .      nr www-height \\$4
 .    HTML <img src="\\$1" alt="Image \\$1" \
-           width=\\n[www-width] height=\\n[www-height]>
+           "width=""\\n[www-width]""" \
+           "height=""\\n[www-height]"""></img>
 .  \}
 .  el \
 .    nop \\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close]
@@ -537,22 +558,22 @@
 .    ie (\\n[www-width] == 0) \{\
 .      ie (\\n[www-height] == 0) \
 .        HTML</p> <p \\*[www-htmlalign]><img "src=""\\$1""" \
-                                             "alt=""Image \\$1""></p>"
+                                             "alt=""Image \\$1"""></img></p>"
 .      el \
 .        HTML</p> <p \\*[www-htmlalign]><img "src=""\\$1""" \
                                              "alt=""Image \\$1""" \
-                                             height=\\n[www-height]></p>
+                                             
"height=""\\n[www-height]"""></img></p>
 .    \}
 .    el \{\
 .      ie (\\n[www-height] == 0) \
 .        HTML</p> <p \\*[www-htmlalign]><img "src=""\\$1""" \
                                              "alt=""Image \\$1""" \
-                                             width=\\n[www-width]></p>
+                                             
"width=""\\n[www-width]"""></img></p>
 .      el \
 .        HTML</p> <p \\*[www-htmlalign]><img "src=""\\$1""" \
                                              "alt=""Image \\$1""" \
-                                             width=\\n[www-width] \
-                                             height=\\n[www-height]></p>
+                                             "width=""\\n[www-width]""" \
+                                             
"height=""\\n[www-height]"""></img></p>
 .    \}
 .  \}
 .  el \{\
@@ -687,7 +708,7 @@
 .
 .  nr www-width 1i
 .  nr www-height 1i
-.  ds www-size-specs width=\\n[www-width] height=\\n[www-height]\"
+.  ds www-size-specs width=""\\n[www-width]" height="\\n[www-height]"
 .  ie !'\\$2'' \{\
 .    nr www-is-absolute 0
 .    nr www-absolute 0
@@ -698,13 +719,13 @@
 .      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]\"
+.      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]\"
+.      ds www-size-specs width=\"\\n[www-width]"
 .    \}
 .
 .    nr www-height \\n[www-width]
@@ -718,13 +739,13 @@
 .        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]\"
+.        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]\"
+.        ds www-size-specs "\\*[www-size-specs] "height="\\*[www-height]"
 .      \}
 .    \}
 .  \}
@@ -732,11 +753,11 @@
 .    \" height not specified; use width value
 .    ie !\\n[www-is-absolute] \{\
 .       \" percentage value
-.       ds www-size-specs \\*[www-size-specs] height=\\*[www-percentage]\"
+.       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]\"
+.       ds www-size-specs "\\*[www-size-specs] "height="\\*[www-width]"
 .       nr www-height \\n[www-width]
 .    \}
 .  \}
@@ -745,13 +766,13 @@
 .    ie !\\n[www-image-just] \
 .      HTML <img "src=""\\$1""" \
                  "alt=""Image \\$1""" \
-                 hspace=\\n[www-htmlimage-gap] \
-                 align=right \\*[www-size-specs]>
+                 "hspace=""\\n[www-htmlimage-gap]""" \
+                 "align=""right"" \\*[www-size-specs]"""></img>
 .    el \
 .      HTML <img "src=""\\$1""" \
                  "alt=""Image \\$1""" \
-                 hspace=\\n[www-htmlimage-gap] \
-                 align=left \\*[www-size-specs]>
+                 "hspace=""\\n[www-htmlimage-gap]""" \
+                 "align=""left"" \\*[www-size-specs]"""></img>
 .  \}
 .  el \{\
 .    tm www-width is \\n[www-width]
@@ -851,7 +872,7 @@
 .\"   Produce a horizontal line.
 .\"
 .de HR
-.  HTML</p> <hr>
+.  HTML</p> <hr></hr>
 ..
 .
 .\" --------------------------------------------------------------------
@@ -933,6 +954,7 @@
 .de www-push-li
 .  nr www-depth +1
 .  ds www-level\\n[www-depth] \\$1\"
+.  ds www-ltag\\n[www-depth]
 .  als LI \\$1
 ..
 .
@@ -941,6 +963,18 @@
 .  als LI \\*[www-level\\n[www-depth]]
 ..
 .
+.\" www-emit-ltag - shuts down a previous open list tag
+.\"                 before issuing a new tag \\$1.
+.\"                 It then records tag \\$1 is open.
+.
+.de www-emit-ltag
+.  if !'\\*[www-ltag\\n[www-depth]]'' \
+.    HTML-NS </\\*[www-ltag\\n[www-depth]]>
+.  if !'\\$1'' \
+.    HTML-NS <\\$1>
+.  ds www-ltag\\n[www-depth] \\$1
+..
+.
 .\"
 .\" Auxiliary macro for ULS.
 .\"
@@ -984,11 +1018,12 @@
 .de ULS
 .  www-push-li www-li-ul
 .  www-push-ul-level
-.  ie \\n[www-html] \
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
 .    HTML</p> <ul>
-.  el \{\
-.    nr www-li-indent +\w'\\*[www-ul-level\\n[www-ul-level]]'u
 .  \}
+.  el \
+.    nr www-li-indent +\w'\\*[www-ul-level\\n[www-ul-level]]'u
 ..
 .
 .\" --------------------------------------------------------------------
@@ -997,8 +1032,10 @@
 .\"   End an unordered list.
 .\"
 .de ULE
-.  ie \\n[www-html] \
-.    HTML </ul>
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
+.    HTML</p> </ul>
+.  \}
 .  el \{\
 .    nr www-li-indent -\w'\\*[www-ul-level\\n[www-ul-level]]'u
 .    in \\n[www-li-indent]u
@@ -1015,9 +1052,11 @@
 .de OLS
 .  www-push-li www-li-ol
 .  www-push-ol-level
-.  ie \\n[www-html] \
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
 .    HTML</p> <ol "style=""list-style-type:" \
                            "\\*[www-ol-level\\n[www-ol-level]]"">"
+.  \}
 .  el \
 .    nr www-li-indent +\w'\\*[www-ol-tmp]'u
 ..
@@ -1028,8 +1067,10 @@
 .\"   End an ordered list.
 .\"
 .de OLE
-.  ie \\n[www-html] \
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
 .    HTML </ol>
+.  \}
 .  el \{\
 .    nr www-li-indent -\w'\\*[www-ol-tmp]'u
 .    in \\n[www-li-indent]u
@@ -1047,8 +1088,10 @@
 .de DLS
 .  www-push-li www-li-dl
 .  nr www-dl-level +1
-.  ie \\n[www-html] \
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
 .    HTML</p> <dl>
+.  \}
 .  el \{\
 .    nr www-li-indent +\\n[www-dl-shift]u
 .    in \\n[www-li-indent]u
@@ -1061,8 +1104,10 @@
 .\"   End a definition list.
 .\"
 .de DLE
-.  ie \\n[www-html] \
+.  ie \\n[www-html] \{\
+.    www-emit-ltag
 .    HTML </dl>
+.  \}
 .  el \{\
 .    nr www-li-indent -\\n[www-dl-shift]u
 .    in \\n[www-li-indent]u
@@ -1081,7 +1126,7 @@
 .\"
 .de www-li-ul
 .  ie \\n[www-html] \
-.    HTML-NS <li>
+.    www-emit-ltag li
 .  el \{\
 .    www:paraspace
 .    in \\n[www-li-indent]u
@@ -1095,7 +1140,7 @@
 .\"
 .de www-li-ol
 .  ie \\n[www-html] \
-.    HTML-NS <li>
+.    www-emit-ltag li
 .  el \{\
 .    www:paraspace
 .    in \\n[www-li-indent]u
@@ -1110,7 +1155,7 @@
 .de www-li-dl
 .  ie \\n[www-html] \{\
 .    HTML <dt>\\$1</dt>
-.    HTML-NS <dd>
+.    www-emit-ltag dd
 .  \}
 .  el \{\
 .    www:paraspace
@@ -1179,8 +1224,8 @@
 .\"
 .do if !d TS .do ds TS HTML-IMAGE\"
 .do if !d TE .do ds TE HTML-IMAGE-END\"
-.do if !d EQ .do ds EQ HTML-IMAGE\"
-.do if !d EN .do ds EN HTML-IMAGE-END\"
+.do if !d EQ .do ds EQ EQN-HTML-IMAGE\"
+.do if !d EN .do ds EN EQN-HTML-IMAGE-END\"
 .
 .\"
 .\" supplementary macros used by other macro sets
@@ -1245,6 +1290,61 @@
 .  HTML-DO-IMAGE \\*[www-unique-name] i
 ..
 .
+.\"  EQN-HTML-IMAGE and friends check to see whether the equation is
+.\"                 not in an image, in which case it allows html
+.\"                 (mathml) to be generated (if -Txhtml was specified).
+.
+.de EQN-HTML-IMAGE
+.  \" generates a centered image
+.  www-make-unique-name
+.  EQN-HTML-DO-IMAGE \\*[www-unique-name] c
+..
+.
+.de EQN-HTML-IMAGE-RIGHT
+.  www-make-unique-name
+.  EQN-HTML-DO-IMAGE \\*[www-unique-name] r
+..
+.
+.de EQN-HTML-IMAGE-LEFT
+.  www-make-unique-name
+.  EQN-HTML-DO-IMAGE \\*[www-unique-name] l
+..
+.
+.de EQN-HTML-IMAGE-INLINE
+.  www-make-unique-name
+.  EQN-HTML-DO-IMAGE \\*[www-unique-name] i
+..
+.\" --------------------------------------------------------------------
+.\" EQN-HTML-DO-IMAGE - tells troff to issue an image marker which can be
+.\"                     read back by pre-html
+.\"
+.de EQN-HTML-DO-IMAGE
+.  ie r xhtml \{\
+.    if !(\\n[.O] == 0) \{\
+.      if r ps4html \
+.        nop \O[5\\$2\\$1.png]\O[1]\O[3]
+.      if \\n[www-html] \
+.        nop \O[5\\$2\\$1.png]\O[0]\O[3]
+.    \}
+.  \}
+.  el .HTML-DO-IMAGE \\$*
+..
+.
+.\" --------------------------------------------------------------------
+.\" EQN-HTML-IMAGE-END - terminates an image for html
+.\"
+.de EQN-HTML-IMAGE-END
+.  ie r xhtml \{\
+.    if !(\\n[.O] == 0) \{\
+.      if r ps4html \
+.        nop \O[4]\O[2]\O[0]
+.      if \\n[www-html] \
+.        nop \O[4]\O[2]\O[1]
+.    \}
+.  \}
+.  el .HTML-IMAGE-END
+..
+.
 .\" --------------------------------------------------------------------
 .\" JOBNAME
 .\"
@@ -1389,6 +1489,13 @@
 .  ds www:close \\$2\"
 ..
 .
+.\" MATHML - enable eqn mathml output to pass through to the device
+.\"          driver
+.
+.de MATHML
+.  if (\\n[.O] == 0) .MATH<?p> \\$*
+..
+.
 .\" --------------------------------------------------------------------
 .\" Final Setup
 .\" --------------------------------------------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]