summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua')
-rw-r--r--Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua178
1 files changed, 178 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua b/Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua
new file mode 100644
index 00000000000..d305fb48a5f
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/odsfile/odsfile.lua
@@ -0,0 +1,178 @@
+module(...,package.seeall)
+require "zip"
+xmlparser = require ("luaxml-mod-xml")
+handler = require("luaxml-mod-handler")
+
+
+function load(filename)
+ local p = {
+ file = zip.open(filename),
+ content_file_name = "content.xml",
+ loadContent = function(self,filename)
+ local treehandler = handler.simpleTreeHandler()
+ local filename = filename or self.content_file_name
+ local xmlfile = self.file:open(filename)
+ local text = xmlfile:read("*a")
+ local xml = xmlparser.xmlParser(treehandler)
+ xml:parse(text)
+ return treehandler
+ end
+ }
+ return p
+end
+
+function getTable(x,table_name)
+ local tables = x.root["office:document-content"]["office:body"]["office:spreadsheet"]["table:table"]
+ if #tables > 1 then
+ if type(tables) == "table" and table_name ~= nil then
+ for k,v in pairs(tables) do
+ if(v["_attr"]["table:name"]==table_name) then
+ return v, k
+ end
+ end
+ elseif type(tables) == "table" and table_name == nil then
+ return tables[1], 1
+ else
+ return tables
+ end
+ else
+ return tables
+ end
+end
+
+function tableValues(tbl,x1,y1,x2,y2)
+ local t= {}
+ if type(tbl["table:table-row"])=="table" then
+ local rows = table_slice(tbl["table:table-row"],y1,y2)
+ for k,v in pairs(rows) do
+ -- In every sheet, there are two rows with no data at the bottom, we need to strip them
+ if(v["_attr"] and v["_attr"]["table:number-rows-repeated"] and tonumber(v["_attr"]["table:number-rows-repeated"])>10000) then break end
+ local j = {}
+ if #v["table:table-cell"] > 1 then
+ local r = table_slice(v["table:table-cell"],x1,x2)
+ for p,n in pairs(r) do
+ table.insert(j,{value=n["text:p"] or "",attr=n["_attr"]})
+ end
+ else
+ local p = {value=v["table:table-cell"]["text:p"],attr=v["table:table-cell"]["_attr"]}
+ table.insert(j,p)
+ end
+ table.insert(t,j)
+ end
+ end
+ return t
+end
+
+function getRange(range)
+ local r = range:lower()
+ local function getNumber(s)
+ if s == "" or s == nil then return nil end
+ local f,ex = 0,0
+ for i in string.gmatch(s:reverse(),"(.)") do
+ f = f + (i:byte()-96) * 26 ^ ex
+ ex = ex + 1
+ end
+ return f
+ end
+ for x1,y1,x2,y2 in r:gmatch("(%a*)(%d*):*(%a*)(%d*)") do
+ return getNumber(x1),tonumber(y1),getNumber(x2),tonumber(y2)
+ --print(string.format("%s, %s, %s, %s",getNumber(x1),y1,getNumber(x2),y2))
+ end
+end
+
+function table_slice (values,i1,i2)
+ -- Function from http://snippets.luacode.org/snippets/Table_Slice_116
+ local res = {}
+ local n = #values
+ -- default values for range
+ i1 = i1 or 1
+ i2 = i2 or n
+ if i2 < 0 then
+ i2 = n + i2 + 1
+ elseif i2 > n then
+ i2 = n
+ end
+ if i1 < 1 or i1 > n then
+ return {}
+ end
+ local k = 1
+ for i = i1,i2 do
+ res[k] = values[i]
+ k = k + 1
+ end
+ return res
+end
+
+function interp(s, tab)
+ return (s:gsub('(-%b{})',
+ function(w)
+ s = w:sub(3, -2)
+ s = tonumber(s) or s
+ return tab[s] or w
+ end)
+ )
+end
+
+
+-- Interface for adding new rows to the spreadsheet
+
+function newRow()
+ local p = {
+ pos = 0,
+ cells = {},
+ -- Generic function for inserting cell
+ addCell = function(self,val, attr,pos)
+ if pos then
+ table.insert(self.cells,pos,{["text:p"] = val, ["_attr"] = attr})
+ self.pos = pos
+ else
+ self.pos = self.pos + 1
+ table.insert(self.cells,self.pos,{["text:p"] = val, ["_attr"] = attr})
+ end
+ end,
+ addString = function(self,s,attr,pos)
+ local attr = attr or {}
+ attr["office:value-type"] = "string"
+ self:addCell(s,attr,pos)
+ end,
+ addFloat = function(self,i,attr,pos)
+ local attr = attr or {}
+ local s = tonumber(i) or 0
+ s = tostring(s)
+ attr["office:value-type"] = "float"
+ attr["office:value"] = s
+ self:addCell(s,attr,pos)
+ end,
+ findLastRow = function(self,sheet)
+ for i= #sheet["table:table-row"],1,-1 do
+ if sheet["table:table-row"][i]["_attr"]["table:number-rows-repeated"] then
+ return i
+ end
+ end
+ return #sheet["table:table-row"]+1
+ end,
+ insert = function(self, sheet, pos)
+ local t = {}
+ local pos = pos or self:findLastRow(sheet)
+ print("pos je: ",pos)
+ if sheet["table:table-column"]["_attr"] and sheet["table:table-column"]["_attr"]["table:number-columns-repeated"] then
+ table_columns = sheet["table:table-column"]["_attr"]["table:number-columns-repeated"]
+ else
+ table_columns = #sheet["table:table-column"]
+ end
+ for i=1, table_columns do
+ table.insert(t,self.cells[i] or {})
+ end
+ t = {["table:table-cell"]=t}
+ table.insert(sheet["table:table-row"],pos,t)
+ end
+ }
+ return p
+end
+
+
+-- function for updateing the archive. Depends on external zip utility
+function updateZip(zipfile, updatefile)
+ local command = string.format("zip %s %s",zipfile, updatefile)
+ print ("Updating an ods file.\n" ..command .."\n Return code: ", os.execute(command))
+end