html: Fix border-right for non-square tables.
[pspp] / src / output / html.c
index 3fb6bb83b5dc49a157c45f72627f21c6a0228243..186b1d3f5eefeee4a19edc134644ab18263995e8 100644 (file)
@@ -33,7 +33,9 @@
 #include "libpspp/i18n.h"
 #include "libpspp/message.h"
 #include "libpspp/version.h"
-#include "output/cairo.h"
+#ifdef HAVE_CAIRO
+#include "output/cairo-chart.h"
+#endif
 #include "output/chart-item.h"
 #include "output/driver-provider.h"
 #include "output/message-item.h"
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
+/* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */
+#define H TABLE_HORZ
+#define V TABLE_VERT
+
 struct html_driver
   {
     struct output_driver driver;
@@ -62,6 +68,7 @@ struct html_driver
     FILE *file;
     size_t chart_cnt;
 
+    bool bare;
     bool css;
     bool borders;
   };
@@ -88,36 +95,9 @@ opt (struct output_driver *d, struct string_map *options, const char *key,
   return driver_option_get (d, options, key, default_value);
 }
 
-static struct output_driver *
-html_create (struct file_handle *fh, enum settings_output_devices device_type,
-             struct string_map *o)
+static void
+put_header (struct html_driver *html)
 {
-  struct output_driver *d;
-  struct html_driver *html;
-
-  html = xzalloc (sizeof *html);
-  d = &html->driver;
-  output_driver_init (&html->driver, &html_driver_class, fh_get_file_name (fh),
-                      device_type);
-  html->css = parse_boolean (opt (d, o, "css", "true"));
-  html->borders = parse_boolean (opt (d, o, "borders", "true"));
-
-  html->handle = fh;
-  html->chart_file_name = parse_chart_file_name (opt (d, o, "charts",
-                                                      fh_get_file_name (fh)));
-  html->file = NULL;
-  html->chart_cnt = 1;
-#ifdef HAVE_CAIRO
-  parse_color (d, o, "background-color", "#FFFFFFFFFFFF", &html->bg);
-  parse_color (d, o, "foreground-color", "#000000000000", &html->fg);
-#endif
-  html->file = fn_open (html->handle, "w");
-  if (html->file == NULL)
-    {
-      msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (html->handle));
-      goto error;
-    }
-
   fputs ("<!doctype html>\n", html->file);
   fprintf (html->file, "<html");
   char *ln = get_language ();
@@ -198,6 +178,41 @@ html_create (struct file_handle *fh, enum settings_output_devices device_type,
     }
   fputs ("</head>\n", html->file);
   fputs ("<body>\n", html->file);
+}
+
+static struct output_driver *
+html_create (struct file_handle *fh, enum settings_output_devices device_type,
+             struct string_map *o)
+{
+  struct output_driver *d;
+  struct html_driver *html;
+
+  html = xzalloc (sizeof *html);
+  d = &html->driver;
+  output_driver_init (&html->driver, &html_driver_class, fh_get_file_name (fh),
+                      device_type);
+  html->bare = parse_boolean (opt (d, o, "bare", "false"));
+  html->css = parse_boolean (opt (d, o, "css", "true"));
+  html->borders = parse_boolean (opt (d, o, "borders", "true"));
+
+  html->handle = fh;
+  html->chart_file_name = parse_chart_file_name (opt (d, o, "charts",
+                                                      fh_get_file_name (fh)));
+  html->file = NULL;
+  html->chart_cnt = 1;
+#ifdef HAVE_CAIRO
+  html->bg = parse_color (opt (d, o, "background-color", "#FFFFFFFFFFFF"));
+  html->fg = parse_color (opt (d, o, "foreground-color", "#000000000000"));
+#endif
+  html->file = fn_open (html->handle, "w");
+  if (html->file == NULL)
+    {
+      msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (html->handle));
+      goto error;
+    }
+
+  if (!html->bare)
+    put_header (html);
 
   return d;
 
