Перейти к содержимому страницы
Переключить меню
Переключить меню настроек
Переключить персональное меню
Вы не представились системе
Ваш IP-адрес будет виден всем, если вы внесёте какие-либо изменения.

Модуль: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