136
* @p : a pointer to a char, start of the string to be processed
137
* @output : output stream where the processed characters are written.
138
* @utf8: is this a utf8 string?
141
* If @p is in form of \L{foo}, return the char pointer pointing to '}' of \L{foo}
142
* else return @p untouched;
144
* Check if @p is in form of \L{foo}.
145
* If it is, the exact "foo" will be put into @output, without any esacaping.
149
latex_raw_str(char const *p, GsfOutput *output, gboolean utf8)
151
char const *p_begin, *p_orig = p;
153
if(strncasecmp(p, "\\L{", 3) == 0){
156
/* find the matching close bracket */
157
for(; *p; p = utf8 ? g_utf8_next_char(p) : p + 1){
158
switch(*p){ /* FIXME: how to put in unmatched brackets? */
165
/* put the string beginning from p_begin to p to output */
166
gsf_output_write(output, p - p_begin, p_begin);
135
177
* latex_fputs_utf :
137
179
* @p : a pointer to a char, start of the string to be processed.
138
180
* @output : output stream where the processed characters are written.
140
* This escapes any special LaTeX characters from the LaTeX engine. Re-ordered
141
* from Rasca's code to have most common first.
182
* This escapes any special LaTeX characters from the LaTeX engine,
183
* except the ones enclosed in "\L{" and "}".
184
* Re-ordered from Rasca's code to have most common first.
144
187
latex_fputs_utf (char const *p, GsfOutput *output)
146
190
for (; *p; p = g_utf8_next_char (p)) {
147
191
switch (g_utf8_get_char (p)) {
149
193
/* These are the classic TeX symbols $ & % # _ { } (see Lamport, p.15) */
150
194
case '$': case '&': case '%': case '#':
151
195
case '_': case '{': case '}':
177
225
* @p : a pointer to a char, start of the string to be processed.
178
226
* @output: output stream where the processed characters are written.
180
* This escapes any special LaTeX characters from the LaTeX engine.
228
* This escapes any special LaTeX characters from the LaTeX engine,
229
* except the ones enclosed in "\L{" and "}".
182
231
* We assume that htis will be set in Mathematics mode.
185
234
latex_math_fputs_utf (char const *p, GsfOutput *output)
187
237
for (; *p; p = g_utf8_next_char (p)) {
188
238
switch (g_utf8_get_char (p)) {
196
246
gsf_output_printf (output, "\\%c{ }", *p);
199
gsf_output_puts (output, "\\backslash");
249
rlt = latex_raw_str(p, output, TRUE);
251
gsf_output_puts (output, "$\\backslash$");
203
256
gsf_output_write (output,
204
257
(g_utf8_next_char (p)) - p, p);
260
313
* @p : a pointer to a char, start of the string to be processed.
261
314
* @output : output stream where the processed characters are written.
263
* This escapes any special LaTeX characters from the LaTeX engine. Re-ordered
264
* from Rasca's code to have most common first.
316
* This escapes any special LaTeX characters from the LaTeX engine,
317
* except the ones enclosed in "\L{" and "}".
318
* Re-ordered from Rasca's code to have most common first.
267
321
latex_fputs_latin (char const *text, GsfOutput *output)
269
323
char * encoded_text = NULL;
272
327
encoded_text = latex_convert_latin_to_utf (text);
284
339
gsf_output_printf (output, "\\%c{ }", *p);
287
gsf_output_puts (output, "$\\backslash$");
342
rlt = latex_raw_str(p, output, FALSE);
344
gsf_output_puts (output, "$\\backslash$");
289
348
/* Are these available only in LaTeX through mathmode? */
290
349
case '>': case '<': case '�':
654
latex2e_write_blank_cell (GsfOutput *output, gint col, gint row, gint index,
655
StyleBorderType *borders, Sheet *sheet)
720
latex2e_write_blank_multicolumn_cell (GsfOutput *output, int start_col, int start_row,
721
int num_merged_cols, int num_merged_rows,
723
StyleBorderType *borders, Sheet *sheet)
658
726
StyleBorderType left_border = STYLE_BORDER_NONE;
659
727
StyleBorderType right_border = STYLE_BORDER_NONE;
729
if (num_merged_cols > 1 || num_merged_rows > 1) {
730
ColRowInfo const * ci;
733
for (i = 0; i < num_merged_cols; i++) {
734
ci = sheet_col_get_info (sheet, start_col + i);
735
merge_width += ci->size_pixels;
664
739
if (index == 0) {
665
740
left_border = *borders;
667
right_border = borders[index + 1];
669
if (left_border == STYLE_BORDER_NONE && right_border == STYLE_BORDER_NONE)
670
gsf_output_printf (output, "\n");
742
right_border = borders[index + num_merged_cols];
744
/* We only set up a multicolumn command if necessary */
745
if (num_merged_cols > 1) {
748
/* Open the multicolumn statement. */
749
gsf_output_printf (output, "\\multicolumn{%d}{", num_merged_cols);
751
if (left_border != STYLE_BORDER_NONE)
752
latex2e_print_vert_border (output, left_border);
754
if (num_merged_rows > 1) {
755
gsf_output_printf (output, "c");
757
gsf_output_printf (output, "p{");
758
for (i = 0; i < num_merged_cols; i++) {
759
gsf_output_printf (output, "\t\\gnumericCol%s+%%\n",
760
col_name (start_col + i));
762
gsf_output_printf (output, "\t\\tabcolsep*2*%i}", num_merged_cols - 1);
765
if (right_border != STYLE_BORDER_NONE)
766
latex2e_print_vert_border (output, right_border);
768
/*Close the right delimiter, as above. Also open the text delimiter.*/
769
gsf_output_printf (output,"}%%\n\t{");
770
} else if (left_border != STYLE_BORDER_NONE || right_border != STYLE_BORDER_NONE) {
672
772
/* Open the multicolumn statement. */
673
773
gsf_output_printf (output, "\\multicolumn{1}{");
676
776
latex2e_print_vert_border (output, left_border);
678
778
/* Drop in the left hand format delimiter. */
679
gsf_output_printf (output, "c");
779
gsf_output_printf (output, "p{\\gnumericCol%s}", col_name(start_col));
681
781
if (right_border != STYLE_BORDER_NONE)
682
782
latex2e_print_vert_border (output, right_border);
684
/*Close the right delimiter, as above. Also add the empty text delimiters.*/
685
gsf_output_printf (output,"}{}%%\n");
784
/*Close the right delimiter, as above. Also open the text delimiter.*/
785
gsf_output_printf (output,"}%%\n\t{");
789
if (num_merged_rows > 1) {
791
/* Open the multirow statement. */
792
gsf_output_printf (output, "\\multirow{%d}[%i]*{\\begin{tabular}{p{",
793
num_merged_rows, num_merged_rows/2);
794
for (i = 0; i < num_merged_cols; i++) {
795
gsf_output_printf (output, "\t\\gnumericCol%s+%%\n", col_name (start_col + i));
797
if (num_merged_cols > 2)
798
gsf_output_printf (output, "\t\\tabcolsep*2*%i}}", num_merged_cols - 2);
800
gsf_output_printf (output, "\t0pt}}");
801
/* Close the multirowtext. */
802
gsf_output_printf (output, "\\end{tabular}}");
805
/* Close the multicolumn text bracket. */
806
if (num_merged_cols > 1 || left_border != STYLE_BORDER_NONE
807
|| right_border != STYLE_BORDER_NONE)
808
gsf_output_printf (output, "}");
810
/* And we are done. */
811
gsf_output_printf (output, "\n");
772
899
latex2e_print_vert_border (output, left_border);
774
901
/* Drop in the left hand format delimiter. */
775
gsf_output_printf (output, "p{\\gnumericCol%s}", col_name(cell->pos.col));
902
gsf_output_printf (output, "p{\\gnumericCol%s}", col_name(start_col));
777
904
if (right_border != STYLE_BORDER_NONE)
778
905
latex2e_print_vert_border (output, right_border);
1080
1207
gsf_output_puts (output, ""
1081
1208
"\\setlength\\gnumericTableWidthComplete{\\gnumericTableWidth+%\n"
1082
1209
" \\tabcolsep*\\gumericNumCols*2+\\arrayrulewidth*\\gumericNumCols}\n"
1083
"\\ifthenelse{\\lengthtest{\\gnumericTableWidthComplete > \\textwidth}}%\n"
1084
" {\\def\\gnumericScale{\\ratio{\\textwidth-%\n"
1210
"\\ifthenelse{\\lengthtest{\\gnumericTableWidthComplete > \\linewidth}}%\n"
1211
" {\\def\\gnumericScale{\\ratio{\\linewidth-%\n"
1085
1212
" \\tabcolsep*\\gumericNumCols*2-%\n"
1086
1213
" \\arrayrulewidth*\\gumericNumCols}%\n"
1087
1214
"{\\gnumericTableWidth}}}%\n"
1179
1309
gsf_output_printf (output, "\t ");
1181
/* Even an empty cell (especially an empty cell!) can be */
1182
/* covered by a span! */
1183
the_span = row_span_get (ri, col);
1184
if (the_span != NULL) {
1185
latex2e_write_multicolumn_cell(output, (GnmCell *)the_span->cell,
1189
col - total_range.start.col,
1190
next_vert, current_sheet);
1191
col += the_span->right - col;
1196
/* A blank cell has only a few options*/
1197
if (cell_is_empty(cell)) {
1198
latex2e_write_blank_cell(output, col, row,
1199
col - total_range.start.col,
1200
next_vert, current_sheet);
1204
1311
/* Check a merge. */
1205
merge_range = sheet_merge_is_corner (current_sheet, &cell->pos);
1312
merge_range = sheet_merge_is_corner (current_sheet, &pos);
1206
1313
if (merge_range == NULL) {
1207
latex2e_write_multicolumn_cell(output, cell, col, 1, 1,
1314
if (cell_is_empty(cell))
1315
latex2e_write_blank_multicolumn_cell(output, col, row,
1317
col - total_range.start.col,
1318
next_vert, current_sheet);
1320
latex2e_write_multicolumn_cell(output, cell, col,
1208
1322
col - total_range.start.col,
1209
1323
next_vert, current_sheet);
1214
1328
num_merged_cols = merge_range->end.col - merge_range->start.col + 1;
1215
1329
num_merged_rows = merge_range->end.row - merge_range->start.row + 1;
1217
latex2e_write_multicolumn_cell(output, cell, col, num_merged_cols,
1219
col - total_range.start.col,
1220
next_vert, current_sheet);
1331
if (cell_is_empty(cell))
1332
latex2e_write_blank_multicolumn_cell(output, col, row,
1335
col - total_range.start.col,
1336
next_vert, current_sheet);
1338
latex2e_write_multicolumn_cell(output, cell, col, num_merged_cols,
1340
col - total_range.start.col,
1341
next_vert, current_sheet);
1221
1342
col += (num_merged_cols - 1);
1257
1378
gsf_output_printf (output, "\\end{longtable}\n\n");
1258
1379
gsf_output_printf (output, "\\gnumericTableEnd\n");
1384
* latex2e_table_cell:
1386
* @output : output stream where the cell contents will be written.
1387
* @cell : the cell whose contents are to be written.
1388
* @sheet : the current sheet.
1390
* This function creates all the LaTeX code for the cell of a table (i.e. all
1391
* the code that might fall between two ampersands (&)).
1395
latex2e_table_write_cell (GsfOutput *output, GnmCell *cell, Sheet *sheet)
1397
GnmStyle const *style = cell_get_style (cell);
1399
if (gnm_style_get_contents_hidden (style))
1402
if (!cell_is_empty (cell)) {
1403
char * rendered_string;
1405
rendered_string = cell_get_rendered_text (cell);
1406
latex_fputs (rendered_string, output);
1407
g_free (rendered_string);
1413
* latex2e_table_write_file_header:
1415
* @output: Output stream where the cell contents will be written.
1417
* This ouputs the LaTeX header. Kept separate for esthetics.
1421
latex2e_table_write_file_header(GsfOutput *output)
1423
gsf_output_puts (output,
1424
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
1426
"%% This is a LaTeX2e table fragment exported from Gnumeric. %%\n"
1428
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
1433
* latex_table_file_save : The LaTeX2e exporter plugin function.
1435
* @FileSaver : New structure for file plugins. I don't understand.
1436
* @IOcontext : currently not used but reserved for the future.
1437
* @WorkbookView : this provides the way to access the sheet being exported.
1438
* @filename : where we'll write.
1440
* This writes the top sheet of a Gnumeric workbook as the content of a latex table environment.
1441
* We try to avoid all formatting.
1444
latex_table_file_save (GOFileSaver const *fs, IOContext *io_context,
1445
WorkbookView const *wb_view, GsfOutput *output)
1448
Sheet *current_sheet;
1449
GnmRange total_range;
1452
/* This is the preamble of the LaTeX2e file. */
1453
latex2e_table_write_file_header(output);
1455
/* Get the topmost sheet and its range from the plugin function argument. */
1456
current_sheet = wb_view_cur_sheet(wb_view);
1457
total_range = sheet_get_extent (current_sheet, TRUE);
1459
/* Step through the sheet, writing cells as appropriate. */
1460
for (row = total_range.start.row; row <= total_range.end.row; row++) {
1461
ColRowInfo const * ri;
1462
ri = sheet_row_get_info (current_sheet, row);
1463
if (ri->needs_respan)
1464
row_calc_spans ((ColRowInfo *) ri, row, current_sheet);
1466
for (col = total_range.start.col; col <= total_range.end.col; col++) {
1468
cell = sheet_cell_get (current_sheet, col, row);
1470
/* Check if we are not the first cell in the row.*/
1471
if (col != total_range.start.col)
1472
gsf_output_printf (output, "\t&");
1474
if (cell_is_empty (cell))
1477
latex2e_table_write_cell(output, cell, current_sheet);
1479
gsf_output_printf (output, "\\\\\n");