Module:Subpages 5

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"] = { "Animation", "Animated Films", "Anime", "Anime and Manga", "Board Games", "Comics", "Comic Books", "Fan Works", "Fanfic", "Fanfiction", "Fan Fiction", "Film", "Folklore", "Literature", "Live Action Television", "Live Action TV", "Machinima", "Manga", "Manga and Anime", "Music", "Musicians", "New Media", "Opera", "Professional Wrestling", "Puppet Shows", "Radio", "Tabletop Games", "Tabletop RPGs", "Television", "TV", "Theatre", "Theater", "Toys", "Webcomics", "Video Games", "Visual Art", "Visual Novels", "Web Original", "Web Animation", "Web Comics", "Websites", "Western Animation", "Wikis", "Wrestling", "Other", "Real Life" }, ["work"] = { "Awesome", "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 = { '* 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 insert(crownerout, text) 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, '* '..ns .. '\n') else insert(missingns, ns) end end

local jsdata = ' '	local crowner_link = next(crownerout) and '*  '..crownername[template]..'\n' or '' local wikipedia_link = nowp and '' or "*  Wikipedia\n' local all_sp_link = '* 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) .. '* Create New \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 allsptxt = frame:callParserFunction('SUBPAGES', { page, sep = "|" }) local subpage_list = split(allsptxt, "|")

local tree = build_tree(page, subpage_list)

if page:match("^Category:") then page = ":"..page end return "; "..page.."\n" .. 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 .. " '..page..'\n' else li = libase ..' '..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