- Welcome to Touhou Wiki!
- Registering is temporarily disabled. Check in our Discord server to request an account and for assistance of any kind.
Module:Navbox
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Navbox/doc
-- lua port of [[Template:Navbox]]
-- by DennouNeko
-- constants
local colors = {
game = {title = '#FFC9C2', above = '#FFD1CA', group = '#FFD9D2', subgroup = '#FFE1DA', dark = '#FFEEE8', background = '#FFF4EE'};
music = {title = '#FFF3B4', above = '#FFF6C0', group = '#FFF7C8', subgroup = '#FFF8D0', dark = '#FFFBE4', background = '#FFFBEE'};
printwork = {title = '#DDE6FF', above = '#E1E7FF', group = '#E6E9FF', subgroup = '#EAECFF', dark = '#EDF2FF', background = '#F4F9FF'}
}
-- helper functions
require("Module:Common")
local function addstyle(tbl, val)
if isset(val) then
local av = trim(val)
if string.sub(av, -1) ~= ';' then av = av .. ';' end
table.insert(tbl, av)
end
end
local function scan_lists(frame)
local idx = {}
local list = {}
local group = {}
local liststyle = {}
local groupstyle = {}
local ret = {}
for k,v in frame:argumentPairs() do
if string.sub(k, 1, 5) == 'group' then
if string.sub(k, -5) == 'style' then
k1 = tonumber(string.sub(k, 6, -6))
if k1 ~= nil then groupstyle[k1] = v end
else
k1 = tonumber(string.sub(k, 6))
if k1 ~= nil then group[k1] = v end
end
elseif string.sub(k, 1, 4) == 'list' then
if string.sub(k, -5) == 'style' then
k1 = tonumber(string.sub(k, 5, -6))
if k1 ~= nil then liststyle[k1] = v end
else
k1 = tonumber(string.sub(k, 5))
if k1 ~= nil then
list[k1] = v
-- only "list#" elements produce valid indexes
table.insert(idx, k1)
end
end
end
end
table.sort(idx)
for k,v in ipairs(idx) do
local tmp = {}
tmp['index'] = v
tmp['list'] = list[v]
if isset(group[v]) then tmp['group'] = group[v] end
if isset(liststyle[v]) then tmp['liststyle'] = liststyle[v] end
if isset(groupstyle[v]) then tmp['groupstyle'] = groupstyle[v] end
table.insert(ret, tmp)
end
return ret
end
-- functions that create the structure
local function start_box(frame, border, type)
local ret = {""}
if border == "subgroup" or border == "child" then
table.insert(ret, '</div>')
elseif border == "none" then
-- nothing to do
else
table.insert(ret, '<table class="navbox')
if isset(frame.args['bodyclass']) then table.insert(ret, " " .. frame.args['bodyclass']) end
table.insert(ret, '" cellspacing="0" style="')
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['background'] .. ';') end
table.insert(ret, 'border:1px solid #aaa; padding:1px;')
table.insert(ret, 'width:100%;vertical-align:middle;margin:auto;clear:both;font-size:88%;text-align:center;')
addstyle(ret, frame.args['bodystyle'])
addstyle(ret, frame.args['style'])
table.insert(ret, '"><tr><td style="padding: 2px;">')
end
table.insert(ret, '<table cellspacing="0" class="nowraplinks')
if isset(frame.args['title']) and frame.args['state'] ~= "plain" and frame.args['state'] ~= "off" then
--table.insert(ret, ' collapsible ')
table.insert(ret, ' mw-collapsible ')
if isset(frame.args['state']) then
table.insert(ret, frame.args['state'])
else
--table.insert(ret, 'autocollapse')
table.insert(ret, 'mw-collapsed')
end
end
if border == "subgroup" or border == "child" or border == "none" then
table.insert(ret, ' navbox-subgroup" style="')
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['background'] .. ';') end
table.insert(ret, 'margin:auto;clear:both;font-size:88%;text-align:center;')
table.insert(ret, 'width:100%;vertical-align:middle;')
addstyle(ret, frame.args['bodystyle'])
addstyle(ret, frame.args['style'])
table.insert(ret, '">')
else
table.insert(ret, '" style="width:100%;background:transparent;color:inherit;">')
end
return table.concat(ret)
end
local function end_box(frame, border, type)
local ret = {""}
table.insert(ret, '</table>')
if border == "subgroup" or border == "child" then
table.insert(ret, '<div>')
elseif border == "none" then
-- nothing to do
else
table.insert(ret, '</td></tr></table>')
end
return table.concat(ret)
end
local function build_title(frame, border, type)
local ret = {""}
if not isset(frame.args['title']) then return '' end
table.insert(ret, '<tr>')
if isset(frame.args['titlegroup']) then
table.insert(ret, '<td class="navbox-group" style="')
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['group'] .. ';') end
table.insert(ret, 'padding-left:1em;padding-right:1em;white-space:nowrap;text-align:right;')
addstyle(ret, frame.args['basestyle'])
addstyle(ret, frame.args['groupstyle'])
addstyle(ret, frame.args['titlegroupstyle'])
table.insert(ret, '">')
table.insert(ret, frame.args['titlegroup'])
table.insert(ret, '</td>')
table.insert(ret, '<th style="border-left:2px solid #fdfdfd;width:100%;')
else
table.insert(ret, '<th style="')
end
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['title'] .. ';') end
table.insert(ret, 'text-align:center;')
addstyle(ret, frame.args['basestyle'])
addstyle(ret, frame.args['titlestyle'])
table.insert(ret, '"')
local cs = 2
if isset(frame.args['imageleft']) then cs = cs + 1 end
if isset(frame.args['image']) then cs = cs + 1 end
if isset(frame.args['titlegroup']) then cs = cs - 1 end
table.insert(ret, ' colspan = "' .. cs .. '"')
table.insert(ret, ' class="navbox-title"')
table.insert(ret, '>')
if frame.args['navbar'] == "plain" or frame.args['navbar'] == "off" or border == "subgroup" or border == "child" or border == "none" then
if frame.args['navbar'] == "off" then
if frame.args['state'] == "plain" then table.insert(ret, '<div style="float:right;width:6em;"> </div>') end
else
if frame.args['state'] ~= "plain" then table.insert(ret, '<div style="float:left; width:6em;text-align:left;"> </div>') end
end
else
if frame.args['state'] == "plain" then table.insert(ret, '<div style="float:right;width:6em;"> </div>') end
table.insert(ret, '<div style="float:left; width:6em;text-align:left;">')
if frame.args['name'] ~= nil then
local args = {}
args[#args+1] = frame.args['name']
local q = {""}
table.insert(q, 'text-align:center;')
addstyle(q, frame.args['basestyle'])
addstyle(q, frame.args['titlestyle'])
table.insert(q, 'border:none;')
args['fontstyle'] = table.concat(q)
args['mini'] = '1'
table.insert(ret, frame:expandTemplate{title = 'Navbar', args = args})
else
table.insert(ret, ' ')
table.insert(ret, '[[Category:Navboxes without name]]')
end
table.insert(ret, '</div>')
end
table.insert(ret, '<span')
if isset(frame.args['titleclass']) then table.insert(ret, ' class="' .. frame.args['titleclass'] .. '"') end
table.insert(ret, ' style="font-size:')
if border == "subgroup" or border == "child" or border == "none" then
table.insert(ret, '100%')
else
table.insert(ret, '110%')
end
table.insert(ret, ';">')
table.insert(ret, frame.args['title'])
table.insert(ret, '</span>')
table.insert(ret, '</th></tr>')
return table.concat(ret)
end
local function build_row(frame, k, group, list, groupstyle, liststyle, border, type)
local ret = {""}
if isset(group) then
table.insert(ret, '<td class="navbox-group" style="')
if border ~= "subgroup" and border ~= "child" then
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['group'] .. ';') end
else
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['subgroup'] .. ';') end
end
table.insert(ret, 'padding-left:1em; padding-right:1em; white-space:nowrap; text-align:right;')
addstyle(ret, frame.args['basestyle'])
if isset(frame.args['groupwidth']) then table.insert(ret, 'width:' .. frame.args['groupwidth'] .. ';') end
addstyle(ret, frame.args['groupstyle'])
addstyle(ret, groupstyle)
table.insert(ret, '"><div style="padding:0;">' .. group .. '</div></td>')
table.insert(ret, '<td style="text-align:left;border-left-width:2px;border-left-style:solid;')
else
table.insert(ret, '<td colspan=2 style="')
end
-- a bit tricky, but it works as XOR
if (frame.args['evenodd'] == "swap") ~= ((k % 2) == 0) then
if isset(colors[type]) then table.insert(ret, 'background:' .. colors[type]['dark'] .. ';') end
else
table.insert(ret, 'background:transparent;')
end
if not isset(frame.args['groupwidth']) then table.insert(ret, 'width:100%;') end
table.insert(ret, 'padding: 0;')
addstyle(ret, frame.args['liststyle'])
if (frame.args['evenodd'] == "swap") ~= ((k % 2) == 0) then
addstyle(ret, frame.args['evenstyle'])
else
addstyle(ret, frame.args['oddstyle'])
end
addstyle(ret, liststyle)
table.insert(ret, '" class="navbox-list')
if (frame.args['evenodd'] == "swap") ~= ((k % 2) == 0) then
table.insert(ret, ' navbox-even')
else
table.insert(ret, ' navbox-odd')
end
table.insert(ret, '">')
table.insert(ret, '<div style="padding:')
if isset(frame.args['list' .. k .. 'padding']) then
table.insert(ret, frame.args['list' .. k .. 'padding'])
elseif isset(frame.args['listpadding']) then
table.insert(ret, frame.args['listpadding'])
else
table.insert(ret, '0em 0.25em')
end
table.insert(ret, ';">\n' .. list .. '</div>')
table.insert(ret, '</td>')
return table.concat(ret)
end
local function build_body(frame, border, type)
local ret = {""}
local sep = isset(frame.args['title'])
local lists = scan_lists(frame)
if isset(frame.args['above']) then
if sep then
table.insert(ret, '<tr style="height: 2px;"><td></td></tr>')
end
sep = true
table.insert(ret, '<tr><td class="navbox-abovebelow" style="')
if isset(colors[type]) then
if border ~= "subgroup" and border ~= "child" then
table.insert(ret, 'background:' .. colors[type]['above'] .. ';')
else
table.insert(ret, 'background:' .. colors[type]['group'] .. ';')
end
end
table.insert(ret, 'padding-left:1em;padding-right:1em;text-align:center;')
addstyle(ret, frame.args['basestyle'])
addstyle(ret, frame.args['abovestyle'])
table.insert(ret, '"')
local cs = 2
if isset(frame.args['imageleft']) then cs = cs + 1 end
if isset(frame.args['image']) then cs = cs + 1 end
table.insert(ret, ' colspan="' .. cs .. '"')
table.insert(ret, '>' .. frame.args['above'] .. '</td></tr>')
end
local imgs = true
local irows = 1
if #lists > 0 then irows = 2 * #lists - 1 end
for k,v in ipairs(lists) do
if sep then
table.insert(ret, '<tr style="height: 2px;"><td></td></tr>')
end
sep = true
table.insert(ret, '<tr>')
if imgs then
if isset(frame.args['imageleft']) then
table.insert(ret, '<td style="width:0%;padding:0px 2px 0px 0px;')
addstyle(ret, frame.args['imageleftstyle'])
table.insert(ret, '"')
table.insert(ret, ' rowspan="' .. irows .. '"')
table.insert(ret, '>' .. frame.args['imageleft'] .. '</td>')
end
end
table.insert(ret, build_row(frame, v['index'], v['group'], v['list'], v['groupstyle'], v['liststyle'], border, type))
if imgs then
if isset(frame.args['image']) then
table.insert(ret, '<td style="width:0%;padding:0px 2px 0px 0px;')
addstyle(ret, frame.args['imagestyle'])
table.insert(ret, '"')
table.insert(ret, ' rowspan="' .. irows .. '"')
table.insert(ret, '>' .. frame.args['image'] .. '</td>')
end
imgs = false
end
table.insert(ret, '</tr>')
end
if isset(frame.args['below']) then
if sep then
table.insert(ret, '<tr style="height: 2px;"><td></td></tr>')
end
sep = true
table.insert(ret, '<tr><td class="navbox-abovebelow" style="')
if isset(colors[type]) then
if border ~= "subgroup" and border ~= "child" then
table.insert(ret, 'background:' .. colors[type]['above'] .. ';')
else
table.insert(ret, 'background:' .. colors[type]['group'] .. ';')
end
end
table.insert(ret, 'padding-left:1em;padding-right:1em;text-align:center;')
addstyle(ret, frame.args['basestyle'])
addstyle(ret, frame.args['belowstyle'])
table.insert(ret, '"')
local cs = 2
if isset(frame.args['imageleft']) then cs = cs + 1 end
if isset(frame.args['image']) then cs = cs + 1 end
table.insert(ret, ' colspan="' .. cs .. '"')
table.insert(ret, '>' .. frame.args['below'] .. '</td></tr>')
end
return table.concat(ret)
end
-- exported functions
local function buildNavbox(frame)
local template = {""}
local border = ""
local type = ""
if isset(frame.args['border']) then
border = trim(frame.args['border'])
elseif isset(frame.args[1]) then
border = trim(frame.args[1])
end
if isset(frame.args['type']) then
type = trim(frame.args['type'])
end
-- TODO: filtering of border and type values?
table.insert(template, start_box(frame, border, type))
table.insert(template, build_title(frame, border, type))
table.insert(template, build_body(frame, border, type))
table.insert(template, end_box(frame, border, type))
return table.concat(template)
end
local function buildNavboxTemplate(frame)
return buildNavbox(frame:getParent())
end
local function buildColorTable(frame)
local ret = {""}
table.insert(ret, '<table class="wikitable" style="text-align: center;">')
table.insert(ret, '<caption>List of colors in order from darkest to brigthest one</caption>')
table.insert(ret, '<tr><th>"type"</th><th>title</th><th>above, below</th><th>group,<br/>sub-above/below</th><th>sub-group</th><th>dark background</th><th>background</th></tr>')
for k,v in pairs(colors) do
table.insert(ret, '<tr>')
table.insert(ret, '<td>' .. k .. '</td>')
table.insert(ret, '<td style="background:' .. v['title'] .. '">' .. v['title'] .. '</td>')
table.insert(ret, '<td style="background:' .. v['above'] .. '">' .. v['above'] .. '</td>')
table.insert(ret, '<td style="background:' .. v['group'] .. '">' .. v['group'] .. '</td>')
table.insert(ret, '<td style="background:' .. v['subgroup'] .. '">' .. v['subgroup'] .. '</td>')
table.insert(ret, '<td style="background:' .. v['dark'] .. '">' .. v['dark'] .. '</td>')
table.insert(ret, '<td style="background:' .. v['background'] .. '">' .. v['background'] .. '</td>')
table.insert(ret, '</tr>')
end
table.insert(ret, '</table>')
return table.concat(ret)
end
-- export local functions
return {
['buildNavbox'] = buildNavbox,
['buildNavboxTemplate'] = buildNavboxTemplate,
['buildColorTable'] = buildColorTable
}