模块:Infobox

来自Age Of History 2 Chinese Wiki
ZAN热评留言 | 贡献2025年6月13日 (五) 13:42的版本 (创建页面,内容为“local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local has_rows = false -- 列表样式检测和处理 local lists = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至:导航、​搜索
0.00
(0票)

此模块的文档可以在模块:Infobox/doc创建

local p = {}
local args = {}
local origArgs = {}
local root
local empty_row_categories = {}
local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'
local has_rows = false 

-- 列表样式检测和处理
local lists = {
    plainlist_t = {
        patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' },
        found = false,
        styles = 'Plainlist/styles.css'
    },
    hlist_t = {
        patterns = { '^hlist$', '%shlist$', '^hlist%s', '%shlist%s' },
        found = false,
        styles = 'Hlist/styles.css'
    }
} 

-- 检测参数中的特定CSS类
local function has_list_class(args_to_check)
    for _, list in pairs(lists) do
        if not list.found then
            for _, arg in pairs(args_to_check) do
                for _, pattern in ipairs(list.patterns) do
                    if mw.ustring.find(arg or '', pattern) then
                        list.found = true
                        break
                    end
                end
                if list.found then break end
            end
        end
    end
end

-- 获取两个表的并集
local function union(t1, t2)
    local vals = {}
    for k, v in pairs(t1) do
        vals[v] = true
    end
    for k, v in pairs(t2) do
        vals[v] = true
    end
    local ret = {}
    for k, v in pairs(vals) do
        table.insert(ret, k)
    end
    return ret
end

-- 获取指定前缀的参数编号
local function getArgNums(prefix)
    local nums = {}
    for k, v in pairs(args) do
        local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
        if num then table.insert(nums, tonumber(num)) end
    end
    table.sort(nums)
    return nums
end

-- 添加信息框行
local function addRow(rowArgs)
    -- 检查是否为空行
    if rowArgs.header then
        has_rows = true
        root:tag('tr'):tag('th')
            :attr('colspan', 2)
            :addClass('infobox-header')
            :addClass(rowArgs.class)
            :cssText(args.headerstyle)
            :cssText(rowArgs.rowstyle)
            :wikitext(rowArgs.header)
    elseif rowArgs.data then
        if rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('%S') then
            has_rows = true
            local row = root:tag('tr')
            if rowArgs.label then
                row:tag('th')
                    :attr('scope', 'row')
                    :addClass('infobox-label')
                    :addClass(rowArgs.class)
                    :cssText(args.labelstyle)
                    :cssText(rowArgs.rowstyle)
                    :wikitext(rowArgs.label)
            end
            local dataCell = row:tag('td')
            if not rowArgs.label then
                dataCell:attr('colspan', 2)
                    :addClass('infobox-full-data')
            else
                dataCell:addClass('infobox-data')
            end
            dataCell:addClass(rowArgs.class)
                :cssText(rowArgs.datastyle)
                :cssText(rowArgs.rowstyle)
                :cssText(rowArgs.rowcellstyle)
                :newline()
                :wikitext(rowArgs.data)
        else
            table.insert(empty_row_categories, rowArgs.data)
        end
    end
end

-- 清理空标题
local function cleanupArgs()
    local lastheader = nil
    for num, _ in pairs(getArgNums('header')) do
        if args['header' .. tostring(num)] then
            lastheader = num
        end
        if args['data' .. tostring(num)] and args['data' .. tostring(num)]:match('%S') then
            local data = args['data' .. tostring(num)]
            if data:gsub(category_in_empty_row_pattern, ''):match('%S') then
                lastheader = nil
            end
        end
    end
    if lastheader then
        args['header' .. tostring(lastheader)] = nil
    end
end

-- 渲染所有行
local function renderRows()
    local rownums = union(getArgNums('header'), getArgNums('data'))
    table.sort(rownums)
    for k, num in ipairs(rownums) do
        addRow({
            header = args['header' .. tostring(num)],
            label = args['label' .. tostring(num)],
            data = args['data' .. tostring(num)],
            datastyle = args.datastyle,
            class = args['class' .. tostring(num)],
            rowclass = args['rowclass' .. tostring(num)],
            rowstyle = args['rowstyle' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)]
        })
    end
end 

-- 渲染导航栏
local function renderNavBar()
    if not args.name then return end
    has_rows = true
    root:tag('tr')
        :tag('td')
        :attr('colspan', '2')
        :addClass('infobox-navbar')
        :wikitext(require('Module:Navbar')._navbar{
            args.name,
            mini = 1,
        })
