Module:Listing: Difference between revisions
Jump to navigation
Jump to search
Want an adless experience? Log in or Create an account.
(support single arg ("The Legend of Zelda Characters" instead of "The Legend of Zelda|Characters"), and parse categories from the listing page) |
(remove remaining staging checks (WW Enemies, HW Characters). Migration is complete.) |
(6 intermediate revisions by the same user not shown) | |
(No difference)
|
Latest revision as of 03:10, August 14, 2020
Documentation for this module may be created at Module:Listing/doc
local Args = require( 'Module:Args' ) local Box = require( 'Module:Box' ).Box -- got this from http://lua-users.org/wiki/SplitJoin -- idk how it works but it's 100x more performant than mw.text.gsplit function gsplit(s,sep) local lasti, done, g = 1, false, s:gmatch('(.-)'..sep..'()') return function() if done then return end local v,i = g() if s == '' or sep == '' then done = true return s end if v == nil then done = true return s:sub(lasti) end lasti = i return v end end function handleLine( line, currentSection ) local headingLevel, headingText = string.match( line, '^%s*(=+)%s*(.-)%s*=+$' ) if headingLevel then -- line is a heading local newSection = { level = #headingLevel, name = headingText, content = "", summary = "", sections = {} } -- find the right parent and insert while currentSection.level >= #headingLevel do currentSection = currentSection.parent end newSection.parent = currentSection currentSection.sections[#currentSection.sections + 1] = newSection currentSection = newSection elseif #currentSection.sections == 0 then -- no child headings yet so this is part of the summary of the current section currentSection.summary = currentSection.summary .. line .. '\n' end -- add to content of all parent sections, plus current section if line isn't a heading local contentBackfillSection = headingLevel and currentSection.parent or currentSection repeat contentBackfillSection.content = contentBackfillSection.content .. line .. '\n' contentBackfillSection = contentBackfillSection.parent until not contentBackfillSection -- determine if line is a category local cat = string.match( line, '^%s*%[%[Category:(.-)]]%s*$' ) cat = cat and mw.text.split( cat, '|' )[1] return currentSection, cat end local Navbox = Box.new() Navbox.__index = Navbox setmetatable( Navbox, Box ) function Navbox.new( args ) local subject = args[2] and (args[1] .. ' ' .. args[2]) or args[1] args.class = 'navbox' args.title = '[[' .. subject .. ']]' args.edit = subject args.hide = args.hide or 'show' local obj = Box.new( 'light', args ) obj.subject = subject obj.categories = args[2] and { args[1], subject, args[2] } or {} -- will be set later when parsing the page return setmetatable( obj, Navbox ) end local p = {} p.Navbox = Navbox function p._parseListing( pageName, pageContent ) local pageContent = pageContent or mw.text.killMarkers( mw.getCurrentFrame():expandTemplate{ title = ':' .. pageName, args = {} } ) local root = { level = 1, name = pageName, content = "", summary = "", sections = {}, categories = {}, topLevelLeaves = {}, -- i.e. L2 sections with no children groups = {} -- i.e. L2 sections that have children } local currentSection = root local cat = nil -- can't think of a regex to split sections so go line by line for line in gsplit( pageContent, '\n' ) do currentSection, cat = handleLine( line, currentSection ) if cat and cat ~= "Listings" then root.categories[#root.categories + 1] = cat end end -- split sections into top-level items and groups with second-level items for _, section in ipairs( root.sections ) do if #section.sections > 0 then root.groups[#root.groups + 1] = section else root.topLevelLeaves[#root.topLevelLeaves + 1] = section end end return root end function p.bullets( frame ) local listing = p._parseListing( frame.args[1] ) local bullets = mw.html.create( 'ul' ) for _, section in ipairs( listing.sections ) do local sublist = bullets:tag( 'li' ) :wikitext( section.name ) :tag( 'ul' ) for _, subsection in ipairs( section.sections ) do sublist:tag( 'li' ):wikitext( subsection.name ) end end return tostring( bullets ) end p.debugFrame = { args = { [1] = 'The Legend of Zelda Locations' } } p.debugContent = [[ Summary {{Infobox|thing=value}} == First Section == Section 1 summary {{Template|prop=val}} === Subsection of First Section === Subsection 1 content {{Template|prop=val}} == Second Section == Section 2 summary {{Template|prop=val}} === Subsection of Second Section === Subsection 2 content {{Template|prop=val}} {{Cat}} ]] return p