Jump to content
Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
If you make an edit, a temporary account will be created for you.

Editing Module:Sandbox/Stevium

From The Petit Planet Wiki
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-- Imported from: https://defaultloadout.wiki.gg/wiki/Module:Navbox
-- version 1.2.5.1
-- config table for RANGER.
-- If you want to change the default config, DO NOT change it here,
-- please do it via the `onLoadConfig` hook in [[Module:Navbox/Hooks]].
local config = {
default_navbox_class = "navigation-not-searchable noexcerpt",  -- Base value of the `class` parameter.
default_title_class = nil,    -- Base value of the `title_class` parameter.
default_above_class = nil,    -- Base value of the `above_class` parameter.
default_below_class = nil,    -- Base value of the `below_class` parameter.
default_section_class =nil,  -- Base value of the `section_class` parameter.
default_header_class = nil,  -- Base value of the `header_class` parameter.
default_group_class = nil,    -- Base value of the `group_class` parameter.
default_list_class = 'hlist', -- Base value of the `list_class` parameter.
default_header_state = nil, -- Base value of the `state` parameter.
editlink_hover_message_key = 'Navbox-edit-hover', -- The system message name for hover text of the edit icon.
auto_flatten_top_level = true, -- If true, when a section has only one list with no content and no corresponding group but has sublists, these sublists will be moved to top level.
-- This helps make the hierarchy of sections and content clearer.
-- An example:
-- {{navbox
-- ...
--  |header1 = Items
--  | group1.1 = Weapons
--  |  list1.1 = Swords · Guns · Wands
--  | group1.2 = Armors
--  |  list1.2 = Head pieces · Capes
--  |header2 = NPCs
--  | group2.1 = Town NPCs
--  |  list2.1 = Guide · Witch
-- ...
-- }}
-- will be equal to:
-- {{navbox
-- ...
--  |header1 = Items
--  | group2 = Weapons
--  |  list2 = Swords · Guns · Wands
--  | group3 = Armors
--  |  list3 = Head pieces · Capes
--  |header5 = NPCs
--  | group6 = Town NPCs
--  |  list6 = Guide · Witch
-- ...
-- }}
custom_render_handle = nil, -- usually for debugging purposes only. if set, it should be a function accept 2 parameters: `dataTree` and `args`, and return a string as module output.
}
---------------------------------------------------------------------
-- Argument alias.
local CANONICAL_NAMES = {
['titlestyle'] = 'title_style',
['listclass'] = 'list_class',
['groupstyle'] = 'group_style',
['collapsible'] = 'state',
['editlink'] = 'meta',
['editlinks'] = 'meta',
['editicon'] = 'meta',
['edit_link'] = 'meta',
['edit_links'] = 'meta',
['edit_icon'] = 'meta',
['navbar'] = 'meta',
['name'] = 'template',
['evenodd'] = 'striped',
['class'] = 'navbox_class',
['css'] = 'navbox_style',
['style'] = 'navbox_style',
['group'] = '1:group',
['list'] = '1:list',
}
local DEFAULT_ARGS = {
['meta'] = true,
}
local STATES = {
['no'] = '',
['off'] = '',
['plain'] = '',
['collapsed'] = 'mw-collapsible mw-collapsed',
['expanded'] = 'mw-collapsible',
}
local BOOL_FALSE = {
['no'] = true,
['off'] = true,
['false'] = true,
}
local STRIPED = {
['odd'] = 'striped-odd',
['swap'] = 'striped-odd',
['y'] = 'striped-even',
['yes'] = 'striped-even',
['on'] = 'striped-even',
['even'] = 'striped-even',
['striped'] = 'striped-even',
}
local NAVBOX_CHILD_INDICATOR = '!!C$H$I$L$D!!'
local NAVBOX_CHILD_INDICATOR_LENGTH = string.len( NAVBOX_CHILD_INDICATOR )
local CLASS_PREFIX = 'ranger-'
---------------------------------------------------------------------
local p = {}
local p = {}
local getArgs = require('Module:Arguments').getArgs
local h = {} -- non-public
local hooks = mw.title.new('Module:Navbox/Hooks').exists and require('Module:Navbox/Hooks') or {}
 
