/usr/share/octave/packages/io-2.4.5/private/__ods_get_sheet_dims__.m is in octave-io 2.4.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | ## Copyright (C) 2013-2016 Philip Nienhuis
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, see
## <http://www.gnu.org/licenses/>.
## __ods_get_sheet_dims__
## Internal function - get dimensions of occupied cell range in an ODS sheet.
## Author: Philip Nienhuis <prnienhuis@users.sf.net>
## Created: 2013-09-29 (split off from __JOD_getusedrange__.m)
function [trow, brow, lcol, rcol ] = __ods_get_sheet_dims__ (sh)
## 1. Get table-row pointers
id_trow = strfind (sh, "<table:table-row");
id = strfind (sh, "</table:table>") - 1;
id_trow = [id_trow id];
trow = rcol = 0;
lcol = 1024; brow = 0;
if (~isempty (id))
## 2. Loop over all table-rows
rowrepcnt = 0;
for irow = 1:length (id_trow)-1
## Isolate single table-row
tablerow = sh(id_trow(irow):id_trow(irow+1)-1);
## Search table-cells. table-c covers both table-cell & table-covered-cell
id_tcell = strfind (tablerow, "<table:table-c");
id_tcell = [id_tcell id];
rowl = length (tablerow);
if (isempty (id_tcell(1:end-1)))
rowend = rowl;
else
rowend = id_tcell(1);
endif
## Add in table-number-rows-repeated attribute values
rowrept = strfind (tablerow(1:rowend), "number-rows-repeated");
if (~isempty (rowrept))
[st, en] = regexp (tablerow(rowrept:min (rowend, rowrept+30)), '\d+');
rowrepcnt += str2double (tablerow(rowrept+st-1:min (rowend, rowrept+en-1))) - 1;
endif
## 3. Search table-cells. table-c is a table-covered-cell that is considered empty
id_tcell = strfind (tablerow, "<table:table-c");
if (~isempty (id_tcell))
## OK, this row has a value cell. Now table-covered-cells must be included.
id_tcell2 = strfind (tablerow, "<table:covered-t");
if (~isempty (id_tcell2)) id_tcell = sort ([id_tcell id_tcell2]); endif
id_tcell = [id_tcell rowl];
## Search for non-empty cells (i.e., with an office:value-type attribute). But:
## jOpenDocument 1.2b3 has a bug: it often doesn't set this attr for string cells
id_valtcell = strfind (tablerow, "office:value-type=");
id_textonlycell = strfind (tablerow, "<text:");
id_valtcell = sort ([id_valtcell id_textonlycell]);
id_valtcell = [id_valtcell rowl];
if (~isempty (id_valtcell(1:end-1)))
brow = irow + rowrepcnt;
## First set trow if it hadn't already been found
if (~trow)
trow = irow + rowrepcnt;
endif
## Search for repeated table-cells
id_reptcell = strfind (tablerow, "number-columns-repeated");
id_reptcell = [id_reptcell rowl];
## Search for leftmost non-empty table-cell. llcol = counter for this table-row
llcol = 1;
while (id_tcell (llcol) < id_valtcell(1) && llcol <= length (id_tcell) - 1)
++llcol;
endwhile
--llcol;
## Compensate for repeated cells. First count all repeats left of llcol
ii = 1;
repcnt = 0;
if (~isempty (id_reptcell(1:end-1)))
## First try lcol
while (ii <= length (id_reptcell) - 1 && id_reptcell(ii) < id_valtcell(1))
## Add all repeat counts left of leftmost data tcell minus 1 for each
[st, en] = ...
regexp (tablerow(id_reptcell(ii):id_reptcell(ii)+30), '\d+');
repcnt += ...
str2num (tablerow(id_reptcell(ii)+st-1:id_reptcell(ii)+en-1)) - 1;
++ii;
endwhile
## Next, add current repcnt value to llcol and update lcol
lcol = min (lcol, llcol + repcnt);
## Get last value table-cell in table-cell idx
jj = 1;
while (id_tcell (jj) < id_valtcell(length (id_valtcell)-1))
++jj;
endwhile
## Get rest of column repeat counts in value table-cell range
while (ii < length (id_reptcell) && id_reptcell(ii) < id_tcell(jj))
## Add all repeat counts minus 1 for each tcell in value tcell range
[st, en] = ...
regexp (tablerow(id_reptcell(ii):id_reptcell(ii)+30), '\d+');
repcnt += ...
str2num (tablerow(id_reptcell(ii)+st-1:id_reptcell(ii)+en-1)) - 1;
++ii;
endwhile
else
## In case left column = A
lcol = min (lcol, llcol);
endif
## Count all table-cells in value table-cell-range
ii = 1; ## Indexes cannot be negative
while (ii < length (id_tcell) ...
&& id_tcell(ii) < id_valtcell(length (id_valtcell) - 1))
++ii;
endwhile
--ii;
rcol = max (rcol, ii + repcnt);
endif
endif
endfor
else
## No data found, empty sheet
lcol = rcol = brow = trow = 0;
endif
endfunction
|