local p = {} local getArgs -- 延迟加载 local args -- 传入参数 local format = string.format -- 简写string.format函数 local stylelib = { tabs = { top = 'border-bottom:2px solid TITLECOLOR; display:flex; align-items:center; margin-bottom:0.5em;', top_iconsys = 'margin-bottom:calc(ICONSIZE/2 - 0.8em); margin-top:calc(ICONSIZE/2 - 1.3em);', top_iconitem = 'margin-left:calc(ICONSIZE/2);', iconmap = 'display:inline-block; height:10px; width:calc(ICONSIZE + 0.15em); position:relative; top:calc(-ICONSIZE/2 + 0.8em); vertical-align:top; margin-left:calc(-ICONSIZE/2 - 0.3em);', icon = 'border-radius:calc(ICONSIZE/2); border:2px solid #fff; box-shadow:0 0 3px TITLECOLOR; overflow:hidden; background:#fff; text-align:center; height:calc(ICONSIZE - 4px); width:calc(ICONSIZE - 4px); box-sizing:content-box;', title = 'background:TITLECOLOR; color:#fff; border-top-left-radius:6px; border-top-right-radius:6px; display:inline-block; padding:0 0.3em; font-weight:bold; font-size:1.2em; margin-bottom:-2px; white-space:nowrap;', alt = 'color:#666; font-size:80%; padding-top:0.2em; padding-left:1em; white-space:nowrap; overflow-x:auto;', defaulttitlemargin = '0.3em', defaultcolor = '#9ecdd9', defaultsize = '48px', defaultmargin = '1em' }, } local function itemValue(parameter, itemnum) local key if itemnum then key = format('item%d-', itemnum) .. parameter else key = parameter end return args[key] end local function findTheme(theme, itemnum) local style = {} local styleref = {} if(stylelib[theme]) then styleref = stylelib[theme] else styleref = stylelib['tabs'] end if itemnum then style.top = string.gsub(styleref.top, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor)) style.top_iconsys = string.gsub(styleref.top_iconsys, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize) style.top_iconitem = string.gsub(styleref.top_iconitem, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize) style.title = string.gsub(styleref.title, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor)) style.alt = styleref.alt style.iconmap = string.gsub(styleref.iconmap, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize) style.icon = string.gsub(styleref.icon, 'TITLECOLOR', (itemValue('color', itemnum) or args['color'] or styleref.defaultcolor)) style.icon = string.gsub(style.icon, 'ICONSIZE', itemValue('iconsize', itemnum) or args['iconsize'] or styleref.defaultsize) end return style end local function renderDummyItem(ctr, dummynum) for i = 1, dummynum do ctr:tag('div') :addClass('flexinfo-itembox') :css('flex-basis', args['dummywidth'] or args['width'] or '400px') :css('flex-grow', args['grow'] or '1') :css('flex-shrink', args['shrink'] or args['grow'] or '1') end end local function renderNest(ctr, itemnum) local style = findTheme(args['theme'], itemnum) -- item box local itembox = ctr:tag('div') :addClass('flexinfo-itembox') :css('flex-basis', itemValue('width', itemnum) or args['width'] or '400px') :css('flex-grow', itemValue('grow', itemnum) or args['grow'] or '1') :css('flex-shrink', itemValue('shrink', itemnum) or args['shrink'] or itemValue('grow', itemnum) or args['grow'] or '1') :cssText(args['style-itembox']) :cssText(itemValue('style-itembox', itemnum)) :wikitext(itemValue('nest', itemnum)) end local function renderItem(ctr, itemnum, hasicon) local style = findTheme(args['theme'], itemnum) -- item box local itembox = ctr:tag('div') :addClass('flexinfo-itembox') :css('flex-basis', itemValue('width', itemnum) or args['width'] or '400px') :css('flex-grow', itemValue('grow', itemnum) or args['grow'] or '1') :css('flex-shrink', itemValue('shrink', itemnum) or args['shrink'] or itemValue('grow', itemnum) or args['grow'] or '1') :css('margin-top', '1em') :cssText(args['style-itembox']) :cssText(itemValue('style-itembox', itemnum)) -- item main div local item = itembox:tag('div') :addClass('flexinfo-item') :css('margin-left', args['margin'] or style.defaultmargin or '1em') :css('margin-right', args['margin'] or style.defaultmargin or '1em') -- item top bar local itemtop = item:tag('div') :addClass('flexinfo-itemtop') :cssText(style.top) if hasicon == true then itemtop:cssText(style.top_iconsys) end -- item title / name local itemtitle = itemtop:tag('div') :addClass('flexinfo-title') :cssText(style.title) :cssText(args['style-title']) :cssText(itemValue('style-title', itemnum)) -- icon config if itemValue('icon', itemnum) then itemtop :cssText(style.top_iconitem) local iconmap = itemtitle:tag('div') :addClass('flexinfo-iconmap') :cssText(style.iconmap) :cssText(args['style-iconmap']) :cssText(itemValue('style-iconmap', itemnum)) local icon = iconmap:tag('div') :addClass('flexinfo-icon') :cssText(style.icon) :wikitext(itemValue('icon', itemnum)) :cssText(args['style-icon']) :cssText(itemValue('style-icon', itemnum)) end itemtop :cssText(args['style-top']) :cssText(itemValue('style-top', itemnum)) itemtitle:wikitext(args[format("item%d", itemnum)]) -- item subhead / alt / cv if itemValue('alt', itemnum) then local itemcv = itemtop:tag('div') :addClass('flexinfo-alt') :cssText(style.alt) :cssText(args['style-alt']) :cssText(itemValue('style-alt', itemnum)) :wikitext(itemValue('alt', itemnum)) elseif itemValue('cv', itemnum) then local itemcv = itemtop:tag('div') :addClass('flexinfo-alt') :cssText(style.alt) :cssText(args['style-alt']) :cssText(itemValue('style-alt', itemnum)) :wikitext('CV:' .. itemValue('cv', itemnum)) end -- item info / text local itemtext = item:tag('p') :wikitext(itemValue('text', itemnum)) end function p._flexinfo(infoArgs) args = infoArgs if(args['theme'] == nil) then args['theme'] = 'tabs' end local style = findTheme(args['theme']) local itemnums = {} local hasicon = false for k, _ in pairs(args) do if type(k) == 'string' then local itemnum = k:match('^item(%d+)$') if itemnum then table.insert(itemnums, tonumber(itemnum)) end local iconnum = k:match('^item(%d+)-icon') if iconnum then hasicon = true end end end table.sort(itemnums) local ctr = mw.html.create('div') :addClass('infoflex') :css('display', 'flex') :css('flex-wrap', 'wrap') local margin = '1em' if(stylelib[theme]) then margin = stylelib[theme]['defaultmargin'] end if not args['nest'] then ctr :css('margin-top', '-0.5em') :css('margin-bottom', '0.5em') :css('margin-left', ('-' .. margin)) :css('margin-right', ('-' .. margin)) end ctr:cssText(args['containerstyle']) local itemnums_size = #itemnums for i, itemnum in ipairs(itemnums) do if(args[format("item%d-nest", i)]) then renderNest(ctr, itemnum) else renderItem(ctr, itemnum, hasicon) end end if(args['dummy']) then renderDummyItem(ctr, args['dummy']); end return ctr end function p.flexinfo(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end args = getArgs(frame) return p._flexinfo(args) end return p