Mercurial > forge
changeset 12340:055e10a4f964 octave-forge
Integrated empty upper rows & empty upper data rows; fix temp file name
author | prnienhuis |
---|---|
date | Fri, 24 Jan 2014 21:53:37 +0000 |
parents | 25c6cc557c31 |
children | f9f064cebe35 |
files | main/io/inst/private/__OCT_oct2ods__.m |
diffstat | 1 files changed, 104 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/main/io/inst/private/__OCT_oct2ods__.m Fri Jan 24 21:51:43 2014 +0000 +++ b/main/io/inst/private/__OCT_oct2ods__.m Fri Jan 24 21:53:37 2014 +0000 @@ -24,6 +24,10 @@ ## Created: 2014-01-18 ## Updates: ## 2014-01-23 Fix writing repeated empty cells +## '' Added writing deafult style names in document +## 2014-01-24 Integrated empty left columns with empty left vals in rawarr +## '' Same for empty upper rows & empty upper data rows +## '' Fix temp file name function [ ods, status ] = __OCT_oct2ods__ (obj, ods, wsh, crange, spsh_opts=0) @@ -140,32 +144,57 @@ endif - ## D. Create a temporary file to hold the new sheet xml + ## D. Get default table/row/column styles + ## Open file content.xml + fids = fopen (sprintf ("%s/content.xml", ods.workbook), "r"); + ## Get first part, til first sheet + contnt = fread (fids, ods.sheets.shtidx(1)-1, "char=>char").'; + fclose (fids); + ## Get default styles stuff + contnt = getxmlnode (contnt, "office:automatic-styles"); + is = 1; + stylenode = " "; ## Any non-empty value + ## Usual default style names + styles = struct ("tbl", "ta1", "row", "ro1", "col", "co1"); + ## Get actual default styles + while (! isempty (stylenode)) + [stylenode, ~, is] = getxmlnode (contnt, "style:style", is, 1); + stylefam = getxmlattv (stylenode, "style:family"); + if (strcmpi (stylefam, "table-column")) + style.col = stylefam; + elseif (strcmpi (stylefam, "table")) + styles.tbl = stylefam; + elseif (strcmpi (stylefam, "table-row")) + styles.row = stylefam; + endif + endwhile + + ## E. Create a temporary file to hold the new sheet xml ## Open sheet file (new or old) tmpfil = tmpnam; - fid = fopen (tmpnam, "w+"); + fid = fopen (tmpfil, "w+"); if (fid < 0) error ("oct2ods: unable to write to file %s", tmpfil); endif + ## Write data to sheet (actually table:table section in content.xml) + status = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, ... + ods.sheets.sh_names{wsh}, styles); - ## Write data to sheet (actually table:table section in content.xml) - status = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, ods.sheets.sh_names{wsh}); - - ## E. Merge new/updated sheet into content.xml + ## F. Merge new/updated sheet into content.xml ## Read first chunk of content.xml until sht_idx<xx> fidc = fopen (sprintf ("%s/content.xml", ods.workbook), "r+"); ## Go to start of requested sheet fseek (fidc, 0, 'bof'); + ## Read and concatenate just adapted/created sheet/table:table content_xml = fread (fidc, idx_s - 1, "char=>char").'; - ## Rewind sheet and read it behind content_xml fseek (fid, 0, "bof"); sheet = fread (fid, Inf, "char=>char").'; lsheet = length (sheet); ## Close & delete sheet file fclose (fid); - unlink (tmpfil); + delete (tmpfil); content_xml = [ content_xml sheet] ; ## Read rest of content.xml, optionally delete overwritten sheet/table:table @@ -186,94 +215,92 @@ endif ods.changed = max (ods.changed, 1); + ## FIXME: Perhaps we'd need to update the metadata in meta.xml + endfunction ## =========================================================================== -function [ status ] = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, tname) +function [ status ] = __OCT__oct2ods_sh__ (fid, rawarr, wsh, lims, onc, onr, tname, styles) ## Write out the lot to requested sheet ## 1. Sheet open tag - fprintf (fid, '<table:table table:name="%s" table:style-name="ta1">', tname); + fprintf (fid, '<table:table table:name="%s" table:style-name="%s">', tname, styles.tbl); - ## 2. Default column styles - fprintf (fid, '<table:table-column table-style-name="co1" table:number-columns-repeated="%d" table:default-cell-style-name="Default" />', lims(1, 2)); - - ## 3. Optional empty rows before data are copied - ## FIXME actually these empty rows should be combined with upper empty rows in rawarr - if (lims(2, 1) > 1) - if (lims(2, 1) > 2) - tnrr = sprintf (' table:number-rows-repeated="%d"', lims(2, 1) - 1); - else - tnrr = ""; - endif + ## 2. Default column styles. If required add columns repeated tag + if (lims(1, 2) > 1) + tncr = sprintf (' table:number-columns-repeated="%d"', lims(1, 2)); + else tncr = ""; - if (lims(1, 2) > 1) - tncr = sprintf (' table:number-columns-repeated="%d"', lims(1, 2)); - endif - fprintf (fid, '<table:table-row%s><table:table-cell%s /></table:table-row>', tnrr, tncr); endif + fprintf (fid, '<table:table-column table-style-name="%s"%s table:default-cell-style-name="Default" />', ... + styles.col, tncr); - ## 4. Spreadsheet rows + ## 3. Spreadsheet rows ii = 1; while (ii <= onr) - ## Check for empty rows - ## FIXME should actually be combined with empty rows above data (see above) - if (all (cellfun ("isempty", rawarr(ii, :)))) - tnrr = 1; - while ((ii + tnrr - 1) < onr && all (cellfun ("isempty", rawarr(++ii, :)))) - ++tnrr; - endwhile - if (tnrr > 1) - tnrr = sprintf (' table:number-rows-repeated="%d"', tnrr); - ii += tnrr - 1; - else - tnrr = ""; + ## 3.1 Check for empty rows + if (ii == 1) + tnrr = lims(2, 1) - 1; + else + tnrr = 0; + endif + ## Check for consecutive empty rows + while (ii <= onr && all (cellfun ("isempty", rawarr(ii, :)))) + ++tnrr; + ++ii; + endwhile + if (tnrr > 1) + tnrrt = sprintf (' table:number-rows-repeated="%d"', tnrr); + else + tnrrt = ""; + endif + if (tnrr) + ## Write empty row, optionally with row repeat tag + if (lims (1, 2) > 1) + ## Add number of empty columns repeat tag + tcell = sprintf ('<table:table-cell table:number-columns-repeated="%d" />', ... + lims(1, 2)); endif - tcell = sprintf ('<table:table-cell table:number-columns-repeated="%d" />', lims(1, 2)); - fprintf (fid, '<table:table-row%s>%s', tnrr, tcell); - ## Row closing tag is written below matching endif below next while loop - else + fprintf (fid, '<table:table-row%s>%s</table:table-row>', tnrrt, tcell); + endif + if (ii <= onr) ## Write table row opening tag - fprintf (fid, '<table:table-row table:style-name="ro1">'); - ## 4.1 Optional empty left spreadsheet columns - if (lims(1, 1) > 1) - if (lims(1, 1) > 2) - fprintf (fid, '<table:table-cell table:number-columns-repeated="%d" />', lims(1, 1) - 1); - else - fprintf (fid, '<table:table-cell />') - endif - endif - ## 4.2 Value cells + fprintf (fid, '<table:table-row table:style-name="%s">', styles.row); + + ## 3.2 Value cells jj = 1; while (jj <= onc) - ## 4.2.1 Check if empty - if (isempty (rawarr{ii, jj})) - ## if empty determine consecutive empty & adapt ncr attr and write - tncr = 1; - while ((jj + tncr - 1) < onc && isempty (rawarr{ii, jj+tncr})) - ++tncr; - endwhile - if (tncr > 1) -% tncr = sprintf (' table:number-columns-repeated="%d"', tncr); - fprintf (fid, '<table:table-cell table:number-columns-repeated="%d" />', tncr); - jj += tncr - 1; - else - fprintf (fid, '<table:table-cell />'); - endif + ## 3.2.1 Check if empty. Include empty columns left of rawarr + if (jj == 1) + tncr = lims(1, 1) - 1; else - ## 4.2.2 Determine value class. Set formula attribute to empty + tncr = 0; + endif + ## Check consecutive empty cells & adapt ncr attr, write empty cells + while (jj <= onc && isempty (rawarr{ii, jj})) + ++tncr; + ++jj; + endwhile + if (tncr > 1) + fprintf (fid, '<table:table-cell table:number-columns-repeated="%d" />', tncr); + elseif (tncr == 1) + fprintf (fid, '<table:table-cell />'); + endif + ## Process non-empty data cells + if (jj <= onc) + ## 3.2.2 Non-empty cell. Determine value type. Set formula attr = empty of = ""; switch class (rawarr{ii, jj}) case {"double", "single"} ovt = ' office:value-type="float"'; - val = strtrim (sprintf ("%17.4f", rawarr{ii, jj})); + val = sprintf ("%.4f", rawarr{ii, jj}); txt = sprintf ('<text:p>%s</text:p>', val); ## Convert to attribute - val = sprintf (' office:value="%17.10f"', rawarr{ii, jj}); + val = sprintf (' office:value="%.10f"', rawarr{ii, jj}); case {"int64", "int32", "int16", "int8", "uint64", "uint32", "uint16", "uint8"} - ovt = "integer"; + ovt = ' office:value-type="integer"'; val = strtrim (sprintf ("%d15", rawarr{ii, jj})); txt = sprintf ('<text:p>%s</text:p>', val); ## Convert to attribute @@ -307,19 +334,22 @@ otherwise ## Unknown, illegal or otherwise unrecognized value ovt = ""; + val = ""; + txt = ""; endswitch # write out table-cell w office-value-type / office:value - fprintf (fid, '<table:table-cell%s%s%s>%s</table:table-cell>', of, ovt, val, txt); + fprintf (fid, '<table:table-cell%s%s%s>%s</table:table-cell>', + of, ovt, val, txt); endif ++jj; endwhile + ## Write table row closing tag + fprintf (fid, '</table:table-row>'); endif - ## Write table row closing tag - fprintf (fid, '</table:table-row>'); ++ii; endwhile - ## 5. Closing tag + ## 4. Closing tag fprintf (fid, '</table:table>'); status = 1;