Модуль:Sequence/PostProcessDataCommon
Материал из «Повелитель Тайн Вики»
Дополнительные действия
Doc
Properties
- prop_name_id: String - Global parameter, which is the property where the original key or name is stored. This property can be directly accessed.
- prop_alt_name_id: String - Global parameter, which is the property where the original and alternative keys/names are stored. On use, it is a table that maps highly butchered keys like lowercased to a more properly formatted alt key/name.
local p = {}
-- Standard property names.
p.prop_name_id = "@name_id"
p.prop_alt_name_id = "@key_to_alt_name"
-- Table related functions.
function p.injectKeyProperty(t)
local prop_name = p.prop_name_id
for key, data in pairs(t) do
if data[prop_name] ~= nil then
error("Property of name '" .. prop_name .. "' exists. You risk overriting existing data.")
end
data[prop_name] = key
end
return t
end
function p.injectKeyMapPropertySingle(data, name_id, eq_key, store_key_direct)
local prop_name = p.prop_alt_name_id
if data[prop_name] == nil then
data[prop_name] = {}
end
if type(data[prop_name]) ~= 'table' then
error(string.format(
"Property of name '%s' exists. You risk overriting existing data. The type of value containing this property is '%s'. Containing %s",
prop_name,
type(data[prop_name]),
require("Module:Inspect")(data[prop_name])
)
)
end
if data[prop_name][eq_key] ~= nil then
error(string.format(
"Equivalent Id '%s' is already used for proper name id '%s'. Tried inserting '%s' for property name id '%s'.",
eq_key,
data[prop_name][eq_key],
eq_key,
name_id
)
)
end
if store_key_direct then
data[prop_name][eq_key] = name_id
else
data[prop_name][eq_key] = data[prop_name][name_id]
end
return t
end
function p.injectKeyMapPropertySelfMultiple(t)
for key, data in pairs(t) do
p.injectKeyMapPropertySingle(data, key, key, true)
end
return t
end
function p.insertValueToLeft(table_add_to, table_add_with)
for add_key, add_data in pairs(table_add_with) do
if table_add_to[add_key] == nil then
table_add_to[add_key] = add_data
else
error(string.format("Key '%s' exists.", add_key))
end
end
return table_add_to
end
function p.addThroughFunc(t, self_keys, arg_func, dupe_solver)
if arg_func == nil then
error("Argument function is nil.")
end
local temp_table = {}
local insert_sheet = {}
local function getKeyInfo(data)
local key_info = data['pathway']
if key_info ~= nil then return " of " .. key_info end
key_info = key_info or data['ats']
if key_info ~= nil then return " of " .. key_info .. " group" end
key_info = key_info or data['from_earth']
if key_info ~= nil then
if key_info then return" of the Earth Above the Sequence group"
else return " of the Great Old Dominators Above the Sequence group" end
end
return nil
end
local function contains_key(eq_key)
return t[eq_key] ~= nil or temp_table[eq_key] ~= nil
end
local function insertEquivalentKey(eq_key, eq_data, orig_key, orig_eq_key)
orig_eq_key = orig_eq_key or eq_key
if eq_key == nil then -- When the dupe solver returns nil, which can be considered as it giving up.
return
end
-- Find fallback
if contains_key(eq_key) then
if type(dupe_solver) == 'string' and dupe_solver == "skip" then
return
elseif type(dupe_solver) == "function" then
local solved_eq_keys = dupe_solver(eq_key, orig_eq_key, eq_data, contains_key)
if type(solved_eq_keys) == 'table' then
for _, solved_eq_key_item in ipairs(solved_eq_keys) do
insertEquivalentKey(solved_eq_key_item, eq_data, orig_key, orig_eq_key)
end
else
insertEquivalentKey(solved_eq_keys, eq_data, orig_key, orig_eq_key)
end
return
else
local key_info = getKeyInfo(t[eq_key] or temp_table[eq_key])
local alt_key_info = getKeyInfo(eq_data)
error(string.format(
"The original key '%s' exists%s. No duplication solver function, risks overriting the same data.<br/>The alt key '%s' is meant to point to '%s'.",
eq_key,
key_info or "",
eq_key,
alt_key_info or "<No provided data>"
)
)
end
-- All good.
else
temp_table[eq_key] = eq_data
table.insert(insert_sheet, { orig_key, eq_key, orig_eq_key, eq_data })
end
end
for key, data in pairs(t) do
local new_key = arg_func(key, data)
if type(new_key) == 'table' then
for _, new_key_item in ipairs(new_key) do
insertEquivalentKey(new_key_item, data, key)
end
elseif new_key ~= nil then
insertEquivalentKey(new_key, data, key)
end
end
for _, sheet in ipairs(insert_sheet) do
local orig_eq_key = sheet[3]
local eq_key = sheet[2]
local name_id = sheet[1]
if self_keys then
name_id = orig_eq_key -- Keys point to self.
end
p.injectKeyMapPropertySingle(sheet[4], name_id, eq_key, self_keys)
end
p.insertValueToLeft(t, temp_table)
return t
end
function p.addAltKeys(t, self_keys, dupe_solver)
local function fn(key, data)
return p.altNames(data)
end
local function default_dupe_solver(inv_key, orig_alt_key, data, contains_key)
local function tryAppendContext(context_data)
if context_data == nil then return nil end
if context_data == orig_alt_key then return nil end
local fallback_key = string.format("%s (%s)", orig_alt_key, context_data)
if contains_key(fallback_key) then return nil
else return fallback_key end
end
-- Use the original key instead of the potentially modified inv_key.
local fallback_key1 = tryAppendContext(data['pathway'] or data['ats']) -- Use pathway or ats group as added context.
local fallback_key2 = tryAppendContext(data[p.prop_name_id]) -- Use item original name as added context.
return { fallback_key1, fallback_key2 }
end
return p.addThroughFunc(t, self_keys, fn, dupe_solver or default_dupe_solver)
end
function p.addLowerCasedKeys(t, self_keys, dupe_solver)
local function fn (key, data)
if type(key) == "string" then return string.lower(key)
else return nil end
end
return p.addThroughFunc(t, self_keys, fn, dupe_solver or "skip")
end
function p.addConcatedKeys(t, str_to_concat, self_keys)
local function fn (key, data)
if type(key) == "string" then return key .. str_to_concat
else return nil end
end
return p.addThroughFunc(t, self_keys, fn, dupe_solver)
end
function p.altNames(data)
if data == nil then
error("Nil value.")
end
local alt_list = data['alt_names']
local alt_names = {}
if alt_list == nil then
return alt_names
end
local seq_name = data[p.prop_name_id]
for _, alt_item in ipairs(alt_list) do
local alt_name = nil
if type(alt_item) == "string" then
alt_name = alt_item
elseif type(alt_item) == 'table' then
alt_name = alt_item['name']
end
if alt_name ~= nil then
table.insert(alt_names, alt_name)
end
end
return alt_names
end
return p