No edit summary |
No edit summary |
||
(29 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
function | function split(str, sep, max) | ||
local z = #sep; sep = '^.-'..sep:gsub('[$%%()*+%-.?%[%]^]', '%%%0') | local z = #sep; sep = '^.-'..sep:gsub('[$%%()*+%-.?%[%]^]', '%%%0') | ||
local t,n,p, q,r = {},1,1, str:find(sep) | local t,n,p, q,r = {},1,1, str:find(sep) | ||
Line 10: | Line 10: | ||
t[n] = str:sub(p) | t[n] = str:sub(p) | ||
return t | return t | ||
end | |||
function trim(s) | |||
return s:match( "^%s*(.-)%s*$" ) | |||
end | end | ||
function toMap(entries) | function toMap(entries) | ||
local fields = | local fields = split(entries, '$$') | ||
local map = {} | local map = {} | ||
for var=1,#fields-1 do | for var=1,#fields-1 do | ||
local tmp = {} | local tmp = {} | ||
local current = fields[var] | local current = fields[var] | ||
for k, s in pairs( | for k, s in pairs(split(current, '$')) do | ||
local tmp2 = | local tmp2 = split(s, '=') | ||
tmp[tmp2[1]] = tmp2[2] | tmp[tmp2[1]] = tmp2[2] | ||
end | end | ||
Line 53: | Line 57: | ||
end | end | ||
function | local function entry(args) | ||
local | local ids = {} | ||
if args["id"] then | |||
for | for i, value in pairs(split(args["id"], ",")) do | ||
ids[trim(value)] = i | |||
end | |||
else | |||
for k, value in pairs(args) do | |||
if not k:find('/') then | |||
local tmp = split(value, ',') | |||
for i = 1, #tmp do | |||
ids[tostring(i)] = i | |||
end | |||
elseif string.sub(k, 1, 4) ~= "file" then | |||
local tmp = split(k, '/')[2] | |||
ids[tmp] = tonumber(tmp) | |||
end | |||
end | |||
end | |||
local idn = 0 | |||
for k, v in pairs(ids) do | |||
idn = idn + 1 | |||
end | end | ||
local filesBySpeed = {} | |||
local | |||
for | local t = {} | ||
for k, value in pairs(args) do | |||
if k:find('/') then | |||
local | local kSplit = split(k, '/') | ||
if | local key = kSplit[1] | ||
local override = kSplit[2] | |||
if not t[key] then | |||
t[key] = {} | |||
end | |||
if key == "file" and tonumber(override) then | |||
filesBySpeed[override] = trim(value) | |||
else | else | ||
t[key][ids[override]] = trim(value) | |||
end | end | ||
else | else | ||
if idn > 1 and value:find(",") then | |||
t[k] = split(value, ",") | |||
for i = 1, idn do | |||
t[k][i] = trim(t[k][i]) | |||
end | |||
else | |||
if not t[k] then | |||
t[k] = {} | |||
end | |||
for i = 1, idn do | |||
if not t[k][i] then | |||
t[k][i] = trim(value) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
for i = 1, idn do | |||
if t["file"] then | |||
if not t["file"][i] then | |||
t["file"][i] = filesBySpeed[t["speed"][i]] | |||
end | |||
end | |||
end | |||
local result = "" | |||
for i = 1, idn do | |||
for key, tvalue in pairs(t) do | |||
local value = tvalue[i] or "" | |||
result = result .. "$" .. key .. "=" .. value | |||
end | |||
result = result .. "$$" | |||
end | |||
return result | |||
end | |||
function p.overrides(frame) | |||
local args = split(frame.args[1], '\n') | |||
local result = '' | |||
for i, t in pairs(args) do | |||
local s = split(t, '=') | |||
local key = s[1] | |||
local value = s[2] | |||
local t = split(tostring(key), '/') | |||
if #t >= 2 then | |||
local tmp = {} | |||
tmp['override'] = '' | |||
tmp['id'] = t[2] | |||
tmp[t[1]] = value | |||
result = result .. entry(tmp) | |||
end | end | ||
end | end | ||
return result | return result | ||
end | |||
function p.entry(frame) | |||
return entry(frame:getParent().args) | |||
end | |||
local function compare(a, b) | |||
if not b["id"] then | |||
return false | |||
elseif not a["id"] then | |||
return true | |||
else | |||
return a["id"] < b["id"] | |||
end | |||
end | |||
local function groupByID(entries) | |||
local table1 = {} | |||
local overrides = {} | |||
local counter = 1 | |||
for i, x in ipairs(entries) do | |||
local id = x["id"] | |||
if not id then | |||
id = counter | |||
counter = counter + 1 | |||
x["id"] = id | |||
end | |||
for key, value in pairs(x) do | |||
if x["override"] then | |||
if key ~= "id" and key ~= "override" then | |||
if not overrides[id] then | |||
overrides[id] = {} | |||
end | |||
overrides[id][key] = value | |||
end | |||
else | |||
if not table1[id] then | |||
table1[id] = {} | |||
end | |||
if not table1[id][key] then | |||
table1[id][key] = {} | |||
end | |||
table1[id][key][value] = 4 | |||
end | |||
end | |||
end | |||
local table2 = {} | |||
for id, x in pairs(table1) do | |||
local tmp = {} | |||
for key, value in pairs(x) do | |||
for entry, q in pairs(value) do | |||
if not tmp[key] then | |||
tmp[key] = entry | |||
else | |||
tmp[key] = tmp[key] .. '<br />' .. entry | |||
end | |||
end | |||
end | |||
for o_id, o_o in pairs(overrides) do | |||
if string.sub(id, 1, #o_id) == o_id then | |||
for key, value in pairs(o_o) do | |||
tmp[key] = o_o[key] | |||
end | |||
end | |||
end | |||
table.insert(table2, tmp) | |||
end | |||
table.sort(table2, compare) | |||
return table2 | |||
end | end | ||
function p.generate(frame) | function p.generate(frame) | ||
local args = frame.args | local args = frame.args | ||
local entries = toMap( | local parentArgs = frame:getParent().args | ||
local columns = | local entries = groupByID(toMap(args['entries'])) | ||
local columns = split(args['columns'], ',') | |||
local result = "" | local result = "" | ||
for var | for var, x in ipairs(entries) do | ||
local subobject = "{{#subobject" | |||
for k, column in pairs(columns) do | for k, column in pairs(columns) do | ||
local val = value(entries, var, column, args) | |||
subobject = subobject .. "\n|BGM/" .. column .. "=" | |||
if column == "location" then | |||
local lines = split(val:gsub('<br />', '\n\n'), '\n\n') | |||
local locations = {} | |||
for _, line in pairs(lines) do | |||
if line:find('%[%[') then | |||
local namespaceName = split(split(line, ':')[1], '[')[3] | |||
local pageName = split(split(split(line, ':')[2], '|')[1], '#')[1] | |||
local displayName = split(split(line, '|')[2], ']')[1] | |||
local label = split(split(line, ']')[3], ':')[2] | |||
local record = namespaceName .. ":" .. pageName .. ";" | |||
if pageName == displayName then | |||
record = record .. trim(label or "") | |||
else | |||
if not label then | |||
record = record .. displayName | |||
else | |||
record = record .. displayName .. ": " .. trim(label) | |||
end | |||
end | |||
table.insert(locations, record) | |||
else | |||
table.insert(locations, line .. ";") | |||
end | |||
end | |||
subobject = subobject .. table.concat(locations, ",") .. "|+sep=," | |||
else | |||
subobject = subobject .. val | |||
end | |||
local id = uniq(entries, var, column, args, columns) | local id = uniq(entries, var, column, args, columns) | ||
if (id ~= uniq(entries, var - 1, column, args, columns)) then | if (id ~= uniq(entries, var - 1, column, args, columns)) then | ||
Line 93: | Line 271: | ||
rowspan = rowspan + 1 | rowspan = rowspan + 1 | ||
end | end | ||
if val ~= '' and args['display/' .. column] then | |||
if | val = args['display/' .. column]:gsub('value', val) | ||
end | end | ||
result = result .. '|rowspan="' .. tostring(rowspan) .. '"|' .. | result = result .. '|rowspan="' .. tostring(rowspan) .. '"|' .. val .. "\n" | ||
end | end | ||
end | end | ||
Line 103: | Line 280: | ||
result = result .. "|-\n" | result = result .. "|-\n" | ||
end | end | ||
subobject = subobject .. "\n}}" | |||
frame:preprocess(subobject) | |||
end | |||
return result | |||
end | |||
function p.formatRecord(frame) | |||
local input = frame.args[1] | |||
if (input == '') then | |||
return 'None' | |||
end | |||
local s = split(input, ',') | |||
local result = '' | |||
for i, x in pairs(s) do | |||
x = trim(x) | |||
local m = x:match('^%d+') | |||
local n = string.sub(x, #m + 1) | |||
while (#m < 4) do | |||
m = '0' .. m | |||
end | |||
result = result .. ',' .. m .. n | |||
end | end | ||
result = string.sub(result, 2) | |||
return result | return result | ||
end | end | ||
return p | return p |
Latest revision as of 19:23, 4 August 2024
Documentation for this module may be created at Module:SoundtrackTable/doc
local p = {} function split(str, sep, max) local z = #sep; sep = '^.-'..sep:gsub('[$%%()*+%-.?%[%]^]', '%%%0') local t,n,p, q,r = {},1,1, str:find(sep) while q and n~=max do t[n],n,p = str:sub(q,r-z),n+1,r+1 q,r = str:find(sep,p) end t[n] = str:sub(p) return t end function trim(s) return s:match( "^%s*(.-)%s*$" ) end function toMap(entries) local fields = split(entries, '$$') local map = {} for var=1,#fields-1 do local tmp = {} local current = fields[var] for k, s in pairs(split(current, '$')) do local tmp2 = split(s, '=') tmp[tmp2[1]] = tmp2[2] end map[var] = tmp end return map end function value(entries, i, j, args) if not entries[i] then return 'Out Of Range' else if not entries[i][j] or entries[i][j] == '' then return args['default/' .. j] or '' else return entries[i][j] end end end function uniq(entries, i, j, args, columns) if not entries[i] then return 'Out Of Range' end if not args['unique/' .. j] then return value(entries, i, j, args) end local ret = args['unique/' .. j] for k, column in pairs(columns) do ret = ret:gsub(column, value(entries, i, column, args)) end return ret end local function entry(args) local ids = {} if args["id"] then for i, value in pairs(split(args["id"], ",")) do ids[trim(value)] = i end else for k, value in pairs(args) do if not k:find('/') then local tmp = split(value, ',') for i = 1, #tmp do ids[tostring(i)] = i end elseif string.sub(k, 1, 4) ~= "file" then local tmp = split(k, '/')[2] ids[tmp] = tonumber(tmp) end end end local idn = 0 for k, v in pairs(ids) do idn = idn + 1 end local filesBySpeed = {} local t = {} for k, value in pairs(args) do if k:find('/') then local kSplit = split(k, '/') local key = kSplit[1] local override = kSplit[2] if not t[key] then t[key] = {} end if key == "file" and tonumber(override) then filesBySpeed[override] = trim(value) else t[key][ids[override]] = trim(value) end else if idn > 1 and value:find(",") then t[k] = split(value, ",") for i = 1, idn do t[k][i] = trim(t[k][i]) end else if not t[k] then t[k] = {} end for i = 1, idn do if not t[k][i] then t[k][i] = trim(value) end end end end end for i = 1, idn do if t["file"] then if not t["file"][i] then t["file"][i] = filesBySpeed[t["speed"][i]] end end end local result = "" for i = 1, idn do for key, tvalue in pairs(t) do local value = tvalue[i] or "" result = result .. "$" .. key .. "=" .. value end result = result .. "$$" end return result end function p.overrides(frame) local args = split(frame.args[1], '\n') local result = '' for i, t in pairs(args) do local s = split(t, '=') local key = s[1] local value = s[2] local t = split(tostring(key), '/') if #t >= 2 then local tmp = {} tmp['override'] = '' tmp['id'] = t[2] tmp[t[1]] = value result = result .. entry(tmp) end end return result end function p.entry(frame) return entry(frame:getParent().args) end local function compare(a, b) if not b["id"] then return false elseif not a["id"] then return true else return a["id"] < b["id"] end end local function groupByID(entries) local table1 = {} local overrides = {} local counter = 1 for i, x in ipairs(entries) do local id = x["id"] if not id then id = counter counter = counter + 1 x["id"] = id end for key, value in pairs(x) do if x["override"] then if key ~= "id" and key ~= "override" then if not overrides[id] then overrides[id] = {} end overrides[id][key] = value end else if not table1[id] then table1[id] = {} end if not table1[id][key] then table1[id][key] = {} end table1[id][key][value] = 4 end end end local table2 = {} for id, x in pairs(table1) do local tmp = {} for key, value in pairs(x) do for entry, q in pairs(value) do if not tmp[key] then tmp[key] = entry else tmp[key] = tmp[key] .. '<br />' .. entry end end end for o_id, o_o in pairs(overrides) do if string.sub(id, 1, #o_id) == o_id then for key, value in pairs(o_o) do tmp[key] = o_o[key] end end end table.insert(table2, tmp) end table.sort(table2, compare) return table2 end function p.generate(frame) local args = frame.args local parentArgs = frame:getParent().args local entries = groupByID(toMap(args['entries'])) local columns = split(args['columns'], ',') local result = "" for var, x in ipairs(entries) do local subobject = "{{#subobject" for k, column in pairs(columns) do local val = value(entries, var, column, args) subobject = subobject .. "\n|BGM/" .. column .. "=" if column == "location" then local lines = split(val:gsub('<br />', '\n\n'), '\n\n') local locations = {} for _, line in pairs(lines) do if line:find('%[%[') then local namespaceName = split(split(line, ':')[1], '[')[3] local pageName = split(split(split(line, ':')[2], '|')[1], '#')[1] local displayName = split(split(line, '|')[2], ']')[1] local label = split(split(line, ']')[3], ':')[2] local record = namespaceName .. ":" .. pageName .. ";" if pageName == displayName then record = record .. trim(label or "") else if not label then record = record .. displayName else record = record .. displayName .. ": " .. trim(label) end end table.insert(locations, record) else table.insert(locations, line .. ";") end end subobject = subobject .. table.concat(locations, ",") .. "|+sep=," else subobject = subobject .. val end local id = uniq(entries, var, column, args, columns) if (id ~= uniq(entries, var - 1, column, args, columns)) then local rowspan = 1 while (id == uniq(entries, var + rowspan, column, args, columns)) do rowspan = rowspan + 1 end if val ~= '' and args['display/' .. column] then val = args['display/' .. column]:gsub('value', val) end result = result .. '|rowspan="' .. tostring(rowspan) .. '"|' .. val .. "\n" end end if (var ~= #entries) then result = result .. "|-\n" end subobject = subobject .. "\n}}" frame:preprocess(subobject) end return result end function p.formatRecord(frame) local input = frame.args[1] if (input == '') then return 'None' end local s = split(input, ',') local result = '' for i, x in pairs(s) do x = trim(x) local m = x:match('^%d+') local n = string.sub(x, #m + 1) while (#m < 4) do m = '0' .. m end result = result .. ',' .. m .. n end result = string.sub(result, 2) return result end return p