"); + escape_string (html->file, s, " ", "\n"); + break; - assert (s->class == &tab_table_class ) ; + case TEXT_ITEM_LOG: + print_title_tag (html->file, "pre", s); /* should be
"); + fprintf (html->file, "
*/
+ break;
- switch (s->type)
+ case TEXT_ITEM_EJECT_PAGE:
+ /* Nothing to do. */
+ break;
+ }
+ }
+ else if (is_message_item (output_item))
{
- case SOM_TABLE:
- output_tab_table ( this, (struct tab_table *) s->ext);
- break;
- case SOM_CHART:
- link_image (x->file, ((struct chart *)s->ext)->file_name);
- break;
- default:
- NOT_REACHED ();
+ const struct message_item *message_item = to_message_item (output_item);
+ char *s = msg_to_string (message_item_get_msg (message_item));
+ print_title_tag (html->file, "p", s);
+ free (s);
}
}
-/* Write LENGTH characters in TEXT to file F, escaping characters
- as necessary for HTML. Spaces are replaced by SPACE, which
- should be " " or " ". */
+/* Write TEXT to file F, escaping characters as necessary for HTML. Spaces are
+ replaced by SPACE, which should be " " or " " New-lines are replaced by
+ NEWLINE, which might be "
" or "\n" or something else appropriate. */
static void
-escape_string (FILE *file,
- const char *text, size_t length,
- const char *space)
+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;
case '&':
fputs ("&", file);
break;
@@ -240,6 +339,9 @@ escape_string (FILE *file,
case ' ':
fputs (space, file);
break;
+ case '"':
+ fputs (""", file);
+ break;
default:
putc (c, file);
break;
@@ -247,172 +349,325 @@ escape_string (FILE *file,
}
}
-/* Outputs content for a cell with options OPTS and contents
- TEXT. */
-void
-html_put_cell_contents (struct outp_driver *this,
- unsigned int opts, const struct substring text)
+static void
+escape_tag (FILE *file, const char *tag,
+ const char *text, const char *space, const char *newline)
{
- struct html_driver_ext *x = this->ext;
+ if (!text || !*text)
+ return;
- if (!(opts & TAB_EMPTY))
+ fprintf (file, "<%s>", tag);
+ escape_string (file, text, space, newline);
+ fprintf (file, "%s>", tag);
+}
+
+static const char *
+border_to_css (int border)
+{
+ switch (border)
{
- if (opts & TAB_EMPH)
- fputs ("", x->file);
- if (opts & TAB_FIX)
- {
- fputs ("", x->file);
- escape_string (x->file, ss_data (text), ss_length (text), " ");
- fputs ("", x->file);
- }
- else
- {
- size_t initial_spaces = ss_span (text, ss_cstr (CC_SPACES));
- escape_string (x->file,
- ss_data (text) + initial_spaces,
- ss_length (text) - initial_spaces,
- " ");
- }
- if (opts & TAB_EMPH)
- fputs ("", x->file);
+ case TABLE_STROKE_NONE:
+ return NULL;
+
+ case TABLE_STROKE_SOLID:
+ return "solid";
+
+ case TABLE_STROKE_DASHED:
+ return "dashed";
+
+ case TABLE_STROKE_THICK:
+ return "thick solid";
+
+ case TABLE_STROKE_THIN:
+ return "thin solid";
+
+ case TABLE_STROKE_DOUBLE:
+ return "double";
+
+ default:
+ return NULL;
}
+
}
-/* Write table T to THIS output driver. */
-static void
-output_tab_table (struct outp_driver *this, struct tab_table *t)
+struct css_style
{
- struct html_driver_ext *x = this->ext;
+ FILE *file;
+ int n_styles;
+};
- if (t->nr == 1 && t->nc == 1)
- {
- fputs ("
", x->file); - html_put_cell_contents (this, t->ct[0], *t->cc); - fputs ("
\n", x->file); +static struct css_style * +style_start (FILE *file) +{ + struct css_style *cs = XMALLOC (struct css_style); + cs->file = file; + cs->n_styles = 0; + fputs (" style=\"", file); + return cs; +} - return; - } +static void +style_end (struct css_style *cs) +{ + fputs ("\"", cs->file); + free (cs); +} - fputs ("or | tag. */ - tag = (r < t->t || r >= t->nr - t->b - || c < t->l || c >= t->nc - t->r) ? "TH" : "TD"; - fprintf (x->file, " <%s ALIGN=%s", - tag, - (*ct & TAB_ALIGN_MASK) == TAB_LEFT ? "LEFT" - : (*ct & TAB_ALIGN_MASK) == TAB_RIGHT ? "RIGHT" - : "CENTER"); - if (*ct & TAB_JOIN) - { - if (j->x2 - j->x1 > 1) - fprintf (x->file, " COLSPAN=%d", j->x2 - j->x1); - if (j->y2 - j->y1 > 1) - fprintf (x->file, " ROWSPAN=%d", j->y2 - j->y1); - } - putc ('>', x->file); - - /* Output cell contents. */ - html_put_cell_contents (this, *ct, *cc); - - /* Output | or . */ - fprintf (x->file, "%s>\n", tag); - } - fputs ("
---|
or | 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));
+ tag = is_header ? "th" : "td";
+ fprintf (html->file, "<%s", tag);
+
+ struct css_style *style = style_start (html->file);
+ enum table_halign halign = table_halign_interpret (
+ cell.style->cell_style.halign, cell.options & TAB_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.style->cell_style.valign != TABLE_VALIGN_TOP)
+ {
+ put_style (style, "vertical-align",
+ (cell.style->cell_style.valign == TABLE_VALIGN_BOTTOM
+ ? "bottom" : "middle"));
+ }
+
+ int colspan = table_cell_colspan (&cell);
+ int rowspan = table_cell_rowspan (&cell);
+
+ if (html->borders)
+ {
+ /* Cell borders. */
+ struct cell_color color;
+
+ int top = table_get_rule (t, TABLE_VERT, x, y, &color);
+ put_border (style, top, "top");
+
+ if (y + rowspan == table_nr (t))
+ {
+ int bottom = table_get_rule (t, TABLE_VERT, x, y + rowspan,
+ &color);
+ put_border (style, bottom, "bottom");
+ }
+
+ int left = table_get_rule (t, TABLE_HORZ, x, y, &color);
+ put_border (style, left, "left");
+
+ if (x + colspan == table_nc (t))
+ {
+ int right = table_get_rule (t, TABLE_HORZ, x + colspan, y,
+ &color);
+ put_border (style, right, "right");
+ }
+ }
+ style_end (style);
+
+ if (colspan > 1)
+ fprintf (html->file, " colspan=\"%d\"", colspan);
+
+ if (rowspan > 1)
+ fprintf (html->file, " rowspan=\"%d\"", rowspan);
+
+ putc ('>', html->file);
+
+ /* Output cell contents. */
+ const char *s = cell.text;
+ if (cell.options & TAB_FIX)
+ escape_tag (html->file, "tt", s, " ", " "); + else + { + s += strspn (s, CC_SPACES); + escape_string (html->file, s, " ", " "); + } + + if (cell.n_subscripts) + { + fputs ("", html->file); + for (size_t i = 0; i < cell.n_subscripts; i++) + { + if (i) + putc (',', html->file); + escape_string (html->file, cell.subscripts[i], + " ", " "); + } + fputs ("", html->file); + } + if (cell.superscript) + escape_tag (html->file, "sup", cell.superscript, " ", " "); + html_put_footnote_markers (html, cell.footnotes, cell.n_footnotes); + + /* output | or . */
+ fprintf (html->file, "%s>\n", tag);
+
+ next_1:
+ x = cell.d[TABLE_HORZ][1];
+ }
+ fputs ("
---|