end 

-- 加载模板样式
local function loadTemplateStyles()
    local frame = mw.getCurrentFrame()
    local hlist_templatestyles = ''
    if lists.hlist_t.found then
        hlist_templatestyles = frame:extensionTag{
            name = 'templatestyles',
            args = { src = lists.hlist_t.styles }
        }
    end
    
    local plainlist_templatestyles = ''
    if lists.plainlist_t.found then
        plainlist_templatestyles = frame:extensionTag{
            name = 'templatestyles',
            args = { src = lists.plainlist_t.styles }
        }
    end
    
    local base_templatestyles = frame:extensionTag{
        name = 'templatestyles',
        args = { src = 'Module:Infobox/styles.css' }
    }
    
    local templatestyles = ''
    if args['templatestyles'] then
        templatestyles = frame:extensionTag{
            name = 'templatestyles',
            args = { src = args['templatestyles'] }
        }
    end
    
    local child_templatestyles = ''
    if args['child templatestyles'] then
        child_templatestyles = frame:extensionTag{
            name = 'templatestyles', 
            args = { src = args['child templatestyles'] }
        }
    end
    
    return table.concat({
        hlist_templatestyles,
        plainlist_templatestyles, 
        base_templatestyles,
        templatestyles,
        child_templatestyles
    })
end 

-- 渲染空行分类
local function renderEmptyRowCategories()
    for _, s in ipairs(empty_row_categories) do
        root:wikitext(s)
    end
end 

-- 渲染跟踪分类
local function renderTrackingCategories()
    if args.decat == 'yes' then return end
    
    if args.child == 'yes' then
        if args.title then
            root:wikitext('[[Category:Pages using embedded infobox templates with the title parameter]]')
        end
    elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
        root:wikitext('[[Category:Articles using infobox templates with no data rows]]')
    end
end 

-- 主信息框函数
function p.infobox(frame)
    -- 参数处理
    args = require('Module:Arguments').getArgs(frame, {
        wrappers = 'Template:Infobox',
        removeBlanks = false
    })
    
    -- 检查列表类样式
    has_list_class({
        args.above, args.title, args.image, args.caption,
        args.header, args.data, args.below
    })
    
    -- 清理参数
    cleanupArgs()
    
    -- 创建根HTML表格
    root = mw.html.create()
    
    -- 加载样式
    root:wikitext(loadTemplateStyles())
    
    -- 构建信息框表格
    local infobox = root:tag('table')
    
    -- 设置基本属性和样式
    if args.child ~= 'yes' then
        infobox:addClass('infobox')
            :addClass(args.bodyclass)
            :css('width', '22em')
            :cssText(args.bodystyle)
    else
        infobox:addClass('infobox-subbox')
            :addClass(args.bodyclass)
            :cssText(args.bodystyle)
    end
    
    -- 添加标题
    if args.title then
        infobox:tag('caption')
            :addClass('infobox-title')
            :addClass(args.titleclass)
            :cssText(args.titlestyle)
            :wikitext(args.title)
    end
    
    -- 添加上方内容
    if args.above then
        infobox:tag('tr')
            :tag('td')
            :attr('colspan', '2')
            :addClass('infobox-above')
            :addClass(args.aboveclass)
            :cssText(args.abovestyle)
            :wikitext(args.above)
    end
    
    -- 添加子标题
    if args.subheader then
        infobox:tag('tr')
            :tag('td')
            :attr('colspan', '2')
            :addClass('infobox-subheader')
            :wikitext(args.subheader)
    end
    
    -- 添加图片
    if args.image then
        infobox:tag('tr')
            :tag('td')
            :attr('colspan', '2')
            :addClass('infobox-image')
            :addClass(args.imageclass)
            :cssText(args.imagestyle)
            :wikitext(args.image)
            :done()
            :tag('tr')
            :tag('td')
            :attr('colspan', '2')
            :addClass('infobox-caption')
            :wikitext(args.caption)
    end
    
    -- 渲染所有数据行
    renderRows()
    
    -- 添加下方内容
    if args.below then
        infobox:tag('tr')
            :tag('td')
            :attr('colspan', '2')
            :addClass('infobox-below')
            :addClass(args.belowclass)
            :cssText(args.belowstyle)
            :wikitext(args.below)
    end
    
    -- 添加导航栏
    renderNavBar()
    
    -- 渲染分类
    renderEmptyRowCategories()
    renderTrackingCategories()
    
    return tostring(root)
end

return p
Loading comments...