4 * Copyright (C) 1999, 2000 Rasca, Berlin
6 * Copyright (c) 2001-2013 Andreas J. Guelzow
7 * EMail: aguelzow@pyrshep.ca
8 * Copyright 2013 Morten Welinder <terra@gnone.org>
11 * Almer. S. Tigelaar <almer1@dds.nl>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses/>.
27 #include <gnumeric-config.h>
29 #include <goffice/goffice.h>
30 #include <workbook-view.h>
32 #include <sheet-style.h>
34 #include <style-color.h>
38 #include <sheet-merge.h>
42 #include <style-border.h>
43 #include <rendered-value.h>
48 #include <gsf/gsf-output.h>
70 * print the string to output encoded all special chars
74 html_print_encoded (GsfOutput
*output
, char const *str
)
80 for (; *str
!= '\0' ; str
= g_utf8_next_char (str
)) {
83 gsf_output_puts (output
, "<");
86 gsf_output_puts (output
, ">");
89 gsf_output_puts (output
, "&");
92 gsf_output_puts (output
, """);
95 gsf_output_puts (output
, "<br>\n");
98 gsf_output_puts (output
, "<br>\r");
99 if( *(str
+1) == '\n' ) {
100 gsf_output_puts (output
, "\n");
105 c
= g_utf8_get_char (str
);
106 if (((c
>= 0x20) && (c
< 0x80)) ||
107 (c
== '\n') || (c
== '\r') || (c
== '\t'))
108 gsf_output_write (output
, 1, str
);
110 gsf_output_printf (output
, "&#%u;", c
);
117 html_get_text_color (GnmCell
*cell
, GnmStyle
const *style
, guint
*r
, guint
*g
, guint
*b
)
119 GOColor fore
= gnm_cell_get_render_color (cell
);
124 *r
= GO_COLOR_UINT_R (fore
);
125 *g
= GO_COLOR_UINT_G (fore
);
126 *b
= GO_COLOR_UINT_B (fore
);
130 html_get_back_color (GnmStyle
const *style
, guint
*r
, guint
*g
, guint
*b
)
132 GnmColor
const *color
= gnm_style_get_back_color (style
);
133 *r
= GO_COLOR_UINT_R (color
->go_color
);
134 *g
= GO_COLOR_UINT_G (color
->go_color
);
135 *b
= GO_COLOR_UINT_B (color
->go_color
);
138 /*****************************************************************************/
142 cb_html_add_chars (GsfOutput
*output
, char const *text
, int len
)
146 g_return_if_fail (len
> 0);
148 str
= g_strndup (text
, len
);
149 html_print_encoded (output
, str
);
154 cb_html_attrs_as_string (GsfOutput
*output
, PangoAttribute
*a
, html_version_t version
)
156 /* PangoColor const *c; */
157 char const *closure
= NULL
;
159 switch (a
->klass
->type
) {
160 case PANGO_ATTR_FAMILY
:
162 case PANGO_ATTR_SIZE
:
164 case PANGO_ATTR_RISE
:
165 if (((PangoAttrInt
*)a
)->value
> 5) {
166 gsf_output_puts (output
, "<sup>");
168 } else if (((PangoAttrInt
*)a
)->value
< -5) {
169 gsf_output_puts (output
, "<sub>");
173 case PANGO_ATTR_STYLE
:
174 if (((PangoAttrInt
*)a
)->value
== PANGO_STYLE_ITALIC
) {
175 gsf_output_puts (output
, "<i>");
179 case PANGO_ATTR_WEIGHT
:
180 if (((PangoAttrInt
*)a
)->value
> 600){
181 gsf_output_puts (output
, "<b>");
185 case PANGO_ATTR_STRIKETHROUGH
:
186 if (((PangoAttrInt
*)a
)->value
== 1) {
187 if (version
== HTML32
) {
188 gsf_output_puts (output
, "<strike>");
189 closure
= "</strike>";
193 "<span style=\"text-decoration: "
199 case PANGO_ATTR_UNDERLINE
:
200 if ((version
!= HTML40
) &&
201 (((PangoAttrInt
*)a
)->value
!= PANGO_UNDERLINE_NONE
)) {
202 gsf_output_puts (output
, "<u>");
206 case PANGO_ATTR_FOREGROUND
:
207 /* c = &((PangoAttrColor *)a)->color; */
208 /* g_string_append_printf (accum, "[color=%02xx%02xx%02x", */
209 /* ((c->red & 0xff00) >> 8), */
210 /* ((c->green & 0xff00) >> 8), */
211 /* ((c->blue & 0xff00) >> 8)); */
214 if (a
->klass
->type
==
215 go_pango_attr_subscript_get_attr_type ()) {
216 if (((GOPangoAttrSubscript
*)a
)->val
) {
217 gsf_output_puts (output
, "<sub>");
220 } else if (a
->klass
->type
==
221 go_pango_attr_superscript_get_attr_type ()) {
222 if (((GOPangoAttrSuperscript
*)a
)->val
) {
223 gsf_output_puts (output
, "<sup>");
234 html_new_markup (GsfOutput
*output
, const PangoAttrList
*markup
, char const *text
,
235 html_version_t version
)
238 PangoAttrIterator
* iter
;
240 int len
= strlen (text
);
241 GString
*closure
= g_string_new ("");
243 iter
= pango_attr_list_get_iterator ((PangoAttrList
*) markup
);
248 g_string_erase (closure
, 0, -1);
249 pango_attr_iterator_range (iter
, &from
, &to
);
250 from
= (from
> len
) ? len
: from
; /* Since "from" can be really big! */
251 to
= (to
> len
) ? len
: to
; /* Since "to" can be really big! */
253 cb_html_add_chars (output
, text
+ handled
, from
- handled
);
254 list
= pango_attr_iterator_get_attrs (iter
);
255 for (l
= list
; l
!= NULL
; l
= l
->next
) {
256 char const *result
= cb_html_attrs_as_string (output
, l
->data
, version
);
258 g_string_prepend (closure
, result
);
262 cb_html_add_chars (output
, text
+ from
, to
- from
);
263 gsf_output_puts (output
, closure
->str
);
265 } while (pango_attr_iterator_next (iter
));
267 g_string_free (closure
, TRUE
);
268 pango_attr_iterator_destroy (iter
);
274 /*****************************************************************************/
277 html_write_cell_content (GsfOutput
*output
, GnmCell
*cell
, GnmStyle
const *style
, html_version_t version
)
282 char *rendered_string
;
283 gboolean hidden
= gnm_style_get_contents_hidden (style
);
284 GnmHLink
* hlink
= gnm_style_get_hlink (style
);
285 const guchar
* hlink_target
= NULL
;
287 if (hlink
&& GNM_IS_HLINK_URL (hlink
)) {
288 hlink_target
= gnm_hlink_get_target (hlink
);
291 if (version
== HTML32
&& hidden
)
292 gsf_output_puts (output
, "<!-- 'HIDDEN DATA' -->");
295 if (gnm_style_get_font_italic (style
))
296 gsf_output_puts (output
, "<i>");
297 if (gnm_style_get_font_bold (style
))
298 gsf_output_puts (output
, "<b>");
299 if (gnm_style_get_font_uline (style
) != UNDERLINE_NONE
)
300 gsf_output_puts (output
, "<u>");
301 if (font_is_monospaced (style
))
302 gsf_output_puts (output
, "<tt>");
303 if (gnm_style_get_font_strike (style
)) {
304 if (version
== HTML32
)
305 gsf_output_puts (output
, "<strike>");
307 gsf_output_puts (output
,
308 "<span style=\"text-decoration: line-through;\">");
310 switch (gnm_style_get_font_script (style
)) {
311 case GO_FONT_SCRIPT_SUB
:
312 gsf_output_puts (output
, "<sub>");
314 case GO_FONT_SCRIPT_SUPER
:
315 gsf_output_puts (output
, "<sup>");
323 gsf_output_printf (output
, "<a href=\"%s\">", hlink_target
);
326 const PangoAttrList
* markup
= NULL
;
328 if (style
!= NULL
&& version
!= HTML40
) {
329 html_get_text_color (cell
, style
, &r
, &g
, &b
);
330 if (r
> 0 || g
> 0 || b
> 0)
331 gsf_output_printf (output
, "<font color=\"#%02X%02X%02X\">", r
, g
, b
);
334 if (VALUE_IS_STRING (cell
->value
)
335 && (VALUE_FMT (cell
->value
) != NULL
)
336 && go_format_is_markup (VALUE_FMT (cell
->value
)))
337 markup
= go_format_get_markup (VALUE_FMT (cell
->value
));
339 if (markup
!= NULL
) {
340 GString
*str
= g_string_new ("");
341 value_get_as_gstring (cell
->value
, str
, NULL
);
342 html_new_markup (output
, markup
, str
->str
, version
);
343 g_string_free (str
, TRUE
);
345 rendered_string
= gnm_cell_get_rendered_text (cell
);
346 html_print_encoded (output
, rendered_string
);
347 g_free (rendered_string
);
351 if (r
> 0 || g
> 0 || b
> 0)
352 gsf_output_puts (output
, "</font>");
354 gsf_output_puts (output
, "</a>");
356 if (gnm_style_get_font_strike (style
)) {
357 if (version
== HTML32
)
358 gsf_output_puts (output
, "</strike>");
360 gsf_output_puts (output
, "</span>");
362 switch (gnm_style_get_font_script (style
)) {
363 case GO_FONT_SCRIPT_SUB
:
364 gsf_output_puts (output
, "</sub>");
366 case GO_FONT_SCRIPT_SUPER
:
367 gsf_output_puts (output
, "</sup>");
372 if (font_is_monospaced (style
))
373 gsf_output_puts (output
, "</tt>");
374 if (gnm_style_get_font_uline (style
) != UNDERLINE_NONE
)
375 gsf_output_puts (output
, "</u>");
376 if (gnm_style_get_font_bold (style
))
377 gsf_output_puts (output
, "</b>");
378 if (gnm_style_get_font_italic (style
))
379 gsf_output_puts (output
, "</i>");
385 html_get_border_style (GnmBorder
*border
)
387 GString
*text
= g_string_new (NULL
);
390 switch (border
->line_type
) {
391 case GNM_STYLE_BORDER_THIN
:
392 g_string_append (text
, "thin solid");
394 case GNM_STYLE_BORDER_MEDIUM
:
395 g_string_append (text
, "medium solid");
397 case GNM_STYLE_BORDER_DASHED
:
398 g_string_append (text
, "thin dashed");
400 case GNM_STYLE_BORDER_DOTTED
:
401 g_string_append (text
, "thin dotted");
403 case GNM_STYLE_BORDER_THICK
:
404 g_string_append (text
, "thick solid");
406 case GNM_STYLE_BORDER_DOUBLE
:
407 g_string_append (text
, "thick double");
409 case GNM_STYLE_BORDER_HAIR
:
410 g_string_append (text
, "0.5pt solid");
412 case GNM_STYLE_BORDER_MEDIUM_DASH
:
413 g_string_append (text
, "medium dashed");
415 case GNM_STYLE_BORDER_DASH_DOT
:
416 g_string_append (text
, "thin dashed");
418 case GNM_STYLE_BORDER_MEDIUM_DASH_DOT
:
419 g_string_append (text
, "medium dashed");
421 case GNM_STYLE_BORDER_DASH_DOT_DOT
:
422 g_string_append (text
, "thin dotted");
424 case GNM_STYLE_BORDER_MEDIUM_DASH_DOT_DOT
:
425 g_string_append (text
, "medium dotted");
427 case GNM_STYLE_BORDER_SLANTED_DASH_DOT
:
428 g_string_append (text
, "thin dashed");
436 r
= GO_COLOR_UINT_R (border
->color
->go_color
);
437 g
= GO_COLOR_UINT_G (border
->color
->go_color
);
438 b
= GO_COLOR_UINT_B (border
->color
->go_color
);
439 g_string_append_printf (text
, " #%02X%02X%02X", r
, g
, b
);
443 g_string_free (text
, FALSE
);
448 html_write_one_border_style_40 (GsfOutput
*output
, GnmBorder
*border
, char const *border_name
)
451 text
= html_get_border_style (border
);
452 if (text
== NULL
|| strlen (text
) == 0)
454 gsf_output_printf (output
, " %s:%s;", border_name
, text
);
459 html_write_border_style_40 (GsfOutput
*output
, GnmStyle
const *style
)
463 border
= gnm_style_get_border (style
, MSTYLE_BORDER_TOP
);
464 if (!gnm_style_border_is_blank (border
))
465 html_write_one_border_style_40 (output
, border
, "border-top");
466 border
= gnm_style_get_border (style
, MSTYLE_BORDER_BOTTOM
);
467 if (!gnm_style_border_is_blank (border
))
468 html_write_one_border_style_40 (output
, border
, "border-bottom");
469 border
= gnm_style_get_border (style
, MSTYLE_BORDER_LEFT
);
470 if (!gnm_style_border_is_blank (border
))
471 html_write_one_border_style_40 (output
, border
, "border-left");
472 border
= gnm_style_get_border (style
, MSTYLE_BORDER_RIGHT
);
473 if (!gnm_style_border_is_blank (border
))
474 html_write_one_border_style_40 (output
, border
, "border-right");
478 html_write_border_style_40_for_merged_cell (GsfOutput
*output
, GnmStyle
const *style
,
479 Sheet
*sheet
, gint row
, gint col
)
482 GnmRange
const *merge_range
;
488 border
= gnm_style_get_border (style
, MSTYLE_BORDER_TOP
);
489 if (!gnm_style_border_is_blank (border
))
490 html_write_one_border_style_40 (output
, border
, "border-top");
491 border
= gnm_style_get_border (style
, MSTYLE_BORDER_LEFT
);
492 if (!gnm_style_border_is_blank (border
))
493 html_write_one_border_style_40 (output
, border
, "border-left");
495 merge_range
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
496 if (merge_range
!= NULL
) {
497 style
= sheet_style_get (sheet
, merge_range
->end
.col
, merge_range
->end
.row
);
502 border
= gnm_style_get_border (style
, MSTYLE_BORDER_BOTTOM
);
503 if (!gnm_style_border_is_blank (border
))
504 html_write_one_border_style_40 (output
, border
, "border-bottom");
505 border
= gnm_style_get_border (style
, MSTYLE_BORDER_RIGHT
);
506 if (!gnm_style_border_is_blank (border
))
507 html_write_one_border_style_40 (output
, border
, "border-right");
511 write_cell (GsfOutput
*output
, Sheet
*sheet
, gint row
, gint col
, html_version_t version
, gboolean is_merge
)
514 GnmStyle
const *style
;
517 style
= sheet_style_get (sheet
, col
, row
);
518 if (style
!= NULL
&& version
!= HTML32
&& version
!= HTML40
&&
519 gnm_style_get_pattern (style
) != 0 &&
520 gnm_style_is_element_set (style
, MSTYLE_COLOR_BACK
)) {
521 html_get_back_color (style
, &r
, &g
, &b
);
522 gsf_output_printf (output
, " bgcolor=\"#%02X%02X%02X\"", r
, g
, b
);
525 cell
= sheet_cell_get (sheet
, col
, row
);
528 switch (gnm_style_get_align_v (style
)) {
530 gsf_output_puts (output
, " valign=\"top\" ");
532 case GNM_VALIGN_BOTTOM
:
533 gsf_output_puts (output
, " valign=\"bottom\" ");
535 case GNM_VALIGN_DISTRIBUTED
:
536 case GNM_VALIGN_CENTER
:
537 gsf_output_puts (output
, " valign=\"center\" ");
539 case GNM_VALIGN_JUSTIFY
:
540 gsf_output_puts (output
, " valign=\"baseline\" ");
545 switch (gnm_style_default_halign (style
, cell
)) {
546 case GNM_HALIGN_RIGHT
:
547 gsf_output_puts (output
, " align=\"right\" ");
549 case GNM_HALIGN_DISTRIBUTED
:
550 case GNM_HALIGN_CENTER
:
551 case GNM_HALIGN_CENTER_ACROSS_SELECTION
:
552 gsf_output_puts (output
, " align=\"center\" ");
554 case GNM_HALIGN_LEFT
:
555 gsf_output_puts (output
, " align=\"left\" ");
557 case GNM_HALIGN_JUSTIFY
:
558 gsf_output_puts (output
, " align=\"justify\" ");
565 if (version
== HTML40
|| version
== HTML40F
|| version
==XHTML
) {
567 gsf_output_printf (output
, " style=\"");
568 if (gnm_style_get_pattern (style
) != 0 &&
569 gnm_style_is_element_set (style
, MSTYLE_COLOR_BACK
)) {
570 html_get_back_color (style
, &r
, &g
, &b
);
571 gsf_output_printf (output
, "background:#%02X%02X%02X;", r
, g
, b
);
574 gint size
= (int) (gnm_style_get_font_size (style
) + 0.5);
575 gsf_output_printf (output
, " font-size:%ipt;", size
);
576 html_get_text_color (cell
, style
, &r
, &g
, &b
);
577 if (r
> 0 || g
> 0 || b
> 0)
578 gsf_output_printf (output
, " color:#%02X%02X%02X;", r
, g
, b
);
579 if (gnm_style_get_contents_hidden (style
))
580 gsf_output_puts (output
, " visibility:hidden;");
583 html_write_border_style_40_for_merged_cell (output
, style
, sheet
, row
, col
);
585 html_write_border_style_40 (output
, style
);
586 gsf_output_printf (output
, "\"");
589 gsf_output_printf (output
, ">");
590 html_write_cell_content (output
, cell
, style
, version
);
591 gsf_output_puts (output
, "</td>\n");
598 * @output: the stream
599 * @sheet: the gnumeric sheet
600 * @row: the row number
602 * Set up a TD node for each cell in the given row, witht eh appropriate
603 * colspan and rowspan.
604 * Call write_cell for each cell.
607 write_row (GsfOutput
*output
, Sheet
*sheet
, gint row
, GnmRange
*range
, html_version_t version
)
610 ColRowInfo
const *ri
= sheet_row_get_info (sheet
, row
);
611 if (ri
->needs_respan
)
612 row_calc_spans ((ColRowInfo
*) ri
, row
, sheet
);
614 for (col
= range
->start
.col
; col
<= range
->end
.col
; col
++) {
615 CellSpanInfo
const *the_span
;
616 GnmRange
const *merge_range
;
622 the_span
= row_span_get (ri
, col
);
623 if (the_span
!= NULL
) {
624 gsf_output_printf (output
, "<td colspan=\"%i\" ", the_span
->right
- col
+ 1);
625 write_cell (output
, sheet
, row
, the_span
->cell
->pos
.col
, version
, FALSE
);
626 col
= the_span
->right
;
630 /* is this covered by a merge */
631 merge_range
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
632 if (merge_range
!= NULL
) {
633 if (merge_range
->start
.col
!= col
||
634 merge_range
->start
.row
!= row
)
636 gsf_output_printf (output
, "<td colspan=\"%i\" rowspan=\"%i\" ",
637 merge_range
->end
.col
- merge_range
->start
.col
+ 1,
638 merge_range
->end
.row
- merge_range
->start
.row
+ 1);
639 write_cell (output
, sheet
, row
, col
, version
, TRUE
);
640 col
= merge_range
->end
.col
;
643 gsf_output_puts (output
, "<td ");
644 write_cell (output
, sheet
, row
, col
, version
, FALSE
);
651 * @output: the stream
652 * @sheet: the gnumeric sheet
654 * set up a table and call write_row for each row
657 write_sheet (GsfOutput
*output
, Sheet
*sheet
,
658 html_version_t version
, GOFileSaveScope save_scope
)
660 GnmRange total_range
;
667 gsf_output_puts (output
, "<p></p><table cellspacing=\"0\" cellpadding=\"3\">\n");
670 gsf_output_puts (output
, "<p><table border=\"1\">\n");
674 if (save_scope
!= GO_FILE_SAVE_RANGE
) {
675 gsf_output_puts (output
, "<caption>");
676 html_print_encoded (output
, sheet
->name_unquoted
);
677 gsf_output_puts (output
, "</caption>\n");
679 total_range
= sheet_get_extent (sheet
, TRUE
, TRUE
);
680 for (row
= total_range
.start
.row
; row
<= total_range
.end
.row
; row
++) {
681 gsf_output_puts (output
, "<tr>\n");
682 write_row (output
, sheet
, row
, &total_range
, version
);
683 gsf_output_puts (output
, "</tr>\n");
685 gsf_output_puts (output
, "</table>\n");
691 * write the html file (version of html according to version argument)
694 html_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
695 WorkbookView
const *wb_view
, GsfOutput
*output
, html_version_t version
)
697 Workbook
*wb
= wb_view_get_workbook (wb_view
);
698 GOFileSaveScope save_scope
;
702 g_return_if_fail (fs
!= NULL
);
703 g_return_if_fail (wb
!= NULL
);
704 g_return_if_fail (output
!= NULL
);
708 gsf_output_puts (output
,
709 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
711 "<head>\n\t<title>Tables</title>\n"
712 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
713 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\">\n"
716 "\tfont-family: courier;\n"
719 "\tfont-family: helvetica, sans-serif;\n"
722 "\tfont-family: helvetica, sans-serif;\n"
723 "\tfont-size: 14pt;\n"
724 "\ttext-align: left;\n"
727 "</head>\n<body>\n");
730 gsf_output_puts (output
,
731 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n"
732 "\t\t\"http://www.w3.org/TR/html4/strict.dtd\">\n"
734 "<head>\n\t<title>Tables</title>\n"
735 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
736 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\">\n"
737 "<style type=\"text/css\">\n"
739 "\tfont-family: courier;\n"
742 "\tfont-family: helvetica, sans-serif;\n"
745 "\tfont-family: helvetica, sans-serif;\n"
746 "\tfont-size: 14pt;\n"
747 "\ttext-align: left;\n"
750 "</head>\n<body>\n");
753 gsf_output_puts (output
,
754 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
755 "\t\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
756 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
757 "<head>\n\t<title>Tables</title>\n"
758 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
759 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\" />\n"
760 "<style type=\"text/css\">\n"
762 "\tfont-family: courier;\n"
765 "\tfont-family: helvetica, sans-serif;\n"
768 "\tfont-family: helvetica, sans-serif;\n"
769 "\tfont-size: 14pt;\n"
770 "\ttext-align: left;\n"
773 "</head>\n<body>\n");
779 save_scope
= go_file_saver_get_save_scope (fs
);
781 sel
= gnm_file_saver_get_sheets (fs
, wb_view
, TRUE
);
782 for (ui
= 0; ui
< sel
->len
; ui
++) {
783 Sheet
*sheet
= g_ptr_array_index (sel
, ui
);
784 write_sheet (output
, sheet
, version
, save_scope
);
786 g_ptr_array_unref (sel
);
788 if (version
== HTML32
|| version
== HTML40
|| version
== XHTML
)
789 gsf_output_puts (output
, "</body>\n</html>\n");
793 html40_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
794 WorkbookView
const *wb_view
, GsfOutput
*output
)
796 html_file_save (fs
, io_context
, wb_view
, output
, HTML40
);
800 html32_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
801 WorkbookView
const *wb_view
, GsfOutput
*output
)
803 html_file_save (fs
, io_context
, wb_view
, output
, HTML32
);
807 html40frag_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
808 WorkbookView
const *wb_view
, GsfOutput
*output
)
810 html_file_save (fs
, io_context
, wb_view
, output
, HTML40F
);
814 xhtml_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
815 WorkbookView
const *wb_view
, GsfOutput
*output
)
817 html_file_save (fs
, io_context
, wb_view
, output
, XHTML
);
821 xhtml_range_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
822 WorkbookView
const *wb_view
, GsfOutput
*output
)
824 /* Identical, but fs->save_scope is different */
825 xhtml_file_save (fs
, io_context
, wb_view
, output
);