Module:Csv
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Csv/doc
local p = {}
local getArgs = require("Dev:Arguments").getArgs
local str_find = string.find
local str_sub = string.sub
local str_gsub = string.gsub
local tbl_insert = table.insert
local function escapeMagicCharacters(s)
-- Lua pattern magic chars are ^$()%.[]*+-?
return str_gsub(s, '[%^%$%(%)%%%.%[%]%*%+%-%?]', '%%%1')
end
function p.main(frame)
local args = getArgs(frame)
local sPageName = args.page
local fmtparams = {
delimiter = args.delimiter,
quotechar = args.quotechar,
}
if sPageName then
return p.csvToHtmlTable(sPageName, fmtparams)
end
end
function p.csvToHtmlTable(sPage, fmtparams)
local tLuaTable = p.convertToLua(sPage, fmtparams)
if tLuaTable then
return p.generateHtml(tLuaTable, fmtparams)
end
end
function p.convertToLua(sPage, fmtparams)
if sPage then
local oData = mw.title.new(sPage)
local arrColumns = {}
if oData then
local contents = oData:getContent()
if contents then
arrColumns = p.parseCSV(contents, fmtparams)
end
end
return arrColumns
end
end
-- //Converts a csv page to html table
function p.generateHtml(arrColumns, fmtparams)
local hTable = mw.html.create("table")
hTable:addClass("wikitable")
for i, v in ipairs(arrColumns) do
local sTag = i == 1 and "th" or "td"
local tr = hTable:tag("tr")
for _, sData in ipairs(v) do
local text = sData:gsub('\n', '<br>')
tr:tag(sTag):wikitext(text)
end
end
return hTable
end
-- http://lua-users.org/wiki/CsvUtils
-- https://docs.python.org/3/library/csv.html
function p.parseCSV(s, fmtparams)
if s == '' then return {} end
local t = {}
local row = {}
local pos = 1
local delimiter = fmtparams and fmtparams.delimiter or ','
if #delimiter ~= 1 then
error('"delimiter" must be a 1-character string')
end
local quotechar = fmtparams and fmtparams.quotechar or '"'
if #quotechar ~= 1 then
error('"quotechar" must be a 1-character string')
end
local escapedDelimiter = escapeMagicCharacters(delimiter)
local escapedQuotechar = escapeMagicCharacters(quotechar)
repeat
if str_find(s, '^'..escapedQuotechar, pos) then
local a, c
local i = pos
repeat
a, i, c = str_find(s, escapedQuotechar..'('..escapedQuotechar..'?)', i + 1)
until c ~= quotechar
if not i then error('Unmatched '..quotechar) end
local f = str_sub(s, pos + 1, i - 1)
local txt = str_gsub(f, escapedQuotechar..escapedQuotechar, quotechar)
tbl_insert(row, txt)
local nexti = str_find(s, escapedDelimiter, i)
pos = (nexti or i) + 1
else -- unquoted; str_find next delimiter, newline, or EOL.
local i = str_find(s, '[\n'..escapedDelimiter..']', pos)
if i then
local txt = str_sub(s, pos, i - 1)
tbl_insert(row, txt)
if str_sub(s, i, i) == '\n' then
tbl_insert(t, row)
row = {}
end
pos = i + 1
else
local txt = str_sub(s, pos)
tbl_insert(row, txt)
break
end
end
until pos > #s
if row and #row > 0 then
tbl_insert(t, row)
end
return t
end
return p