Модуль:Сущность/data: различия между версиями

Нет описания правки
Отмена версии 213664, сделанной Pok (обсуждение)
Метка: отмена
 
(не показано 5 промежуточных версий этого же участника)
Строка 162: Строка 162:
local function makeSourceLink(s)
local function makeSourceLink(s)
     local className =
     local className =
         (s.name:sub(1,1):upper() .. s.name:sub(2)) ..
         (s.name:sub(1, 1):upper() .. s.name:sub(2)) ..
         (s.kind and (s.kind:sub(1,1):upper() .. s.kind:sub(2)) or "")
         (s.kind and (s.kind:sub(1, 1):upper() .. s.kind:sub(2)) or "")


     local tplLabel = "Template:" .. s.tplPath
     local tplLabel = "Template:" .. s.tplPath
Строка 195: Строка 195:
     end
     end
     return table.concat(parts, "\n")
     return table.concat(parts, "\n")
end
local function split_title_key(key)
    local main, sub = (key or ""):match("^([^_]+)_(.+)$")
    if main and sub then
        return main, sub
    end
    return key, nil
end
local function renderGroupedTitleBlocks(frame, keyOrder, keyToTemplates, noHeaders, showSource)
    local groups = {}
    local groupOrder = {}
    for _, key in ipairs(keyOrder or {}) do
        local mainTitle, subTitle = split_title_key(key)
        if mainTitle and mainTitle ~= "" then
            local group = groups[mainTitle]
            if not group then
                group = { blocks = {} }
                groups[mainTitle] = group
                groupOrder[#groupOrder + 1] = mainTitle
            end
            group.blocks[#group.blocks + 1] = {
                subTitle = subTitle,
                entries = keyToTemplates[key] or {}
            }
        end
    end
    local out = {}
    for _, mainTitle in ipairs(groupOrder) do
        local group = groups[mainTitle]
        local parts = {}
        if not noHeaders then
            parts[#parts + 1] = "<h2>" .. mw.text.encode(mainTitle) .. "</h2>"
        end
        for _, block in ipairs(group.blocks or {}) do
            local tplCalls, sources = collect_tpl_calls(block.entries or {})
            local blockText = renderTitleBlock(block.subTitle or mainTitle, tplCalls, sources, false, frame, showSource)
            if blockText ~= "" then
                if block.subTitle and not noHeaders then
                    parts[#parts + 1] = "<h3>" .. mw.text.encode(block.subTitle) .. "</h3>"
                end
                parts[#parts + 1] = blockText
            end
        end
        if #parts > 0 then
            out[#out + 1] = table.concat(parts, "\n")
        end
    end
    return table.concat(out, "\n")
end
local function matches_card_list(list, callKey, compositeKey)
    if not list then
        return false
    end
    return list[callKey] or list[compositeKey] or false
end
end


Строка 246: Строка 310:
end
end


local function cardWrapper(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders)
local function cardWrapper(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders, cardFilter)
     local merged = {
     local merged = {
         sections = {},
         sections = {},
Строка 257: Строка 321:
         tagSet = {}
         tagSet = {}
     }
     }
    local rawContentParts = {}
     for _, callKey in ipairs(keyOrder or {}) do
     for _, callKey in ipairs(keyOrder or {}) do
         local entries = keyToTemplates[callKey] or {}
         local entries = keyToTemplates[callKey] or {}
Строка 271: Строка 336:
                 local section = (callKey:find("_", 1, true)) and callKey:match("^([^_]+)") or "Сущность"
                 local section = (callKey:find("_", 1, true)) and callKey:match("^([^_]+)") or "Сущность"


                 if displayLabel ~= "" or content ~= "" then
                local isWhitelisted = cardFilter and matches_card_list(cardFilter.whitelist, callKey, compositeKey) or
                false
                local isBlacklisted = cardFilter and matches_card_list(cardFilter.blacklist, callKey, compositeKey) or
                false
                if isWhitelisted and content ~= "" then
                    rawContentParts[#rawContentParts + 1] = content
                end
 
                local allowCardEntry = not isWhitelisted and not isBlacklisted and
                    ((not cardFilter) or (not cardFilter.hasWhitelist) or
                        matches_card_list(cardFilter.cardWhitelist, callKey, compositeKey))
 
                 if allowCardEntry and (displayLabel ~= "" or content ~= "") then
                     if not merged.sectionsMap[section] then
                     if not merged.sectionsMap[section] then
                         merged.sectionsMap[section] = true
                         merged.sectionsMap[section] = true
Строка 297: Строка 374:
                 end
                 end


                 if tagText ~= "" then
                 if allowCardEntry and tagText ~= "" then
                     if not merged.tagSet[tagText] then
                     if not merged.tagSet[tagText] then
                         merged.tagSet[tagText] = true
                         merged.tagSet[tagText] = true
Строка 306: Строка 383:
         end
         end
     end
     end
    local out = {}
    if #rawContentParts > 0 then
        out[#out + 1] = table.concat(rawContentParts, "\n")
    end
    local cardCall = buildCardCall(merged, entityId)


     if noHeaders then
     if noHeaders then
         local hasLabel = false
         local hasLabel = false
         for _, v in pairs(merged.labelOverrides or {}) do
         for _, v in pairs(merged.labelOverrides or {}) do
             if v and v ~= "" then hasLabel = true break end
             if v and v ~= "" then
                hasLabel = true
                break
            end
         end
         end
         if not hasLabel then
         if not hasLabel then
             for _, lst in pairs(merged.labelLists or {}) do
             for _, lst in pairs(merged.labelLists or {}) do
                 if #lst > 0 then hasLabel = true break end
                 if #lst > 0 then
                    hasLabel = true
                    break
                end
             end
             end
         end
         end
Строка 320: Строка 410:
         local hasContent = false
         local hasContent = false
         for _, v in pairs(merged.contentByKey or {}) do
         for _, v in pairs(merged.contentByKey or {}) do
             if v and v ~= "" then hasContent = true break end
             if v and v ~= "" then
                hasContent = true
                break
            end
         end
         end


         if not hasLabel and not hasContent then
         if not hasLabel and not hasContent then
             return ""
             return table.concat(out, "\n")
         end
         end
     end
     end


     return buildCardCall(merged, entityId)
    if cardCall ~= "" then
        out[#out + 1] = cardCall
    end
 
     return table.concat(out, "\n")
end
end


Строка 361: Строка 458:
         end
         end
     end,
     end,
     render_full = function(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders)
     render_full = function(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders, showSource, cardFilter)
         return cardWrapper(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders)
         return cardWrapper(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders, cardFilter)
     end
     end
})
})


register_switch_mode("title", {
register_switch_mode("title", {
    full = true,
     build_entry = function(ctx, key)
     build_entry = function(ctx, key)
         return {
         return {
Строка 381: Строка 479:
         }
         }
     end,
     end,
     render_key = function(frame, key, entries, noHeaders, showSource)
     render_full = function(frame, keyOrder, keyToTemplates, keySources, entityId, noHeaders, showSource)
        local tplCalls, sources = collect_tpl_calls(entries)
         return renderGroupedTitleBlocks(frame, keyOrder, keyToTemplates, noHeaders, showSource)
         return renderTitleBlock(key, tplCalls, sources, not noHeaders, frame, showSource)
     end
     end
})
})
Строка 443: Строка 540:
     filter.blacklist = parseListArg(args.blacklist or "")
     filter.blacklist = parseListArg(args.blacklist or "")
     filter.whitelist = parseListArg(args.whitelist or "")
     filter.whitelist = parseListArg(args.whitelist or "")
     filter.hasWhitelist = next(filter.whitelist) ~= nil
     filter.hasWhitelist = false
    for _, sw in ipairs(switchModeOrder) do
        if filter.whitelist[sw] and next(filter.whitelist[sw]) ~= nil then
            filter.hasWhitelist = true
            break
        end
    end
    if not filter.hasWhitelist and filter.whitelist.cardContent and next(filter.whitelist.cardContent) ~= nil then
        filter.hasWhitelist = true
    end
     return filter
     return filter
end
local function build_render_options(filter)
    return {
        noHeaders = false,
        cardFilter = {
            hasWhitelist = filter.whitelist.cardContent and next(filter.whitelist.cardContent) ~= nil or false,
            cardWhitelist = filter.whitelist.card or {},
            blacklist = filter.blacklist.cardContent or {},
            whitelist = filter.whitelist.cardContent or {}
        }
    }
end
end


local function should_include_key(filter, sw, key)
local function should_include_key(filter, sw, key)
     if filter.hasWhitelist then
     if filter.hasWhitelist then
         return filter.whitelist[sw] and filter.whitelist[sw][key]
         if filter.whitelist[sw] and filter.whitelist[sw][key] then
            return true
        end
        if sw == "card" and filter.whitelist.cardContent and filter.whitelist.cardContent[key] then
            return true
        end
        return false
     end
     end
     return not (filter.blacklist[sw] and filter.blacklist[sw][key])
     return not (filter.blacklist[sw] and filter.blacklist[sw][key])
Строка 466: Строка 590:
end
end


local function collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents, ignorePrototypes)
local function parse_csv_set(str)
    local res = {}
    each_csv_value(str, function(name)
        res[name] = true
    end)
    return res
end
 
local function apply_entity_set_filters(foundSet, whitelistSet, blacklistSet)
    local hasWhitelist = next(whitelistSet or {}) ~= nil
 
    if hasWhitelist then
        for name in pairs(foundSet) do
            if not whitelistSet[name] then
                foundSet[name] = nil
            end
        end
    end
 
    for name in pairs(blacklistSet or {}) do
        foundSet[name] = nil
    end
end
 
local function collect_entity_sets(id, componentDefs, prototypeStoreDefs,
                                  componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
     local foundComponents, foundPrototypes = {}, {}
     local foundComponents, foundPrototypes = {}, {}


Строка 488: Строка 637:
     end)
     end)


     each_csv_value(ignoreComponents, function(name)
     apply_entity_set_filters(foundComponents, parse_csv_set(componentWhitelist), parse_csv_set(componentBlacklist))
        foundComponents[name] = nil
     apply_entity_set_filters(foundPrototypes, parse_csv_set(prototypeWhitelist), parse_csv_set(prototypeBlacklist))
    end)
 
     each_csv_value(ignorePrototypes, function(name)
        foundPrototypes[name] = nil
    end)


     return foundComponents, foundPrototypes
     return foundComponents, foundPrototypes
Строка 578: Строка 722:
end
end


local function renderBlocks(frame, state, noHeaders, entityId, showSource)
local function renderBlocks(frame, state, renderOptions, entityId, showSource)
     local outLocal = {}
     local outLocal = {}
    local noHeaders = renderOptions and renderOptions.noHeaders
    local cardFilter = renderOptions and renderOptions.cardFilter
     for _, sw in ipairs(switchModeOrder) do
     for _, sw in ipairs(switchModeOrder) do
         local mode = switchModeRegistry[sw] or {}
         local mode = switchModeRegistry[sw] or {}
Строка 586: Строка 732:
             if type(mode.render_full) == "function" then
             if type(mode.render_full) == "function" then
                 outStr = mode.render_full(frame, state.keyOrder[sw], state.keyToTemplates[sw], state.keySources[sw],
                 outStr = mode.render_full(frame, state.keyOrder[sw], state.keyToTemplates[sw], state.keySources[sw],
                     entityId, noHeaders)
                     entityId, noHeaders, showSource, cardFilter)
             end
             end
             if outStr and outStr ~= "" then table.insert(outLocal, outStr) end
             if outStr and outStr ~= "" then table.insert(outLocal, outStr) end
Строка 610: Строка 756:


     local filter = build_key_filter(args)
     local filter = build_key_filter(args)
    local renderOptions = build_render_options(filter)


     local ignoreComponents = args.ignoreComponents or args.ignoreComponent or ""
     local componentWhitelist = args.componentWhitelist or args.componentwhitelist or ""
     local ignorePrototypes = args.ignorePrototypes or args.ignorePrototype or ""
     local componentBlacklist = args.componentBlacklist or args.componentblacklist or ""
    local prototypeWhitelist = args.prototypeWhitelist or args.prototypewhitelist or ""
    local prototypeBlacklist = args.prototypeBlacklist or args.prototypeblacklist or ""


     local componentDefs = load_module_data("component.json")
     local componentDefs = load_module_data("component.json")
Строка 618: Строка 767:
     if not componentDefs or not prototypeStoreDefs then return "" end
     if not componentDefs or not prototypeStoreDefs then return "" end


     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs, ignoreComponents,
     local foundComponents, foundPrototypes = collect_entity_sets(id, componentDefs, prototypeStoreDefs,
         ignorePrototypes)
         componentWhitelist, componentBlacklist, prototypeWhitelist, prototypeBlacklist)
     local state = new_switch_state()
     local state = new_switch_state()


Строка 694: Строка 843:
     end
     end


     local blocks = renderBlocks(frame, state, filter.hasWhitelist, id, showSource)
    renderOptions.noHeaders = filter.hasWhitelist
 
     local blocks = renderBlocks(frame, state, renderOptions, id, showSource)
     for _, b in ipairs(blocks) do
     for _, b in ipairs(blocks) do
         table.insert(out, b)
         table.insert(out, b)
Строка 708: Строка 859:


     local showSource = trim(args.nosource or "") == ""
     local showSource = trim(args.nosource or "") == ""
    local previewFilter = build_key_filter(args)
    local renderOptions = build_render_options(previewFilter)


     local content = load_template_content(tplPath)
     local content = load_template_content(tplPath)
Строка 728: Строка 881:
     }, nil, true)
     }, nil, true)


     local whitelist = parseListArg(args.whitelist or "")
     local whitelist = previewFilter.whitelist
     local hasWhitelist = next(whitelist) ~= nil
     local hasWhitelist = previewFilter.hasWhitelist
    renderOptions.noHeaders = hasWhitelist


     local out = {}
     local out = {}
     local blocks = renderBlocks(frame, state, hasWhitelist, "", showSource)
     local blocks = renderBlocks(frame, state, renderOptions, "", showSource)
     for _, b in ipairs(blocks) do
     for _, b in ipairs(blocks) do
         table.insert(out, b)
         table.insert(out, b)