Module:Listing: Difference between revisions

From Zelda Dungeon Wiki
Jump to navigation Jump to search
Want an adless experience? Log in or Create an account.
(add Listbox class to be inherited by Navbox and Galbox)
(split sections into top-level items and groups with second-level items)
Line 51: Line 51:
     content = "",
     content = "",
     summary = "",
     summary = "",
     sections = {}
     sections = {},
    topLevelLeaves = {}, -- i.e. L2 sections with no children
    groups = {} -- i.e. L2 sections that have children
   }
   }
   local currentSection = root
   local currentSection = root
Line 84: Line 86:
       contentBackfillSection = contentBackfillSection.parent
       contentBackfillSection = contentBackfillSection.parent
     until not contentBackfillSection
     until not contentBackfillSection
  end
  -- split sections into top-level items and groups with second-level items
  for _, section in root.sections do
    if #section.sections then
      root.groups[#root.groups + 1] = section
    else
      root.topLevelLeaves[#topLevelLeaves + 1] = section
    end
   end
   end



Revision as of 19:33, July 25, 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

local Listbox = Box.new()
Listbox.__index = Listbox
setmetatable( Listbox, Box )

function Listbox.new( args )
  local subject = args[1] .. ' ' .. args[2]
  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[1], subject, args[2] }
  return setmetatable( obj, Listbox )
end

local p = {}

p.Listbox = Listbox

function p._parseListing( pageName, pageContent )
  local pageContent = pageContent or mw.title.new( pageName ):getContent()
  local root = {
    level = 1,
    name = pageName,
    content = "",
    summary = "",
    sections = {},
    topLevelLeaves = {}, -- i.e. L2 sections with no children
    groups = {} -- i.e. L2 sections that have children
  }
  local currentSection = root

  -- can't think of a regex to split sections so go line by line
  for line in gsplit( pageContent, '\n' ) do
    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
  end

  -- split sections into top-level items and groups with second-level items
  for _, section in root.sections do
    if #section.sections then
      root.groups[#root.groups + 1] = section
    else
      root.topLevelLeaves[#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] = 'User:Locke/Sandbox/Listing'
  }
}

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