+static void
+style_end (struct css_style *cs)
+{
+ if (cs->n_styles > 0)
+ fputs ("'", cs->file);
+}
+
+static void
+next_style (struct css_style *st)
+{
+ bool first = !st->n_styles++;
+ fputs (first ? " style='" : "; ", st->file);
+}
+
+static void
+put_style (struct css_style *st, const char *name, const char *value)
+{
+ next_style (st);
+ fprintf (st->file, "%s: %s", name, value);
+}
+
+static bool
+format_color (const struct cell_color color,
+ const struct cell_color default_color,
+ char *buf, size_t bufsize)
+{
+ bool retval = !cell_color_equal (color, default_color);
+ if (retval)
+ {
+ if (color.alpha == 255)
+ snprintf (buf, bufsize, "#%02x%02x%02x", color.r, color.g, color.b);
+ else
+ snprintf (buf, bufsize, "rgba(%d, %d, %d, %.3f)",
+ color.r, color.g, color.b, color.alpha / 255.0);
+ }
+ return retval;
+}
+
+static void
+put_border (const struct table *table, const struct table_cell *cell,
+ struct css_style *style,
+ enum table_axis axis, int h, int v,
+ const char *border_name)
+{
+ struct table_border_style border
+ = table_get_rule (table, axis, cell->d[H][h], cell->d[V][v]);
+ const char *css = border_to_css (border.stroke);
+ if (css)
+ {
+ next_style (style);
+ fprintf (style->file, "border-%s: %s", border_name, css);
+
+ char buf[32];
+ if (format_color (border.color, (struct cell_color) CELL_COLOR_BLACK,
+ buf, sizeof buf))
+ fprintf (style->file, " %s", buf);
+ }
+}
+
+static void
+html_put_table_cell (struct html_driver *html, const struct pivot_table *pt,
+ const struct table_cell *cell,
+ const char *tag, const struct table *t)
+{
+ fprintf (html->file, "<%s", tag);
+
+ struct css_style style;
+ style_start (&style, html->file);
+
+ struct string body = DS_EMPTY_INITIALIZER;
+ bool numeric = pivot_value_format_body (cell->value, pt, &body);
+
+ enum table_halign halign = table_halign_interpret (cell->cell_style->halign,
+ numeric);
+
+ switch (halign)
+ {
+ case TABLE_HALIGN_RIGHT:
+ put_style (&style, "text-align", "right");
+ break;
+ case TABLE_HALIGN_CENTER:
+ put_style (&style, "text-align", "center");
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ if (cell->options & TABLE_CELL_ROTATE)
+ put_style (&style, "writing-mode", "sideways-lr");
+
+ if (cell->cell_style->valign != TABLE_VALIGN_TOP)
+ {
+ put_style (&style, "vertical-align",
+ (cell->cell_style->valign == TABLE_VALIGN_BOTTOM
+ ? "bottom" : "middle"));
+ }
+
+ const struct font_style *fs = cell->font_style;
+ char bgcolor[32];
+ if (format_color (fs->bg[cell->d[V][0] % 2],
+ (struct cell_color) CELL_COLOR_WHITE,
+ bgcolor, sizeof bgcolor))
+ put_style (&style, "background", bgcolor);
+
+ char fgcolor[32];
+ if (format_color (fs->fg[cell->d[V][0] % 2],
+ (struct cell_color) CELL_COLOR_BLACK,
+ fgcolor, sizeof fgcolor))
+ put_style (&style, "color", fgcolor);
+
+ if (fs->typeface)
+ {
+ put_style (&style, "font-family", "\"");
+ escape_string (html->file, fs->typeface, " ", "\n");
+ putc ('"', html->file);
+ }
+ if (fs->bold)
+ put_style (&style, "font-weight", "bold");
+ if (fs->italic)
+ put_style (&style, "font-style", "italic");
+ if (fs->underline)
+ put_style (&style, "text-decoration", "underline");
+ if (fs->size)
+ {
+ char buf[32];
+ snprintf (buf, sizeof buf, "%dpt", fs->size);
+ put_style (&style, "font-size", buf);
+ }
+
+ if (t && html->borders)