Module:Navbox

From Lifecraft Wiki
Jump to navigation Jump to search

-- lua port of Template:Navbox -- by DennouNeko

-- == Helper functions == --libraries local U = require("Module:Core")

local colors = U.main_colors

if mw.text == nil then mw.text = require("Module:MW.text") end

--[[ Retrieve a full list of 'list#', 'list#style', 'group#' and 'group#style' arguments

    as a table of objects with 'index', 'list', 'liststyle', 'group' and 'groupstyle' fields,
    where 'index' is the number in 'list#' argument name.
    Only 'list' and 'index' are always defined. Elements that weren't specified will be empty.
    If 'list#' wasn't defined, rest of elements for that given index will be ignored.
    Key of argument matches the number in arguments name. ]]

local function scan_lists(frame)

 local idx = {}
 local list = {}
 local group = {}
 local liststyle = {}
 local groupstyle = {}
 local ret = {}
 local s,e,t
 for k,v in frame:argumentPairs() do
   -- accept only parameters without leading zeros
   s,e,t = string.find(k, '^group([1-9]%d*)style$')
   if s ~= nil then groupstyle[tonumber(t)] = v end
   s,e,t = string.find(k, '^list([1-9]%d*)style$')
   if s ~= nil then liststyle[tonumber(t)] = v end
   s,e,t = string.find(k, '^group([1-9]%d*)$')
   if s ~= nil then group[tonumber(t)] = v end
   s,e,t = string.find(k, '^list([1-9]%d*)$')
   if s ~= nil then
     list[tonumber(t)] = v
     idx[#idx+1] = tonumber(t)
   end
 end
 table.sort(idx)
 for k,v in pairs(idx) do
   local tmp = {}
   tmp['index'] = v
   tmp['list'] = list[v]
   if U.isset(group[v]) then tmp['group'] = group[v] end
   if U.isset(liststyle[v]) then tmp['liststyle'] = liststyle[v] end
   if U.isset(groupstyle[v]) then tmp['groupstyle'] = groupstyle[v] end
   ret[#ret+1] = tmp
 end
 return ret

end


-- == Functions generating the document elements ==

--Generates the beginning of box, based on specified 'ttype' and 'border'. local function start_box(frame, border, ttype)

 local ret = {}
 if border == "subgroup" or border == "child" then

-- since we're in a cell of parent navbox, we have to close its

element ret[#ret+1] = '

'

 elseif border == "none" then
   -- nothing to do
 else
   -- new, independent navbox - create a frame around it

ret[#ret+1] = '

'

 end
 return table.concat(ret)

end

--[[ Generates the title row: 'v(iew) • d(iscuss) • e(dit)' + title + '[Expand]'/'[Collapse]' buttons. ]] local function build_title(frame, border, ttype)

 local ret = {""}
 if not U.isset(frame.args['title']) then return  end

table.insert(ret, '') if U.isset(frame.args['titlegroup']) then -- in case that there's a group for title ret[#ret+1] = '\n'

   ret[#ret+1] = frame.args['titlegroup']

ret[#ret+1] = '' ret[#ret+1] = '<th style="border-left:2px solid ' ret[#ret+1] = U.cv(U.isset(colors[ttype]), colors[ttype]['background'], '#fdfdfd') ret[#ret+1] = ';width:100%;' else -- no group for title table.insert(ret, ''

 -- add navbars and/or padding when needed
 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 ret[#ret+1] = '

 

' end

   else

if frame.args['state'] ~= "plain" then ret[#ret+1] = '

 

' end

   end
 else

if frame.args['state'] == "plain" then ret[#ret+1] = '

 

' end ret[#ret+1] = '

'
   if frame.args['name'] ~= nil then
     local args = {}
     args[#args+1] = frame.args['name']
     args['mini'] = '1'
     -- TODO: Build the navbar without using external template?
     local q = {""}
     q[#q+1] = 'text-align:left;'
     U.addStyle(q, frame.args['basestyle'])
     U.addStyle(q, frame.args['titlestyle'])
     q[#q+1] = 'border:none;'
     args['fontstyle'] = table.concat(q)
     ret[#ret+1] = frame:expandTemplate{title = 'Navbar', args = args}
   else
     ret[#ret+1] = ' '
     ret[#ret+1] = 
   end
ret[#ret+1] = '

'

 end
 -- the title starts here
 ret[#ret+1] = '<span'
 if U.isset(frame.args['titleclass']) then ret[#ret+1] = ' class="' .. frame.args['titleclass'] .. '"' end
 ret[#ret+1] = ' style="font-size:' .. U.cv((border == "subgroup" or border == "child" or border == "none"), '100%', '110%') .. ';">\n'
 ret[#ret+1] = frame.args['title']
 
 ret[#ret+1] = ''

ret[#ret+1] = '' return table.concat(ret) end --[[ Generates the 'above' and 'below' rows. Returns the generated row and updated 'sep' value (if separation is going to be needed). ]] local function build_above_below(frame, border, ttype, text, rstyle, sep) local ret = {} if U.isset(text) then if sep then -- if separation is needed table.insert(ret, '')

   end
   -- start the 'above' or 'below' row

ret[#ret+1] = '' ret[#ret+1] = '\n'

   -- row content
   ret[#ret+1] = text

ret[#ret+1] = '' sep = true -- now we're going to need separation end return table.concat(ret),sep end --Generates a single row of the list. local function build_row(frame, border, ttype, k, group, list, groupstyle, liststyle) local ret = {""} if U.isset(group) then -- there's a group name for current list, so add a cell for it ret[#ret+1] = '' ret[#ret+1] = '

\n'
   ret[#ret+1] = group
ret[#ret+1] = '

'

   -- start the content cell
   ret[#ret+1] = '<td style="text-align:left;border-left-width:2px;border-left-style:solid;'
 else
   -- no group name, start the content already

ret[#ret+1] = '' -- add the

with content (same
that child navbox has to close when starting table) ret[#ret+1] = '
\n'
 ret[#ret+1] = list
ret[#ret+1] = '
'
 return table.concat(ret)

end

--Generates the "body" of table (everything below title) local function build_body(frame, border, ttype, lists)

 local ret = {}
 local sep = U.isset(frame.args['title']) -- if there was a title, we have to add separation for first row
 local imgs = true -- add images if present
 local irows = U.cv( (#lists > 0), (2 * #lists - 1), 1 )
 -- aff the 'above' row
 ret[#ret+1],sep = build_above_below(frame, border, ttype, frame.args['above'], frame.args['abovestyle'], sep)
 
 for k,v in pairs(lists) do
   if sep then -- add separation if needed
ret[#ret+1] = ''
   end
table.insert(ret, '') -- add left image (if wasn't added yet and is present) if imgs then if U.isset(frame.args['imageleft']) then ret[#ret+1] = '' .. frame.args['imageleft'] .. ''
     end
   end
   -- add the list content
   ret[#ret+1] = build_row(frame, border, ttype, v['index'], v['group'], v['list'], v['groupstyle'], v['liststyle'])
   -- add right image (if wasn't added yet and is present)
   if imgs then
     if U.isset(frame.args['image']) then
ret[#ret+1] = '' .. frame.args['image'] .. ''
     end
     -- mark that images were added already
     imgs = false
   end
ret[#ret+1] = '' sep = true -- now the separation is going to be needed for sure end ret[#ret+1],sep = build_above_below(frame, border, ttype, frame.args['below'], frame.args['belowstyle'], sep) return table.concat(ret) end -- == Exported functions == --Generates and returns the whole navbox table. local function buildNavbox(frame) local template = {} local border = "" local ttype = "" if U.isset(frame.args['border']) then border = frame.args['border'] elseif U.isset(frame.args[1]) then border = mw.text.trim(frame.args[1]) end if U.isset(frame.args['type']) then ttype = frame.args['type'] end -- TODO: filtering of border and type values? -- prepare the data first local lists = scan_lists(frame) -- build the content template[#template+1] = start_box(frame, border, ttype) template[#template+1] = build_title(frame, border, ttype) template[#template+1] = build_body(frame, border, ttype, lists) template[#template+1] = end_box(frame, border, ttype) return table.concat(template) end -- Workaround for the "Navbox subgroup" template local function buildNavboxSubgroup(frame) if not U.isset(frame.args['border']) then frame.args['border'] = 'child' end -- TODO: add/modify/remove other params? -- call the main function return buildNavbox(frame) end --[[ Mostly for debugging, generates and returns a table of sets of colors and the values in cells with colors used as backgrounds. ]] local function buildColorTable(frame) local ret = {""} table.insert(ret, '') table.insert(ret, '') table.insert(ret, '')
 for k,v in pairs(colors) do
table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') table.insert(ret, '') end table.insert(ret, '
List of colors in order from darkest to brigthest one
"type"titleabove, belowgroup,
sub-above/below
sub-groupdark backgroundbackground
' .. k .. '' .. v['title'] .. '' .. v['above'] .. '' .. v['group'] .. '' .. v['subgroup'] .. '' .. v['dark'] .. '' .. v['background'] .. '
')
 return table.concat(ret)

end

-- export local functions return {

 ['buildNavbox'] = buildNavbox,
 ['buildNavboxTemplate'] = function(frame) return buildNavbox(frame:getParent()) end, -- for wrappers
 ['buildNavboxSubgroup'] = buildNavboxSubgroup,
 ['buildNavboxSubgroupTemplate'] = function(frame) return buildNavboxSubgroup(frame:getParent()) end, -- for wrappers
 ['buildColorTable'] = buildColorTable

}

--