---------------------------------------------------------------------
 
-- For templates: {{#invoke:navbox|main|...}}
function p.main(frame)
local args = p.mergeArgs(frame)
return p.build(args, true)
end
 
-- For modules: return require('module:navbox').build(args)
-- By default this method will skip the arguments sanitizing phase
-- (and onSanitizeArgsStart/onSanitizeArgsEnd hooks).
-- Set `doParseArgs` to true to do arguments sanitizing.
-- If `customConfig` table is provided, it will be merged into default config table (after onLoadConfig()).
-- If `customHooks` table is provided, all default hook handles will be overrided, unprovided hooks will be empty.
function p.build(args, doParseArgs, customConfig, customHooks)
if customHooks then
hooks = customHooks
end
if doParseArgs then
args = h.parseArgs(args)
end
 
h.runHook('onLoadConfig', config, args)
 
if customConfig then
for k,v in pairs(customConfig) do
config[k] = v
end
end
--merge default args
for k,v in pairs(DEFAULT_ARGS) do
if args[k] == nil then
args[k] = DEFAULT_ARGS[k]
end
end
 
h.runHook('onBuildTreeStart', args)
local dataTree = h.buildDataTree(args)
h.runHook('onBuildTreeEnd', dataTree, args)
if type(config.custom_render_handle) == 'function' then
return config.custom_render_handle(dataTree, args)
else
return h.render(dataTree)
end
end
 
-- merge args from frame and frame:getParent()
-- It may be used when creating custom wrapping navbox module.
--
-- For example, Module:PillNavbox
--
-- local RANGER = require('Module:Navbox')
-- local p = {}
-- function p.main(frame)
--    return RANGER.build(RANGER.mergeArgs(frame), true, {
--        default_navbox_class = 'pill', -- use "pill" style by default.
--    })
-- end
-- return p
--
function p.mergeArgs(frame)
local inputArgs = {}
for k, v in pairs(frame.args) do
v = mw.text.trim(tostring(v))
if v ~= '' then
inputArgs[k] = v
end
end
for k, v in pairs(frame:getParent().args) do
v = mw.text.trim(v)
if v ~= '' then
inputArgs[k] = v
end
end
return inputArgs
end
 
------------------------------------------------------------------------
 
-- equivalent to mw.text.split(str, div, true) for non-empty separator, but can be over 60x faster, since the latter is Unicode-aware.
-- Original version credit: http://richard.warburton.it.
function h.explode(div, str)
if (div=='') then return nil end
local pos,arr = 0,{}
-- for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
arr[#arr+1] = string.sub(str,pos,st-1) -- Attach chars left of current divider
pos = sp+1 -- Jump past current divider
end
arr[#arr+1] = string.sub(str,pos) -- Attach chars right of last divider
return arr
end
 
function h.parseArgs(inputArgs)
h.runHook('onSanitizeArgsStart', inputArgs)
local args = {}
for k, v in pairs(inputArgs) do
if type(k) == 'string' then
-- all named args have already been trimmed
local key = h.normalizeKey(k)
args[key] = h.normalizeValue(key, v)
else
args[k] = mw.text.trim(v) -- keep number-index arguments (for {{navbox|child|...}})
end
end
h.runHook('onSanitizeArgsEnd', args, inputArgs)
return args
end
 
-- Normalize the name string of arguments.
-- the normalized form is (index:)?name, in which:
-- index is number index such as 1, 1.3, 1.2.45,
-- name is in lowercase underscore-case, such as group, group_style
-- e.g: header_state, 1.3:list_style
-- the input argument name can be:
-- * camel-case: listStyle, ListStyle
-- * space separated: list style
-- * prefix+index+postfix?, and can be in camel-case or space/hyphen separated or mixed: list 1 style, list1, list1Style, list1_style
-- * index.name: 1.3.list
-- * index_name: 1.3_list (Space separated are treated as underscore separated, therefore 1.3 list are vaild too)
function h.normalizeKey(s)
-- camel-case to lowercase underscore-case
s = s:gsub('%l%f[%u]', '%0_') -- listStyle to list_style
s = (s:gsub(' ', '_')):lower() -- space to underscore
s = s:gsub('%l%f[%d]', '%0_') -- group1* to group_1*
s = s:gsub('%d%f[%l]', '%0_') -- *1style to *1_style
-- number format x_y_z to x.y.z
s = s:gsub('(%d)_%f[%d]', '%1%.')
-- move index to the beginning:
-- group_1.2_style to 1.2:group_style
-- group_1 to 1:group
s = s:gsub('^([%l_]+)_([%d%.]+)', '%2:%1')
-- support index.name and index_name:
-- 1.2.group / 1.2_group to 1.2:group
s = s:gsub('^([%d%.]+)[%._]%f[%l]', '%1:')
-- now the key should be in normalized form, if the origin key is vaild
 
-- standardize *_css to *_style
s = s:gsub('_css$', '_style')
-- standardize *collapsible to *state
s = s:gsub('collapsible$', 'state')
 
-- standardize all aliases to the canonical name
return CANONICAL_NAMES[s] or s
end
 
function h.normalizeValue(k, v)
k = tostring(k)
if k:find('_style$') then
v = (v .. ';'):gsub(';;', ';')
return v
elseif k:find('state$') then
return STATES[v]
elseif k == 'striped' then
return STRIPED[v]
elseif k == 'meta' then
return not BOOL_FALSE[v]
elseif v:sub(1, 2) == '{|' or v:match('^[*:;#]') then
-- Applying nowrap to lines in a table does not make sense.
-- Add newlines to compensate for trim of x in |parm=x in a template.
return '\n' .. v ..'\n'
end
return v
end
 
-- parse arguments, convert them to structured data tree
function h.buildDataTree(args)
-- parse args to a tree
local tree = h.buildTree(args)
 
-- build root navbox data
local data = h.buildNavboxData(tree.info)
-- Recursively build section tree
if tree.children then
data.sections = h.buildSections(tree.children, {
listClass = h.mergeAttrs(args.list_class, config.default_list_class),
listStyle =  args.list_style,
groupClass = h.mergeAttrs(args.group_class, config.default_group_class),
groupStyle = args.group_style,
sectionClass = h.mergeAttrs(args.section_class, config.default_section_class),
sectionStyle = args.section_style,
headerClass = h.mergeAttrs(args.header_class, config.default_header_class),
headerStyle = args.header_style,
headerState = args.header_state or config.default_header_state,
})
end
if args[1] == 'child' then
data.CHILD_MODE = true
end


function p.show(frame)
return data
local args = getArgs(frame)
end
local bucket_name = mw.text.trim(args[1] or '')
 
local select_field = mw.text.trim(args[2] or '')
function h.buildSections(list, defaults)
local sections = {}
local section = nil
for k, node in h.orderedPairs(list) do
local info = node.info or {}
--start a new section if needed
if info.header or not section then
section = {
class = h.mergeAttrs(info.section_class, defaults.sectionClass),
style = h.mergeAttrs(info.section_style, defaults.sectionStyle),
body = {}
}
-- Section header if needed.
-- If the value of a `|header_n=` is two or more consecutive "-" characters (e.g. --, -----),
-- it means start a new section without header, and the new section will be not collapsable.
if info.header and not string.match(info.header, '^%-%-+$') then
section.header = {
content = info.header,
class = h.mergeAttrs(info.header_class, defaults.headerClass),
style = h.mergeAttrs(info.header_style, defaults.headerStyle),
}
section.state = info.state or defaults.headerState or 'mw-collapsible'
end
sections[#sections+1] = section
end
-- above/below for this section
if info.above then
section.above = {
content = info.above,
class= h.mergeAttrs(info.above_class, config.default_above_class),
style = info.above_style,
}
end
if info.below then
section.below = {
content = info.below,
class= h.mergeAttrs(info.below_class, config.default_below_class),
style = info.below_style,
}
end
-- this group+list row
if info.group or info.list or node.children then
local row = {}
section.body[#section.body+1] = row
if info.group then
row.group = {
content = info.group,
class = h.mergeAttrs(info.group_class, defaults.groupClass),
style = h.mergeAttrs(info.group_style, defaults.groupStyle),
}
end
if info.list then
if string.sub(info.list, 1, NAVBOX_CHILD_INDICATOR_LENGTH) == NAVBOX_CHILD_INDICATOR then
-- it is from {{navbox|child| ... }}
row.sections = mw.text.jsonDecode(string.sub(info.list, NAVBOX_CHILD_INDICATOR_LENGTH+1))
else
row.list = {
content = info.list,
class = h.mergeAttrs(info.list_class, defaults.listClass),
style = h.mergeAttrs(info.list_style, defaults.listStyle),
}
end
end
-- sub-nodes, will override {{navbox|child| ... }}
if node.children then
row.sections = h.buildSections(node.children, defaults)
end
end
end
-- flatten if needed:
-- If a section has only one list with no content and no corresponding group but has sublists, these sublists will be moved to upper level.
if config.auto_flatten_top_level then
for _, sect in ipairs(sections) do
if #sect.body == 1 then
local node = sect.body[1]
if not node.group and not node.list and node.sections and #node.sections == 1 and not node.sections[1].header then
sect.body = node.sections[1].body
end
end
end
end
return sections
end
local b = mw.bucket(bucket_name).select(select_field)
function h.buildNavboxData(info)
local data = {
state = info.state or 'mw-collapsible', -- here we need a default value for empty input
striped = info.striped,
class = h.mergeAttrs(info.navbox_class, config.default_navbox_class),
style = info.navbox_style,
}
for k, v in pairs(args) do
-- data for titlebar
if k ~= 1 and k ~= 2 then
if info.title or info.meta or data.state ~= '' then
b.where(k, v)
data.title = {
content = info.title,
class = h.mergeAttrs(info.title_class, config.default_title_class),
style = info.title_style,
}
if info.meta then
data.metaLinks = {
link = info.meta_link, -- will be used as [[$link|$text]]
url = info.meta_url,  -- will be used as [$url $text], only if there is no data.metaLinks.link
text = info.meta_text, --hovertext
}
if not info.meta_link and not info.meta_url then
-- default link target
local title = mw.title.new(info.template or mw.getCurrentFrame():getParent():getTitle(), 'Template')
if not title then
error('Invalid title ' .. info.template)
end
data.metaLinks.link = title.fullText
end
if not info.meta_text then
local msg = mw.message.new(config.editlink_hover_message_key)
data.metaLinks.text = msg:exists() and msg:plain() or 'View or edit this template'
end
end
end
end
end
return b.run()
-- above/below
if info.above then
data.above = {
content = info.above,
class= h.mergeAttrs(info.above_class, config.default_above_class),
style = info.above_style,
}
end
 
if info.below then
data.below = {
content = info.below,
class= h.mergeAttrs(info.below_class, config.default_below_class),
style = info.below_style,
}
end
return data
end
 
-- parse arguments, convert them into a tree based on their index
-- each node on tree is { info = { #data for this node# }, children = {#children nodes#}  }
function h.buildTree(args, defaults)
local tree = { info = {} }
local check = function(key, value)
local index, name = string.match(key, '^([%d%.]+):(.+)$')
 
-- no number index found, for root node
if not index then
tree.info[key] = value
return
end
 
-- filter invalid number index
if string.match(index, '^%.') or string.match(index, '%.$') or string.match(index, '%.%.') then
return
end
-- find the node that matches the index in the tree
local arr = h.explode('.', index)
local node = tree
for _, v in ipairs(arr) do
v = tonumber(v)
if not node.children then
node.children = {}
end
if not node.children[v] then
node.children[v] = { info = {} }
end
node = node.children[v]
end
node.info[name] = value
end
for k,v in pairs(args) do
check(k, v)
end
return tree
end
 
function h.render(data)
-- handle {{navbox|child|...}} syntax
if data.CHILD_MODE then
return NAVBOX_CHILD_INDICATOR..mw.text.jsonEncode(data.sections)
end
 
-----  normal case -----
local out = mw.html.create()
-- build navbox container
local navbox = out:tag('div')
:attr('role', 'navigation'):attr('aria-label', 'Navbox')
:addClass(CLASS_PREFIX..'navbox')
:addClass(data.class)
:addClass(data.striped)
:addClass(data.state)
:cssText(data.style)
 
--title bar
if data.title then
local titlebar = navbox:tag('div'):addClass(CLASS_PREFIX..'title')
titlebar:tag('div'):addClass('mw-collapsible-toggle-placeholder')
if data.metaLinks then
titlebar:node(h.renderMetaLinks(data.metaLinks))
end
if data.title then
titlebar:addClass(data.title.class):tag('div')
:addClass(CLASS_PREFIX..'title-text')
:addClass(data.title.class)
:cssText(data.title.style)
:wikitext(data.title.content)
end
end
 
--above
if data.above then
navbox:tag('div')
:addClass(CLASS_PREFIX..'above mw-collapsible-content')
:addClass(data.above.class)
:cssText(data.above.style)
:wikitext(data.above.content)
:attr('id', (not data.title) and mw.uri.anchorEncode(data.above.content) or nil) -- id for aria-labelledby attribute, if no title
end
-- sections
if data.sections then
h.renderSections(data.sections, navbox, 0, true)
else
-- Insert a blank section for completely empty navbox to ensure it behaves correctly when collapsed.
if not data.above and not data.below then
navbox:tag('div'):addClass(CLASS_PREFIX..'section mw-collapsible-content')
end
end
 
--below
if data.below then
navbox:tag('div')
:addClass(CLASS_PREFIX..'below mw-collapsible-content')
:addClass(data.below.class)
:cssText(data.below.style)
:wikitext(data.below.content)
end
return tostring(out)
end
 
function h.renderSections(data, container, level, even)
for i,sect in ipairs(data) do
--section box
local section = container:tag('div')
:addClass(CLASS_PREFIX..'section mw-collapsible-content')
:addClass(sect.class)
:addClass(sect.state)
:cssText(sect.style)
-- section header
if sect.header then
section:tag('div')
:addClass(CLASS_PREFIX..'header')
:addClass(sect.header.class)
:cssText(sect.header.style)
:tag('div'):addClass('mw-collapsible-toggle-placeholder'):done()
:tag('div'):addClass(CLASS_PREFIX..'header-text'):wikitext(sect.header.content)
end
-- above:
if sect.above then
section:tag('div')
:addClass(CLASS_PREFIX..'above mw-collapsible-content')
:addClass(sect.above.class)
:cssText(sect.above.style)
:wikitext(sect.above.content)
end
-- body: groups&lists
local box = section:tag('div'):addClass(CLASS_PREFIX..'section-body mw-collapsible-content')
even = h.renderBody(sect.body, box, level, (level==0) and true or even) -- reset even status each section
-- below:
if sect.below then
section:tag('div')
:addClass(CLASS_PREFIX..'below mw-collapsible-content')
:addClass(sect.below.class)
:cssText(sect.below.style)
:wikitext(sect.below.content)
end
end
return even
end
 
 
function h.renderMetaLinks(info)
local box = mw.html.create('span'):addClass(CLASS_PREFIX..'meta')
local meta = box:tag('span'):addClass('nv nv-view')
if info.link then
meta:wikitext('[['..info.link..'|')
:tag('span'):wikitext(info.text):attr('title', info.text):done()
:wikitext(']]')
elseif info.url then
meta:wikitext('['..info.url..' ')
:tag('span'):wikitext(info.text):attr('title', info.text):done()
:wikitext(']')
end
return box
end
 
function h.renderBody(info, box, level, even)
local count = 0
for _,v in h.orderedPairs(info) do
if v.group or v.list or v.sections then
count = count + 1
-- row container
local row = box:tag('div'):addClass(CLASS_PREFIX..'row')
-- group cell
if v.group or (v.sections and level > 0 and not v.list) then
local groupCell = row:tag('div')
:addClass(CLASS_PREFIX..'group level-'..level)
:addClass((level > 0) and CLASS_PREFIX..'subgroup' or nil)
local groupContentWrap = groupCell:tag('div'):addClass(CLASS_PREFIX..'wrap')
if v.group then
groupCell:addClass(v.group.class):cssText(v.group.style)
groupContentWrap:wikitext(v.group.content)
else
groupCell:addClass('empty')
row:addClass('empty-group-list')
end
else
row:addClass('empty-group')
end
-- list cell
local listCell = row:tag('div'):addClass(CLASS_PREFIX..'listbox')
if not v.list and not v.sections then
listCell:addClass('empty')
row:addClass('empty-list')
end
if v.list or (v.group and not v.sections) then
--listCell:node(h.renderList(v['list'] or '', k, level, args))
even = not even -- flip even/odd status
local cell = listCell:tag('div')
:addClass(CLASS_PREFIX..'wrap')
:addClass(even and CLASS_PREFIX..'even' or CLASS_PREFIX..'odd')
if v.list then
cell:addClass(v.list.class):cssText(v.list.style)
:tag('div'):addClass(CLASS_PREFIX..'list'):wikitext(v.list.content)
end
end
if v.sections then
local sublistBox = listCell:tag('div'):addClass(CLASS_PREFIX..'sublist level-'..level)
even = h.renderSections(v.sections, sublistBox, level+1, even)
end
end
end
if count > 0 then
box:css('--count', count) -- for flex-grow
end
return even
end
 
-- pairs, but sort the keys alphabetically
function h.orderedPairs(t, f)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0      -- iterator variable
local iter = function ()  -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
 
-- For cascading parameters, such as style or class, they are merged in exact order (from general to specific).
-- Any parameter starting with multiple hyphens(minus signs) will terminate the cascade.
-- An example:
-- For group_1.1, its style is affected by parameters |group_1.1_style=... , |subgroup_level_1_style=... , and |subgroup_style=... .
-- If we have |group_1.1_style= color:red; |subgroup_level_1_style= font-weight: bold; and |subgroup_style= color: green; ,
-- the style of group_1.1 will be style="color:green; font-weight: bold; color: red;" ;
-- if we have |group_1.1_style= -- color:red; |subgroup_level_1_style= font-weight: bold; and |subgroup_style= color: green; ,
-- the style of group_1.1 will be style="color: red;" only, and the cascade is no longer performed for |subgroup_level_1_style and |subgroup_style.
function h.mergeAttrs(...)
local trim = mw.text.trim
local s = ''
for i=1, select('#', ...) do
local v = trim(select(i, ...) or '')
local str = string.match(v, '^%-%-+(.*)$')
if str then
s = trim(str..' '..s)
break
else
s = trim(v..' '..s)
end
end
if s == '' then s = nil end
return s
end
 
function h.runHook(key, ...)
if hooks[key] then
hooks[key](...)
end
end
end


-----------------------------------------------
return p
return p
Please note that all contributions to The Petit Planet Wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see Petit Planet Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template
Below are commonly used wikitext from MediaWiki:Edittools. Click on any to insert them in the edit box.
File Pages==Summary====Licensing=={{Fairuse}}{{File|}}
Dynamic Page List¦²«»²{¦}²«»«/»«!----»
Array in DPL¹^2{}^2^2{¹}^2
Parser Functions{{#if:||}}
{{#ifeq:|||}}
{{#expr:}}
{{#switch:||#default=}}
{{#replace:||}}
{{#titleparts:}}
{{#tag:|}}
Markup{{}}|[][[]][[Category:]]#REDIRECT [[]] [[Category:Redirect Pages]]<code></code><includeonly></includeonly><noinclude></noinclude><nowiki></nowiki><!----><br>§
Notices{{Stub|}}{{Stub Dialogue}}{{Upcoming}}{{Under Construction}}{{Placeholder|}}
Magic Words{{!}}{{formatnum:}}{{lc:}}{{uc:}}{{PAGENAME}}{{FULLPAGENAME}}{{ROOTPAGENAME}}{{BASEPAGENAME}}{{SUBPAGENAME}}{{DISPLAYTITLE:|noreplace}}__TOC____NOTOC____EXPECTUNUSEDCATEGORY____HIDDENCAT__
HTML Entities&mdash;&nbsp;&comma;&shy;