Модуль:GetField: различия между версиями
Pok (обсуждение | вклад) Нет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| Строка 646: | Строка 646: | ||
return false | return false | ||
end | |||
local function split_csv_list(text) | |||
text = mw.text.unstripNoWiki(text or "") | |||
local out = {} | |||
for part in string.gmatch(text, "([^,]+)") do | |||
part = mw.text.trim(part) | |||
if part ~= "" then | |||
out[#out + 1] = part | |||
end | |||
end | |||
return out | |||
end | |||
local function add_scalar_values(value, set) | |||
if type(value) == "table" then | |||
if is_array(value) then | |||
for _, item in ipairs(value) do | |||
add_scalar_values(item, set) | |||
end | |||
else | |||
for _, item in pairs(value) do | |||
add_scalar_values(item, set) | |||
end | |||
end | |||
elseif value ~= nil then | |||
set[tostring(value)] = true | |||
end | |||
end | |||
local function table_has_all_values(value, targets) | |||
if type(targets) ~= "table" or #targets == 0 then | |||
return false | |||
end | |||
if type(value) ~= "table" then | |||
return #targets == 1 and tostring(value) == targets[1] | |||
end | |||
local set = {} | |||
add_scalar_values(value, set) | |||
for i = 1, #targets do | |||
if not set[targets[i]] then | |||
return false | |||
end | |||
end | |||
return true | |||
end | end | ||
| Строка 698: | Строка 749: | ||
return "" | return "" | ||
end | |||
function p.search(frame) | |||
local args = getArgs(frame, { removeBlanks = false }) | |||
local mode = (args[1] or ""):lower() | |||
local rawList = args[2] or "" | |||
if mode ~= "component" and mode ~= "tag" then | |||
return "[]" | |||
end | |||
local targets = split_csv_list(rawList) | |||
if #targets == 0 then | |||
return "[]" | |||
end | |||
local moduleName = JsonPaths.get("component/tag.json") | |||
local data = load_cached_data(moduleName) | |||
if not data or type(data) ~= "table" then | |||
return "[]" | |||
end | |||
local fieldNames | |||
if mode == "component" then | |||
fieldNames = { "components", "component" } | |||
else | |||
fieldNames = { "tags", "tag" } | |||
end | |||
local ids = collect_id_keys(data) | |||
if #ids == 0 then | |||
return "[]" | |||
end | |||
table.sort(ids, function(a, b) | |||
return tostring(a) < tostring(b) | |||
end) | |||
local matches = {} | |||
for _, idKey in ipairs(ids) do | |||
local entry = resolve_entry(data, idKey) | |||
if type(entry) == "table" then | |||
for _, fieldName in ipairs(fieldNames) do | |||
if table_has_all_values(entry[fieldName], targets) then | |||
matches[#matches + 1] = idKey | |||
break | |||
end | |||
end | |||
end | |||
end | |||
local ok, json = pcall(mw.text.jsonEncode, matches) | |||
if ok and json then | |||
return json | |||
end | |||
return "[]" | |||
end | end | ||
| Строка 1333: | Строка 1442: | ||
local pairPattern = mw.text.unstripNoWiki(args.pattern or "(.*)") | local pairPattern = mw.text.unstripNoWiki(args.pattern or "(.*)") | ||
local pairReplace = mw.text.unstripNoWiki(args.replace or "\\1") | local pairReplace = mw.text.unstripNoWiki(args.replace or "\\1") | ||
local maxItems = tonumber(args.max or args.limit or args.max_count or args.maxCount or "") | |||
if maxItems ~= nil then | |||
maxItems = math.floor(maxItems) | |||
if maxItems < 0 then | |||
maxItems = nil | |||
end | |||
end | |||
local out = {} | local out = {} | ||
if is_array(data) then | if is_array(data) then | ||
local processed = 0 | |||
for _, v in ipairs(data) do | for _, v in ipairs(data) do | ||
processed = processed + 1 | |||
if maxItems ~= nil and processed > maxItems then | |||
break | |||
end | |||
local text = "" | local text = "" | ||
| Строка 1380: | Строка 1504: | ||
return tostring(a) < tostring(b) | return tostring(a) < tostring(b) | ||
end) | end) | ||
local processed = 0 | |||
for _, k in ipairs(keys) do | for _, k in ipairs(keys) do | ||
processed = processed + 1 | |||
if maxItems ~= nil and processed > maxItems then | |||
break | |||
end | |||
local v = data[k] | local v = data[k] | ||
local vStr | local vStr | ||