--[[
Navbox Module
- Fully CSS styled (inline styles possible but not default)
- Supports unlimited rows
by User:Tjcool007
http://layton.wikia.com/wiki/Module:Navbox
Next changes are applied by User:Cafeinlove:
- Parameter names are translated into Korean.
- CSS class names reflect BEM rules
- Parameters `name`, `border` are removed.
- VDE linkset no more requires Template:Vdelinks. It is generated out of
- `참조` argument, and the links color is customizable via `참조색` argument.
- Parameters related to alternative group/list have been removed.
- Instead, parameters for individual cells such as
- `제목클래스n`, `제목모양n`, `내용클래스n`, `내용모양n` are introduced.
- List items are separated by a middot(plain text) instead of CSS pseudo.
- List parameter accepts both list items and non-list items.
- Class `navbox__title` is assigned to `th` element instead of `tr` element.
]]
local p = {}
-- Default config. Values will be replaced with
-- proprecessed arguments passed to template
local args = {}
local navbox -- Actual navbox
local rownums, skiprows = {}, {}
local alt, hasrows, hasData, isChild = false, false, false, false
local activeSection, sections, cimage, cimageleft
local colspan, rowspan
local showText, hideText = '보이기', '숨기기'
-- Title
--- Processes the VDE links in the title
--
-- @param titlecell The table cell of the title
local function processVde( titlecell )
- if not args['참조'] then return end
local vde = { '보기', '토론', '편집' }
- local vdeLinks = {}
- local link, ns, fullurl
- local page = args['참조']
- local color = args['참조색'] or '#111'
for k, v in pairs(vde) do
- ns = '틀'
if v ~= '편집' then
- if v == '토론' then ns = '틀토론' end
- link = '' .. v .. ''
- else
- fullurl = mw.uri.fullUrl( ns .. ':' .. page, 'action=edit')
- link = '[' .. tostring(fullurl) .. ' ' .. v .. ']'
- end
- table.insert(vdeLinks, link)
- end
titlecell
- tag('span')
- addClass('navbox__vde')
- wikitext( table.concat(vdeLinks, ' ᛫ ') )
- tag('span')
end
--- Processes the main title row
local function processTitle()
- local titlerow = mw.html.create('tr')
- local titlecell = mw.html.create('th'):addClass('navbox__title'):attr('colspan',colspan):attr('scope','col')
processVde( titlecell )
titlecell:wikitext( args['큰제목'] or ' ' )
if args['큰제목클래스'] then titlerow:addClass( args['큰제목클래스'] ) end
- if args['큰제목모양'] then titlecell:cssText( args['큰제목모양'] ) end
titlerow:node( titlecell )
- navbox:node( titlerow )
end
local function _addGutter( parent, incRowspan )
- parent:tag('tr'):addClass('navbox__gutter'):tag('td'):attr('colspan',2)
if incRowspan then
- rowspan = rowspan + 1
- end
end
-- Above/Below
--- Processes the above and below rows
--
-- @param rowtype Either 'above' or 'below'
local function processAboveBelow( rowtype, prefix )
- if not args[rowtype .. '글'] then return end
local abrow = mw.html.create('tr'):addClass('navbox__'..rowtype)
- local abcell = mw.html.create('td'):attr('colspan',colspan):wikitext( args[rowtype .. '글'] )
if args[rowtype .. '클래스'] then abrow:addClass( args[rowtype .. '클래스'] ) end
- if args[rowtype .. '모양'] then abcell:cssText( args[rowtype .. '모양'] ) end
abrow:node( abcell )
- _addGutter( navbox )
- navbox:node( abrow )
end
-- Main Rows
--- Processes the images
local function _processImage(row, imgtype)
- if not args[imgtype] then return end
local iclass = imgtype == '그림' and 'navboximageright' or 'navboximageleft'
local imagecell = mw.html.create('td'):addClass('navbox__image'):addClass(iclass)
local image = args[imgtype]
- if image:sub(1,1) ~= '[' then
- local width = args[imgtype .. '너비'] or '100px'
- imagecell:css('width',width):wikitext('' .. width .. '|link=' .. (args[imgtype .. '링크'] or ) .. '')
- else
- imagecell:css('width','0%'):wikitext(image)
- end
- if image:sub(1,1) ~= '[' then
if args[imgtype .. '클래스'] then imagecell:addClass( args[imgtype .. '클래스'] ) end
- if args[imgtype .. '모양'] then imagecell:cssText( args[imgtype .. '모양'] ) end
row:node( imagecell )
- if imgtype == '그림' then
- cimage = imagecell
- else
- cimageleft = imagecell
- end
- if imgtype == '그림' then
end
--- Closes the currently active section (if any)
local function _closeCurrentSection()
- if not activeSection then return end
local row = mw.html.create('tr'):addClass('navbox__section-row')
- local cell = mw.html.create('td'):attr('colspan',2)
-
- if not hasrows then
- _processImage(row,'왼쪽그림')
- end
- if not hasrows then
cell:node(sections[activeSection])
- row:node(cell)
local firstRow = false
- if not hasrows then
- firstRow = true
- hasrows = true
- _processImage(row,'그림')
- end
- if not hasrows then
_addGutter(navbox,not firstRow)
- navbox:node(row)
- rowspan = rowspan + 1
activeSection = false
- hasData = false
end
--- Handles alternating rows
--
-- @return Alternatingly returns true or false. Always returns false if alternating rows
-- are disabled with "alternaterows = no"
local function _alternateRow()
- if args['색교차'] == 'no' then return false end
if alt then
- alt = false
- return true
- else
- alt = true
- return false
- end
end
--- Process a single Header "row"
--
-- @param num Number of the row to be processed
local function processHeader(num)
- if not args['작은제목'..num] then return end
-
- _closeCurrentSection()
local subtable = mw.html.create('table'):addClass('navbox__section')
- local headerrow = mw.html.create('tr')
- local header = mw.html.create('th'):addClass('navbox__header'):attr('colspan',2):attr('scope','col'):wikitext( args['작은제목'..num] )
local collapseme = args['작은제목상태'..num] or false
- local state = false
if collapseme then
- -- Look at this one
- if collapseme ~= 'plain' then
- state = collapseme == 'expanded' and 'expanded' or 'collapsed'
- end
- else
- -- Look at default
- local collapseall = args['작은제목기본상태'] or false
- if collapseall then
- state = collapseall == 'expanded' and 'expanded' or 'collapsed'
- end
- end
if state then
- subtable:addClass('mw-collapsible'):attr('data-expandtext',showText):attr('data-collapsetext',hideText)
- if state == 'collapsed' then
- subtable:addClass('mw-collapsed')
- end
- end
if args['작은제목클래스'] then headerrow:addClass( args['작은제목클래스'] ) end
- if args['작은제목모양'] then header:cssText( args['작은제목모양'] ) end
headerrow:node(header)
- subtable:node(headerrow)
sections[num] = subtable
- activeSection = num
end
--- Processes a single list row
--
-- @param num Number of the row to be processed
local function processList(num)
- if not args['내용'..num] then return end
local row = mw.html.create('tr'):addClass('navbox__row')
-
- if not hasrows and not activeSection then
- _processImage(row, '왼쪽그림')
- end
- if not hasrows and not activeSection then
local listcell = mw.html.create('td'):addClass('navbox__list')
- local data = args['내용'..num]
- local listTable = {}
- local list =
- local separator = ' ᛫ '
- local function forwardJoined(str, tbl, sep)
- local joined = table.concat(tbl, sep)
- for i = 0, #tbl do tbl[i] = nil end -- empty tbl
- return str .. joined
- end
- local function forwardJoined(str, tbl, sep)
- local function appendWrapped(str, item, patt)
- return str .. string.format(patt, item)
- end
- local function appendWrapped(str, item, patt)
- for line in data:gmatch('[^\r\n]+') do -- get line by line
- if string.len(line) == 0 then break end
- for line in data:gmatch('[^\r\n]+') do -- get line by line
- if line:sub(1, 2) == '* ' then -- line starting with '* '
- table.insert(listTable, line:sub(3))
- else -- other lines
- if #listTable ~= 0 then
- list = forwardJoined(list, listTable, separator)
- end
- list = appendWrapped(list, line, '%s')
- if #listTable ~= 0 then
- end
- if line:sub(1, 2) == '* ' then -- line starting with '* '
- end
- list = forwardJoined(list, listTable, separator)
listcell:wikitext( list )
local altRow = _alternateRow()
- if altRow then row:addClass( 'alt' ) end -- 홀수 행
if args['모든내용클래스'] then listcell:addClass( args['모든내용클래스'] ) end
- if args['모든내용모양'] then listcell:cssText( args['모든내용모양'] ) end
local listclass = args['내용클래스'..num] or false
- if listclass then listcell:addClass( listclass ) end
local liststyle = args['내용모양'..num] or false
- if liststyle then listcell:cssText( liststyle ) end
if args['제목'..num] then
- local groupcell = mw.html.create('th'):addClass('navbox__group'):attr('scope','row'):wikitext( args['제목'..num] )
if args['모든제목클래스'] then groupcell:addClass( args['모든제목클래스'] ) end
- if args['모든제목모양'] then groupcell:cssText( args['모든제목모양'] ) end
local groupclass = args['제목클래스'..num] or false
- if groupclass then groupcell:addClass( groupclass ) end
local groupstyle = args['제목모양'..num] or false
- if groupstyle then groupcell:cssText( groupstyle ) end
row:node( groupcell )
- else
- listcell:attr('colspan',2):addClass('no-group')
- end
- else
row:node( listcell )
local firstRow = false
- if not hasrows and not activeSection then
- firstRow = true
- hasrows = true
- _processImage(row, '그림')
- end
- if not hasrows and not activeSection then
if activeSection then
- local parent = sections[activeSection]
- if not isChild or not firstRow then
- _addGutter(parent)
- end
- parent:node(row)
- hasData = true
- else
- if not isChild or not firstRow then
- _addGutter(navbox,not firstRow)
- end
- navbox:node( row )
- rowspan = rowspan + 1
- if not isChild or not firstRow then
- end
end
--- Processes all rows
local function processRows()
- sections = {}
- for i=1,#rownums do
- local num = rownums[i]
- if not skiprows[num] then
- processHeader(num)
- processList(num)
- end
- end
- _closeCurrentSection()
if cimageleft then
- cimageleft:attr('rowspan',rowspan)
- end
- if cimage then
- cimage:attr('rowspan',rowspan)
- end
end
-- ARGUMENTS PREPROCESSOR
-- * Extracts arguments from frame and stores them in args table
-- * At the same time, checks for valid row numbers
--- Preprocessor for the arguments.
-- Will fill up the args table with the parameters from the frame grouped by their type.
--
-- @param frame The frame passed to the Module.
local function preProcessArgs(frame)
- local tmp = {}
if frame == mw.getCurrentFrame() then
- tmp = frame:getParent().args
- else
- tmp = frame
- end
-- Storage tables
- local nums = {}
-- Loop over all the args
- for k,v in pairs(tmp) do
- -- Skip empty args, which are useless
- if v ~= then
- local cat,num = tostring(k):match('^(.-)([1-9]%d*)$')
- for k,v in pairs(tmp) do
if cat == '제목' or cat == '내용' then
- nums[num] = true
- end
args[k] = v -- Simple copy
- end
- end
colspan = args['그림'] and 3 or 2
- if args['왼쪽그림'] then colspan = colspan + 1 end
- rowspan = 0
if args['색교차'] == '반전' then alt = true end
for k, v in pairs(nums) do
- table.insert(rownums, tonumber(k))
- end
table.sort(rownums)
-- Calculate skip rows
- local cSection, cSkip
- local showall = args['상태']
- for i = 1, #rownums do
- local num = rownums[i]
- if args['작은제목'..num] then
- cSection = true
- cSkip = false
- local showme = args['작은제목상태'..num]
- if showme == hideText then
- cSkip = true
- elseif showme == '자동' or (showme ~= showText and showall ~= showText) then
- if not args['내용'..num] then
- local nextNum = rownums[i+1]
- cSkip = not nextNum or args['작은제목'..nextNum] -- If next has a header -> skip
- end
- if not args['내용'..num] then
- end
- end
- if cSection and cSkip then
- skiprows[num] = true
- end
- end
end
-- MAIN FUNCTIONS
--- Processes the arguments to create the navbox.
--
-- @return A string with HTML that is the navbox.
local function _navbox()
- -- Create the root HTML element
- local trim = function(s)
- return s and mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") or
- end
- isChild = (trim(args[1]) == '하위')
if isChild then
- navbox = mw.html.create('table'):addClass('navbox__subgroup')
- else
- navbox = mw.html.create('table'):addClass('navbox')
if args['상태'] ~= 'plain' then
- navbox:addClass('mw-collapsible'):attr('data-expandtext',showText):attr('data-collapsetext',hideText)
- if args['상태'] == 'collapsed' then
- navbox:addClass('mw-collapsed')
- end
- end
- end
if args['클래스'] then navbox:addClass(args['클래스']) end
- if args['모양'] then navbox:cssText(args['모양']) end
-- Process...
- if not isChild then
- processTitle()
- processAboveBelow('above', '윗')
- processRows()
- processAboveBelow('below', '아랫')
- if not isChild then
return tostring(navbox)
- else
- processRows()
- else
return tostring(navbox)
- end
end
--- Main module entry point.
-- To be called with
or directly from another module.
--
-- @param frame The frame passed to the module via the #invoke. If called from another
-- module directly, this should be a table with the parameter definition.
function p.main(frame)
- -- Save the arguments in a local variable so other functions can use them.
- preProcessArgs(frame)
return _navbox()
end
return p