add csv module
This commit is contained in:
@@ -24,7 +24,8 @@ The type of script is determined by the line (meta tag) at the beginning of the
|
|||||||
* 4.4.0 - markdown support;
|
* 4.4.0 - markdown support;
|
||||||
* 4.4.1 - rich text editor support;
|
* 4.4.1 - rich text editor support;
|
||||||
* 4.4.2 - added `fmt` and `html` utility modules;
|
* 4.4.2 - added `fmt` and `html` utility modules;
|
||||||
* 4.4.4 - added `tasker` module.
|
* 4.4.4 - added `tasker` module;
|
||||||
|
* 4.4.4 - added `csv` module.
|
||||||
|
|
||||||
# Widget scripts
|
# Widget scripts
|
||||||
|
|
||||||
@@ -469,6 +470,7 @@ AIO Launcher also includes:
|
|||||||
* [fmt](lib/fmt.lua) - HTML formatting module;
|
* [fmt](lib/fmt.lua) - HTML formatting module;
|
||||||
* [utf8](https://gist.github.com/Stepets/3b4dbaf5e6e6a60f3862) - UTF-8 module from Lua 5.3;
|
* [utf8](https://gist.github.com/Stepets/3b4dbaf5e6e6a60f3862) - UTF-8 module from Lua 5.3;
|
||||||
* [json.lua](https://github.com/rxi/json.lua) - JSON parser;
|
* [json.lua](https://github.com/rxi/json.lua) - JSON parser;
|
||||||
|
* [csv.lua](lib/csv.lua) - CSV parser;
|
||||||
* [Lua-Simple-XML-Parser](https://github.com/Cluain/Lua-Simple-XML-Parser) - XML parser (see example `xml-test.lua`).
|
* [Lua-Simple-XML-Parser](https://github.com/Cluain/Lua-Simple-XML-Parser) - XML parser (see example `xml-test.lua`).
|
||||||
* [luaDate](https://github.com/Tieske/date) - time functions;
|
* [luaDate](https://github.com/Tieske/date) - time functions;
|
||||||
* [LuaFun](https://github.com/luafun/luafun) - high-performance functional programming library for Lua;
|
* [LuaFun](https://github.com/luafun/luafun) - high-performance functional programming library for Lua;
|
||||||
|
|||||||
100
lib/csv.lua
Normal file
100
lib/csv.lua
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
-- type = "module"
|
||||||
|
-- CSV Module
|
||||||
|
-- http://help.interfaceware.com/kb/parsing-csv-files
|
||||||
|
|
||||||
|
local function parse_line(line,sep)
|
||||||
|
local res = {}
|
||||||
|
local pos = 1
|
||||||
|
sep = sep or ','
|
||||||
|
while true do
|
||||||
|
local c = string.sub(line,pos,pos)
|
||||||
|
if (c == "") then break end
|
||||||
|
local posn = pos
|
||||||
|
local ctest = string.sub(line,pos,pos)
|
||||||
|
|
||||||
|
while ctest == ' ' do
|
||||||
|
-- handle space(s) at the start of the line (with quoted values)
|
||||||
|
posn = posn + 1
|
||||||
|
ctest = string.sub(line,posn,posn)
|
||||||
|
if ctest == '"' then
|
||||||
|
pos = posn
|
||||||
|
c = ctest
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (c == '"') then
|
||||||
|
-- quoted value (ignore separator within)
|
||||||
|
local txt = ""
|
||||||
|
repeat
|
||||||
|
local startp,endp = string.find(line,'^%b""',pos)
|
||||||
|
txt = txt..string.sub(line,startp+1,endp-1)
|
||||||
|
pos = endp + 1
|
||||||
|
c = string.sub(line,pos,pos)
|
||||||
|
if (c == '"') then
|
||||||
|
txt = txt..'"'
|
||||||
|
-- check first char AFTER quoted string, if it is another
|
||||||
|
-- quoted string without separator, then append it
|
||||||
|
-- this is the way to "escape" the quote char in a quote. example:
|
||||||
|
-- value1,"blub""blip""boing",value3 will result in blub"blip"boing for the middle
|
||||||
|
elseif c == ' ' then
|
||||||
|
-- handle space(s) before the delimiter (with quoted values)
|
||||||
|
while c == ' ' do
|
||||||
|
pos = pos + 1
|
||||||
|
c = string.sub(line,pos,pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
until (c ~= '"')
|
||||||
|
table.insert(res,txt)
|
||||||
|
|
||||||
|
if not (c == sep or c == "") then
|
||||||
|
error("ERROR: Invalid CSV field - near character "..pos.." in this line of the CSV file: \n"..line, 3)
|
||||||
|
end
|
||||||
|
pos = pos + 1
|
||||||
|
posn = pos
|
||||||
|
ctest = string.sub(line,pos,pos)
|
||||||
|
|
||||||
|
while ctest == ' ' do
|
||||||
|
-- handle space(s) after the delimiter (with quoted values)
|
||||||
|
posn = posn + 1
|
||||||
|
ctest = string.sub(line,posn,posn)
|
||||||
|
if ctest == '"' then
|
||||||
|
pos = posn
|
||||||
|
c = ctest
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- no quotes used, just look for the first separator
|
||||||
|
local startp,endp = string.find(line,sep,pos)
|
||||||
|
if (startp) then
|
||||||
|
table.insert(res,string.sub(line,pos,startp-1))
|
||||||
|
pos = endp + 1
|
||||||
|
else
|
||||||
|
-- no separator found -> use rest of string and terminate
|
||||||
|
table.insert(res,string.sub(line,pos))
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
---- Module Interface functions ----
|
||||||
|
------------------------------------
|
||||||
|
local csv = {}
|
||||||
|
|
||||||
|
function csv.parse(data, separator)
|
||||||
|
-- handle '\r\n\' as line separator
|
||||||
|
data = data:gsub('\r\n','\n')
|
||||||
|
-- handle '\r' (bad form) as line separator
|
||||||
|
data = data:gsub('\r','\n')
|
||||||
|
local result={}
|
||||||
|
|
||||||
|
for line in data:gmatch("([^\n]+)") do
|
||||||
|
local parsed_line = parse_line(line, separator)
|
||||||
|
table.insert(result, parsed_line)
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
return csv
|
||||||
Reference in New Issue
Block a user