From ecad0be303b46ecdaf6900c60d6ebd2ac5ccc3c7 Mon Sep 17 00:00:00 2001 From: wlemb Date: Fri, 13 Apr 2001 09:03:52 +0000 Subject: * src/devices/grohtml/grohtml.man: Updated manual page regarding simple anchor. * src/preproc/html/pre-html.cc (createImage): Fixed right hand cropping of images. (removeTempFiles): New function to tidy up temporary files. * src/preproc/html/pre-html.cc (main): Calls `removeTempFiles()'. Many fixes to do with the new inline suppress node and image regions are much tighter. * src/devices/grohtml/post-html.cc: New method `is_auto_img'. (generate_img_src): New function. (html_printer::do_auto_image): Utilizes it. (do_heading, do_title): Include inline images within their contents. (html_printer::begin_page): Tidied up comments that are issued to the html output file. (html_printer::do_fill): Fixed so that `.nf' works with fonts other than courier. (text_glob::is_br): New method used by do_heading. * tmac/s.tmac: If -Thtml then emit $1 in .IP rather than its equivalent diversion. * src/include/html-strings.h: Altered image tags to reflect the inline image node. * src/include/htmlindicate.h (html_end_suppress): Added `is_inline' parameter. * src/preproc/eqn/main.cc: Will suppress generation of image tags if it is already inside a pic image. Only emit tags if the argument `-Tps:html' is present. * src/preproc/tbl/main.cc: Changes to reflect additional `html_end_suppress' parameter. * src/roff/troff/env.cc: Only emit eol tag if a node has been emitted since the last eol tag was written. * src/roff/troff/env.h: New boolean `emitted_node'. * src/roff/troff/input.cc (do_suppress): Handles extra suppress nodes O3, O4, O5. No longer use `output_low_mark_miny'. * src/roff/troff/node.cc (check_charinfo): New method. (troff_output_file::determine_line_limits): Alterations to limit checking. * tmac/www.tmac: Changes to reflect new suppress nodes. * src/devices/grohtml/post-html.cc (html_printer::add_to_sbuf): Escape the html_glyph in the buffer. (str_translate_to_html): Output the unescaped escaped_char. * src/devices/grohtml/html-text.cc (issue_table_begin): Set `frame=void', not `frame=none'. Add `border=0'. * contrib/mm/groff_mm.man: Fixing some typos. * PROBLEMS: Add some words on how to avoid wrapper macros. * doc/groff.texinfo: Improve documentation of troff's -a option. Documentation for pic added (doc/pic.ms). --- ChangeLog | 60 +++++++++++++- PROBLEMS | 13 +++ contrib/mm/groff_mm.man | 8 +- src/devices/grohtml/grohtml.man | 3 +- src/devices/grohtml/html-text.cc | 8 +- src/devices/grohtml/post-html.cc | 165 +++++++++++++++++++++++++++++--------- src/include/html-strings.h | 11 +-- src/include/htmlindicate.h | 20 ++--- src/libs/libgroff/htmlindicate.cc | 51 ++++++------ src/preproc/eqn/main.cc | 67 ++++++++++++---- src/preproc/html/pre-html.cc | 129 +++++++++++++++++------------ src/preproc/tbl/main.cc | 4 +- src/roff/groff/groff.cc | 2 +- src/roff/troff/env.cc | 9 ++- src/roff/troff/env.h | 1 + src/roff/troff/input.cc | 53 +++++++----- src/roff/troff/node.cc | 100 +++++++++++++++-------- tmac/html.tmac | 1 - tmac/s.tmac | 2 +- tmac/www.tmac | 10 +-- 20 files changed, 497 insertions(+), 220 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d93b072..a3e54a18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,59 @@ +2001-04-12 Gaius Mulley + + * src/devices/grohtml/grohtml.man: Updated manual page regarding + simple anchor. + * src/preproc/html/pre-html.cc (createImage): Fixed right hand + cropping of images. + (removeTempFiles): New function to tidy up temporary files. + * src/preproc/html/pre-html.cc (main): Calls `removeTempFiles()'. + Many fixes to do with the new inline suppress node and image regions + are much tighter. + * src/devices/grohtml/post-html.cc: New method `is_auto_img'. + (generate_img_src): New function. + (html_printer::do_auto_image): Utilizes it. + (do_heading, do_title): Include inline images within their contents. + (html_printer::begin_page): Tidied up comments that are issued to + the html output file. + (html_printer::do_fill): Fixed so that `.nf' works with fonts other + than courier. + (text_glob::is_br): New method used by do_heading. + * tmac/s.tmac: If -Thtml then emit $1 in .IP rather than its + equivalent diversion. + * src/include/html-strings.h: Altered image tags to reflect the + inline image node. + * src/include/htmlindicate.h (html_end_suppress): Added `is_inline' + parameter. + * src/preproc/eqn/main.cc: Will suppress generation of image tags if + it is already inside a pic image. Only emit tags if the argument + `-Tps:html' is present. + * src/preproc/tbl/main.cc: Changes to reflect additional + `html_end_suppress' parameter. + * src/roff/troff/env.cc: Only emit eol tag if a node has been + emitted since the last eol tag was written. + * src/roff/troff/env.h: New boolean `emitted_node'. + * src/roff/troff/input.cc (do_suppress): Handles extra suppress + nodes \O3, \O4, \O5. No longer use `output_low_mark_miny'. + * src/roff/troff/node.cc (check_charinfo): New method. + (troff_output_file::determine_line_limits): Alterations to limit + checking. + * tmac/www.tmac: Changes to reflect new suppress nodes. + +2001-04-08 Bruno Haible + + * src/devices/grohtml/post-html.cc (html_printer::add_to_sbuf): + Escape the html_glyph in the buffer. + (str_translate_to_html): Output the unescaped escaped_char. + * src/devices/grohtml/html-text.cc (issue_table_begin): Set + `frame=void', not `frame=none'. Add `border=0'. + +2001-04-10 Ruslan Ermilov + + * contrib/mm/groff_mm.man: Fixing some typos. + +2001-04-12 Werner LEMBERG + + * PROBLEMS: Add some words on how to avoid wrapper macros. + 2001-04-11 Blake McBride * src/include/nonposix.h (fileno) [_MSC_VER]: Removed. @@ -1341,7 +1397,7 @@ * NEWS, src/roff/nroff/nroff.man, src/roff/groff/groff.man, doc/groff.texinfo: Document it. - * doc/groff.texinfo: Improve documentation of troff's -a option. + * doc/groff.texinfo: Improve documentation of troff's -a option. 2000-10-17 Gaius Mulley @@ -3444,7 +3500,7 @@ Fri Aug 15 08:51:47 1997 Eric S. Raymond * README, PROJECTS, NEWS, INSTALL, VERSION, doc/Makefile. doc/pic.ms, groff/groff.man: Prepare for 1.11 release. No code changes. - Documentation for pic added (doc/pic.ms). + Documentation for pic added (doc/pic.ms). Sun Nov 26 11:45:13 1995 James Clark diff --git a/PROBLEMS b/PROBLEMS index e31ef015..001610e6 100644 --- a/PROBLEMS +++ b/PROBLEMS @@ -232,6 +232,19 @@ request. ---------------------------------------------------------------------- +* groff produces wrapper macros for `ms' and friends which call the + system's original macros. Then, to get groff's ms macro package I + have to use `-mgs' instead `-ms'. Can I avoid this? + +Yes. Configure and compile groff as usual, but install it with + + make install tmac_wrap="" + +Then no wrapper files are produced, and `-ms' will use groff's `ms' +macros. + +---------------------------------------------------------------------- + * Groff doesn't use the font names I'm used to. Use the `ftr' request. See (g)troff(1). diff --git a/contrib/mm/groff_mm.man b/contrib/mm/groff_mm.man index e90eacf6..6af75c66 100644 --- a/contrib/mm/groff_mm.man +++ b/contrib/mm/groff_mm.man @@ -1,5 +1,5 @@ .\" -.\" $Id: groff_mm.man,v 2.0 2000/09/14 03:40:24 jhaegg Exp $ +.\" $Id: groff_mm.man,v 2.1 2001/04/13 09:03:52 wlemb Exp $ .\" .de T2 .ne 2v @@ -1181,7 +1181,7 @@ page number. The default page-header is "''- % -''", the page number between two dashes. .TP .B PS -Picture start (from pic). Begins a picture for \fB@TMAC@pic\fP, see +Picture start (from pic). Begins a picture for \fB@g@pic\fP, see the manual. .TP .B PX @@ -1390,9 +1390,9 @@ Linelength is preserved though. .TP .B "TS [H]" Table start. This is the start of a table specification -to \fB@TMAC@tbl\fP. See separate manual for \fB@TMAC@tbl\fP. +to \fB@g@tbl\fP. See separate manual for \fB@g@tbl\fP. \fBTS\fP ends with \fBTE\fP. -Argument \fIH\fP tells \fBm@TMAC@m\fP that the table +Argument \fIH\fP tells \fBm@TMAC_M_PREFIX@m\fP that the table has a header. See \fBTH\fP. .TP .B TX diff --git a/src/devices/grohtml/grohtml.man b/src/devices/grohtml/grohtml.man index 3fa302c3..8796d8f8 100644 --- a/src/devices/grohtml/grohtml.man +++ b/src/devices/grohtml/grohtml.man @@ -1,5 +1,5 @@ .ig \"-*- nroff -*- -Copyright (C) 1999-2000 Free Software Foundation, Inc. +Copyright (C) 1999-2000, 2001 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -90,6 +90,7 @@ Turns off the automatic header and footer line (html rule). Generate simple heading anchors whenever a section/number heading is found. Without the option the anchor value is the textual heading. This can cause problems when a heading contains a `?' on some brousers (netscape). +This flag is automatically turned on if a heading contains an image. .TP .BI \-F dir Prepend directory diff --git a/src/devices/grohtml/html-text.cc b/src/devices/grohtml/html-text.cc index 14f0b5a9..0b63aa0a 100644 --- a/src/devices/grohtml/html-text.cc +++ b/src/devices/grohtml/html-text.cc @@ -140,7 +140,7 @@ void html_text::issue_table_begin (tag_definition *t) int width=current_indentation*100/linelength; if (width > 0) { - out->put_string("").nl(); + out->put_string("
").nl(); out->put_string("").nl(); if ((t->arg1 == 0) || (strcmp(t->arg1, "") == 0)) out->put_string(""); @@ -612,7 +612,11 @@ char *html_text::done_para (void) void html_text::do_space (void) { - do_para(done_para()); + if (is_in_pre()) { + do_emittext("", 0); + } else { + do_para(done_para()); + } space_emitted = TRUE; } diff --git a/src/devices/grohtml/post-html.cc b/src/devices/grohtml/post-html.cc index 716e138d..0237bfc1 100644 --- a/src/devices/grohtml/post-html.cc +++ b/src/devices/grohtml/post-html.cc @@ -340,16 +340,19 @@ char *char_buffer::add_string (char *s, unsigned int length) class text_glob { public: text_glob (style *s, char *string, unsigned int length, - int min_vertical, int min_horizontal, - int max_vertical, int max_horizontal, - int is_html , int is_troff_command, - int is_a_line , int thickness); + int min_vertical , int min_horizontal, + int max_vertical , int max_horizontal, + int is_html , int is_troff_command, + int is_auto_image, + int is_a_line , int thickness); text_glob (void); ~text_glob (void); - int is_a_line (void); - int is_a_tag (void); - int is_raw (void); - int is_eol (void); + int is_a_line (void); + int is_a_tag (void); + int is_raw (void); + int is_eol (void); + int is_auto_img (void); + int is_br (void); style text_style; char *text_string; @@ -358,6 +361,7 @@ public: int is_raw_command; // should the text be sent directly to the device? int is_tag; // is this a .br, .sp, .tl etc int is_line; // is the command a ? + int is_img_auto; // image created by eqn delim int thickness; // the thickness of a line }; @@ -365,11 +369,12 @@ text_glob::text_glob (style *s, char *string, unsigned int length, int min_vertical, int min_horizontal, int max_vertical, int max_horizontal, int is_html, int is_troff_command, + int is_auto_image, int is_a_line, int line_thickness) : text_style(*s), text_string(string), text_length(length), minv(min_vertical), minh(min_horizontal), maxv(max_vertical), maxh(max_horizontal), - is_raw_command(is_html), is_tag(is_troff_command), is_line(is_a_line), - thickness(line_thickness) + is_raw_command(is_html), is_tag(is_troff_command), is_img_auto(is_auto_image), + is_line(is_a_line), thickness(line_thickness) { } @@ -419,6 +424,25 @@ int text_glob::is_raw (void) return( is_raw_command ); } +/* + * is_auto_img - returns TRUE if the glob contains an automatically + * generated image. + */ + +int text_glob::is_auto_img (void) +{ + return( is_img_auto ); +} + +/* + * is_br - returns TRUE if the glob is a tag containing a .br + */ + +int text_glob::is_br (void) +{ + return( is_a_tag() && (strcmp("html-tag:.br", text_string) == 0) ); +} + /* * the class and methods used to construct ordered double linked lists. * In a previous implementation we used templates via #include "ordered-list.h", @@ -748,7 +772,7 @@ void page::add (style *s, char *string, unsigned int length, if (length > 0) { text_glob *g=new text_glob(s, buffer.add_string(string, length), length, min_vertical, min_horizontal, max_vertical, max_horizontal, - FALSE, FALSE, FALSE, 0); + FALSE, FALSE, FALSE, FALSE, 0); glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical, max_horizontal); } } @@ -765,7 +789,7 @@ void page::add_html (style *s, char *string, unsigned int length, if (length > 0) { text_glob *g=new text_glob(s, buffer.add_string(string, length), length, min_vertical, min_horizontal, max_vertical, max_horizontal, - TRUE, FALSE, FALSE, 0); + TRUE, FALSE, FALSE, FALSE, 0); glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical, max_horizontal); } } @@ -782,7 +806,9 @@ void page::add_tag (style *s, char *string, unsigned int length, if (length > 0) { text_glob *g=new text_glob(s, buffer.add_string(string, length), length, min_vertical, min_horizontal, max_vertical, max_horizontal, - FALSE, TRUE, FALSE, 0); + FALSE, TRUE, + (strncmp(string, "html-tag:.auto-image", 20) == 0), + FALSE, 0); glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical, max_horizontal); } } @@ -799,7 +825,7 @@ void page::add_line (style *s, if (y1 == y2) { text_glob *g = new text_glob(s, "", 0, min(y1, y2), min(x1, y2), max(y1, y2), max(x1, x2), - FALSE, TRUE, FALSE, thickness); + FALSE, TRUE, FALSE, FALSE, thickness); glyphs.add(g, line_number, min(y1, y2), min(x1, y2), max(y1, y2), max(x1, x2)); } } @@ -1195,6 +1221,30 @@ static int exists (const char *filename) } } +/* + * generate_img_src - returns a html image tag for the filename + * providing that the image exists. + */ + +static char *generate_img_src (const char *filename) +{ + static char buffer[MAX_STRING_LENGTH]; + + while (filename && (filename[0] == ' ')) { + filename++; + } + if (exists(filename)) { + strcpy(buffer, "", 3); + } + return( (char *)&buffer ); + } else { + return( 0 ); + } +} + /* * do_auto_image - tests whether the image, indicated by filename, * is present, if so then it emits an html image tag. @@ -1205,24 +1255,17 @@ static int exists (const char *filename) void html_printer::do_auto_image (text_glob *g, const char *filename) { - while (filename && (filename[0] == ' ')) { - filename++; - } - if (exists(filename)) { + char *buffer = generate_img_src(filename); + + if (buffer) { /* * utilize emit_raw by creating a new text_glob. */ text_glob h = *g; - char buffer[MAX_STRING_LENGTH]; - strcpy(buffer, "", 3); - h.text_string = (char *)&buffer; - h.text_length = strlen(buffer); - emit_raw(&h); - } + h.text_string = buffer; + h.text_length = strlen(buffer); + emit_raw(&h); } else { next_tag = INLINE; } @@ -1245,7 +1288,21 @@ void html_printer::do_title (void) do { t = page_contents->glyphs.get_data(); removed_from_head = FALSE; - if (t->is_raw_command) { + if (t->is_auto_img()) { + char *img=generate_img_src((char *)(t->text_string + 20)); + + if (img) { + if (found_title_start) { + strcat(title.text, " "); + } + found_title_start = TRUE; + title.has_been_found = TRUE; + strcat(title.text, img); + } + page_contents->glyphs.sub_move_right(); /* move onto next word */ + removed_from_head = ((!page_contents->glyphs.is_empty()) && + (page_contents->glyphs.is_equal_to_head())); + } else if (t->is_raw_command) { /* skip raw commands */ page_contents->glyphs.sub_move_right(); /* move onto next word */ @@ -1304,7 +1361,7 @@ void html_printer::write_header (void) strlen(header.header_buffer), header.no_of_headings, header.header_level, header.no_of_headings, header.header_level, - FALSE, FALSE, FALSE, FALSE); + FALSE, FALSE, FALSE, FALSE, FALSE); header.headers.add(h, header.no_of_headings, header.no_of_headings, header.no_of_headings, @@ -1368,7 +1425,18 @@ void html_printer::do_heading (char *arg) if (! page_contents->glyphs.is_equal_to_head()) { g = page_contents->glyphs.get_data(); do { - if (! (g->is_a_line() || g->is_a_tag() || g->is_raw())) { + if (g->is_auto_img()) { + char *img=generate_img_src((char *)(g->text_string + 20)); + + if (img) { + simple_anchors = TRUE; // we cannot use full heading anchors with images + if (l != 0) { + strcat(header.header_buffer, " "); + } + l = g; + strcat(header.header_buffer, img); + } + } else if (! (g->is_a_line() || g->is_a_tag() || g->is_raw())) { /* * we ignore raw commands when constructing a heading */ @@ -1382,7 +1450,7 @@ void html_printer::do_heading (char *arg) page_contents->glyphs.move_right(); g = page_contents->glyphs.get_data(); } while ((! page_contents->glyphs.is_equal_to_head()) && - (! g->is_a_tag())); + (! g->is_br())); } determine_header_level(level); @@ -1505,7 +1573,18 @@ void html_printer::do_indentedparagraph (void) do { t = page_contents->glyphs.get_data(); removed_from_head = FALSE; - if (t->is_raw_command) { + if (t->is_auto_img()) { + char *img=generate_img_src((char *)(t->text_string + 20)); + + if (img) { + if (found_indent_start) { + strcat(indent.text, " "); + } + found_indent_start = TRUE; + strcat(indent.text, img); + } + page_contents->glyphs.sub_move_right(); /* move onto next word */ + } else if (t->is_raw_command) { /* skip raw commands */ page_contents->glyphs.sub_move_right(); /* move onto next word */ @@ -1568,12 +1647,10 @@ void html_printer::do_fill (int on) supress_sub_sup = TRUE; if (fill_on != on) { - if (is_font_courier(output_style.f) && (is_courier_until_eol())) { - if (on) { - current_paragraph->do_pre(); - } else { - current_paragraph->done_pre(); - } + if (on) { + current_paragraph->done_pre(); + } else { + current_paragraph->do_pre(); } } fill_on = on; @@ -2276,9 +2353,14 @@ void html_printer::add_to_sbuf (unsigned char code, const char *name) int l = strlen(html_glyph); int i; + // Escape the name, so that "&" doesn't get expanded to "&" + // later during translate_to_html. + add_char_to_sbuf('\\'); add_char_to_sbuf('('); + for (i=0; i tag * and the postscript device driver works out the min/max limits - * of the graphic region. These region limits are read by pre-html + * of the graphic region. These region limits are read by pre-html * and an image is generated via troff -Tps -> gs -> png */ static int is_in_graphic_start = 0; +static int is_inline_image = 0; /* - * html_begin_suppress - + * html_begin_suppress - emit a start of image tag which will be seen + * by pre-html. */ - -void html_begin_suppress (int is_inline) +void html_begin_suppress(int is_inline) { - if (is_inline) { - put_string(HTML_IMAGE_INLINE, stdout); - } else { + if (is_inline) + put_string(HTML_IMAGE_INLINE_BEGIN, stdout); + else { put_string(HTML_IMAGE_CENTERED, stdout); + put_string("\n", stdout); } - put_string("\n", stdout); } /* - * html_end_suppress - + * html_end_suppress - emit an end of image tag which will be seen + * by pre-html. */ - -void html_end_suppress (void) +void html_end_suppress(int is_inline) { - put_string(HTML_IMAGE_END, stdout); - put_string("\n", stdout); + if (is_inline) + put_string(HTML_IMAGE_INLINE_END, stdout); + else { + put_string(HTML_IMAGE_END, stdout); + put_string("\n", stdout); + } } /* @@ -70,12 +75,12 @@ void html_end_suppress (void) * FALSE if this is called via EQ, TS, PS, and * TRUE if issued via delim $$ $ x over y $ etc. */ - -void graphic_start (int is_inline) +void graphic_start(int is_inline) { - if (! is_in_graphic_start) { - put_string(".if '\\*(.T'html-old' \\X(graphic-start(\\c\n", stdout); + if (!is_in_graphic_start) { + // put_string(".if '\\*(.T'html-old' \\X(graphic-start(\\c\n", stdout); html_begin_suppress(is_inline); + is_inline_image = is_inline; is_in_graphic_start = 1; } } @@ -84,11 +89,11 @@ void graphic_start (int is_inline) * graphic_end - tell troff that the image region is ending. */ -void graphic_end (void) +void graphic_end(void) { if (is_in_graphic_start) { - html_end_suppress(); - put_string(".if '\\*(.T'html-old' \\X(graphic-end(\\c\n", stdout); + html_end_suppress(is_inline_image); + // put_string(".if '\\*(.T'html-old' \\X(graphic-end(\\c\n", stdout); is_in_graphic_start = 0; } } diff --git a/src/preproc/eqn/main.cc b/src/preproc/eqn/main.cc index e5c03aa4..6dc03f0b 100644 --- a/src/preproc/eqn/main.cc +++ b/src/preproc/eqn/main.cc @@ -25,6 +25,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "searchpath.h" #include "macropath.h" #include "htmlindicate.h" +#include "pbox.h" #define STARTUP_FILE "eqnrc" @@ -41,7 +42,11 @@ int draw_flag = 0; int one_size_reduction_flag = 0; int compatible_flag = 0; int no_newline_in_delim_flag = 0; - +int html = 0; +// if we encounter a region marked as an image then we +// do not mark up inline equations. +int suppress_html = 0; + int read_line(FILE *fp, string *p) { @@ -75,12 +80,33 @@ void do_file(FILE *fp, const char *filename) if (interpret_lf_args(linebuf.contents() + 3)) current_lineno--; } + else if (linebuf.length() >= 12 + && linebuf[0] == '.' && linebuf[1] == 'H' && linebuf[2] == 'T' + && linebuf[3] == 'M' && linebuf[4] == 'L' && linebuf[5] == '-' + && linebuf[6] == 'I' && linebuf[7] == 'M' && linebuf[8] == 'A' + && linebuf[9] == 'G' && linebuf[10] == 'E' + && linebuf[11] == '\n') { + put_string(linebuf, stdout); + suppress_html++; + } + else if (linebuf.length() >= 16 + && linebuf[0] == '.' && linebuf[1] == 'H' && linebuf[2] == 'T' + && linebuf[3] == 'M' && linebuf[4] == 'L' && linebuf[5] == '-' + && linebuf[6] == 'I' && linebuf[7] == 'M' && linebuf[8] == 'A' + && linebuf[9] == 'G' && linebuf[10] == 'E' && linebuf[11] == '-' + && linebuf[12] == 'E' && linebuf[13] == 'N' && linebuf[14] == 'D' + && linebuf[15] == '\n') { + put_string(linebuf, stdout); + suppress_html--; + } else if (linebuf.length() >= 4 && linebuf[0] == '.' && linebuf[1] == 'E' && linebuf[2] == 'Q' - && (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) { - graphic_start(0); + && (linebuf[3] == ' ' || linebuf[3] == '\n' + || compatible_flag)) { + if (html && (suppress_html == 0)) + graphic_start(0); put_string(linebuf, stdout); int start_lineno = current_lineno + 1; str.clear(); @@ -112,7 +138,8 @@ void do_file(FILE *fp, const char *filename) restore_compatibility(); printf(".lf %d\n", current_lineno); put_string(linebuf, stdout); - graphic_end(); + if (html && (suppress_html == 0)) + graphic_end(); } else if (start_delim != '\0' && linebuf.search(start_delim) >= 0 && inline_equation(fp, linebuf, str)) @@ -124,9 +151,8 @@ void do_file(FILE *fp, const char *filename) current_lineno = 0; } -/* Handle an inline equation. Return 1 if it was an inline equation, -0 otherwise. */ - +// Handle an inline equation. Return 1 if it was an inline equation, +// otherwise. static int inline_equation(FILE *fp, string &linebuf, string &str) { linebuf += '\0'; @@ -168,9 +194,18 @@ static int inline_equation(FILE *fp, string &linebuf, string &str) ptr = &linebuf[0]; } str += '\0'; - graphic_start(1); + if (html && (suppress_html == 0)) { + printf(".as %s ", LINE_STRING); + graphic_start(1); + printf("\n"); + } init_lex(str.contents(), current_filename, start_lineno); yyparse(); + if (html && (suppress_html == 0)) { + printf(".as %s ", LINE_STRING); + graphic_end(); + printf("\n"); + } start = delim_search(ptr, start_delim); if (start == 0) { char *nl = strchr(ptr, '\n'); @@ -183,7 +218,6 @@ static int inline_equation(FILE *fp, string &linebuf, string &str) printf(".lf %d\n", current_lineno); output_string(); restore_compatibility(); - graphic_end(); printf(".lf %d\n", current_lineno + 1); return 1; } @@ -207,7 +241,8 @@ static char *delim_search(char *ptr, int delim) case '\\': break; case '(': - if (*++ptr != '\\' && *ptr != '\0' && *++ptr != '\\' && *ptr != '\0') + if (*++ptr != '\\' && *ptr != '\0' + && *++ptr != '\\' && *ptr != '\0') ptr++; break; case '[': @@ -237,8 +272,8 @@ static char *delim_search(char *ptr, int delim) void usage(FILE *stream) { fprintf(stream, - "usage: %s [ -rvDCNR ] -dxx -fn -sn -pn -mn -Mdir -Ts [ files ... ]\n", - program_name); + "usage: %s [ -rvDCNR ] -dxx -fn -sn -pn -mn -Mdir -Ts [ files ... ]\n", + program_name); } int main(int argc, char **argv) @@ -290,6 +325,10 @@ int main(int argc, char **argv) break; case 'T': device = optarg; + if (strcmp(device, "ps:html") == 0) { + device = "ps"; + html = 1; + } break; case 's': if (!set_gsize(optarg)) @@ -337,8 +376,8 @@ int main(int argc, char **argv) init_table(device); init_char_table(); printf(".if !'\\*(.T'%s' " - ".if !'\\*(.T'html' " /* the html device uses `-Tps' to render - equations as images */ + ".if !'\\*(.T'html' " // the html device uses `-Tps' to render + // equations as images ".tm warning: %s should have been given a `-T\\*(.T' option\n", device, program_name); printf(".if '\\*(.T'html' " diff --git a/src/preproc/html/pre-html.cc b/src/preproc/html/pre-html.cc index 6aae6cb4..8357dd6e 100644 --- a/src/preproc/html/pre-html.cc +++ b/src/preproc/html/pre-html.cc @@ -55,13 +55,17 @@ extern char *strerror(); #define POSTSCRIPTRES 72000 // maybe there is a better way to find this? --fixme-- #define DEFAULT_IMAGE_RES 80 // 80 pixels per inch resolution -#define DEFAULT_VERTICAL_OFFSET 40 // 40/72 of an inch -#define IMAGE_BOARDER_PIXELS 10 +#define DEFAULT_VERTICAL_OFFSET 45 // DEFAULT_VERTICAL_OFFSET/72 of an inch +#define IMAGE_BOARDER_PIXELS 0 +#define MAX_WIDTH 8 // inches +#define INLINE_LEADER_CHAR '\\' #define TRANSPARENT "-background \"#FFF\" -transparent \"#FFF\"" -// #define DEBUGGING -// #define DEBUG_HTML +#if 0 +# define DEBUGGING +# define DEBUG_HTML +#endif #if !defined(TRUE) # define TRUE (1==1) @@ -146,7 +150,7 @@ public: int do_image(int argc, char *argv[]); void write_file_html(void); void write_file_troff(void); - void write_upto_newline (char_block **t, int *i); + void write_upto_newline (char_block **t, int *i, int is_html); int can_see(char_block **t, int *i, char *string); int skip_spaces(char_block **t, int *i); void skip_to_newline(char_block **t, int *i); @@ -258,19 +262,17 @@ void makeFileName () static void write_end_image (int is_html) { - writeString(".end \\{\\\n"); if (is_html) { /* * emit image name and enable output */ - writeString("\\O2\\O1\n"); + writeString("\\O2\\O1\\O4\n"); } else { /* * postscript, therefore emit image boundaries */ - writeString("\\O2\n"); + writeString("\\O2\\O4\n"); } - writeString(".\\}\n"); } /* @@ -283,57 +285,77 @@ static void write_end_image (int is_html) static void write_start_image (IMAGE_ALIGNMENT pos, int is_html) { - writeString(".begin \\{\\\n"); - switch (pos) { - - case LEFT: - writeString(". image l "); - break; - case RIGHT: - writeString(". image r "); - break; - case INLINE: - writeString(". image i "); - break; - case CENTERED: - default: - writeString(". image c "); + if (pos == INLINE) { + writeString("\\O3\\O5'"); + writeString(image_template); writeString(".png'"); + } else { + writeString(".begin \\{\\\n"); + switch (pos) { + + case LEFT: + writeString(". image l "); + break; + case RIGHT: + writeString(". image r "); + break; + case CENTERED: + default: + writeString(". image c "); + } + writeString(image_template); writeString(".png\n"); + if (! is_html) { + writeString(".bp\n"); + writeString(".tl ''''\n"); + } + writeString("\\}\n"); } - writeString(image_template); writeString(".png\n"); if (is_html) { writeString("\\O0\n"); } else { - writeString(".bp\n"); - writeString(".tl ''''\n"); // reset min/max registers writeString("\\O0\\O1\n"); } - writeString("\\}\n"); } /* * write_upto_newline - writes the contents of the buffer until a newline is seen. + * It checks for HTML_IMAGE_INLINE_BEGIN and HTML_IMAGE_INLINE_END + * and if they are present it processes them. */ -void char_buffer::write_upto_newline (char_block **t, int *i) +void char_buffer::write_upto_newline (char_block **t, int *i, int is_html) { int j=*i; if (*t) { - while ((j < (*t)->used) && ((*t)->buffer[j] != '\n')) { + while ((j < (*t)->used) && ((*t)->buffer[j] != '\n') && + ((*t)->buffer[j] != INLINE_LEADER_CHAR)) { j++; } if ((j < (*t)->used) && ((*t)->buffer[j] == '\n')) { j++; } writeNbytes((*t)->buffer+(*i), j-(*i)); + if ((*t)->buffer[j] == INLINE_LEADER_CHAR) { + if (can_see(t, &j, HTML_IMAGE_INLINE_BEGIN)) + write_start_image(INLINE, is_html); + else if (can_see(t, &j, HTML_IMAGE_INLINE_END)) + write_end_image(is_html); + else { + if (j < (*t)->used) { + *i = j; + j++; + writeNbytes((*t)->buffer+(*i), j-(*i)); + } + } + } if (j == (*t)->used) { *i = 0; if ((*t)->buffer[j-1] == '\n') { *t = (*t)->next; } else { *t = (*t)->next; - write_upto_newline(t, i); + write_upto_newline(t, i, is_html); } } else { // newline was seen @@ -451,14 +473,11 @@ void char_buffer::write_file_troff (void) } else if (can_see(&t, &i, HTML_IMAGE_RIGHT)) { write_start_image(RIGHT, FALSE); skip_to_newline(&t, &i); - } else if (can_see(&t, &i, HTML_IMAGE_INLINE)) { - write_start_image(INLINE, FALSE); - skip_to_newline(&t, &i); } else if (can_see(&t, &i, HTML_IMAGE_CENTERED)) { write_start_image(CENTERED, FALSE); skip_to_newline(&t, &i); } else { - write_upto_newline(&t, &i); + write_upto_newline(&t, &i, FALSE); } } while (t != 0); } @@ -582,13 +601,14 @@ static void createAllPages (void) static void removeAllPages (void) { +#if !defined(DEBUGGING) char buffer[4096]; + int i=1; -#if !defined(DEBUGGING) - sprintf(buffer, - "/bin/rm -f %s* \n", - imagePageStem); - system(buffer); + do { + sprintf(buffer, "%s%d", imagePageStem, i); + i++; + } while (remove(buffer) == 0); #endif } @@ -640,13 +660,13 @@ static void createImage (imageItem *i) if (i->X1 != -1) { char buffer[4096]; int x1 = max(min(i->X1, i->X2)*image_res/POSTSCRIPTRES-1*IMAGE_BOARDER_PIXELS, 0); - int y1 = max((image_res*vertical_offset/72)+min(i->Y1, i->Y2)*image_res/POSTSCRIPTRES, 0); - int x2 = min(max(i->X1, i->X2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS, i->maxx*image_res/POSTSCRIPTRES); - int y2 = (image_res*vertical_offset/72)+max(i->Y1, i->Y2)*image_res/POSTSCRIPTRES+2*IMAGE_BOARDER_PIXELS; + int y1 = max((image_res*vertical_offset/72)+min(i->Y1, i->Y2)*image_res/POSTSCRIPTRES-IMAGE_BOARDER_PIXELS, 0); + int x2 = max(i->X1, i->X2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS; + int y2 = (image_res*vertical_offset/72)+max(i->Y1, i->Y2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS; sprintf(buffer, "pnmcut %d %d %d %d < %s%d | pnmtopng %s > %s \n", - x1, y1, x2-x1, y2-y1, + x1, y1, x2-x1+1, y2-y1+1, imagePageStem, i->pageNo, TRANSPARENT, @@ -710,16 +730,12 @@ void char_buffer::write_file_html (void) } else if (can_see(&t, &i, HTML_IMAGE_RIGHT)) { write_start_image(RIGHT, TRUE); skip_to_newline(&t, &i); - } else if (can_see(&t, &i, HTML_IMAGE_INLINE)) { - stop(); - write_start_image(INLINE, TRUE); - skip_to_newline(&t, &i); } else if (can_see(&t, &i, HTML_IMAGE_CENTERED)) { stop(); write_start_image(CENTERED, TRUE); skip_to_newline(&t, &i); } else { - write_upto_newline(&t, &i); + write_upto_newline(&t, &i, TRUE); } } while (t != 0); } @@ -753,7 +769,7 @@ static void generateImages (char *regionFileName) int y1 = f->readInt(); int x2 = f->readInt(); int y2 = f->readInt(); - int maxx = f->readInt(); + int maxx = max(f->readInt(), MAX_WIDTH*image_res); char *name = f->readString(); int res = POSTSCRIPTRES; // --fixme-- prefer (f->readInt()) providing that troff can discover the value listOfImages.add(x1, y1, x2, y2, page, res, maxx, name); @@ -1052,6 +1068,18 @@ static void makeTempFiles (void) #endif } +/* + * removeTempFiles - remove the temporary files + */ + +static void removeTempFiles (void) +{ +#if !defined(DEBUGGING) + remove(psFileName); + remove(regionFileName); +#endif +} + /* * findPrefix - finds the optional prefix to the groff utilities. * It also builds the 'troff' executable name. @@ -1103,6 +1131,7 @@ int main(int argc, char **argv) ok = inputFile.do_html(argc, argv); removeAllPages(); } + removeTempFiles(); return ok; } diff --git a/src/preproc/tbl/main.cc b/src/preproc/tbl/main.cc index efc8fdcc..a08ea0be 100644 --- a/src/preproc/tbl/main.cc +++ b/src/preproc/tbl/main.cc @@ -243,7 +243,7 @@ void process_input_file(FILE *fp) while ((c = getc(fp)) != '\n') { if (c == EOF) { printf(".if '\\*(.T'html' \\X(table-end(\n"); - html_end_suppress(); + html_end_suppress(0); putchar('\n'); return; } @@ -251,7 +251,7 @@ void process_input_file(FILE *fp) } putchar('\n'); printf(".if '\\*(.T'html' \\X(table-end(\n"); - html_end_suppress(); + html_end_suppress(0); current_lineno++; } } diff --git a/src/roff/groff/groff.cc b/src/roff/groff/groff.cc index 0cdfb94b..aaca4e1f 100644 --- a/src/roff/groff/groff.cc +++ b/src/roff/groff/groff.cc @@ -348,7 +348,7 @@ int main(int argc, char **argv) commands[TROFF_INDEX].append_arg("-T", device); // html renders equations as images via ps if (strcmp(device, "html") == 0) - commands[EQN_INDEX].append_arg("-Tps"); + commands[EQN_INDEX].append_arg("-Tps:html"); else commands[EQN_INDEX].append_arg("-T", device); diff --git a/src/roff/troff/env.cc b/src/roff/troff/env.cc index 060850d1..b4f65117 100644 --- a/src/roff/troff/env.cc +++ b/src/roff/troff/env.cc @@ -133,9 +133,10 @@ void environment::output(node *nd, int no_fill, vunits vs, vunits post_vs, #ifdef WIDOW_CONTROL && (!widow_control || no_fill) #endif /* WIDOW_CONTROL */ - ) + ) { curdiv->output(nd, no_fill, vs, post_vs, width); - else { + emitted_node = 1; + } else { pending_output_line **p; for (p = &pending_lines; *p; p = &(*p)->next) ; @@ -598,6 +599,7 @@ environment::environment(symbol nm) #endif /* WIDOW_CONTROL */ need_eol(0), ignore_next_eol(0), + emitted_node(0), name(nm), control_char('.'), no_break_control_char('\''), @@ -2023,8 +2025,9 @@ void environment::add_html_tag_eol(void) need_eol--; add_html_tag("eol"); } - else if (!fill) { + else if (!fill && emitted_node) { add_html_tag("eol"); + emitted_node = 0; } } } diff --git a/src/roff/troff/env.h b/src/roff/troff/env.h index dd5273a0..3e0f70c1 100644 --- a/src/roff/troff/env.h +++ b/src/roff/troff/env.h @@ -183,6 +183,7 @@ class environment { #endif /* WIDOW_CONTROL */ int need_eol; int ignore_next_eol; + int emitted_node; // have we emitted a node since the last html eol tag? tab_type distance_to_next_tab(hunits *); void start_line(); diff --git a/src/roff/troff/input.cc b/src/roff/troff/input.cc index b5e17eb4..982e5bd5 100644 --- a/src/roff/troff/input.cc +++ b/src/roff/troff/input.cc @@ -4273,15 +4273,35 @@ node *do_suppress() { tok.next(); int c = tok.ch(); - - if (c == '0') - return new suppress_node(0, 0); - else if (c == '1') - return new suppress_node(1, 0); - else if (c == '2') - return new suppress_node(1, 1); - else - error("invalid argument to \\O"); + switch (c) { + case '0': + if (begin_level == 1) + return new suppress_node(0, 0); + break; + case '1': + if (begin_level == 1) + return new suppress_node(1, 0); + break; + case '2': + if (begin_level == 1) + return new suppress_node(1, 1); + break; + case '3': + begin_level++; + break; + case '4': + begin_level--; + break; + case '5': { + symbol filename = get_delim_name(); + if (begin_level == 1) + return new suppress_node(filename, 'i'); + return 0; + break; + } + default: + error("`%1' is an invalid argument to \\O", char(c)); + } return 0; } @@ -4567,12 +4587,10 @@ void image() error("l, r, c, or i expected (got %1)", tok.description()); position = 'c'; } - else { - tok.next(); - symbol filename = get_long_name(1); - if (!filename.is_null()) - curenv->add_node(new suppress_node(filename, position)); - } + tok.next(); + symbol filename = get_long_name(1); + if (!filename.is_null()) + curenv->add_node(new suppress_node(filename, position)); } skip_line(); } @@ -6285,7 +6303,6 @@ static int output_reg_minx_contents = -1; static int output_reg_miny_contents = -1; static int output_reg_maxx_contents = -1; static int output_reg_maxy_contents = -1; -static int output_low_mark_miny = -1; // internal only (limits miny) void check_output_limits(int x, int y) { @@ -6293,8 +6310,7 @@ void check_output_limits(int x, int y) output_reg_minx_contents = x; if (x > output_reg_maxx_contents) output_reg_maxx_contents = x; - if (((output_reg_miny_contents == -1) || (y < output_reg_miny_contents)) - && (y >= output_low_mark_miny)) + if ((output_reg_miny_contents == -1) || (y < output_reg_miny_contents)) output_reg_miny_contents = y; if (y > output_reg_maxy_contents) output_reg_maxy_contents = y; @@ -6303,7 +6319,6 @@ void check_output_limits(int x, int y) void reset_output_registers(int miny) { // fprintf(stderr, "reset_output_registers\n"); - output_low_mark_miny = miny; output_reg_minx_contents = -1; output_reg_miny_contents = -1; output_reg_maxx_contents = -1; diff --git a/src/roff/troff/node.cc b/src/roff/troff/node.cc index 3de11d58..680d13d7 100644 --- a/src/roff/troff/node.cc +++ b/src/roff/troff/node.cc @@ -765,6 +765,7 @@ public: void really_off(); void draw(char, hvpair *, int, font_size); void determine_line_limits (char code, hvpair *point, int npoints); + void check_charinfo(tfont *tf, charinfo *ci); int get_hpos() { return hpos; } int get_vpos() { return vpos; } }; @@ -928,8 +929,8 @@ void troff_output_file::flush_tbuf() put(tbuf_kern); put(' '); } - - check_output_limits(output_hpos, output_vpos); + check_output_limits(hpos, vpos); + check_output_limits(hpos, vpos + current_size + current_height); for (int i = 0; i < tbuf_len; i++) put(tbuf[i]); @@ -937,6 +938,19 @@ void troff_output_file::flush_tbuf() tbuf_len = 0; } +void troff_output_file::check_charinfo(tfont *tf, charinfo *ci) +{ + int size = tf->get_size().to_scaled_points(); + int height = tf->get_char_height(ci).to_units(); + int width = tf->get_width(ci).to_units() + + tf->get_italic_correction(ci).to_units(); + int depth = tf->get_char_depth(ci).to_units(); + check_output_limits(output_hpos, + output_vpos - height); + check_output_limits(output_hpos + width, + output_vpos + size + depth); +} + void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w, hunits k) { @@ -949,6 +963,7 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w, if (c == '\0') { flush_tbuf(); do_motion(); + check_charinfo(tf, ci); if (ci->numbered()) { put('N'); put(ci->get_number()); @@ -970,6 +985,7 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w, if (tbuf_len > 0 && hpos == output_hpos && vpos == output_vpos && kk == tbuf_kern && tbuf_len < TBUF_SIZE) { + check_charinfo(tf, ci); tbuf[tbuf_len++] = c; output_hpos += w.to_units() + kk; hpos = output_hpos; @@ -977,6 +993,7 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w, } flush_tbuf(); do_motion(); + check_charinfo(tf, ci); tbuf[tbuf_len++] = c; output_hpos += w.to_units() + kk; tbuf_kern = kk; @@ -985,6 +1002,8 @@ void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w, else { // flush_tbuf(); int n = hpos - output_hpos; + check_charinfo(tf, ci); + // check_output_limits(output_hpos, output_vpos); if (vpos == output_vpos && n > 0 && n < 100 && !force_motion) { put(char(n/10 + '0')); put(char(n%10 + '0')); @@ -1096,35 +1115,53 @@ void troff_output_file::set_font(tfont *tf) current_tfont = tf; } -/* - * determine_line_limits - works out the smallest box which will contain - * the entity, code, built from the point array. - */ - -void troff_output_file::determine_line_limits (char code, hvpair *point, int npoints) +// determine_line_limits - works out the smallest box which will contain +// the entity, code, built from the point array. +void troff_output_file::determine_line_limits(char code, hvpair *point, + int npoints) { int i, x, y; - switch (code) { - case 'c': case 'C': - /* only the h field is used when defining a circle */ - check_output_limits(output_hpos, output_vpos-point[0].h.to_units()/2); - check_output_limits(output_hpos+point[0].h.to_units(), output_vpos+point[0].h.to_units()/2); + // only the h field is used when defining a circle + check_output_limits(output_hpos, + output_vpos - point[0].h.to_units()/2); + check_output_limits(output_hpos + point[0].h.to_units(), + output_vpos + point[0].h.to_units()/2); break; case 'E': case 'e': - check_output_limits(output_hpos, output_vpos-point[1].v.to_units()/2); - check_output_limits(output_hpos+point[0].h.to_units(), output_vpos+point[1].v.to_units()/2); + check_output_limits(output_hpos, + output_vpos - point[0].v.to_units()/2); + check_output_limits(output_hpos + point[0].h.to_units(), + output_vpos + point[0].v.to_units()/2); + break; + case 'P': + case 'p': + x = output_hpos; + y = output_vpos; + check_output_limits(x, y); + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } + break; + case 't': + x = output_hpos; + y = output_vpos; + for (i = 0; i < npoints; i++) { + x += point[i].h.to_units(); + y += point[i].v.to_units(); + check_output_limits(x, y); + } break; default: - /* - * remember this doesn't work for arc.. - */ - x=output_hpos; - y=output_vpos; - for (i=0; iget_value(&prev_value))) - return( (int)prev_value ); + return (int)prev_value; else warning(WARN_REG, "number register `%1' not defined", p); - return( 0 ); + return 0; } -const char *get_reg_str (const char *p) +const char *get_reg_str(const char *p) { reg *r = (reg *)number_reg_dictionary.lookup(p); if (r) return r->get_string(); else warning(WARN_REG, "register `%1' not defined", p); - return( 0 ); + return 0; } void suppress_node::put(troff_output_file *out, const char *s) { - int i=0; - + int i = 0; while (s[i] != (char)0) { out->special_char(s[i]); i++; @@ -3518,13 +3555,12 @@ void suppress_node::tprint(troff_output_file *out) error("suppression limit registers span more than one page;\n" "image description %1 will be wrong", image_no); // remember that the filename will contain a %d in which the - // image_no is placed */ + // image_no is placed fprintf(stderr, "grohtml-info:page %d %d %d %d %d %d %s %d %d %s\n", current_page, get_reg_int("opminx"), get_reg_int("opminy"), - get_reg_int("opmaxx"), min(get_reg_int("opmaxy"), - out->get_vpos()), + get_reg_int("opmaxx"), get_reg_int("opmaxy"), // page offset + line length get_reg_int(".o") + get_reg_int(".l"), name, hresolution, vresolution, get_reg_str(".F")); diff --git a/tmac/html.tmac b/tmac/html.tmac index 199245b1..c5591c8d 100644 --- a/tmac/html.tmac +++ b/tmac/html.tmac @@ -39,7 +39,6 @@ .if d eh .eh '''' .tl '''' .\" it doesn't make sense to use hyphenation with html, so we turn it off. -.\" avoid line breaks after hyphen-like characters. .hy 0 .nr HY 0 .\" avoid line breaks after hyphen-like characters. diff --git a/tmac/s.tmac b/tmac/s.tmac index ad32d70a..7d1ad49c 100644 --- a/tmac/s.tmac +++ b/tmac/s.tmac @@ -1156,7 +1156,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. . ie '\*(.T'html' \{\ . if \\n[dl]+1n<=\\n[\\n[.ev]:ai] .HTML-TAG ".ip" . ti 0 -\\*[par*label] +\&\\$1 . br . \} . el \{\ diff --git a/tmac/www.tmac b/tmac/www.tmac index 985c485f..bd015e07 100644 --- a/tmac/www.tmac +++ b/tmac/www.tmac @@ -160,7 +160,7 @@ . if r ps4html .begin \{\ . image \\$2 \\$1.png . bp -. tl ''' +. tl '''' \O0\O1 . \} . if '\*(.T'html' .begin \{ @@ -172,12 +172,8 @@ .\" HTML-IMAGE-END - terminates an image for html .\" .de HTML-IMAGE-END -. if r ps4html .end \{\ -\O2\O1 -. \} -. if '\*(.T'html' .end \{ -\O2\O1 -. \} +. if r ps4html \O2\O1\O4 +. if '\*(.T'html' \O2\O1\O4 .. .nr png-no 0 .\" -- cgit v1.2.1