Module:Array: Difference between revisions
Jump to navigation
Jump to search
Created page with "local p = {} local lib = require('Module:Feature') function p.main(frame) local args = require('Module:Arguments').getArgs(frame, { wrapper = { 'Template:Array' } }) --mw.logObject(args,'args') --debug return p._main(args, frame) end function p._main(args, frame) local arrayString = args[1] or nil local separator = args[2] or args.delim or nil local form = args[3] or args['format'] or nil local join = args[4] or args.join or '' local dedupe = args['dedupe']..." |
Add more features from Array module in zzz/wuwa wikis |
||
| Line 4: | Line 4: | ||
function p.main(frame) | function p.main(frame) | ||
local args = require('Module:Arguments').getArgs(frame, { | local args = require('Module:Arguments').getArgs(frame, { | ||
parentFirst = true, | |||
wrapper = { 'Template:Array' } | wrapper = { 'Template:Array' } | ||
}) | }) | ||
return p._main(args, frame) | return p._main(args, frame) | ||
end | end | ||
function p._main(args, frame) | function p._main(args, frame) | ||
local arrayString = args[1] or nil | local arrayString = args[1] or args["arrayString"] or nil | ||
local separator = args[2] or args | local separator = args[2] or args["sep"] or args["delim"] or args["separator"] or nil | ||
local | local format = args[3] or args["format"] or "{item}" | ||
local join = args[4] or args | local join = args[4] or args["join"] or "" | ||
local dedupe = args[ | local dedupe = args["dedupe"] or nil | ||
local sort = args[ | local sort = args["sort"] or nil | ||
local sentence = args[' | local sentence = args["sentence"] or nil | ||
local | local sentence_last = args['sentence_last'] or ' and ' | ||
local sentence_join = args['sentence_join'] or ', ' | |||
local firstItemOnly = args["firstItemOnly"] or nil | |||
local offsetStart = args["offsetStart"] or nil | |||
local offsetEnd = args["offsetEnd"] or nil | |||
local prefix = args['prefix'] or '' | local prefix = args['prefix'] or '' | ||
local suffix = args['suffix'] or '' | local suffix = args['suffix'] or '' | ||
local | local template = args['template'] or nil | ||
local split_opt = { | local split_opt = { | ||
removeEmpty = args['removeEmpty'] or nil, | removeEmpty = args['removeEmpty'] or nil, | ||
| Line 30: | Line 32: | ||
-- argument validation | -- argument validation | ||
if arrayString == nil then return | if arrayString == nil then return "" end | ||
if separator == nil then return error( | if separator == nil then return error("Second argument (separator) must not be empty.") end | ||
if separator == | if separator == "" then return error("Second argument (separator) must not be empty string.") end | ||
if | if format == nil then return error("Third argument (format) must not be empty.") end | ||
-- split string to array | -- split string to array | ||
if string.find(separator, "{newline}") then | |||
separator = separator:gsub("{newline}", "\n") | |||
end | |||
if string.find(separator, "{space}") then | |||
separator = separator:gsub("{space}", " ") | |||
end | |||
local array = lib.split(arrayString, separator, split_opt) | local array = lib.split(arrayString, separator, split_opt) | ||
-- remove | -- remove duplicates from array | ||
if dedupe = | if dedupe ~= nil then | ||
array = p._removeDuplicates(array) | array = p._removeDuplicates(array) | ||
end | end | ||
| Line 47: | Line 54: | ||
if sort ~= nil then | if sort ~= nil then | ||
array = p._sort(array, sort) | array = p._sort(array, sort) | ||
end | |||
-- filter by offset | |||
if offsetStart ~= nil or offsetEnd ~= nil then | |||
array = lib.arraySlice(array, lib.toNullableNumber(offsetStart), lib.toNullableNumber(offsetEnd)) | |||
end | end | ||
-- replace keywords in array | -- replace keywords in array | ||
for key, value in pairs(array) do | for key, value in pairs(array) do | ||
local item = | -- get format (may have override) | ||
item = item:gsub( | local item = format | ||
item = item:gsub( | if args["format" .. key] ~= nil then | ||
item = args["format" .. key] | |||
end | |||
-- Basic substitutions | |||
if string.find(item, "{index}") then | |||
item = item:gsub("{index}", key) | |||
end | |||
if string.find(item, "{newline}") then | |||
item = item:gsub("{newline}", "\n") | |||
end | |||
if string.find(item, "{space}") then | |||
item = item:gsub("{space}", " ") | |||
end | |||
-- figure out sub-divisions if any | -- figure out sub-divisions if any | ||
| Line 70: | Line 95: | ||
split(values, '2') | split(values, '2') | ||
item = item:gsub( | -- Item substitutions | ||
item = item:gsub("{item}", value) | |||
item = item:gsub('{item([%d%.]*)}', | item = item:gsub('{item([%d%.]*)}', | ||
function(suffix) | function(suffix) | ||
| Line 85: | Line 111: | ||
end | end | ||
) | ) | ||
if string.find(item, "{itemLink}") then | |||
item = item:gsub("{itemLink}", mw.InfoboxBuilderHF.Link(value)) | |||
end | |||
if string.find(item, "{itemLinkSafe}") then | |||
item = item:gsub("{itemLinkSafe}", mw.InfoboxBuilderHF.Link_safe(value)) | |||
end | |||
array[key] = item | array[key] = item | ||
end | end | ||
| Line 92: | Line 123: | ||
-- create result array | -- create result array | ||
local result = | local result = "" | ||
-- join as sentence | -- join as sentence | ||
if sentence ~= nil then | if sentence ~= nil then | ||
if #array == 0 then return | if #array == 0 then return "" | ||
elseif #array == 1 then | elseif #array == 1 then return array[1] | ||
elseif #array == 2 then | elseif #array == 2 then return array[1] .. sentence_last .. array[2] | ||
else | else | ||
local last = table.remove(array, #array) | local last = table.remove(array, #array) | ||
result = table.concat(array, sentence_join) .. | result = table.concat(array, sentence_join) .. sentence_join .. sentence_last .. last | ||
end | end | ||
-- first item only | |||
elseif firstItemOnly ~= nil then | |||
return array[1] | |||
-- join with join string | -- join with join string | ||
else | else | ||
if string.find(join, "{newline}") then | |||
join = join:gsub("{newline}", "\n") | |||
end | |||
if string.find(join, "{space}") then | |||
join = join:gsub("{space}", " ") | |||
end | |||
result = table.concat(array, join) | |||
end | end | ||
result = prefix .. result .. suffix | result = prefix .. result .. suffix | ||
if template then | if template then | ||
if args.debug then mw.logObject(result, 'final result pre-preprocess') end | if args.debug then mw.logObject(result, 'final result pre-preprocess') end | ||
| Line 144: | Line 185: | ||
function p._sort(arr, dir) | function p._sort(arr, dir) | ||
local order = nil | local order = nil | ||
if (dir == -1 or dir == | if (dir == -1 or dir == "-1") then | ||
order = function(tVal, a, b) return a > b end | order = function(tVal, a, b) return a > b end | ||
elseif (dir == 1 or dir == | elseif (dir == 1 or dir == "1") then | ||
order = function(tVal, a, b) return a < b end | order = function(tVal, a, b) return a < b end | ||
else | else | ||
Revision as of 11:51, 29 August 2025
Documentation for this module may be created at Module:Array/doc
local p = {}
local lib = require('Module:Feature')
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
parentFirst = true,
wrapper = { 'Template:Array' }
})
return p._main(args, frame)
end
function p._main(args, frame)
local arrayString = args[1] or args["arrayString"] or nil
local separator = args[2] or args["sep"] or args["delim"] or args["separator"] or nil
local format = args[3] or args["format"] or "{item}"
local join = args[4] or args["join"] or ""
local dedupe = args["dedupe"] or nil
local sort = args["sort"] or nil
local sentence = args["sentence"] or nil
local sentence_last = args['sentence_last'] or ' and '
local sentence_join = args['sentence_join'] or ', '
local firstItemOnly = args["firstItemOnly"] or nil
local offsetStart = args["offsetStart"] or nil
local offsetEnd = args["offsetEnd"] or nil
local prefix = args['prefix'] or ''
local suffix = args['suffix'] or ''
local template = args['template'] or nil
local split_opt = {
removeEmpty = args['removeEmpty'] or nil,
noTrim = args['noTrim'] or nil
}
-- argument validation
if arrayString == nil then return "" end
if separator == nil then return error("Second argument (separator) must not be empty.") end
if separator == "" then return error("Second argument (separator) must not be empty string.") end
if format == nil then return error("Third argument (format) must not be empty.") end
-- split string to array
if string.find(separator, "{newline}") then
separator = separator:gsub("{newline}", "\n")
end
if string.find(separator, "{space}") then
separator = separator:gsub("{space}", " ")
end
local array = lib.split(arrayString, separator, split_opt)
-- remove duplicates from array
if dedupe ~= nil then
array = p._removeDuplicates(array)
end
-- sort array
if sort ~= nil then
array = p._sort(array, sort)
end
-- filter by offset
if offsetStart ~= nil or offsetEnd ~= nil then
array = lib.arraySlice(array, lib.toNullableNumber(offsetStart), lib.toNullableNumber(offsetEnd))
end
-- replace keywords in array
for key, value in pairs(array) do
-- get format (may have override)
local item = format
if args["format" .. key] ~= nil then
item = args["format" .. key]
end
-- Basic substitutions
if string.find(item, "{index}") then
item = item:gsub("{index}", key)
end
if string.find(item, "{newline}") then
item = item:gsub("{newline}", "\n")
end
if string.find(item, "{space}") then
item = item:gsub("{space}", " ")
end
-- figure out sub-divisions if any
function split(arr, index)
if args['delim' .. index] then
for v in lib.gsplit(arr.main, args['delim' .. index], split_opt) do
local subarr = {main = v}
split(subarr, tostring(tonumber(index)+1))
table.insert(arr, subarr)
end
else
return
end
end
local values = { main = value }
split(values, '2')
-- Item substitutions
item = item:gsub("{item}", value)
item = item:gsub('{item([%d%.]*)}',
function(suffix)
local val = values
for index in lib.gsplit(suffix, '.') do
if val[tonumber(index)] then
val = val[tonumber(index)]
else
val = {main=''}
break
end
end
return val.main
end
)
if string.find(item, "{itemLink}") then
item = item:gsub("{itemLink}", mw.InfoboxBuilderHF.Link(value))
end
if string.find(item, "{itemLinkSafe}") then
item = item:gsub("{itemLinkSafe}", mw.InfoboxBuilderHF.Link_safe(value))
end
array[key] = item
end
if args.debug then mw.logObject(array, 'input array') end
-- create result array
local result = ""
-- join as sentence
if sentence ~= nil then
if #array == 0 then return ""
elseif #array == 1 then return array[1]
elseif #array == 2 then return array[1] .. sentence_last .. array[2]
else
local last = table.remove(array, #array)
result = table.concat(array, sentence_join) .. sentence_join .. sentence_last .. last
end
-- first item only
elseif firstItemOnly ~= nil then
return array[1]
-- join with join string
else
if string.find(join, "{newline}") then
join = join:gsub("{newline}", "\n")
end
if string.find(join, "{space}") then
join = join:gsub("{space}", " ")
end
result = table.concat(array, join)
end
result = prefix .. result .. suffix
if template then
if args.debug then mw.logObject(result, 'final result pre-preprocess') end
if not args.nodpl then
result = result
:gsub('²{','{{')
:gsub('}²','}}')
:gsub('¦','|')
end
result = result
:gsub('%^2{','{{') -- for use inside DPL
:gsub('}%^2','}}') --
:gsub('¹','|') --
result = frame:preprocess(result)
end
if args.debug then mw.logObject(result, 'final result') end
return result
end
function p._removeDuplicates(arr)
local hash = {}
local res = {}
for _,v in ipairs(arr) do
if (not hash[v]) then
res[#res+1] = v
hash[v] = true
end
end
return res
end
function p._sort(arr, dir)
local order = nil
if (dir == -1 or dir == "-1") then
order = function(tVal, a, b) return a > b end
elseif (dir == 1 or dir == "1") then
order = function(tVal, a, b) return a < b end
else
return arr
end
table.sort(arr, function(a, b) return order(t, a, b) end)
return arr
end
return p