Module:Graph:Utils
Module documentation
[create]
local p = {}
function p.titleToJson(title)
-- Load mediawiki page and decodes it as json
local t = mw.title.new(title)
if not t.exists then
return nil
else
return mw.text.jsonDecode(t:getContent(), mw.text.JSON_TRY_FIXING)
end
end
function p.recodeListToMap(frame)
-- a function to re-code a json table in format [{},{},{}] to a map {},
-- with each source object containing the same set of values, and the response
-- mapping the "from" value to "to" value
-- parameters: tbl, from, to
local args = frame.args
local tbl = p.titleToJson(args[1])
local from = args[2]
local to = args[3]
local result = p.recodeListToMapFunc(tbl, from, to, args)
return mw.text.jsonEncode(result)
end
function p.recodeListToMapFunc(tbl, from, to, values)
-- a function to re-code a json table in format [{},{},{}] to a map {},
-- with each source object containing the same set of values, and the response
-- mapping the "from" values to "to" values
-- parameters: tbl, from, to
local dict = {}
for k, v in pairs(tbl) do
if v[from] ~= nil and v[to] ~= nil then
dict[v[from]] = v[to]
end
end
local result = {}
for key, val in pairs(values) do
if type(key) == "string" then
local k = dict[key]
if k ~= nil then
result[k] = val
end
end
end
return result
end
function p.parseCsv(frame)
local args = frame.args
local content = mw.title.new(args[1]):getContent()
local columnName = args[2]
local result = p.parseCsvFunc(content, columnName)
return mw.text.jsonEncode(result)
end
function p.parseCsvFunc(content, columnName)
-- Simple, no escaping, csv parser. Assumes first row contains column names
-- given csv text, extracts first column and names it 'id', and any other
-- column that has the same name as the given columnName, and names it 'v'
-- the result is in form: [{id=...,v=...}, {id=...,v=...}], ...]
-- if coulmn is not found, v= will not be given
local result = {}
local numberIdx = false
for v in string.gmatch(content, '([^\n]*)') do
local val = mw.text.trim(v)
if val ~= '' then
local parts = mw.text.split( val, ',', true )
if numberIdx == false then
numberIdx = true
for i, v in ipairs(parts) do
local val = mw.text.trim(v)
if val == columnName then
numberIdx = i
break
end
end
else
local val = nil
if numberIdx ~= true then
val = tonumber(mw.text.trim(parts[numberIdx]))
end
table.insert(result, {
id=mw.text.trim(parts[1]),
v=val
})
end
end
end
return result
end
function p.parseHCsv(frame)
local args = frame.args
local content = mw.title.new(args[1]):getContent()
local rowId = args[2]
local result = p.parseHCsvFunc(content, rowId)
return mw.text.jsonEncode(result)
end
function p.parseHCsvFunc(content, id)
-- Simple, no escaping, csv parser. Assumes first row contains column names
-- given csv text, extracts just the row whos first column matches given id
-- first column is not returned, all other column's headers become IDs
-- the result is in form: [{id=...,v=...}, {id=...,v=...}], ...]
-- DEBUG: =mw.text.jsonEncode(p.parseHCsvFunc('i,x,y,z\nb,1,2,3\na,2,3,4','a'))
local result = {}
local headers = false
for v in string.gmatch(content, '([^\n]*)') do
local val = mw.text.trim(v)
if val ~= '' then
local parts = mw.text.split( val, ',', true )
if headers == false then
headers = {}
for i, v in ipairs(parts) do
table.insert(headers, mw.text.trim(v))
end
elseif mw.text.trim(parts[1]) == id then
local isFirst = true
for i, v in ipairs(parts) do
if isFirst then
isFirst = false
else
table.insert(result, {
id=headers[i],
v=tonumber(mw.text.trim(v))
})
end
end
break
end
end
end
return result
end
function p.expandDict(frame)
return mw.text.jsonEncode(p.expandDictFunc(mw.text.jsonDecode(frame.args[1])))
end
function p.expandDictFunc(inp)
-- Converts compressed format json table to expanded format, for example:
-- { "a": 10, "b": 20 }
-- will be converted to
-- [{ "id": "a", "v": 10 }, { "id": "b", "v": 20 }]
-- DEBUG: =mw.text.jsonEncode(p.expandDictFunc(mw.text.jsonDecode('{ "a": 10, "b": 20 }')))
local result = {}
for k, v in pairs(inp) do
table.insert(result, {
id=k,
v=v
})
end
return result
end
return p