Модуль:GetField: различия между версиями
Pok (обсуждение | вклад) Нет описания правки |
Pok (обсуждение | вклад) Нет описания правки Метка: отменено |
||
| Строка 100: | Строка 100: | ||
local t = type(v) | local t = type(v) | ||
if t == "string" | if t == "string" then | ||
return v | |||
elseif t == "number" or t == "boolean" then | |||
return tostring(v) | return tostring(v) | ||
elseif t == "table" then | elseif t == "table" then | ||
| Строка 114: | Строка 116: | ||
local function is_array(tbl) | local function is_array(tbl) | ||
local | local n = #tbl | ||
if n == 0 then | |||
return false | |||
end | |||
if tbl[n] == nil then | |||
return false | |||
end | |||
local count = 0 | local count = 0 | ||
for k in pairs(tbl) do | for k in pairs(tbl) do | ||
| Строка 120: | Строка 128: | ||
return false | return false | ||
end | end | ||
count = count + 1 | count = count + 1 | ||
end | end | ||
return count | return count == n | ||
end | |||
local function is_array_of_primitives(tbl) | |||
if type(tbl) ~= "table" then return false end | |||
local n = #tbl | |||
if n == 0 or tbl[n] == nil then return false end | |||
local count = 0 | |||
for k, v in pairs(tbl) do | |||
if type(k) ~= "number" then return false end | |||
if type(v) == "table" then return false end | |||
count = count + 1 | |||
end | |||
return count == n | |||
end | end | ||
| Строка 140: | Строка 158: | ||
end | end | ||
local function | local function merge_copy(base, specific) | ||
for k, v in pairs( | local result = {} | ||
if type(v) == "table" and type( | for k, v in pairs(base) do | ||
local specificV = specific[k] | |||
if specificV ~= nil then | |||
if type(v) == "table" and type(specificV) == "table" then | |||
result[k] = merge_copy(v, specificV) | |||
elseif type(specificV) == "table" then | |||
result[k] = deep_copy(specificV) | |||
else | |||
result[k] = specificV | |||
end | |||
elseif type(v) == "table" then | elseif type(v) == "table" then | ||
result[k] = deep_copy(v) | |||
else | else | ||
result[k] = v | |||
end | |||
end | |||
for k, v in pairs(specific) do | |||
if result[k] == nil then | |||
if type(v) == "table" then | |||
result[k] = deep_copy(v) | |||
else | |||
result[k] = v | |||
end | |||
end | end | ||
end | end | ||
return result | |||
end | end | ||
| Строка 169: | Строка 205: | ||
local base = data["default"] | local base = data["default"] | ||
if type(base) == "table" then | if type(base) == "table" then | ||
return merge_copy(base, specific) | |||
end | end | ||
return specific | return specific | ||
| Строка 220: | Строка 254: | ||
end | end | ||
if type(v) == "table" then | if type(v) == "table" then | ||
for _, item in pairs(v) do | for _, item in pairs(v) do | ||
if tostring(item) == target then | if tostring(item) == target then | ||
| Строка 307: | Строка 332: | ||
local function walk(tbl, prefix) | local function walk(tbl, prefix) | ||
local | local entries = {} | ||
for k in pairs(tbl) do | for k in pairs(tbl) do | ||
entries[#entries + 1] = { k, tostring(k) } | |||
end | end | ||
table.sort( | table.sort(entries, function(a, b) return a[2] < b[2] end) | ||
for _, | for _, e in ipairs(entries) do | ||
local k = e[1] | |||
local kStr = e[2] | |||
local v = tbl[k] | local v = tbl[k] | ||
local key = (prefix == "" and kStr or prefix .. "." .. kStr) | local key = (prefix == "" and kStr or prefix .. "." .. kStr) | ||
| Строка 439: | Строка 463: | ||
local templatePath = resolve_template_path(tplPath) | local templatePath = resolve_template_path(tplPath) | ||
local | local tplParts = { "{{Шаблон:" .. templatePath } | ||
if extraTplArgs ~= "" then | if extraTplArgs ~= "" then | ||
tplParts[#tplParts + 1] = extraTplArgs | |||
end | end | ||
tplParts[#tplParts + 1] = "id=" .. tostring(id) | |||
if extra ~= "" then | if extra ~= "" then | ||
tplParts[#tplParts + 1] = extra | |||
end | end | ||
tplParts[#tplParts + 1] = "}}" | |||
return table.concat(tplParts, "|") | |||
return | |||
end | end | ||
| Строка 654: | Строка 677: | ||
local function add_scalar_values(value, set) | local function add_scalar_values(value, set) | ||
if type(value) == "table" then | if type(value) == "table" then | ||
for _, item in pairs(value) do | |||
add_scalar_values(item, set) | |||
end | end | ||
elseif value ~= nil then | elseif value ~= nil then | ||
| Строка 738: | Строка 755: | ||
return "" | return "" | ||
end | |||
local function entry_has_all_targets_component(entry, wanted) | |||
if type(entry) ~= "table" then | |||
return false | |||
end | |||
local set = {} | |||
for _, v in pairs(entry) do | |||
set[tostring(v)] = true | |||
end | |||
for i = 1, #wanted do | |||
if not set[wanted[i]] then | |||
return false | |||
end | |||
end | |||
return true | |||
end | |||
local function entry_has_all_targets_tag(entry, wanted) | |||
if type(entry) ~= "table" then | |||
return false | |||
end | |||
local tags = entry.tags or entry.tag | |||
if type(tags) ~= "table" then | |||
return false | |||
end | |||
local set = {} | |||
for _, v in pairs(tags) do | |||
set[tostring(v)] = true | |||
end | |||
for i = 1, #wanted do | |||
if not set[wanted[i]] then | |||
return false | |||
end | |||
end | |||
return true | |||
end | end | ||
| Строка 771: | Строка 831: | ||
end | end | ||
local sortedIds = {} | |||
for i = 1, #ids do | |||
sortedIds[i] = { ids[i], tostring(ids[i]) } | |||
local | |||
end | end | ||
table.sort(sortedIds, function(a, b) return a[2] < b[2] end) | |||
local matches = {} | local matches = {} | ||
for _, | for _, e in ipairs(sortedIds) do | ||
local idKey = e[1] | |||
local entry = resolve_entry_from_data(data, idKey) | local entry = resolve_entry_from_data(data, idKey) | ||
if mode == "component" then | if mode == "component" then | ||
| Строка 1186: | Строка 1200: | ||
end | end | ||
return nil | return nil | ||
end | |||
local function collect_sorted_entries(tbl, stringOnly) | |||
if stringOnly then | |||
local keys = {} | |||
for k in pairs(tbl) do | |||
if type(k) == "string" then | |||
keys[#keys + 1] = k | |||
end | |||
end | |||
table.sort(keys) | |||
local entries = {} | |||
for i = 1, #keys do | |||
entries[i] = { keys[i], keys[i] } | |||
end | |||
return entries | |||
end | |||
local entries = {} | |||
for k in pairs(tbl) do | |||
entries[#entries + 1] = { k, tostring(k) } | |||
end | |||
table.sort(entries, function(a, b) return a[2] < b[2] end) | |||
return entries | |||
end | end | ||
local function collect_sorted_keys(tbl, stringOnly) | local function collect_sorted_keys(tbl, stringOnly) | ||
local entries = collect_sorted_entries(tbl, stringOnly) | |||
local keys = {} | local keys = {} | ||
for | for i = 1, #entries do | ||
keys[i] = entries[i][1] | |||
end | end | ||
return keys | return keys | ||
end | end | ||
local function choose_id_key(obj) | local function choose_id_key(obj) | ||
local | local entries = {} | ||
for k in pairs(obj) do | for k in pairs(obj) do | ||
if type(k) == "string" then | if type(k) == "string" then | ||
entries[#entries + 1] = { k, type(obj[k]) ~= "table" } | |||
end | end | ||
end | end | ||
if # | if #entries == 0 then | ||
return nil | return nil | ||
end | end | ||
table.sort( | table.sort(entries, function(a, b) | ||
if a[2] ~= b[2] then | |||
return not a[2] | |||
return not | |||
end | end | ||
return a[1] < b[1] | |||
return | |||
end) | end) | ||
return | return entries[1][1] | ||
end | end | ||
local function is_wrapper_block_key(key) | local function is_wrapper_block_key(key) | ||
return type(key) == "string" and not key:match("^[%a_][%w_]*$") | return type(key) == "string" and not key:match("^[%a_][%w_]*$") | ||
end | end | ||
| Строка 1266: | Строка 1276: | ||
end | end | ||
local | local entries = collect_sorted_entries(value, false) | ||
for _, | for _, e in ipairs(entries) do | ||
local k = e[1] | |||
local kStr = e[2] | |||
if not (options.nestedKeyMode == "raw" and type(k) == "number") then | if not (options.nestedKeyMode == "raw" and type(k) == "number") then | ||
local v = value[k] | local v = value[k] | ||
local key | local key | ||
if prefix then | if prefix then | ||
key = prefix .. "." .. | key = prefix .. "." .. kStr | ||
else | else | ||
key = | key = kStr | ||
end | end | ||
| Строка 1307: | Строка 1319: | ||
end | end | ||
end | end | ||
end | |||
local function is_object_map(tbl) | |||
local count = 0 | |||
for k, v in pairs(tbl) do | |||
if type(k) ~= "string" or type(v) ~= "table" then | |||
return false | |||
end | |||
count = count + 1 | |||
end | |||
return count > 1 | |||
end | end | ||
| Строка 1336: | Строка 1359: | ||
skipPrimitiveRoot = true, | skipPrimitiveRoot = true, | ||
} | } | ||
local firstParamOverride = mw.text.unstripNoWiki(args.first or args.firstParam or args.idKey or "") | local firstParamOverride = mw.text.unstripNoWiki(args.first or args.firstParam or args.idKey or "") | ||
| Строка 1369: | Строка 1381: | ||
end | end | ||
parts[#parts + 1] = | parts[#parts + 1] = idKey | ||
local | local entries = collect_sorted_entries(obj, true) | ||
for _, | for _, e in ipairs(entries) do | ||
local k = e[1] | |||
local v = obj[k] | local v = obj[k] | ||
| Строка 1426: | Строка 1439: | ||
end | end | ||
elseif is_object_map(data) then | elseif is_object_map(data) then | ||
local | local dataEntries = collect_sorted_entries(data, true) | ||
for _, | for _, e in ipairs(dataEntries) do | ||
makeCall({ [ | makeCall({ [e[1]] = data[e[1]] }) | ||
end | end | ||
else | else | ||
| Строка 1523: | Строка 1536: | ||
end | end | ||
out[#out + 1] = line | |||
end | end | ||
end | end | ||
else | else | ||
local | local dataEntries = {} | ||
for k in pairs(data) do | for k in pairs(data) do | ||
dataEntries[#dataEntries + 1] = { k, tostring(k) } | |||
end | end | ||
table.sort( | table.sort(dataEntries, function(a, b) return a[2] < b[2] end) | ||
local processed = 0 | local processed = 0 | ||
for _, | for _, de in ipairs(dataEntries) do | ||
processed = processed + 1 | processed = processed + 1 | ||
if maxItems ~= nil and processed > maxItems then | if maxItems ~= nil and processed > maxItems then | ||
| Строка 1543: | Строка 1554: | ||
end | end | ||
local k = de[1] | |||
local kStr = de[2] | |||
local v = data[k] | local v = data[k] | ||
local vStr | local vStr | ||
| Строка 1557: | Строка 1570: | ||
end | end | ||
local baseKey = apply_pattern( | local baseKey = apply_pattern(kStr, keyPattern, "\\1") | ||
local MARK_KEY = "\31KEY\31" | local MARK_KEY = "\31KEY\31" | ||
| Строка 1566: | Строка 1579: | ||
local MARK_VAL = "\31VAL\31" | local MARK_VAL = "\31VAL\31" | ||
local kRepl = (keyReplace or "\\1"):gsub("\\2", MARK_VAL) | local kRepl = (keyReplace or "\\1"):gsub("\\2", MARK_VAL) | ||
local keyStr0 = apply_pattern( | local keyStr0 = apply_pattern(kStr, keyPattern, kRepl) | ||
local keyStr = tostring(keyStr0):gsub(MARK_VAL, vStr0) | local keyStr = tostring(keyStr0):gsub(MARK_VAL, vStr0) | ||
| Строка 1585: | Строка 1598: | ||
end | end | ||
out[#out + 1] = line | |||
end | end | ||
end | end | ||