diff options
-rw-r--r-- | ChangeLog | 129 | ||||
-rw-r--r-- | NEWS | 27 | ||||
-rw-r--r-- | doc/groff.texinfo | 215 | ||||
-rw-r--r-- | man/groff_font.man | 31 | ||||
-rw-r--r-- | src/devices/grohtml/grohtml.man | 54 | ||||
-rw-r--r-- | src/devices/grohtml/html-table.cpp | 128 | ||||
-rw-r--r-- | src/devices/grohtml/html-table.h | 6 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.cpp | 35 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.h | 11 | ||||
-rw-r--r-- | src/devices/grohtml/post-html.cpp | 371 | ||||
-rw-r--r-- | src/preproc/eqn/box.cpp | 9 | ||||
-rw-r--r-- | src/preproc/eqn/eqn.h | 1 | ||||
-rw-r--r-- | src/preproc/eqn/main.cpp | 14 | ||||
-rw-r--r-- | src/preproc/eqn/text.cpp | 2 | ||||
-rw-r--r-- | src/preproc/html/pre-html.cpp | 168 | ||||
-rw-r--r-- | src/roff/groff/groff.cpp | 47 | ||||
-rw-r--r-- | src/roff/troff/input.cpp | 1 | ||||
-rw-r--r-- | tmac/s.tmac | 63 | ||||
-rw-r--r-- | tmac/troffrc-end | 21 | ||||
-rw-r--r-- | tmac/www.tmac | 171 |
20 files changed, 1174 insertions, 330 deletions
@@ -1,3 +1,132 @@ +2007-09-19 Gaius Mulley <gaius@glam.ac.uk> + + * 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 <wl@gnu.org> + + * man/groff_font.man: Document `unicode' keyword. + * doc/groff.texinfo (DESC File Format): Synchronize with + groff_font.man. + 2007-09-15 Werner LEMBERG <wl@nu.org> * man/groff.man: Document `\_'. @@ -14,6 +14,16 @@ VERSION 1.19.3 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. @@ -63,6 +73,9 @@ o The PS font definition files have been regenerated with newer AFM versions 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 @@ Eqn 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 @@ Grotty 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 --------- diff --git a/doc/groff.texinfo b/doc/groff.texinfo index 06b43c42..a883be17 100644 --- a/doc/groff.texinfo +++ b/doc/groff.texinfo @@ -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 @@ Software Foundation raise funds for GNU development.'' @title groff @subtitle The GNU implementation of @code{troff} @subtitle Edition 1.19.3 -@subtitle Summer 2006 +@subtitle Autumn 2007 @author by Trent A.@tie{}Fisher @author and Werner Lemberg (@email{bug-groff@@gnu.org}) @@ -553,7 +554,7 @@ Software Foundation raise funds for GNU development.'' @chapter Introduction @cindex introduction -GNU @code{troff} (or @code{groff}) is a system for typesetting documents. +GNU @code{troff} (or @code{groff}) is a system for typesetting documents. @code{troff} is very flexible and has been used extensively for some thirty years. It is well entrenched in the @acronym{UNIX} community. @@ -4019,7 +4020,7 @@ The @code{PT} macro defines a custom header; the @code{BT} macro defines a custom footer. These macros must handle odd/even/first page differences if necessary. -The @code{HD} macro defines additional header processing +The @code{HD} macro defines additional header processing to take place after executing the @code{PT} macro. @endDefmac @@ -4386,7 +4387,7 @@ number register. Emulations of a few ancient Bell Labs macros can be re-enabled by calling the otherwise undocumented @code{SC} section-header macro. Calling @code{SC} -enables @code{UC} for marking up a product or application name, and the pair +enables @code{UC} for marking up a product or application name, and the pair @code{P1}/@code{P2} for surrounding code example displays. These are not enabled by default because (a)@tie{}they were not documented, @@ -6472,6 +6473,11 @@ If the command line option @option{-a} is used to produce an @acronym{ASCII} approximation of the output, this is set to@tie{}1, zero otherwise. @xref{Groff Options}. +@item \n[.O] +@vindex .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 to@tie{}1 (and to@tie{}0 otherwise) if the current @@ -7187,7 +7193,7 @@ page: @endExample @noindent -A call to @samp{.y-from-bot-up 10c} means that the bottom of the next line +A call to @samp{.y-from-bot-up 10c} means that the bottom of the next line will be at 10@dmn{cm} from the paper edge at the bottom. If a vertical trap is sprung during execution of @code{sp}, the amount of @@ -12854,9 +12860,13 @@ to @code{\O}. @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}. +@xref{Built-in Registers}. @item \O4 End a nesting level. +The current level is contained within the read-only register @code{.O}. +@xref{Built-in Registers}. @item \O[5@var{P}@var{filename}] This escape is @code{grohtml} specific. Provided that this escape @@ -15670,14 +15680,25 @@ called@tie{}@file{@var{f}}. 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 -@item res @var{n} -@kindex res -@cindex device resolution -@cindex resolution, device -There are @var{n}@tie{}machine units per inch. +@item charset +@kindex charset +This line and everything following in the file are ignored. It is +allowed for the sake of backwards compatibility. + +@item family @var{fam} +@kindex family +The default font family is @var{fam}. + +@item fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn} +@kindex fonts +Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions +@var{m}+1, @dots{}, @var{m}+@var{n} where @var{m} is the number of +styles. This command may extend over more than one line. A font name +of@tie{}0 means no font is mounted on the corresponding font position. @item hor @var{n} @kindex hor @@ -15686,29 +15707,54 @@ There are @var{n}@tie{}machine units per inch. The horizontal resolution is @var{n}@tie{}machine units. All horizontal quantities are rounded to be multiples of this value. -@item vert @var{n} -@kindex vert -@cindex vertical resolution -@cindex resolution, vertical -The vertical resolution is @var{n}@tie{}machine units. All vertical -quantities are rounded to be multiples of this value. +@item image_generator @var{string} +@kindex image_generator +@cindex PostScript, PNG image generation +@cindex 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 +@code{gs} but under other systems (notably cygwin) it might be set to +another name. + +@item paperlength @var{n} +@kindex 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. -@item sizescale @var{n} -@kindex sizescale -The scale factor for point sizes. By default this has a value of@tie{}1. -One scaled point is equal to one point/@var{n}. The arguments to the -@code{unitwidth} and @code{sizes} commands are given in scaled points. -@xref{Fractional Type Sizes}, for more information. +@item papersize @var{string} @dots{} +@kindex papersize +Select a paper size. Valid values for @var{string} are the ISO paper +types @code{A0}-@code{A7}, @code{B0}-@code{B7}, @code{C0}-@code{C7}, +@code{D0}-@code{D7}, @code{DL}, and the US paper types @code{letter}, +@code{legal}, @code{tabloid}, @code{ledger}, @code{statement}, +@code{executive}, @code{com10}, and @code{monarch}. Case is not significant +for @var{string} if it holds predefined paper types. Alternatively, +@var{string} 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 +@code{@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 +@samp{P} 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. -@item unitwidth @var{n} -@kindex unitwidth -Quantities in the font files are given in machine units for fonts whose -point size is @var{n}@tie{}scaled points. +More than one argument can be specified; @code{groff} scans from left to +right and uses the first valid paper specification. -@item prepro @var{program} -@kindex prepro -Call @var{program} as a preprocessor. Currently, this keyword is used -by @code{groff} with option @option{-Thtml} only. +@item paperwidth @var{n} +@kindex 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. + +@item pass_filenames +@kindex pass_filenames +Tell @code{gtroff} to emit the name of the source file currently +being processed. This is achieved by the intermediate output command +@samp{F}. Currently, this is only used by the @acronym{HTML} output +device. @item postpro @var{program} @kindex postpro @@ -15722,10 +15768,21 @@ postpro grodvi in the file @file{devdvi/DESC} makes @code{groff} call @code{grodvi} if option @option{-Tdvi} is given (and @option{-Z} isn't used). -@item tcommand -@kindex tcommand -This means that the postprocessor can handle the @samp{t} and @samp{u} -intermediate output commands. +@item prepro @var{program} +@kindex prepro +Call @var{program} as a preprocessor. Currently, this keyword is used +by @code{groff} with option @option{-Thtml} only. + +@item print @var{program} +@kindex print +Use @var{program} as a spooler program for printing. If omitted, +the @option{-l} and @option{-L} options of @code{groff} are ignored. + +@item res @var{n} +@kindex res +@cindex device resolution +@cindex resolution, device +There are @var{n}@tie{}machine units per inch. @item sizes @var{s1} @var{s2} @dots{} @var{sn} 0 @kindex sizes @@ -15734,65 +15791,59 @@ This means that the device has fonts at @var{s1}, @var{s2}, @dots{} (this is digit zero). Each @var{si} can also be a range of sizes @var{m}-@var{n}. The list can extend over more than one line. +@item sizescale @var{n} +@kindex sizescale +The scale factor for point sizes. By default this has a value of@tie{}1. +One scaled point is equal to one point/@var{n}. The arguments to the +@code{unitwidth} and @code{sizes} commands are given in scaled points. +@xref{Fractional Type Sizes}, for more information. + @item styles @var{S1} @var{S2} @dots{} @var{Sm} @kindex styles The first @var{m}@tie{}font positions are associated with styles @var{S1} @dots{} @var{Sm}. -@item fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn} -@kindex fonts -Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions -@var{m}+1, @dots{}, @var{m}+@var{n} where @var{m} is the number of -styles. This command may extend over more than one line. A font name -of@tie{}0 means no font is mounted on the corresponding font position. +@item tcommand +@kindex tcommand +This means that the postprocessor can handle the @samp{t} and @samp{u} +intermediate output commands. -@item family @var{fam} -@kindex family -The default font family is @var{fam}. +@item unicode +@kindex 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 +@code{groff} is used. However, if there are entries in a +@code{charset} 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}. +@item unitwidth @var{n} +@kindex unitwidth +Quantities in the font files are given in machine units for fonts whose +point size is @var{n}@tie{}scaled points. + +@item unscaled_charwidths +@kindex 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}. -@item papersize @var{string} @dots{} -@kindex papersize -Select a paper size. Valid values for @var{string} are the ISO paper -types @code{A0}-@code{A7}, @code{B0}-@code{B7}, @code{C0}-@code{C7}, -@code{D0}-@code{D7}, @code{DL}, and the US paper types @code{letter}, -@code{legal}, @code{tabloid}, @code{ledger}, @code{statement}, -@code{executive}, @code{com10}, and @code{monarch}. Case is not significant -for @var{string} if it holds predefined paper types. Alternatively, -@var{string} 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 -@code{@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 -@samp{P} 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. - -@item pass_filenames -@kindex pass_filenames -Tell @code{gtroff} to emit the name of the source file currently -being processed. This is achieved by the intermediate output command -@samp{F}. Currently, this is only used by the @acronym{HTML} output -device. - -@item print @var{program} -@kindex print -Use @var{program} as a spooler program for printing. If omitted, -the @option{-l} and @option{-L} options of @code{groff} are ignored. - -@item charset -@kindex charset -This line and everything following in the file are ignored. It is -allowed for the sake of backwards compatibility. +@item vert @var{n} +@kindex vert +@cindex vertical resolution +@cindex resolution, vertical +The vertical resolution is @var{n}@tie{}machine 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 diff --git a/man/groff_font.man b/man/groff_font.man index e6ef8d38..679bf7ab 100644 --- a/man/groff_font.man +++ b/man/groff_font.man @@ -287,6 +287,37 @@ and 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 diff --git a/src/devices/grohtml/grohtml.man b/src/devices/grohtml/grohtml.man index a4d4ece0..d1c6d28c 100644 --- a/src/devices/grohtml/grohtml.man +++ b/src/devices/grohtml/grohtml.man @@ -1,5 +1,5 @@ .ig -Copyright (C) 1999-2000, 2001, 2002, 2003, 2004, 2006 +Copyright (C) 1999-2000, 2001, 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this @@ -58,6 +58,7 @@ grohtml \- html driver for groff .OP \-o \%image-vertical-offset .OP \-s size .OP \-S level +.OP \-x \%html-dialect .RI "[\ " files\|.\|.\|. "\ ]" .br .ad \na @@ -130,6 +131,24 @@ to place all image files into directory .IR dir . . .TP +.B \-e +This option should not be directly invoked by the user as it is +an internal option utilized by +.B groff +when +.B \-Thtml +or +.B \-Txhtml +is specified. +It is used by the +.B grohtml +preprocessor to determine whether +.B eqn +should attempt to produce MathML (if +.B \-Txhtml +is specified). +. +.TP .BI \-F dir Prepend directory .IB dir /dev name @@ -241,6 +260,39 @@ split at the heading level (or higher) defined by .B \-v Print the version number. . +.TP +.B \-V +Create an XHTML validator button at the bottom of each page of +the document. +. +.TP +.BI \-x dialect +Select HTML dialect. +Currently, +.I dialect +should be either the digit\~\c +.B 4 +or the letter\~\c +.B x +which indicates whether +.B grohtml +should generate HTML\~4 or XHTML, respectively. +This option should not be directly invoked by the user as it is +an internal option utilized by +.B groff +when +.B \-Thtml +or +.B \-Txhtml +is specified. +. +.TP +.B \-y +Produce a right-justified groff signature at the end of the document. +This is only generated if the +.B \-V +flag is also specified. +. . .SH USAGE There are styles called diff --git a/src/devices/grohtml/html-table.cpp b/src/devices/grohtml/html-table.cpp index 7e5b2dc5..c752b766 100644 --- a/src/devices/grohtml/html-table.cpp +++ b/src/devices/grohtml/html-table.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-table.cpp * @@ -41,6 +41,9 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ # define FALSE (1==0) #endif +extern html_dialect dialect; + + tabs::tabs () : tab(NULL) { @@ -294,7 +297,7 @@ void html_table::set_linelength (int linelen) } p = c; } - if (p != NULL && p->right > 0) + if (p != NULL && p->right > 0 && linelength > p->right) add_column(p->no+1, p->right, linelength, 'L'); } @@ -337,10 +340,12 @@ void html_table::emit_table_header (int space) out->nl(); out->put_string("<table width=\"100%\"") - .put_string(" border=0 rules=\"none\" frame=\"void\"\n") + .put_string(" border=\"0\" rules=\"none\" frame=\"void\"\n") .put_string(" cellspacing=\"0\" cellpadding=\"0\""); out->put_string(">") .nl(); + if (dialect == xhtml) + emit_colspan(); out->put_string("<tr valign=\"top\" align=\"left\""); if (space) { out->put_string(" style=\"margin-top: "); @@ -375,6 +380,82 @@ void html_table::set_space (int space) } /* + * emit_colspan - emits a series of colspan entries defining the + * table columns. + */ + +void html_table::emit_colspan (void) +{ + cols *b = columns; + cols *c = columns; + int width = 0; + + out->put_string("<colgroup>"); + while (c != NULL) { + if (b != NULL && b != c && is_gap(b)) + /* + * blank column for gap + */ + out->put_string("<col width=\"") + .put_number(is_gap(b)) + .put_string("%\" class=\"center\"></col>") + .nl(); + + width = (get_right(c)*100 + get_effective_linelength()/2) + / get_effective_linelength() + - (c->left*100 + get_effective_linelength()/2) + /get_effective_linelength(); + switch (c->alignment) { + case 'C': + out->put_string("<col width=\"") + .put_number(width) + .put_string("%\" class=\"center\"></col>") + .nl(); + break; + case 'R': + out->put_string("<col width=\"") + .put_number(width) + .put_string("%\" class=\"right\"></col>") + .nl(); + break; + default: + out->put_string("<col width=\"") + .put_number(width) + .put_string("%\"></col>") + .nl(); + } + b = c; + c = c->next; + } + out->put_string("</colgroup>").nl(); +} + +/* + * emit_td - writes out a <td> tag with a corresponding width + * if the dialect is html4. + */ + +void html_table::emit_td (int percentage, const char *s) +{ + if (percentage) { + if (dialect == html4) { + out->put_string("<td width=\"") + .put_number(percentage) + .put_string("%\""); + if (s != NULL) + out->put_string(s); + out->nl(); + } + else { + out->put_string("<td"); + if (s != NULL) + out->put_string(s); + out->nl(); + } + } +} + +/* * emit_col - moves onto column, n. */ @@ -405,11 +486,7 @@ void html_table::emit_col (int n) // have we a gap? if (last_col != NULL) { - if (is_gap(b)) - out->put_string("<td width=\"") - .put_number(is_gap(b)) - .put_string("%\"></td>") - .nl(); + emit_td(is_gap(b), "></td>"); b = b->next; } @@ -421,17 +498,9 @@ void html_table::emit_col (int n) / get_effective_linelength() - (b->left*100 + get_effective_linelength()/2) /get_effective_linelength(); - if (width) - out->put_string("<td width=\"") - .put_number(width) - .put_string("%\"></td>") - .nl(); + emit_td(width, "></td>"); // have we a gap? - if (is_gap(b)) - out->put_string("<td width=\"") - .put_number(is_gap(b)) - .put_string("%\"></td>") - .nl(); + emit_td(is_gap(b), "></td>"); b = b->next; } width = (get_right(b)*100 + get_effective_linelength()/2) @@ -440,22 +509,13 @@ void html_table::emit_col (int n) /get_effective_linelength(); switch (b->alignment) { case 'C': - out->put_string("<td width=\"") - .put_number(width) - .put_string("%\" align=center>") - .nl(); + emit_td(width, " align=center>"); break; case 'R': - out->put_string("<td width=\"") - .put_number(width) - .put_string("%\" align=right>") - .nl(); + emit_td(width, " align=right>"); break; default: - out->put_string("<td width=\"") - .put_number(width) - .put_string("%\">") - .nl(); + emit_td(width); } // remember column, b last_col = b; @@ -477,7 +537,13 @@ void html_table::finish_row (void) if (n > 0) emit_col(n); - out->put_string("</td>").nl(); +#if 1 + if (last_col != NULL) { + out->put_string("</td>"); + last_col = NULL; + } +#endif + out->put_string("</tr>").nl(); } } diff --git a/src/devices/grohtml/html-table.h b/src/devices/grohtml/html-table.h index dc6cebe2..5f1cfe56 100644 --- a/src/devices/grohtml/html-table.h +++ b/src/devices/grohtml/html-table.h @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-table.h * @@ -93,6 +93,8 @@ public: void finish_row (void); int get_effective_linelength (void); void set_space (int space); + void emit_colspan (void); + void emit_td (int percentage, const char *s = ">"); tabs *tab_stops; /* tab stop positions */ simple_output *out; @@ -121,7 +123,7 @@ public: // the indent is shutdown when it is deleted private: - void end (void); + void end (void); int is_used; int pg; // values of the registers as passed via initialization int ll; diff --git a/src/devices/grohtml/html-text.cpp b/src/devices/grohtml/html-text.cpp index b58d5e4a..f2b36025 100644 --- a/src/devices/grohtml/html-text.cpp +++ b/src/devices/grohtml/html-text.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-text.cpp @@ -44,10 +44,11 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ #undef DEBUGGING // #define DEBUGGING -html_text::html_text (simple_output *op) : - stackptr(NULL), lastptr(NULL), out(op), space_emitted(TRUE), - current_indentation(-1), pageoffset(-1), linelength(-1), - blank_para(TRUE), start_space(FALSE) +html_text::html_text (simple_output *op, html_dialect d) : + stackptr(NULL), lastptr(NULL), out(op), dialect(d), + space_emitted(TRUE), current_indentation(-1), + pageoffset(-1), linelength(-1), blank_para(TRUE), + start_space(FALSE) { } @@ -165,8 +166,12 @@ void html_text::end_tag (tag_definition *t) delete t->indent; t->indent = NULL; break; - case SMALL_TAG: out->put_string("</small>"); break; - case BIG_TAG: out->put_string("</big>"); break; + case SMALL_TAG: if (dialect != xhtml || (! is_in_pre ())) + out->put_string("</small>"); + break; + case BIG_TAG: if (dialect != xhtml || (! is_in_pre ())) + out->put_string("</big>"); + break; case COLOR_TAG: out->put_string("</font>"); break; default: @@ -196,8 +201,10 @@ void html_text::issue_tag (const char *tagname, const char *arg, out->put_string(STYLE_VERTICAL_SPACE); out->put_string("\""); } +#if 0 if (space == TRUE || space == FALSE) out->put_string(" valign=\"top\""); +#endif out->put_string(">"); } @@ -258,8 +265,12 @@ void html_text::start_tag (tag_definition *t) issue_tag("", (char *)t->arg1); } out->enable_newlines(FALSE); break; - case SMALL_TAG: issue_tag("<small", (char *)t->arg1); break; - case BIG_TAG: issue_tag("<big", (char *)t->arg1); break; + case SMALL_TAG: if (dialect != xhtml || (! is_in_pre ())) + issue_tag("<small", (char *)t->arg1); + break; + case BIG_TAG: if (dialect != xhtml || (! is_in_pre ())) + issue_tag("<big", (char *)t->arg1); + break; case BREAK_TAG: break; case COLOR_TAG: issue_color_begin(&t->col); break; @@ -652,9 +663,11 @@ void html_text::do_emittext (const char *s, int length) int text = remove_break(); check_emit_text(stackptr); if (text) { - if (is_present(PRE_TAG)) { + if (is_present(PRE_TAG)) out->nl(); - } else + else if (dialect == xhtml) + out->put_string("<br/>").nl(); + else out->put_string("<br>").nl(); } } else diff --git a/src/devices/grohtml/html-text.h b/src/devices/grohtml/html-text.h index e0e3cc75..d6e11cd8 100644 --- a/src/devices/grohtml/html-text.h +++ b/src/devices/grohtml/html-text.h @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote html-text.h @@ -32,6 +32,12 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ #define STYLE_VERTICAL_SPACE "1em" /* + * supported html dialects. + */ + +typedef enum {xhtml, html4} html_dialect; + +/* * html tags */ @@ -56,7 +62,7 @@ typedef struct tag_definition { class html_text { public: - html_text (simple_output *op); + html_text (simple_output *op, html_dialect d); ~html_text (void); void flush_text (void); void do_emittext (const char *s, int length); @@ -105,6 +111,7 @@ private: tag_definition *stackptr; /* the current paragraph state */ tag_definition *lastptr; /* the end of the stack */ simple_output *out; + html_dialect dialect; /* which dialect of html? */ int space_emitted; /* just emitted a space? */ int current_indentation; /* current .in value */ int pageoffset; /* .po value */ diff --git a/src/devices/grohtml/post-html.cpp b/src/devices/grohtml/post-html.cpp index 3d93dc72..4a6e0cbc 100644 --- a/src/devices/grohtml/post-html.cpp +++ b/src/devices/grohtml/post-html.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 +/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * Free Software Foundation, Inc. * * Gaius Mulley (gaius@glam.ac.uk) wrote post-html.cpp @@ -90,6 +90,10 @@ static int base_point_size = 0; /* which troff font size ma static int split_level = 2; /* what heading level to split at? */ static string head_info; /* user supplied information to be placed */ /* into <head> </head> */ +static int valid_flag = FALSE; /* has user requested a valid flag at the */ + /* end of each page? */ +static int groff_sig = FALSE; /* "This document was produced using" */ +html_dialect dialect = html4; /* which html dialect should grohtml output */ /* @@ -1570,6 +1574,8 @@ void header_desc::write_headings (FILE *f, int force) headers.start_from_head(); header_filename.start_from_head(); + if (dialect == xhtml) + fputs("<p>", f); do { g = headers.get_data(); fputs("<a href=\"", f); @@ -1589,12 +1595,18 @@ void header_desc::write_headings (FILE *f, int force) h++; fputs("\">", f); fputs(g->text_string, f); - fputs("</a><br>\n", f); + fputs("</a>", f); + if (dialect == xhtml) + fputs("<br/>\n", f); + else + fputs("<br>\n", f); headers.move_right(); if (multiple_files && (! header_filename.is_empty())) header_filename.move_right(); } while (! headers.is_equal_to_head()); fputs("\n", f); + if (dialect == xhtml) + fputs("</p>\n", f); } } } @@ -2091,6 +2103,10 @@ class html_printer : public printer { int round_width (int x); void handle_tag_within_title (text_glob *g); void writeHeadMetaStyle (void); + void handle_valid_flag (void); + void do_math (text_glob *g); + void write_html_anchor (text_glob *h); + void write_xhtml_anchor (text_glob *h); // ADD HERE public: @@ -2167,7 +2183,10 @@ void html_printer::end_of_line() void html_printer::emit_line (text_glob *) { // --fixme-- needs to know the length in percentage - html.put_string("<hr>"); + if (dialect == xhtml) + html.put_string("<hr/>"); + else + html.put_string("<hr>"); } /* @@ -2206,13 +2225,22 @@ void html_printer::emit_raw (text_glob *g) switch (next_tag) { case CENTERED: - current_paragraph->do_para("align=center", space); + if (dialect == html4) + current_paragraph->do_para("align=\"center\"", space); + else + current_paragraph->do_para("class=\"center\"", space); break; case LEFT: - current_paragraph->do_para(&html, "align=left", get_troff_indent(), pageoffset, linelength, space); + if (dialect == html4) + current_paragraph->do_para(&html, "align=\"left\"", get_troff_indent(), pageoffset, linelength, space); + else + current_paragraph->do_para(&html, "class=\"left\"", get_troff_indent(), pageoffset, linelength, space); break; case RIGHT: - current_paragraph->do_para(&html, "align=right", get_troff_indent(), pageoffset, linelength, space); + if (dialect == html4) + current_paragraph->do_para(&html, "align=\"right\"", get_troff_indent(), pageoffset, linelength, space); + else + current_paragraph->do_para(&html, "class=\"right\"", get_troff_indent(), pageoffset, linelength, space); break; default: fatal("unknown enumeration"); @@ -2308,9 +2336,12 @@ static string &generate_img_src (const char *filename) while (filename && (filename[0] == ' ')) { filename++; } - if (exists(filename)) + if (exists(filename)) { *s += string("<img src=\"") + filename + "\" " + "alt=\"Image " + filename + "\">"; + if (dialect == xhtml) + *s += "</img>"; + } return *s; } @@ -2409,14 +2440,60 @@ void html_printer::do_title (void) } } +/* + * write_html_anchor - writes out an anchor. The style of the anchor + * dependent upon simple_anchor. + */ + +void html_printer::write_html_anchor (text_glob *h) +{ + if (dialect == html4) { + if (h != NULL) { + html.put_string("<a name=\""); + if (simple_anchors) { + string buffer(ANCHOR_TEMPLATE); + + buffer += as_string(header.no_of_headings); + buffer += '\0'; + html.put_string(buffer.contents()); + } else + html.put_string(header.header_buffer); + html.put_string("\"></a>").nl(); + } + } +} + +/* + * write_xhtml_anchor - writes out an anchor. The style of the anchor + * dependent upon simple_anchor. + */ + +void html_printer::write_xhtml_anchor (text_glob *h) +{ + if (dialect == xhtml) { + if (h != NULL) { + html.put_string(" id=\""); + if (simple_anchors) { + string buffer(ANCHOR_TEMPLATE); + + buffer += as_string(header.no_of_headings); + buffer += '\0'; + html.put_string(buffer.contents()); + } else + html.put_string(header.header_buffer); + html.put_string("\""); + } + } +} + void html_printer::write_header (void) { if (! header.header_buffer.empty()) { + text_glob *a = NULL; int space = current_paragraph->retrieve_para_space() || seen_space; - if (header.header_level > 7) { + if (header.header_level > 7) header.header_level = 7; - } // firstly we must terminate any font and type faces current_paragraph->done_para(); @@ -2427,33 +2504,22 @@ void html_printer::write_header (void) header.no_of_headings++; style st; - text_glob *h=new text_glob(); - h->text_glob_html(&st, + a = new text_glob(); + a->text_glob_html(&st, header.headings.add_string(header.header_buffer), header.header_buffer.length(), header.no_of_headings, header.header_level, header.no_of_headings, header.header_level); - header.headers.add(h, + // and add this header to the header list + header.headers.add(a, header.no_of_headings, header.no_of_headings, header.no_of_headings, - header.no_of_headings, header.no_of_headings); // and add this header to the header list - - // lastly we generate a tag - - html.nl().nl().put_string("<a name=\""); - if (simple_anchors) { - string buffer(ANCHOR_TEMPLATE); - - buffer += as_string(header.no_of_headings); - buffer += '\0'; - html.put_string(buffer.contents()); - } else { - html.put_string(header.header_buffer); - } - html.put_string("\"></a>").nl(); + header.no_of_headings, header.no_of_headings); } + html.nl().nl(); + if (manufacture_headings) { // line break before a header if (!current_paragraph->emitted_text()) @@ -2462,11 +2528,14 @@ void html_printer::write_header (void) if (header.header_level<4) { html.put_string("<b><font size=\"+1\">"); html.put_string(header.header_buffer); - html.put_string("</font></b>").nl(); + html.put_string("</font>").nl(); + write_html_anchor(a); + html.put_string("</b>").nl(); } else { html.put_string("<b>"); - html.put_string(header.header_buffer); + html.put_string(header.header_buffer).nl(); + write_html_anchor(a); html.put_string("</b>").nl(); } } @@ -2474,8 +2543,10 @@ void html_printer::write_header (void) // and now we issue the real header html.put_string("<h"); html.put_number(header.header_level); + write_xhtml_anchor(a); html.put_string(">"); - html.put_string(header.header_buffer); + html.put_string(header.header_buffer).nl(); + write_html_anchor(a); html.put_string("</h"); html.put_number(header.header_level); html.put_string(">").nl(); @@ -2810,10 +2881,15 @@ void html_printer::do_check_center(void) int space = current_paragraph->retrieve_para_space() || seen_space; current_paragraph->done_para(); supress_sub_sup = TRUE; - current_paragraph->do_para("align=center", space); + if (dialect == html4) + current_paragraph->do_para("align=\"center\"", space); + else + current_paragraph->do_para("class=\"center\"", space); } else - if (strcmp("align=center", - current_paragraph->get_alignment()) != 0) { + if ((strcmp("align=\"center\"", + current_paragraph->get_alignment()) != 0) && + (strcmp("class=\"center\"", + current_paragraph->get_alignment()) != 0)) { /* * different alignment, so shutdown paragraph and open * a new one. @@ -2821,7 +2897,10 @@ void html_printer::do_check_center(void) int space = current_paragraph->retrieve_para_space() || seen_space; current_paragraph->done_para(); supress_sub_sup = TRUE; - current_paragraph->do_para("align=center", space); + if (dialect == html4) + current_paragraph->do_para("align=\"center\"", space); + else + current_paragraph->do_para("class=\"center\"", space); } else /* * same alignment, if we have emitted text then issue a break. @@ -2898,7 +2977,10 @@ void html_printer::insert_split_file (void) split_file += string("-"); split_file += as_string(header.no_of_level_one_headings); - split_file += string(".html"); + if (dialect == xhtml) + split_file += string(".xhtml"); + else + split_file += string(".html"); split_file += '\0'; file_list.set_file_name(split_file); @@ -3092,9 +3174,15 @@ void html_printer::troff_tag (text_glob *g) * firstly skip over devtag: */ char *t=(char *)g->text_string+strlen("devtag:"); - if (strncmp(g->text_string, "html</p>:", strlen("html</p>:")) == 0) { do_end_para(g); + } else if (strncmp(g->text_string, "html<?p>:", strlen("html<?p>:")) == 0) { + if (current_paragraph->emitted_text()) + html.put_string(g->text_string+9); + else + do_end_para(g); + } else if (strncmp(g->text_string, "math<?p>:", strlen("math<?p>:")) == 0) { + do_math(g); } else if (g->is_eol()) { do_eol(); } else if (g->is_eol_ce()) { @@ -3177,6 +3265,19 @@ void html_printer::troff_tag (text_glob *g) } /* + * do_math - prints out the equation + */ + +void html_printer::do_math (text_glob *g) +{ + do_font(g); + if (current_paragraph->emitted_text()) + html.put_string(g->text_string+9); + else + do_end_para(g); +} + +/* * is_in_middle - returns TRUE if the positions left..right are in the center of the page. */ @@ -4720,7 +4821,10 @@ void html_printer::write_title (int in_head) } else { title.has_been_written = TRUE; if (title.with_h1) { - html.put_string("<h1 align=center>"); + if (dialect == xhtml) + html.put_string("<h1>"); + else + html.put_string("<h1 align=\"center\">"); html.put_string(title.text); html.put_string("</h1>").nl().nl(); } @@ -4737,8 +4841,12 @@ void html_printer::write_title (int in_head) static void write_rule (void) { - if (auto_rule) - fputs("<hr>\n", stdout); + if (auto_rule) { + if (dialect == xhtml) + fputs("<hr/>\n", stdout); + else + fputs("<hr>\n", stdout); + } } void html_printer::begin_page(int n) @@ -4757,7 +4865,7 @@ void html_printer::begin_page(int n) output_hpos = -1; output_vpos = -1; output_vpos_max = -1; - current_paragraph = new html_text(&html); + current_paragraph = new html_text(&html, dialect); do_indent(get_troff_indent(), pageoffset, linelength); current_paragraph->do_para("", FALSE); } @@ -4815,7 +4923,13 @@ void html_printer::write_navigation (const string &top, const string &prev, int need_bar = FALSE; if (multiple_files) { + current_paragraph->done_para(); write_rule(); + if (groff_sig) + fputs("\n\n<table width=\"100%\" border=\"0\" rules=\"none\"\n" + "frame=\"void\" cellspacing=\"1\" cellpadding=\"0\">\n" + "<colgroup><col class=\"left\"></col><col class=\"right\"></col></colgroup>\n" + "<tr><td class=\"left\">", stdout); fputs("[ ", stdout); if ((strcmp(prev.contents(), "") != 0) && prev != top && prev != current) { emit_link(prev, "prev"); @@ -4833,6 +4947,16 @@ void html_printer::write_navigation (const string &top, const string &prev, emit_link(top, "top"); } fputs(" ]\n", stdout); + handle_valid_flag(); + + if (groff_sig) { + fputs("</td><td class=\"right\"><i><small>" + "This document was produced using " + "<a href=\"http://www.gnu.org/software/groff/\">" + "groff-", stdout); + fputs(Version_string, stdout); + fputs("</a>.</small></i></td></tr></table>\n", stdout); + } write_rule(); } } @@ -4857,7 +4981,10 @@ void html_printer::do_file_components (void) file_list.start_of_list(); top = string(job_name); - top += string(".html"); + if (dialect == xhtml) + top += string(".xhtml"); + else + top += string(".html"); top += '\0'; next = file_list.next_file_name(); next += '\0'; @@ -4870,6 +4997,12 @@ void html_printer::do_file_components (void) file_list.move_next(); if (file_list.is_new_output_file()) { +#ifdef LONG_FOR_TIME_T + long t; +#else + time_t t; +#endif + if (fragment_no > 1) write_navigation(top, prev, next, current); prev = current; @@ -4881,7 +5014,27 @@ void html_printer::do_file_components (void) fflush(stdout); freopen(split_file.contents(), "w", stdout); fragment_no++; - writeHeadMetaStyle(); + if (dialect == xhtml) + writeHeadMetaStyle(); + + html.begin_comment("Creator : ") + .put_string("groff ") + .put_string("version ") + .put_string(Version_string) + .end_comment(); + + t = time(0); + html.begin_comment("CreationDate: ") + .put_string(ctime(&t), strlen(ctime(&t))-1) + .end_comment(); + + if (dialect == html4) + writeHeadMetaStyle(); + + html.put_string("<title>"); + html.put_string(split_file.contents()); + html.put_string("</title>").nl().nl(); + fputs(head_info.contents(), stdout); fputs("</head>\n", stdout); write_navigation(top, prev, next, current); @@ -4891,8 +5044,27 @@ void html_printer::do_file_components (void) } if (fragment_no > 1) write_navigation(top, prev, next, current); - else + else { + current_paragraph->done_para(); write_rule(); + if (valid_flag && dialect == xhtml) { + if (groff_sig) + fputs("\n\n<table width=\"100%\" border=\"0\" rules=\"none\"\n" + "frame=\"void\" cellspacing=\"1\" cellpadding=\"0\">\n" + "<colgroup><col class=\"left\"></col><col class=\"right\"></col></colgroup>\n" + "<tr><td class=\"left\">", stdout); + handle_valid_flag(); + if (groff_sig) { + fputs("</td><td class=\"right\"><i><small>" + "This document was produced using " + "<a href=\"http://www.gnu.org/software/groff/\">" + "groff-", stdout); + fputs(Version_string, stdout); + fputs("</a>.</small></i></td></tr></table>\n", stdout); + } + write_rule(); + } + } } /* @@ -4902,21 +5074,43 @@ void html_printer::do_file_components (void) void html_printer::writeHeadMetaStyle (void) { - fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n", stdout); - fputs("\"http://www.w3.org/TR/html4/loose.dtd\">\n", stdout); - - fputs("<html>\n", stdout); - fputs("<head>\n", stdout); - fputs("<meta name=\"generator\" " - "content=\"groff -Thtml, see www.gnu.org\">\n", stdout); - fputs("<meta http-equiv=\"Content-Type\" " - "content=\"text/html; charset=US-ASCII\">\n", stdout); - fputs("<meta name=\"Content-Style\" content=\"text/css\">\n", stdout); - - fputs("<style type=\"text/css\">\n", stdout); - fputs(" p { margin-top: 0; margin-bottom: 0; }\n", stdout); - fputs(" pre { margin-top: 0; margin-bottom: 0; }\n", stdout); - fputs(" table { margin-top: 0; margin-bottom: 0; }\n", stdout); + if (dialect == html4) { + fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n", stdout); + fputs("\"http://www.w3.org/TR/html4/loose.dtd\">\n", stdout); + fputs("<html>\n", stdout); + fputs("<head>\n", stdout); + fputs("<meta name=\"generator\" " + "content=\"groff -Thtml, see www.gnu.org\">\n", stdout); + fputs("<meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=US-ASCII\">\n", stdout); + fputs("<meta name=\"Content-Style\" content=\"text/css\">\n", stdout); + fputs("<style type=\"text/css\">\n", stdout); + } + else { + fputs("<?xml version=\"1.0\" encoding=\"us-ascii\"?>\n", stdout); + fputs("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN\"\n", stdout); + fputs(" \"http://www.w3.org/TR/MathML2/dtd/xhtml-math11-f.dtd\"\n", stdout); + fputs(" [<!ENTITY mathml \"http://www.w3.org/1998/Math/MathML\">]>\n", stdout); + + fputs("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n", + stdout); + fputs("<head>\n", stdout); + fputs("<meta name=\"generator\" " + "content=\"groff -Txhtml, see www.gnu.org\"/>\n", stdout); + fputs("<meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=US-ASCII\"/>\n", stdout); + fputs("<meta name=\"Content-Style\" content=\"text/css\"/>\n", stdout); + fputs("<style type=\"text/css\">\n", stdout); + fputs(" .center { text-align: center }\n", stdout); + fputs(" .right { text-align: right }\n", stdout); + } + fputs(" p { margin-top: 0; margin-bottom: 0; " + "vertical-align=\"top\" }\n", stdout); + fputs(" pre { margin-top: 0; margin-bottom: 0; " + "vertical-align=\"top\" }\n", stdout); + fputs(" table { margin-top: 0; margin-bottom: 0; " + "vertical-align=\"top\" }\n", stdout); + fputs(" h1 { text-align: center }\n", stdout); fputs("</style>\n", stdout); } @@ -4932,6 +5126,10 @@ html_printer::~html_printer() current_paragraph->flush_text(); html.end_line(); html.set_file(stdout); + + if (dialect == xhtml) + writeHeadMetaStyle(); + html.begin_comment("Creator : ") .put_string("groff ") .put_string("version ") @@ -4943,7 +5141,8 @@ html_printer::~html_printer() .put_string(ctime(&t), strlen(ctime(&t))-1) .end_comment(); - writeHeadMetaStyle(); + if (dialect == html4) + writeHeadMetaStyle(); write_title(TRUE); head_info += '\0'; @@ -5123,9 +5322,12 @@ void html_printer::special(char *s, const environment *env, char type) * requesting that the formatting move right by the appropriate * amount. */ - } else if (strncmp(s, "html</p>:", 9) == 0) { + } else if ((strncmp(s, "html</p>:", 9) == 0) || + (strncmp(s, "html<?p>:", 9) == 0) || + (strncmp(s, "math<?p>:", 9) == 0)) { int r=font::res; /* resolution of the device */ font *f=sbuf_style.f; + string t; if (f == NULL) { int found=FALSE; @@ -5133,6 +5335,17 @@ void html_printer::special(char *s, const environment *env, char type) f = font::load_font("TR", &found); } + if (strncmp(s, "math<?p>:", 9) == 0) { + if (strncmp((char *)&s[9], "<math>", 6) == 0) { + s[9] = '\0'; + t = s; + t += "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"; + t += (char *)&s[15]; + t += '\0'; + s = (char *)&t[0]; + } + } + /* * need to pass all of string through to html output during flush */ @@ -5148,6 +5361,7 @@ void html_printer::special(char *s, const environment *env, char type) * requesting that the formatting move right by the appropriate * amount. */ + } else if (strncmp(s, "index:", 6) == 0) { cutoff_heading = atoi(&s[6]); } else if (strncmp(s, "assertion:[", 11) == 0) { @@ -5211,6 +5425,21 @@ int html_printer::round_width(int x) return n * r; } +/* + * handle_valid_flag - emits a valid xhtml 1.1 button, provided -V and -x + * were supplied on the command line. + */ + +void html_printer::handle_valid_flag (void) +{ + if (valid_flag && dialect == xhtml) + fputs("<p>" + "<a href=\"http://validator.w3.org/check?uri=referer\"><img " + "src=\"http://www.w3.org/Icons/valid-xhtml11\" " + "alt=\"Valid XHTML 1.1 Transitional\" height=\"31\" width=\"88\" /></a>\n" + "</p>\n", stdout); +} + int main(int argc, char **argv) { program_name = argv[0]; @@ -5222,7 +5451,7 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "a:bdD:F:g:hi:I:j:lno:prs:S:v", + while ((c = getopt_long(argc, argv, "a:bdD:eF:g:hi:I:j:lno:prs:S:vVx:y", long_options, NULL)) != EOF) switch(c) { @@ -5240,6 +5469,9 @@ int main(int argc, char **argv) case 'D': /* handled by pre-html */ break; + case 'e': + /* handled by pre-html */ + break; case 'F': font::command_line_font_dir(optarg); break; @@ -5285,6 +5517,21 @@ int main(int argc, char **argv) printf("GNU post-grohtml (groff) version %s\n", Version_string); exit(0); break; + case 'V': + valid_flag = TRUE; + break; + case 'x': + if (strcmp(optarg, "x") == 0) { + dialect = xhtml; + simple_anchors = TRUE; + } else if (strcmp(optarg, "4") == 0) + dialect = html4; + else + printf("unsupported html dialect %s (defaulting to html4)\n", optarg); + break; + case 'y': + groff_sig = TRUE; + break; case CHAR_MAX + 1: // --help usage(stdout); exit(0); @@ -5307,6 +5554,6 @@ int main(int argc, char **argv) static void usage(FILE *stream) { - fprintf(stream, "usage: %s [-vblnh] [-D dir] [-I image_stem] [-F dir] [files ...]\n", + fprintf(stream, "usage: %s [-vbelnhVy] [-D dir] [-I image_stem] [-F dir] [-x x] [files ...]\n", program_name); } diff --git a/src/preproc/eqn/box.cpp b/src/preproc/eqn/box.cpp index 9067302b..6ca528a5 100644 --- a/src/preproc/eqn/box.cpp +++ b/src/preproc/eqn/box.cpp @@ -237,7 +237,7 @@ void output_string() { 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 @@ void do_text(const char *s) 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 @@ void box::top_level() b->uid, body_height, b->uid, body_depth); } else if (output_format == mathml) { + if (xhtml) + printf(".MATHML "); printf("<math>"); b->output(); printf("</math>"); diff --git a/src/preproc/eqn/eqn.h b/src/preproc/eqn/eqn.h index 8d655b38..e9eed1c1 100644 --- a/src/preproc/eqn/eqn.h +++ b/src/preproc/eqn/eqn.h @@ -41,6 +41,7 @@ extern int one_size_reduction_flag; 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, diff --git a/src/preproc/eqn/main.cpp b/src/preproc/eqn/main.cpp index 9bd3ce3b..9794943c 100644 --- a/src/preproc/eqn/main.cpp +++ b/src/preproc/eqn/main.cpp @@ -45,6 +45,7 @@ int one_size_reduction_flag = 0; 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 @@ static int inline_equation(FILE *fp, string &linebuf, string &str) 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 @@ int main(int argc, char **argv) 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)) diff --git a/src/preproc/eqn/text.cpp b/src/preproc/eqn/text.cpp index 84dc873f..8563199a 100644 --- a/src/preproc/eqn/text.cpp +++ b/src/preproc/eqn/text.cpp @@ -57,7 +57,7 @@ struct map entity_table[] = { {"*L", "Λ"}, // ISOgrk3 {"*m", "μ"}, // ISOgrk3 {"*M", "M"}, - {"*n", "&nu"}, // ISOgrk3 + {"*n", "ν"}, // ISOgrk3 {"*N", "N"}, {"*o", "o"}, {"*O", "O"}, diff --git a/src/preproc/html/pre-html.cpp b/src/preproc/html/pre-html.cpp index ec5c29b6..1b7112fc 100644 --- a/src/preproc/html/pre-html.cpp +++ b/src/preproc/html/pre-html.cpp @@ -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 (gaius@glam.ac.uk). * @@ -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 @@ extern "C" const char *Version_string; #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 @@ typedef enum { 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 *troffFileName = NULL; // output of pre-html output which 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 @@ static const char *image_gen = NULL; // the `gs' program 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,28 +317,37 @@ static unsigned int get_resolution(void) void html_system(const char *s, int redirect_stdout) { - // Redirect standard error to the null device. This is more - // portable than using "2> /dev/null", since it doesn't require a - // Unixy shell. - int save_stderr = dup(2); - int save_stdout = dup(1); - int fdnull = open(NULL_DEV, O_WRONLY|O_BINARY, 0666); - if (save_stderr > 2 && fdnull > 2) - dup2(fdnull, 2); - if (redirect_stdout && save_stdout > 1 && fdnull > 1) - dup2(fdnull, 1); - if (fdnull >= 0) - close(fdnull); - int status = system(s); - dup2(save_stderr, 2); - if (redirect_stdout) - dup2(save_stdout, 1); - if (status == -1) - fprintf(stderr, "Calling `%s' failed\n", s); - else if (status) - fprintf(stderr, "Calling `%s' returned status %d\n", s, status); - close(save_stderr); - close(save_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. + int save_stderr = dup(2); + int save_stdout = dup(1); + int fdnull = open(NULL_DEV, O_WRONLY|O_BINARY, 0666); + if (save_stderr > 2 && fdnull > 2) + dup2(fdnull, 2); + if (redirect_stdout && save_stdout > 1 && fdnull > 1) + dup2(fdnull, 1); + if (fdnull >= 0) + close(fdnull); + int status = system(s); + dup2(save_stderr, 2); + if (redirect_stdout) + dup2(save_stdout, 1); + if (status == -1) + fprintf(stderr, "Calling `%s' failed\n", s); + else if (status) + fprintf(stderr, "Calling `%s' returned status %d\n", s, status); + close(save_stderr); + close(save_stdout); + } } /* @@ -921,12 +934,6 @@ int imageList::createPage(int pageno) 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 @@ int imageList::createPage(int pageno) 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 @@ void imageList::createImage(imageItem *i) 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 @@ static void alterDeviceTo(int argc, char *argv[], int toImage) 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,7 +1206,10 @@ static void alterDeviceTo(int argc, char *argv[], int toImage) else { while (i < argc) { if (strcmp(argv[i], IMAGE_DEVICE) == 0) - argv[i] = (char *)"-Thtml"; + if (dialect == xhtml) + argv[i] = (char *)"-Txhtml"; + else + argv[i] = (char *)"-Thtml"; i++; } argv[troff_arg] = (char *)"groff"; /* use groff -Z */ @@ -1218,10 +1217,10 @@ static void alterDeviceTo(int argc, char *argv[], int toImage) } /* - * 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 @@ char **addZ(int argc, char *argv[]) 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 @@ void dump_args(int argc, char *argv[]) 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 @@ int char_buffer::do_html(int argc, char *argv[]) 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 @@ int char_buffer::do_image(int argc, char *argv[]) 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 @@ static int scanArguments(int argc, char **argv) { "version", no_argument, 0, 'v' }, { NULL, 0, 0, 0 } }; - while ((c = getopt_long(argc, argv, "+a:bdD:F:g:hi:I:j:lno:prs:S:v", + while ((c = getopt_long(argc, argv, "+a:bdD:eF:g:hi:I:j:lno:prs:S:vVx:y", long_options, NULL)) != EOF) switch(c) { @@ -1570,6 +1612,9 @@ static int scanArguments(int argc, char **argv) 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 @@ static int scanArguments(int argc, char **argv) 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); diff --git a/src/roff/groff/groff.cpp b/src/roff/groff/groff.cpp index 748715c7..2930ebee 100644 --- a/src/roff/groff/groff.cpp +++ b/src/roff/groff/groff.cpp @@ -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 (jjc@jclark.com) @@ -74,6 +74,7 @@ class possible_command { 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 main(int argc, char **argv) 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 @@ int main(int argc, char **argv) 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 @@ int main(int argc, char **argv) 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 @@ int main(int argc, char **argv) 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,11 +388,21 @@ int main(int argc, char **argv) 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 (oflag) - fatal("`-o' option is invalid with device `html'"); - commands[EQN_INDEX].append_arg("-Tps:html"); + 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 @@ void possible_command::set_name(const char *s) 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; diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp index 397f2ba4..414bad8b 100644 --- a/src/roff/troff/input.cpp +++ b/src/roff/troff/input.cpp @@ -7757,6 +7757,7 @@ void init_input_requests() 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); diff --git a/tmac/s.tmac b/tmac/s.tmac index ba392797..c873e158 100644 --- a/tmac/s.tmac +++ b/tmac/s.tmac @@ -221,6 +221,7 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. . ps \\n[PS] .\} .. +. .de LP .if !'\\n[.z]'' \{\ . br @@ -229,8 +230,9 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .br .cov*ab-init .cov*print -\\*[\\$0]\\ +.nop \\*[\\$0]\\ .. +. .als IP LP .als PP LP .als XP LP @@ -241,6 +243,7 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .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 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .als AI par@AI .als TL par@TL .. +. .de @AB .if !'\\n(.z'' \{\ . br @@ -342,7 +346,7 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .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 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .\} .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 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. . \} . 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 @@ Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. .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' \{\ -. 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 +.if '\*(.T'html' \{\ +. rm KF +. als KF KS +. +. rm FS +. de FS +. sp +. HTML-NS <cite> \\.. -. rm FE -. de FE -. br -. HTML-IMAGE-END +. rm FE +. de FE +. HTML-NS </cite> +. sp \\.. -. \} +.\} .. .par@load-init .\" **************************** diff --git a/tmac/troffrc-end b/tmac/troffrc-end index 53f1bef5..d8ff8b0d 100644 --- a/tmac/troffrc-end +++ b/tmac/troffrc-end @@ -8,12 +8,19 @@ .do if r ps4html .do mso www.tmac . .\" for all other devices blank out these macros -.do if !d HTML-IMAGE-INLINE .do ds HTML-IMAGE-INLINE -.do if !d HTML-IMAGE .do ds HTML-IMAGE -.do if !d HTML-IMAGE-RIGHT .do ds HTML-IMAGE-RIGHT -.do if !d HTML-IMAGE-LEFT .do ds HTML-IMAGE-LEFT -.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 HTML-IMAGE-INLINE .do ds HTML-IMAGE-INLINE +.do if !d HTML-IMAGE .do ds HTML-IMAGE +.do if !d HTML-IMAGE-RIGHT .do ds HTML-IMAGE-RIGHT +.do if !d HTML-IMAGE-LEFT .do ds HTML-IMAGE-LEFT +.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. diff --git a/tmac/www.tmac b/tmac/www.tmac index 506b0ba6..d1c07936 100644 --- a/tmac/www.tmac +++ b/tmac/www.tmac @@ -301,6 +301,26 @@ www functionality. It should work with any macro set. . \} .. . +.\" +.\" 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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. . . 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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. . \" 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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. .\" Produce a horizontal line. .\" .de HR -. HTML</p> <hr> +. HTML</p> <hr></hr> .. . .\" -------------------------------------------------------------------- @@ -933,6 +954,7 @@ www functionality. It should work with any macro set. .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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. .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 @@ www functionality. It should work with any macro set. .\" 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 @@ www functionality. It should work with any macro set. .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 @@ www functionality. It should work with any macro set. .\" 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 @@ www functionality. It should work with any macro set. .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 @@ www functionality. It should work with any macro set. .\" 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 @@ www functionality. It should work with any macro set. .\" .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 @@ www functionality. It should work with any macro set. .\" .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 @@ www functionality. It should work with any macro set. .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 @@ www functionality. It should work with any macro set. .\" .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 @@ www functionality. It should work with any macro set. . 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 @@ www functionality. It should work with any macro set. . 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 .\" -------------------------------------------------------------------- |