1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright (C) 1999, 2000 Rasca, Berlin
7 * Copyright (c) 2001-2013 Andreas J. Guelzow
8 * EMail: aguelzow@pyrshep.ca
9 * Copyright 2013 Morten Welinder <terra@gnone.org>
12 * Almer. S. Tigelaar <almer1@dds.nl>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses/>.
28 #include <gnumeric-config.h>
30 #include <goffice/goffice.h>
31 #include "workbook-view.h"
33 #include "sheet-style.h"
35 #include "style-color.h"
39 #include "sheet-merge.h"
43 #include "style-border.h"
44 #include <rendered-value.h>
48 #include <gsf/gsf-output.h>
51 #define SHEET_SELECTION_KEY "sheet-selection"
72 * print the string to output encoded all special chars
76 html_print_encoded (GsfOutput
*output
, char const *str
)
82 for (; *str
!= '\0' ; str
= g_utf8_next_char (str
)) {
85 gsf_output_puts (output
, "<");
88 gsf_output_puts (output
, ">");
91 gsf_output_puts (output
, "&");
94 gsf_output_puts (output
, """);
97 gsf_output_puts (output
, "<br>\n");
100 gsf_output_puts (output
, "<br>\r");
101 if( *(str
+1) == '\n' ) {
102 gsf_output_puts (output
, "\n");
107 c
= g_utf8_get_char (str
);
108 if (((c
>= 0x20) && (c
< 0x80)) ||
109 (c
== '\n') || (c
== '\r') || (c
== '\t'))
110 gsf_output_write (output
, 1, str
);
112 gsf_output_printf (output
, "&#%u;", c
);
119 html_get_text_color (GnmCell
*cell
, GnmStyle
const *style
, guint
*r
, guint
*g
, guint
*b
)
121 GOColor fore
= gnm_cell_get_render_color (cell
);
126 *r
= GO_COLOR_UINT_R (fore
);
127 *g
= GO_COLOR_UINT_G (fore
);
128 *b
= GO_COLOR_UINT_B (fore
);
132 html_get_back_color (GnmStyle
const *style
, guint
*r
, guint
*g
, guint
*b
)
134 GnmColor
const *color
= gnm_style_get_back_color (style
);
135 *r
= GO_COLOR_UINT_R (color
->go_color
);
136 *g
= GO_COLOR_UINT_G (color
->go_color
);
137 *b
= GO_COLOR_UINT_B (color
->go_color
);
140 /*****************************************************************************/
144 cb_html_add_chars (GsfOutput
*output
, char const *text
, int len
)
148 g_return_if_fail (len
> 0);
150 str
= g_strndup (text
, len
);
151 html_print_encoded (output
, str
);
156 cb_html_attrs_as_string (GsfOutput
*output
, PangoAttribute
*a
, html_version_t version
)
158 /* PangoColor const *c; */
159 char const *closure
= NULL
;
161 switch (a
->klass
->type
) {
162 case PANGO_ATTR_FAMILY
:
164 case PANGO_ATTR_SIZE
:
166 case PANGO_ATTR_RISE
:
167 if (((PangoAttrInt
*)a
)->value
> 5) {
168 gsf_output_puts (output
, "<sup>");
170 } else if (((PangoAttrInt
*)a
)->value
< -5) {
171 gsf_output_puts (output
, "<sub>");
175 case PANGO_ATTR_STYLE
:
176 if (((PangoAttrInt
*)a
)->value
== PANGO_STYLE_ITALIC
) {
177 gsf_output_puts (output
, "<i>");
181 case PANGO_ATTR_WEIGHT
:
182 if (((PangoAttrInt
*)a
)->value
> 600){
183 gsf_output_puts (output
, "<b>");
187 case PANGO_ATTR_STRIKETHROUGH
:
188 if (((PangoAttrInt
*)a
)->value
== 1) {
189 if (version
== HTML32
) {
190 gsf_output_puts (output
, "<strike>");
191 closure
= "</strike>";
195 "<span style=\"text-decoration: "
201 case PANGO_ATTR_UNDERLINE
:
202 if ((version
!= HTML40
) &&
203 (((PangoAttrInt
*)a
)->value
!= PANGO_UNDERLINE_NONE
)) {
204 gsf_output_puts (output
, "<u>");
208 case PANGO_ATTR_FOREGROUND
:
209 /* c = &((PangoAttrColor *)a)->color; */
210 /* g_string_append_printf (accum, "[color=%02xx%02xx%02x", */
211 /* ((c->red & 0xff00) >> 8), */
212 /* ((c->green & 0xff00) >> 8), */
213 /* ((c->blue & 0xff00) >> 8)); */
216 if (a
->klass
->type
==
217 go_pango_attr_subscript_get_attr_type ()) {
218 if (((GOPangoAttrSubscript
*)a
)->val
) {
219 gsf_output_puts (output
, "<sub>");
222 } else if (a
->klass
->type
==
223 go_pango_attr_superscript_get_attr_type ()) {
224 if (((GOPangoAttrSuperscript
*)a
)->val
) {
225 gsf_output_puts (output
, "<sup>");
236 html_new_markup (GsfOutput
*output
, const PangoAttrList
*markup
, char const *text
,
237 html_version_t version
)
240 PangoAttrIterator
* iter
;
242 int len
= strlen (text
);
243 GString
*closure
= g_string_new ("");
245 iter
= pango_attr_list_get_iterator ((PangoAttrList
*) markup
);
250 g_string_erase (closure
, 0, -1);
251 pango_attr_iterator_range (iter
, &from
, &to
);
252 from
= (from
> len
) ? len
: from
; /* Since "from" can be really big! */
253 to
= (to
> len
) ? len
: to
; /* Since "to" can be really big! */
255 cb_html_add_chars (output
, text
+ handled
, from
- handled
);
256 list
= pango_attr_iterator_get_attrs (iter
);
257 for (l
= list
; l
!= NULL
; l
= l
->next
) {
258 char const *result
= cb_html_attrs_as_string (output
, l
->data
, version
);
260 g_string_prepend (closure
, result
);
264 cb_html_add_chars (output
, text
+ from
, to
- from
);
265 gsf_output_puts (output
, closure
->str
);
267 } while (pango_attr_iterator_next (iter
));
269 g_string_free (closure
, TRUE
);
270 pango_attr_iterator_destroy (iter
);
276 /*****************************************************************************/
279 html_write_cell_content (GsfOutput
*output
, GnmCell
*cell
, GnmStyle
const *style
, html_version_t version
)
284 char *rendered_string
;
285 gboolean hidden
= gnm_style_get_contents_hidden (style
);
286 GnmHLink
* hlink
= gnm_style_get_hlink (style
);
287 const guchar
* hlink_target
= NULL
;
289 if (hlink
&& GNM_IS_HLINK_URL (hlink
)) {
290 hlink_target
= gnm_hlink_get_target (hlink
);
293 if (version
== HTML32
&& hidden
)
294 gsf_output_puts (output
, "<!-- 'HIDDEN DATA' -->");
297 if (gnm_style_get_font_italic (style
))
298 gsf_output_puts (output
, "<i>");
299 if (gnm_style_get_font_bold (style
))
300 gsf_output_puts (output
, "<b>");
301 if (gnm_style_get_font_uline (style
) != UNDERLINE_NONE
)
302 gsf_output_puts (output
, "<u>");
303 if (font_is_monospaced (style
))
304 gsf_output_puts (output
, "<tt>");
305 if (gnm_style_get_font_strike (style
)) {
306 if (version
== HTML32
)
307 gsf_output_puts (output
, "<strike>");
309 gsf_output_puts (output
,
310 "<span style=\"text-decoration: line-through;\">");
312 switch (gnm_style_get_font_script (style
)) {
313 case GO_FONT_SCRIPT_SUB
:
314 gsf_output_puts (output
, "<sub>");
316 case GO_FONT_SCRIPT_SUPER
:
317 gsf_output_puts (output
, "<sup>");
325 gsf_output_printf (output
, "<a href=\"%s\">", hlink_target
);
328 const PangoAttrList
* markup
= NULL
;
330 if (style
!= NULL
&& version
!= HTML40
) {
331 html_get_text_color (cell
, style
, &r
, &g
, &b
);
332 if (r
> 0 || g
> 0 || b
> 0)
333 gsf_output_printf (output
, "<font color=\"#%02X%02X%02X\">", r
, g
, b
);
336 if (VALUE_IS_STRING (cell
->value
)
337 && (VALUE_FMT (cell
->value
) != NULL
)
338 && go_format_is_markup (VALUE_FMT (cell
->value
)))
339 markup
= go_format_get_markup (VALUE_FMT (cell
->value
));
341 if (markup
!= NULL
) {
342 GString
*str
= g_string_new ("");
343 value_get_as_gstring (cell
->value
, str
, NULL
);
344 html_new_markup (output
, markup
, str
->str
, version
);
345 g_string_free (str
, TRUE
);
347 rendered_string
= gnm_cell_get_rendered_text (cell
);
348 html_print_encoded (output
, rendered_string
);
349 g_free (rendered_string
);
353 if (r
> 0 || g
> 0 || b
> 0)
354 gsf_output_puts (output
, "</font>");
356 gsf_output_puts (output
, "</a>");
358 if (gnm_style_get_font_strike (style
)) {
359 if (version
== HTML32
)
360 gsf_output_puts (output
, "</strike>");
362 gsf_output_puts (output
, "</span>");
364 switch (gnm_style_get_font_script (style
)) {
365 case GO_FONT_SCRIPT_SUB
:
366 gsf_output_puts (output
, "</sub>");
368 case GO_FONT_SCRIPT_SUPER
:
369 gsf_output_puts (output
, "</sup>");
374 if (font_is_monospaced (style
))
375 gsf_output_puts (output
, "</tt>");
376 if (gnm_style_get_font_uline (style
) != UNDERLINE_NONE
)
377 gsf_output_puts (output
, "</u>");
378 if (gnm_style_get_font_bold (style
))
379 gsf_output_puts (output
, "</b>");
380 if (gnm_style_get_font_italic (style
))
381 gsf_output_puts (output
, "</i>");
387 html_get_border_style (GnmBorder
*border
)
389 GString
*text
= g_string_new (NULL
);
392 switch (border
->line_type
) {
393 case GNM_STYLE_BORDER_THIN
:
394 g_string_append (text
, "thin solid");
396 case GNM_STYLE_BORDER_MEDIUM
:
397 g_string_append (text
, "medium solid");
399 case GNM_STYLE_BORDER_DASHED
:
400 g_string_append (text
, "thin dashed");
402 case GNM_STYLE_BORDER_DOTTED
:
403 g_string_append (text
, "thin dotted");
405 case GNM_STYLE_BORDER_THICK
:
406 g_string_append (text
, "thick solid");
408 case GNM_STYLE_BORDER_DOUBLE
:
409 g_string_append (text
, "thick double");
411 case GNM_STYLE_BORDER_HAIR
:
412 g_string_append (text
, "0.5pt solid");
414 case GNM_STYLE_BORDER_MEDIUM_DASH
:
415 g_string_append (text
, "medium dashed");
417 case GNM_STYLE_BORDER_DASH_DOT
:
418 g_string_append (text
, "thin dashed");
420 case GNM_STYLE_BORDER_MEDIUM_DASH_DOT
:
421 g_string_append (text
, "medium dashed");
423 case GNM_STYLE_BORDER_DASH_DOT_DOT
:
424 g_string_append (text
, "thin dotted");
426 case GNM_STYLE_BORDER_MEDIUM_DASH_DOT_DOT
:
427 g_string_append (text
, "medium dotted");
429 case GNM_STYLE_BORDER_SLANTED_DASH_DOT
:
430 g_string_append (text
, "thin dashed");
438 r
= GO_COLOR_UINT_R (border
->color
->go_color
);
439 g
= GO_COLOR_UINT_G (border
->color
->go_color
);
440 b
= GO_COLOR_UINT_B (border
->color
->go_color
);
441 g_string_append_printf (text
, " #%02X%02X%02X", r
, g
, b
);
445 g_string_free (text
, FALSE
);
450 html_write_one_border_style_40 (GsfOutput
*output
, GnmBorder
*border
, char const *border_name
)
453 text
= html_get_border_style (border
);
454 if (text
== NULL
|| strlen (text
) == 0)
456 gsf_output_printf (output
, " %s:%s;", border_name
, text
);
461 html_write_border_style_40 (GsfOutput
*output
, GnmStyle
const *style
)
465 border
= gnm_style_get_border (style
, MSTYLE_BORDER_TOP
);
466 if (!gnm_style_border_is_blank (border
))
467 html_write_one_border_style_40 (output
, border
, "border-top");
468 border
= gnm_style_get_border (style
, MSTYLE_BORDER_BOTTOM
);
469 if (!gnm_style_border_is_blank (border
))
470 html_write_one_border_style_40 (output
, border
, "border-bottom");
471 border
= gnm_style_get_border (style
, MSTYLE_BORDER_LEFT
);
472 if (!gnm_style_border_is_blank (border
))
473 html_write_one_border_style_40 (output
, border
, "border-left");
474 border
= gnm_style_get_border (style
, MSTYLE_BORDER_RIGHT
);
475 if (!gnm_style_border_is_blank (border
))
476 html_write_one_border_style_40 (output
, border
, "border-right");
480 html_write_border_style_40_for_merged_cell (GsfOutput
*output
, GnmStyle
const *style
,
481 Sheet
*sheet
, gint row
, gint col
)
484 GnmRange
const *merge_range
;
490 border
= gnm_style_get_border (style
, MSTYLE_BORDER_TOP
);
491 if (!gnm_style_border_is_blank (border
))
492 html_write_one_border_style_40 (output
, border
, "border-top");
493 border
= gnm_style_get_border (style
, MSTYLE_BORDER_LEFT
);
494 if (!gnm_style_border_is_blank (border
))
495 html_write_one_border_style_40 (output
, border
, "border-left");
497 merge_range
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
498 if (merge_range
!= NULL
) {
499 style
= sheet_style_get (sheet
, merge_range
->end
.col
, merge_range
->end
.row
);
504 border
= gnm_style_get_border (style
, MSTYLE_BORDER_BOTTOM
);
505 if (!gnm_style_border_is_blank (border
))
506 html_write_one_border_style_40 (output
, border
, "border-bottom");
507 border
= gnm_style_get_border (style
, MSTYLE_BORDER_RIGHT
);
508 if (!gnm_style_border_is_blank (border
))
509 html_write_one_border_style_40 (output
, border
, "border-right");
513 write_cell (GsfOutput
*output
, Sheet
*sheet
, gint row
, gint col
, html_version_t version
, gboolean is_merge
)
516 GnmStyle
const *style
;
519 style
= sheet_style_get (sheet
, col
, row
);
520 if (style
!= NULL
&& version
!= HTML32
&& version
!= HTML40
&&
521 gnm_style_get_pattern (style
) != 0 &&
522 gnm_style_is_element_set (style
, MSTYLE_COLOR_BACK
)) {
523 html_get_back_color (style
, &r
, &g
, &b
);
524 gsf_output_printf (output
, " bgcolor=\"#%02X%02X%02X\"", r
, g
, b
);
527 cell
= sheet_cell_get (sheet
, col
, row
);
530 switch (gnm_style_get_align_v (style
)) {
532 gsf_output_puts (output
, " valign=\"top\" ");
534 case GNM_VALIGN_BOTTOM
:
535 gsf_output_puts (output
, " valign=\"bottom\" ");
537 case GNM_VALIGN_DISTRIBUTED
:
538 case GNM_VALIGN_CENTER
:
539 gsf_output_puts (output
, " valign=\"center\" ");
541 case GNM_VALIGN_JUSTIFY
:
542 gsf_output_puts (output
, " valign=\"baseline\" ");
547 switch (gnm_style_default_halign (style
, cell
)) {
548 case GNM_HALIGN_RIGHT
:
549 gsf_output_puts (output
, " align=\"right\" ");
551 case GNM_HALIGN_DISTRIBUTED
:
552 case GNM_HALIGN_CENTER
:
553 case GNM_HALIGN_CENTER_ACROSS_SELECTION
:
554 gsf_output_puts (output
, " align=\"center\" ");
556 case GNM_HALIGN_LEFT
:
557 gsf_output_puts (output
, " align=\"left\" ");
559 case GNM_HALIGN_JUSTIFY
:
560 gsf_output_puts (output
, " align=\"justify\" ");
567 if (version
== HTML40
|| version
== HTML40F
|| version
==XHTML
) {
569 gsf_output_printf (output
, " style=\"");
570 if (gnm_style_get_pattern (style
) != 0 &&
571 gnm_style_is_element_set (style
, MSTYLE_COLOR_BACK
)) {
572 html_get_back_color (style
, &r
, &g
, &b
);
573 gsf_output_printf (output
, "background:#%02X%02X%02X;", r
, g
, b
);
576 gint size
= (int) (gnm_style_get_font_size (style
) + 0.5);
577 gsf_output_printf (output
, " font-size:%ipt;", size
);
578 html_get_text_color (cell
, style
, &r
, &g
, &b
);
579 if (r
> 0 || g
> 0 || b
> 0)
580 gsf_output_printf (output
, " color:#%02X%02X%02X;", r
, g
, b
);
581 if (gnm_style_get_contents_hidden (style
))
582 gsf_output_puts (output
, " visibility:hidden;");
585 html_write_border_style_40_for_merged_cell (output
, style
, sheet
, row
, col
);
587 html_write_border_style_40 (output
, style
);
588 gsf_output_printf (output
, "\"");
591 gsf_output_printf (output
, ">");
592 html_write_cell_content (output
, cell
, style
, version
);
593 gsf_output_puts (output
, "</td>\n");
600 * @output: the stream
601 * @sheet: the gnumeric sheet
602 * @row: the row number
604 * Set up a TD node for each cell in the given row, witht eh appropriate
605 * colspan and rowspan.
606 * Call write_cell for each cell.
609 write_row (GsfOutput
*output
, Sheet
*sheet
, gint row
, GnmRange
*range
, html_version_t version
)
612 ColRowInfo
const *ri
= sheet_row_get_info (sheet
, row
);
613 if (ri
->needs_respan
)
614 row_calc_spans ((ColRowInfo
*) ri
, row
, sheet
);
616 for (col
= range
->start
.col
; col
<= range
->end
.col
; col
++) {
617 CellSpanInfo
const *the_span
;
618 GnmRange
const *merge_range
;
624 the_span
= row_span_get (ri
, col
);
625 if (the_span
!= NULL
) {
626 gsf_output_printf (output
, "<td colspan=\"%i\" ", the_span
->right
- col
+ 1);
627 write_cell (output
, sheet
, row
, the_span
->cell
->pos
.col
, version
, FALSE
);
628 col
= the_span
->right
;
632 /* is this covered by a merge */
633 merge_range
= gnm_sheet_merge_contains_pos (sheet
, &pos
);
634 if (merge_range
!= NULL
) {
635 if (merge_range
->start
.col
!= col
||
636 merge_range
->start
.row
!= row
)
638 gsf_output_printf (output
, "<td colspan=\"%i\" rowspan=\"%i\" ",
639 merge_range
->end
.col
- merge_range
->start
.col
+ 1,
640 merge_range
->end
.row
- merge_range
->start
.row
+ 1);
641 write_cell (output
, sheet
, row
, col
, version
, TRUE
);
642 col
= merge_range
->end
.col
;
645 gsf_output_puts (output
, "<td ");
646 write_cell (output
, sheet
, row
, col
, version
, FALSE
);
653 * @output: the stream
654 * @sheet: the gnumeric sheet
656 * set up a table and call write_row for each row
659 write_sheet (GsfOutput
*output
, Sheet
*sheet
,
660 html_version_t version
, GOFileSaveScope save_scope
)
662 GnmRange total_range
;
669 gsf_output_puts (output
, "<p></p><table cellspacing=\"0\" cellpadding=\"3\">\n");
672 gsf_output_puts (output
, "<p><table border=\"1\">\n");
676 if (save_scope
!= GO_FILE_SAVE_RANGE
) {
677 gsf_output_puts (output
, "<caption>");
678 html_print_encoded (output
, sheet
->name_unquoted
);
679 gsf_output_puts (output
, "</caption>\n");
681 total_range
= sheet_get_extent (sheet
, TRUE
, TRUE
);
682 for (row
= total_range
.start
.row
; row
<= total_range
.end
.row
; row
++) {
683 gsf_output_puts (output
, "<tr>\n");
684 write_row (output
, sheet
, row
, &total_range
, version
);
685 gsf_output_puts (output
, "</tr>\n");
687 gsf_output_puts (output
, "</table>\n");
693 * write the html file (version of html according to version argument)
696 html_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
697 WorkbookView
const *wb_view
, GsfOutput
*output
, html_version_t version
)
699 Workbook
*wb
= wb_view_get_workbook (wb_view
);
700 GOFileSaveScope save_scope
;
704 g_return_if_fail (fs
!= NULL
);
705 g_return_if_fail (wb
!= NULL
);
706 g_return_if_fail (output
!= NULL
);
710 gsf_output_puts (output
,
711 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"
713 "<head>\n\t<title>Tables</title>\n"
714 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
715 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\">\n"
718 "\tfont-family: courier;\n"
721 "\tfont-family: helvetica, sans-serif;\n"
724 "\tfont-family: helvetica, sans-serif;\n"
725 "\tfont-size: 14pt;\n"
726 "\ttext-align: left;\n"
729 "</head>\n<body>\n");
732 gsf_output_puts (output
,
733 "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n"
734 "\t\t\"http://www.w3.org/TR/html4/strict.dtd\">\n"
736 "<head>\n\t<title>Tables</title>\n"
737 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n"
738 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\">\n"
739 "<style type=\"text/css\">\n"
741 "\tfont-family: courier;\n"
744 "\tfont-family: helvetica, sans-serif;\n"
747 "\tfont-family: helvetica, sans-serif;\n"
748 "\tfont-size: 14pt;\n"
749 "\ttext-align: left;\n"
752 "</head>\n<body>\n");
755 gsf_output_puts (output
,
756 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
757 "\t\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
758 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"
759 "<head>\n\t<title>Tables</title>\n"
760 "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
761 "<meta name=\"generator\" content=\"Gnumeric " GNM_VERSION_FULL
" via " G_PLUGIN_FOR_HTML
"\" />\n"
762 "<style type=\"text/css\">\n"
764 "\tfont-family: courier;\n"
767 "\tfont-family: helvetica, sans-serif;\n"
770 "\tfont-family: helvetica, sans-serif;\n"
771 "\tfont-size: 14pt;\n"
772 "\ttext-align: left;\n"
775 "</head>\n<body>\n");
781 save_scope
= go_file_saver_get_save_scope (fs
);
783 sel
= g_object_get_data (G_OBJECT (wb
), SHEET_SELECTION_KEY
);
784 count
= sel
? sel
->len
: workbook_sheet_count (wb
);
785 for (ui
= 0; ui
< count
; ui
++) {
787 ? g_ptr_array_index (sel
, ui
)
788 : workbook_sheet_by_index (wb
, ui
);
789 write_sheet (output
, sheet
, version
, save_scope
);
792 if (version
== HTML32
|| version
== HTML40
|| version
== XHTML
)
793 gsf_output_puts (output
, "</body>\n</html>\n");
797 html40_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
798 WorkbookView
const *wb_view
, GsfOutput
*output
)
800 html_file_save (fs
, io_context
, wb_view
, output
, HTML40
);
804 html32_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
805 WorkbookView
const *wb_view
, GsfOutput
*output
)
807 html_file_save (fs
, io_context
, wb_view
, output
, HTML32
);
811 html40frag_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
812 WorkbookView
const *wb_view
, GsfOutput
*output
)
814 html_file_save (fs
, io_context
, wb_view
, output
, HTML40F
);
818 xhtml_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
819 WorkbookView
const *wb_view
, GsfOutput
*output
)
821 html_file_save (fs
, io_context
, wb_view
, output
, XHTML
);
825 xhtml_range_file_save (GOFileSaver
const *fs
, GOIOContext
*io_context
,
826 WorkbookView
const *wb_view
, GsfOutput
*output
)
828 /* Identical, but fs->save_scope is different */
829 xhtml_file_save (fs
, io_context
, wb_view
, output
);