Module:Subpages 6
Documentation for this module may be created at Module:Subpages 6/doc
local sp = {}
local pageorder = {
["trope"] = {
"Analysis", "Haiku", "Headscratchers", "Image Links", "Laconic",
"Playing With", "Quotes", "Useful Notes"
},
["work"] = {
"Analysis", "Characters", "Laconic", "Recap", "Trivia", "Setting", "YMMV",
"Fridge", "Fanfic Recs", "Haiku", "Headscratchers", "Ho Yay", "Image Links",
"Memes", "Radar", "Quotes", "Source", "Useful Notes", "WMG"
},
["creator"] = {"YMMV", "Quotes", "Fanfic Recs", "Analysis", "Trivia", "WMG",
"Image Links", "Haiku", "Laconic"}
}
local crowners = {
["trope"] = { "Advertising", "Anime and Manga", "Comic Books", "Fan Works",
"Film", "Literature", "Live-Action TV", "Music", "Newspaper Comics",
"Oral Tradition", "Professional Wrestling", "Puppet Shows", "Radio",
"Recorded and Stand Up Comedy", "Tabletop Games", "Theatre", "Toys",
"Video Games", "Web Animation", "Web Comics", "Web Original",
"Western Animation", "Other Media", "Real Life" },
["work"] = { "Awesome", "Awesome Music", "Funny", "Heartwarming",
"Nightmare Fuel", "Tear Jerker" },
["creator"] = { "Awesome", "Funny", "Heartwarming", "Nightmare Fuel", "Tear Jerker" }
}
local crownername = {
["trope"] = "By Medium",
["work"] = "Crowners",
["creator"] = "Crowners"
}
local addns = {
["trope"] = { },
["work"] = { "Reviews" },
["creator"] = { }
}
-- localize functions
local insert = table.insert
local concat = table.concat
local find = string.find
local len = string.len
local sub = string.sub
local rep = string.rep
local listlevel = { '*', '**', '***', '****', '*****' }
-- This function is the main page menu type, with dropdowns for subpages
function sp.menu ( frame )
local page = frame.args[1] or frame:callParserFunction('TOPLEVELPAGE')
local template = frame.args[2] or "work"
local wppage = frame.args[3] or page
local nowp = (frame.args[4] ~= "" )
if wppage == "" then wppage = page end
-- create variant top level page variables
local mainpage = page;
if template == "index" then
template = "trope"
crowners["trope"] = {}
mainpage = ":" .. page
page = page:gsub("Category:", "", 1)
end
local pageslash = page..'/'
if pageorder[template] == nil then return "Module error: invalid template argument" end
local allsptxt = frame:callParserFunction('SUBPAGES', { page, sep = "|" })
local subpage_list = split(allsptxt, "|")
local tree = build_tree(page, subpage_list)
-- initialize result with Main link
local linkout = { '* [[' .. mainpage .. '|<span id="tm-main"></span>Main]]\n' }
local crownerout = { }
local otherout = { }
local missingout = { }
local linkns = { }
local missingns = { }
for _, subpage in ipairs(pageorder[template]) do
text = build_list( { [subpage] = tree[subpage] }, pageslash, 1 )
if text ~= '' then
insert(linkout, text)
else
insert(missingout, subpage)
end
tree[subpage] = nil
end
for _, subpage in ipairs(crowners[template]) do
text = build_list( { [subpage] = tree[subpage] }, pageslash, 2 )
if text ~= '' then
-- Don't use "by medium" section on works because it's too hard to list
-- everything, but do provide a standard selection for the create page menu below
if template ~= 'trope' then insert(crownerout, text) end
else
insert(missingout, subpage)
end
tree[subpage] = nil
end
--deal with the leftover subpages
if next(tree) then
local ordered_keys = {}
for k in pairs(tree) do
insert(ordered_keys, k)
end
table.sort(ordered_keys)
for i = 1, #ordered_keys do
local subpage = ordered_keys[i]
text = build_list( { [subpage] = tree[subpage] }, pageslash, 2 )
if text ~= '' then
insert(otherout, text)
end
end
end
for _, ns in ipairs(addns[template]) do
local tobj = mw.title.new( page, ns )
if tobj.exists then
insert(linkns, '* [[' .. tobj.fullText .. '|<span id="tm-'..ns..'"></span>'..ns .. ']]\n')
else
insert(missingns, ns)
end
end
local jsdata = '<div id="tm-data" style="display:none" '
.. 'data-toplevelpage="' .. page .. '" '
.. 'data-wanted="' .. concat( missingout, "	" ) .. '" '
.. 'data-nswanted="' .. concat( missingns, "	" ) .. '" '
.. 'data-templatetype="' .. template .. '" '
.. '></div>'
local crowner_link = next(crownerout)
and '* [[#top|<span id="tm-' .. crownername[template].. '"></span>'..crownername[template]..']]\n'
or ''
local wikipedia_link = nowp
and ''
or "* [[wikipedia:" .. wppage ..
'|<span id="tm-Wikipedia"'.. (frame.args[3] == "" and ' class="tm-wpdefault"' or '') ..'></span>Wikipedia]]\n'
local all_sp_link = '* [[Special:PrefixIndex/' .. pageslash .. '|<span id="tm-Allothers"></span>All Subpages]]\n'
local italictitle = ( template == "work" )
and italictitle(frame, page)
or ''
return concat(linkout)
.. concat(linkns)
.. crowner_link
.. concat(crownerout)
.. wikipedia_link
.. all_sp_link
.. concat(otherout)
.. '* <strong><span id="tm-New"></span>Create New</strong><ul id="tm-wantedpages"></ul>\n'
.. jsdata
.. italictitle
end
-- Another output function, which makes an ordinary bullet tree of subpages
function sp.tree ( frame )
local page = frame.args[1] or frame:callParserFunction('TOPLEVELPAGE')
local filter = frame.args['filter'] or ''
local allsptxt = frame:callParserFunction('SUBPAGES', { page, sep = "|" })
local subpage_list = split(allsptxt, "|")
local tree = build_tree(page, subpage_list)
if filter ~= '' then
for _, subpage in ipairs(pageorder[filter]) do tree[ subpage ] = nil end
if filter ~= 'trope' then
for _, subpage in ipairs(crowners[filter]) do tree[ subpage ] = nil end
end
end
if page:match("^Category:") then page = ":"..page end
local thispage = mw.title.getCurrentTitle().text ~= page
and "; [["..page.."]]\n" or ''
return thispage .. build_list( tree, page..'/', 1 )
end
-- transforms an array (table) of subpages into a tree data structure
function build_tree ( page, subpage_list )
local path_tree = { }
local pagelenoffset = len(page) + 2
for _, fullpath in ipairs(subpage_list) do
local path = sub(fullpath, pagelenoffset)
local list = split(path, '/')
local lastdir = path_tree
for i, dir in ipairs(list) do
if lastdir[dir] == nil then lastdir[dir] = { } end
lastdir = lastdir[dir]
end
end
return path_tree
end
-- given a tree of subpages, outputs an indented list
-- recursively calls itself to build deeper trees
function build_list ( tree, prefix, level )
local libase = listlevel[level] or rep('*', level)
local ul = {}
local ordered_sp = {}
for page in pairs(tree) do
insert(ordered_sp, page)
end
table.sort(ordered_sp)
for i = 1, #ordered_sp do
local page = ordered_sp[i]
local branch = tree[page]
local li
if level <= 2 then
li = libase .. " [["..prefix..page..'|<span id="tm-'..page..'"></span>'..page..']]\n'
else
li = libase ..' [['..prefix..page..'|'..page..']]\n'
end
insert(ul, li)
if next(branch) then
local nextprefix = (prefix..page..'/')
insert(ul, build_list(branch, nextprefix, level+1))
end
end
return concat(ul)
end
-- split() implementation reproduced from, uh, somewhere
function split(str, sSeparator, nMax, bRegexp)
assert(sSeparator ~= '')
assert(nMax == nil or nMax >= 1)
local aRecord = {}
if len(str) > 0 then
local bPlain = not bRegexp
nMax = nMax or -1
local nField=1 nStart=1
local nFirst,nLast = find(str, sSeparator, nStart, bPlain)
while nFirst and nMax ~= 0 do
aRecord[nField] = sub(str, nStart, nFirst-1)
nField = nField+1
nStart = nLast+1
nFirst,nLast = find(str, sSeparator, nStart, bPlain)
nMax = nMax-1
end
aRecord[nField] = sub(str, nStart)
end
return aRecord
end
-- for work type pages, italicizes the title of the work
function italictitle(frame, basepage)
local title = mw.title.getCurrentTitle()
-- don't italicize subpages
-- but we can't just naively split on '/' due to top level pages with slashes
local subpages = (len(title.text) > len(basepage))
and sub(title.text, len( mw.text.decode(basepage, 1))+1 ) or ''
-- Find the parts before and after the disambiguation parentheses, if any.
local prefix, parentheses = mw.ustring.match(basepage, '^(.+) (%([^%(%)]+%))$')
-- If parentheses were found, italicise only the part before them. Otherwise
-- italicise the whole title.
local result
if prefix and parentheses then
result = "''" .. prefix .. "'' " .. parentheses .. subpages
else
result = "''" .. basepage .. "''" .. subpages
end
-- Add the namespace if we're not in mainspace.
if title.namespace ~= 0 then
result = mw.site.namespaces[title.namespace].name .. ':' .. result
end
-- Call displaytitle with the text we generated.
return mw.getCurrentFrame():callParserFunction(
'DISPLAYTITLE',
result
)
end
return sp