groff
[Top][All Lists]
Advanced

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

Re: [Groff] HTML output in Mozilla


From: Gaius Mulley
Subject: Re: [Groff] HTML output in Mozilla
Date: Thu, 12 Apr 2001 14:09:16 +0100

Hi Werner,

here are the improved patches together with the inline image fixes.
These patches generate better equation handling, fix alot of image
bugs, produce better html tables and fix a html glyph translation
bug.

Can I ask the members of the list to examine:

troff_output_file::check_charinfo

in particular and see whether this is correct in evaluating the
miny/maxy limits for a character. The images it generates seem
to suggest that the veryical region defined by miny and maxy
is too large.

Thanks

Gaius


2001-04-12  Gaius Mulley <address@hidden>

        * src/devices/grohtml/grohtml.man: updated manual page regarding simple
          anchor.
        * src/preproc/html/pre-html.cc (createImage): fixed right hand cropping
          of images.
        * src/preproc/html/pre-html.cc (removeTempFiles): new function to tidy 
up
          temporary files.
        * src/preproc/html/pre-html.cc (main): calls removeTempFiles.
        * src/preproc/html/pre-html.cc: 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.
        * src/devices/grohtml/post-html.cc (generate_img_src): new function.
        * src/devices/grohtml/post-html.cc (html_printer::do_auto_image):
          utilizes it.
        * src/devices/grohtml/post-html.cc (do_heading) (do_title):
          include inline images within their contents.
        * src/devices/grohtml/post-html.cc (html_printer::begin_page):
          tidied up comments that are issued to the html output file.
        * src/devices/grohtml/post-html.cc (html_printer::do_fill):
          fixed so that .nf works with fonts other than courier.
        * src/devices/grohtml/post-html.cc (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.
        * src/roff/troff/node.cc (troff_output_file::determine_line_limits):
          Alterations to limit checking.
        * tmac/www.tmac: changes to reflect new suppress nodes.
          
2001-04-08  Bruno Haible  <address@hidden>

        * 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.


--- groff-cvs/src/devices/grohtml/grohtml.man   Mon Mar 19 15:33:03 2001
+++ groff-html/src/devices/grohtml/grohtml.man  Thu Apr 12 12:59:42 2001
@@ -90,6 +90,7 @@
 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
--- groff-cvs/src/devices/grohtml/html-text.cc  Mon Mar 19 15:33:03 2001
+++ groff-html/src/devices/grohtml/html-text.cc Thu Apr 12 12:59:42 2001
@@ -140,7 +140,7 @@
     int width=current_indentation*100/linelength;
 
     if (width > 0) {
-      out->put_string("<table width=\"100%\" rules=\"none\" frame=\"none\"\n   
    cols=\"2\" cellspacing=\"0\" cellpadding=\"0\">").nl();
+      out->put_string("<table width=\"100%\" border=0 rules=\"none\" 
frame=\"void\"\n       cols=\"2\" cellspacing=\"0\" cellpadding=\"0\">").nl();
       out->put_string("<tr valign=\"top\" align=\"left\">").nl();
       if ((t->arg1 == 0) || (strcmp(t->arg1, "") == 0))
        out->put_string("<td 
width=\"").put_number(width).put_string("%\"></td>");
@@ -612,7 +612,11 @@
 
 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;
 }
 
--- groff-cvs/src/devices/grohtml/post-html.cc  Thu Apr 12 12:51:10 2001
+++ groff-html/src/devices/grohtml/post-html.cc Thu Apr 12 12:59:42 2001
@@ -340,16 +340,19 @@
 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 @@
   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 <line>?
+  int             is_img_auto;          // image created by eqn delim
   int             thickness;            // the thickness of a line
 };
 
@@ -365,11 +369,12 @@
                      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)
 {
 }
 