@@ -226,10 +241,11 @@ html_destroy (struct output_driver *driver)
 
   if (html->file != NULL)
     {
-      fprintf (html->file,
-               "</body>\n"
-               "</html>\n"
-               "<!-- end of file -->\n");
+      if (!html->bare)
+        fprintf (html->file,
+                 "</body>\n"
+                 "</html>\n"
+                 "<!-- end of file -->\n");
       fn_close (html->handle, html->file);
     }
   free (html->chart_file_name);
@@ -295,10 +311,6 @@ html_submit (struct output_driver *driver,
         case TEXT_ITEM_LOG:
           print_title_tag (html->file, "pre", s); /* should be <P><TT> */
           break;
-
-        case TEXT_ITEM_EJECT_PAGE:
-          /* Nothing to do. */
-          break;
         }
     }
   else if (is_message_item (output_item))
@@ -440,7 +452,7 @@ put_tfoot (struct html_driver *html, const struct table *t, bool *tfoot)
     {
       fputs ("<tfoot>\n", html->file);
       fputs ("<tr>\n", html->file);
-      fprintf (html->file, "<td colspan=%d>\n", table_nc (t));
+      fprintf (html->file, "<td colspan=%d>\n", t->n[H]);
       *tfoot = true;
     }
   else
@@ -497,7 +509,14 @@ html_output_table (struct html_driver *html, const struct table_item *item)
   bool tfoot = false;
   int y;
 
-  fputs ("<table>\n", html->file);
+  fputs ("<table", html->file);
+  if (item->notes)
+    {
+      fputs (" title=\"", html->file);
+      escape_string (html->file, item->notes, " ", "\n");
+      putc ('"', html->file);
+    }
+  fputs (">\n", html->file);
 
   const struct table_item_text *caption = table_item_get_caption (item);
   if (caption)
@@ -538,12 +557,12 @@ html_output_table (struct html_driver *html, const struct table_item *item)
 
   fputs ("<tbody>\n", html->file);
 
-  for (y = 0; y < table_nr (t); y++)
+  for (y = 0; y < t->n[V]; y++)
     {
       int x;
 
       fputs ("<tr>\n", html->file);
-      for (x = 0; x < table_nc (t);)
+      for (x = 0; x < t->n[H];)
         {
           struct table_cell cell;
           const char *tag;
@@ -553,10 +572,10 @@ html_output_table (struct html_driver *html, const struct table_item *item)
             goto next_1;
 
           /* output <td> or <th> tag. */
-          bool is_header = (y < table_ht (t)
-                       || y >= table_nr (t) - table_hb (t)
-                       || x < table_hl (t)
-                       || x >= table_nc (t) - table_hr (t));
+          bool is_header = (y < t->h[V][0]
+                            || y >= t->n[V] - t->h[V][1]
+                            || x < t->h[H][0]
+                            || x >= t->n[H] - t->h[H][1]);
           tag = is_header ? "th" : "td";
           fprintf (html->file, "<%s", tag);
 
@@ -595,7 +614,7 @@ html_output_table (struct html_driver *html, const struct table_item *item)
              int top = table_get_rule (t, TABLE_VERT, x, y, &color);
               put_border (style, top, "top");
 
-             if (y + rowspan == table_nr (t))
+             if (y + rowspan == t->n[V])
                {
                  int bottom = table_get_rule (t, TABLE_VERT, x, y + rowspan,
                                            &color);
@@ -605,7 +624,7 @@ html_output_table (struct html_driver *html, const struct table_item *item)
              int left = table_get_rule (t, TABLE_HORZ, x, y, &color);
               put_border (style, left, "left");
 
-             if (x + colspan == table_nc (t))
+             if (x + colspan == t->n[H])
                {
                  int right = table_get_rule (t, TABLE_HORZ, x + colspan, y,
                                           &color);