spv: Make parser generators compatible with python3.
[pspp] / src / output / html.c
index f5639cc0abb05c3ef2423e4ecb804bb9601a3668..989476ecaadd394b0133bdae7040966b16bec08d 100644 (file)
@@ -50,8 +50,8 @@ struct html_driver
   {
     struct output_driver driver;
 #ifdef HAVE_CAIRO
-    struct xr_color fg;
-    struct xr_color bg;
+    struct cell_color fg;
+    struct cell_color bg;
 #endif
     struct file_handle *handle;
     char *chart_file_name;
@@ -66,8 +66,7 @@ struct html_driver
 static const struct output_driver_class html_driver_class;
 
 static void html_output_table (struct html_driver *, const struct table_item *);
-static void escape_string (FILE *file,
-                           const char *text, size_t length,
+static void escape_string (FILE *file, const char *text,
                            const char *space, const char *newline);
 static void print_title_tag (FILE *file, const char *name,
                              const char *content);
@@ -201,7 +200,7 @@ print_title_tag (FILE *file, const char *name, const char *content)
   if (content != NULL)
     {
        fprintf (file, "<%s>", name);
-      escape_string (file, content, strlen (content), " ", " - ");
+      escape_string (file, content, " ", " - ");
       fprintf (file, "</%s>\n", name);
     }
 }
@@ -275,22 +274,14 @@ html_submit (struct output_driver *driver,
 
         case TEXT_ITEM_SYNTAX:
           fprintf (html->file, "<PRE class=\"syntax\">");
-          escape_string (html->file, s, strlen (s), " ", "<BR>");
+          escape_string (html->file, s, " ", "<BR>");
           fprintf (html->file, "</PRE>\n");
           break;
 
-        case TEXT_ITEM_PARAGRAPH:
-          print_title_tag (html->file, "P", s);
-          break;
-
         case TEXT_ITEM_LOG:
           print_title_tag (html->file, "PRE", s); /* should be <P><TT> */
           break;
 
-        case TEXT_ITEM_BLANK_LINE:
-          fputs ("<BR>", html->file);
-          break;
-
         case TEXT_ITEM_EJECT_PAGE:
           /* Nothing to do. */
           break;
@@ -305,20 +296,20 @@ html_submit (struct output_driver *driver,
     }
 }
 
-/* Write LENGTH characters in TEXT to file F, escaping characters as necessary
-   for HTML.  Spaces are replaced by SPACE, which should be " " or "&nbsp;"
-   New-lines are replaced by NEWLINE, which might be "<BR>" or "\n" or
-   something else appropriate. */
+/* Write TEXT to file F, escaping characters as necessary for HTML.  Spaces are
+   replaced by SPACE, which should be " " or "&nbsp;" New-lines are replaced by
+   NEWLINE, which might be "<BR>" or "\n" or something else appropriate. */
 static void
-escape_string (FILE *file,
-               const char *text, size_t length,
+escape_string (FILE *file, const char *text,
                const char *space, const char *newline)
 {
-  while (length-- > 0)
+  for (;;)
     {
       char c = *text++;
       switch (c)
         {
+        case 0:
+          return;
         case '\n':
           fputs (newline, file);
           break;
@@ -344,27 +335,39 @@ escape_string (FILE *file,
     }
 }
 
+static void
+escape_tag (FILE *file, const char *tag,
+            const char *text, const char *space, const char *newline)
+{
+  if (!text || !*text)
+    return;
+
+  fprintf (file, "<%s>", tag);
+  escape_string (file, text, space, newline);
+  fprintf (file, "</%s>", tag);
+}
+
 static const char *
 border_to_css (int border)
 {
   switch (border)
     {
-    case TAL_NONE:
+    case TABLE_STROKE_NONE:
       return NULL;
 
-    case TAL_SOLID:
+    case TABLE_STROKE_SOLID:
       return "solid";
 
-    case TAL_DASHED:
+    case TABLE_STROKE_DASHED:
       return "dashed";
 
-    case TAL_THICK:
+    case TABLE_STROKE_THICK:
       return "thick solid";
 
-    case TAL_THIN:
+    case TABLE_STROKE_THIN:
       return "thin solid";
 
-    case TAL_DOUBLE:
+    case TABLE_STROKE_DOUBLE:
       return "double";
 
     default:
@@ -411,8 +414,7 @@ html_put_footnote_markers (struct html_driver *html,
 
           if (i > 0)
             putc (',', html->file);
-          escape_string (html->file, f->marker,
-                         strlen (f->marker), " ", "<BR>");
+          escape_string (html->file, f->marker, " ", "<BR>");
         }
       fputs ("</SUP>", html->file);
     }
@@ -422,11 +424,25 @@ static void
 html_put_table_item_text (struct html_driver *html,
                           const struct table_item_text *text)
 {
-  escape_string (html->file, text->content, strlen (text->content),
-                 " ", "<BR>");
+  escape_string (html->file, text->content, " ", "<BR>");
   html_put_footnote_markers (html, text->footnotes, text->n_footnotes);
 }
 
+static void
+html_put_table_item_layers (struct html_driver *html,
+                            const struct table_item_layers *layers)
+{
+  for (size_t i = 0; i < layers->n_layers; i++)
+    {
+      if (i)
+        fputs ("<BR>\n", html->file);
+
+      const struct table_item_layer *layer = &layers->layers[i];
+      escape_string (html->file, layer->content, " ", "<BR>");
+      html_put_footnote_markers (html, layer->footnotes, layer->n_footnotes);
+    }
+}
+
 static void
 html_output_table (struct html_driver *html, const struct table_item *item)
 {
@@ -446,16 +462,11 @@ html_output_table (struct html_driver *html, const struct table_item *item)
   size_t n_footnotes = table_collect_footnotes (item, &f);
 
   for (size_t i = 0; i < n_footnotes; i++)
-    if (f[i])
-      {
-        put_tfoot (html, t, &tfoot);
-        fputs ("<SUP>", html->file);
-        escape_string (html->file, f[i]->marker, strlen (f[i]->marker),
-                       " ", "<BR>");
-        fputs ("</SUP> ", html->file);
-        escape_string (html->file, f[i]->content, strlen (f[i]->content),
-                       " ", "<BR>");
-      }
+    {
+      put_tfoot (html, t, &tfoot);
+      escape_tag (html->file, "SUP", f[i]->marker, " ", "<BR>");
+      escape_string (html->file, f[i]->content, " ", "<BR>");
+    }
   free (f);
   if (tfoot)
     fputs ("</TD></TR></TFOOT>\n", html->file);
@@ -463,7 +474,7 @@ html_output_table (struct html_driver *html, const struct table_item *item)
   fputs ("<TBODY VALIGN=\"TOP\">\n", html->file);
 
   const struct table_item_text *title = table_item_get_title (item);
-  const struct table_item_text *layers = table_item_get_layers (item);
+  const struct table_item_layers *layers = table_item_get_layers (item);
   if (title || layers)
     {
       fputs ("  <CAPTION>", html->file);
@@ -472,7 +483,7 @@ html_output_table (struct html_driver *html, const struct table_item *item)
       if (title && layers)
         fputs ("<BR>\n", html->file);
       if (layers)
-        html_put_table_item_text (html, layers);
+        html_put_table_item_layers (html, layers);
       fputs ("</CAPTION>\n", html->file);
     }
 
@@ -483,7 +494,6 @@ html_output_table (struct html_driver *html, const struct table_item *item)
       fputs ("  <TR>\n", html->file);
       for (x = 0; x < table_nc (t); )
         {
-          const struct cell_contents *c;
           struct table_cell cell;
           const char *tag;
           bool is_header;
@@ -502,19 +512,23 @@ html_output_table (struct html_driver *html, const struct table_item *item)
           tag = is_header ? "TH" : "TD";
           fprintf (html->file, "    <%s", tag);
 
-          int halign = (cell.n_contents > 0
-                        ? cell.contents[0].options & TAB_HALIGN
-                        : TAB_LEFT);
-          if (halign != TAB_LEFT)
-            fprintf (html->file, " ALIGN=\"%s\"",
-                     halign == TAB_RIGHT ? "RIGHT" : "CENTER");
+          enum table_halign halign = table_halign_interpret (
+            cell.style->cell_style.halign, cell.options & TAB_NUMERIC);
+          if (halign != TABLE_HALIGN_LEFT)
+            {
+              fprintf (html->file, " ALIGN=\"%s\"",
+                       (halign == TABLE_HALIGN_RIGHT ? "RIGHT"
+                        : halign == TABLE_HALIGN_CENTER ? "CENTER"
+                        : "CHAR"));
+              if (cell.style->cell_style.decimal_char)
+                fprintf (html->file, " CHAR=\"%c\"",
+                         cell.style->cell_style.decimal_char);
+            }
 
-          int valign = (cell.n_contents > 0
-                        ? cell.contents[0].options & TAB_VALIGN
-                        : TAB_LEFT);
-          if (valign != TAB_TOP)
+          if (cell.style->cell_style.valign != TABLE_VALIGN_TOP)
             fprintf (html->file, " ALIGN=\"%s\"",
-                     valign == TAB_BOTTOM ? "BOTTOM" : "MIDDLE");
+                     (cell.style->cell_style.valign == TABLE_VALIGN_BOTTOM
+                      ? "BOTTOM" : "MIDDLE"));
 
           colspan = table_cell_colspan (&cell);
           if (colspan > 1)
@@ -557,35 +571,36 @@ html_output_table (struct html_driver *html, const struct table_item *item)
           putc ('>', html->file);
 
           /* Output cell contents. */
-          for (c = cell.contents; c < &cell.contents[cell.n_contents]; c++)
+          const char *s = cell.text;
+          if (cell.options & TAB_FIX)
+            escape_tag (html->file, "TT", s, "&nbsp;", "<BR>");
+          else
             {
-              const char *s = c->text;
+              s += strspn (s, CC_SPACES);
+              escape_string (html->file, s, " ", "<BR>");
+            }
 
-              if (c->options & TAB_EMPH)
-                fputs ("<EM>", html->file);
-              if (c->options & TAB_FIX)
-                {
-                  fputs ("<TT>", html->file);
-                  escape_string (html->file, s, strlen (s), "&nbsp;", "<BR>");
-                  fputs ("</TT>", html->file);
-                }
-              else
+          if (cell.n_subscripts)
+            {
+              fputs ("<SUB>", html->file);
+              for (size_t i = 0; i < cell.n_subscripts; i++)
                 {
-                  s += strspn (s, CC_SPACES);
-                  escape_string (html->file, s, strlen (s), " ", "<BR>");
+                  if (i)
+                    putc (',', html->file);
+                  escape_string (html->file, cell.subscripts[i],
+                                 "&nbsp;", "<BR>");
                 }
-              if (c->options & TAB_EMPH)
-                fputs ("</EM>", html->file);
-
-              html_put_footnote_markers (html, c->footnotes, c->n_footnotes);
+              fputs ("</SUB>", html->file);
             }
+          if (cell.superscript)
+            escape_tag (html->file, "SUP", cell.superscript, "&nbsp;", "<BR>");
+          html_put_footnote_markers (html, cell.footnotes, cell.n_footnotes);
 
           /* Output </TH> or </TD>. */
           fprintf (html->file, "</%s>\n", tag);
 
        next_1:
           x = cell.d[TABLE_HORZ][1];
-          table_cell_free (&cell);
         }
       fputs ("  </TR>\n", html->file);
     }