@@ -420,6 +425,25 @@
 }
 
 /*
+ *  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",
  *  but this does assume that all C++ compilers can handle this feature. 
Pragmatically
@@ -748,7 +772,7 @@
   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 @@
   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 @@
   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 @@
   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));
   }
 }
@@ -1196,6 +1222,30 @@
 }
 
 /*
+ *  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, "<img src=\"");
+    strncat(buffer, filename, MAX_STRING_LENGTH-strlen("<img src=\"")-1);
+    if (strlen(buffer) < MAX_STRING_LENGTH-3) {
+      strncat(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.
  *                  An image tag may be passed through from pic, eqn
@@ -1205,24 +1255,17 @@
 
 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, "<img src=\"");
-    strncat(buffer, filename, MAX_STRING_LENGTH-strlen("<img src=\"")-1);
-    if (strlen(buffer) < MAX_STRING_LENGTH-3) {
-      strncat(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 @@
       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 @@
                                 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 @@
   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 @@
       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 @@
     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 @@
   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 @@
        int   l          = strlen(html_glyph);
        int   i;
 
+       // Escape the name, so that "&" doesn't get expanded to "&amp;"
+       // later during translate_to_html.
+       add_char_to_sbuf('\\'); add_char_to_sbuf('(');
+
        for (i=0; i<l; i++) {
          add_char_to_sbuf(html_glyph[i]);
        }
+       add_char_to_sbuf('\\'); add_char_to_sbuf(')');
       }
     }
   }
@@ -2632,7 +2714,9 @@
 void html_printer::begin_page(int n)
 {
   page_number            =  n;
+#if defined(DEBUGGING)
   html.begin_comment("Page: ").put_string(i_to_a(page_number)).end_comment();;
+#endif
   no_of_printed_pages++;
 
   output_style.f         =  0;
@@ -2700,10 +2784,13 @@
 #endif
     t = time(0);
     html.begin_comment("CreationDate: ")
-      .put_string(ctime(&t))
+      .put_string(ctime(&t), strlen(ctime(&t))-1)
       .end_comment();
   }
+#if defined(DEBUGGING)
   html.begin_comment("Total number of pages: 
").put_string(i_to_a(no_of_printed_pages)).end_comment();
+#endif
+  html.end_line();
   html.end_line();
   /*
    *  now run through the file list copying each temporary file in turn and 
emitting the links.
--- groff-cvs/src/include/html-strings.h        Wed Jan 17 14:17:23 2001
+++ groff-html/src/include/html-strings.h       Thu Apr 12 12:59:42 2001
@@ -23,8 +23,9 @@
  *  and later detected by pre-html.cc
  */
 
-#define HTML_IMAGE_INLINE     ".HTML-IMAGE-INLINE"
-#define HTML_IMAGE_CENTERED   ".HTML-IMAGE"
-#define HTML_IMAGE_RIGHT      ".HTML-IMAGE-RIGHT"
-#define HTML_IMAGE_LEFT       ".HTML-IMAGE-LEFT"
-#define HTML_IMAGE_END        ".HTML-IMAGE-END"
+#define HTML_IMAGE_INLINE_BEGIN     "\\O[HTML-IMAGE-INLINE-BEGIN]"
+#define HTML_IMAGE_INLINE_END       "\\O[HTML-IMAGE-INLINE-END]"
+#define HTML_IMAGE_CENTERED         ".HTML-IMAGE"
+#define HTML_IMAGE_RIGHT            ".HTML-IMAGE-RIGHT"
+#define HTML_IMAGE_LEFT             ".HTML-IMAGE-LEFT"
+#define HTML_IMAGE_END              ".HTML-IMAGE-END"
--- groff-cvs/src/include/htmlindicate.h        Wed Jan 17 14:17:23 2001
+++ groff-html/src/include/htmlindicate.h       Thu Apr 12 12:59:42 2001
@@ -61,7 +61,7 @@
  *  html_end_suppress - end the suppression of output.
  */
 
-extern void html_end_suppress (void);
+extern void html_end_suppress (int is_inline);
 
 #endif
 
--- groff-cvs/src/libs/libgroff/htmlindicate.cc Wed Jan 17 14:17:24 2001
+++ groff-html/src/libs/libgroff/htmlindicate.cc        Thu Apr 12 12:59:42 2001
@@ -39,29 +39,36 @@
  */
 
 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)
 {
   if (is_inline) {
-    put_string(HTML_IMAGE_INLINE, stdout);
+    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);
+  }
 }
 
 /*
@@ -74,8 +81,9 @@
 void graphic_start (int is_inline)
 {
   if (! is_in_graphic_start) {
-    put_string(".if '\\*(.T'html-old' \\X(graphic-start(\\c\n", stdout);
+    // 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;
   }
 }
@@ -87,8 +95,8 @@
 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;
   }
 }
--- groff-cvs/src/preproc/eqn/main.cc   Thu Apr 12 12:51:31 2001
+++ groff-html/src/preproc/eqn/main.cc  Thu Apr 12 13:46:00 2001
@@ -25,6 +25,7 @@
 #include "searchpath.h"
 #include "macropath.h"
 #include "htmlindicate.h"
+#include "pbox.h"
 
 #define STARTUP_FILE "eqnrc"
 
@@ -41,7 +42,13 @@
 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 +82,31 @@
       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);
+      if (html && (suppress_html == 0))
+       graphic_start(0);
       put_string(linebuf, stdout);
       int start_lineno = current_lineno + 1;
       str.clear();
@@ -112,7 +138,8 @@
       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))
@@ -168,9 +195,17 @@
       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 @@
   printf(".lf %d\n", current_lineno);
   output_string();
   restore_compatibility();
-  graphic_end();
   printf(".lf %d\n", current_lineno + 1);
   return 1;
 }
@@ -290,6 +324,10 @@
       break;
     case 'T':
       device = optarg;
+      if (strcmp(device, "ps:html") == 0) {
+       device = "ps";
+       html = 1;
+      }
       break;
     case 's':
       if (!set_gsize(optarg))
--- groff-cvs/src/preproc/html/pre-html.cc      Thu Apr 12 12:51:35 2001
+++ groff-html/src/preproc/html/pre-html.cc     Thu Apr 12 12:59:42 2001
@@ -55,13 +55,17 @@
 
 #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 @@
   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 @@
 
 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_start_image (IMAGE_ALIGNMENT pos, int is_html)
 {
-  writeString(".begin \\{\\\n");
-  switch (pos) {
+  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 INLINE:
-    writeString(".    image i ");
-    break;
-  case CENTERED:
-  default:
-    writeString(".    image c ");
+    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 @@
       } 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 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 @@
   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 @@
       } 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 @@
       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);
@@ -1053,6 +1069,18 @@
 }
 
 /*
+ *  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 @@
     ok = inputFile.do_html(argc, argv);
     removeAllPages();
   }
+  removeTempFiles();
   return ok;
 }
 
--- groff-cvs/src/roff/groff/groff.cc   Thu Apr 12 12:51:41 2001
+++ groff-html/src/roff/groff/groff.cc  Thu Apr 12 12:59:42 2001
@@ -348,7 +348,7 @@
   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);
 
--- groff-cvs/src/preproc/tbl/main.cc   Thu Apr 12 12:51:40 2001
+++ groff-html/src/preproc/tbl/main.cc  Thu Apr 12 12:59:42 2001
@@ -243,7 +243,7 @@
            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 @@
            }
            putchar('\n');
            printf(".if '\\*(.T'html' \\X(table-end(\n");
-           html_end_suppress();
+           html_end_suppress(0);
            current_lineno++;
          }
        }
--- groff-cvs/src/roff/troff/env.cc     Thu Apr 12 12:51:47 2001
+++ groff-html/src/roff/troff/env.cc    Thu Apr 12 12:59:42 2001
@@ -133,9 +133,10 @@
 #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 @@
 #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 @@
       need_eol--;
       add_html_tag("eol");
     }
-    else if (!fill) {
+    else if (!fill && emitted_node) {
       add_html_tag("eol");
+      emitted_node = 0;
     }
   }
 }
--- groff-cvs/src/roff/troff/env.h      Thu Apr 12 12:51:48 2001
+++ groff-html/src/roff/troff/env.h     Thu Apr 12 12:59:42 2001
@@ -183,6 +183,7 @@
 #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();
--- groff-cvs/src/roff/troff/input.cc   Thu Apr 12 12:51:57 2001
+++ groff-html/src/roff/troff/input.cc  Thu Apr 12 13:43:58 2001
@@ -4274,14 +4274,37 @@
   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 +4590,10 @@
       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 +6306,6 @@
 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 +6313,7 @@
     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 +6322,6 @@
 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;
--- groff-cvs/src/roff/troff/node.cc    Thu Apr 12 12:52:03 2001
+++ groff-html/src/roff/troff/node.cc   Thu Apr 12 13:35:54 2001
@@ -765,6 +765,7 @@
   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 @@
     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,17 @@
   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+current_size+depth);
+}
+
 void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w,
                                       hunits k)
 {
@@ -949,6 +961,7 @@
   if (c == '\0') {
     flush_tbuf();
     do_motion();
+    check_charinfo(tf, ci);
     if (ci->numbered()) {
       put('N');
       put(ci->get_number());
@@ -970,6 +983,7 @@
     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 +991,7 @@
     }
     flush_tbuf();
     do_motion();
+    check_charinfo(tf, ci);
     tbuf[tbuf_len++] = c;
     output_hpos += w.to_units() + kk;
     tbuf_kern = kk;
@@ -985,6 +1000,8 @@
   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'));
@@ -1110,17 +1127,37 @@
   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                      , 
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..
+     *  remember this doesn't work for arc.. yet
      */
     x=output_hpos;
     y=output_vpos;
@@ -3523,8 +3560,7 @@
                "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"));
--- groff-cvs/tmac/html.tmac    Wed Jan 17 14:17:26 2001
+++ groff-html/tmac/html.tmac   Thu Apr 12 12:59:42 2001
@@ -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.
--- groff-cvs/tmac/s.tmac       Mon Mar 19 15:33:04 2001
+++ groff-html/tmac/s.tmac      Thu Apr 12 12:59:42 2001
@@ -1156,7 +1156,7 @@
 .      ie '\*(.T'html' \{\
 .              if \\n[dl]+1n<=\\n[\\n[.ev]:ai] .HTML-TAG ".ip"
 .              ti 0
-\\*[par*label]
+\&\\$1
 .              br
 .      \}
 .      el \{\
--- groff-cvs/tmac/www.tmac     Fri Mar 30 13:52:03 2001
+++ groff-html/tmac/www.tmac    Thu Apr 12 12:59:42 2001
@@ -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
 .\"

reply via email to

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