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.
(comment out some things to try to reduce cpu usage... this doesn't seem like it should be so expensive though)
(remove remaining staging checks (WW Enemies, HW Characters). Migration is complete.)
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
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 = {}
local p = {}


function p._parseListing( pageName )
p.Navbox = Navbox
   local pageContent = mw.title.new( pageName ):getContent()
 
function p._parseListing( pageName, pageContent )
   local pageContent = pageContent or mw.text.killMarkers( mw.getCurrentFrame():expandTemplate{ title = ':' .. pageName, args = {} } )
   local root = {
   local root = {
     level = 1,
     level = 1,
Line 8: Line 87:
     content = "",
     content = "",
     summary = "",
     summary = "",
     sections = {}
     sections = {},
    categories = {},
    topLevelLeaves = {}, -- i.e. L2 sections with no children
    groups = {} -- i.e. L2 sections that have children
   }
   }
   local currentSection = root
   local currentSection = root
  local cat = nil


   -- can't think of a regex to split sections so go line by line
   -- can't think of a regex to split sections so go line by line
   for line in mw.text.gsplit( pageContent, '\n' ) do
   for line in gsplit( pageContent, '\n' ) do
     local headingLevel, headingText = string.match( line, '^%s*(=+)%s*(.-)%s*=+$' )
     currentSection, cat = handleLine( line, currentSection )
     if headingLevel then -- line is a heading
     if cat and cat ~= "Listings" then root.categories[#root.categories + 1] = cat end
      local newSection = {
  end
        level = #headingLevel,
        name = headingText,
        content = "",
        summary = "",
        sections = {}
      }


      -- find the right parent and insert
  -- split sections into top-level items and groups with second-level items
      while currentSection.level >= #headingLevel do
  for _, section in ipairs( root.sections ) do
        currentSection = currentSection.parent
    if #section.sections > 0 then
      end
       root.groups[#root.groups + 1] = section
       newSection.parent = currentSection
    else
      currentSection.sections[#currentSection.sections + 1] = newSection
       root.topLevelLeaves[#root.topLevelLeaves + 1] = section
       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
     end
    -- add to content of all parent sections, plus current section if line isn't a heading
-- content currently isn't needed so disabling this for perf
--    local contentBackfillSection = headingLevel and currentSection.parent or currentSection
--    repeat
--      contentBackfillSection.content = contentBackfillSection.content .. line .. '\n'
--      contentBackfillSection = contentBackfillSection.parent
--    until not contentBackfillSection
   end
   end


Line 63: Line 129:
p.debugFrame = {
p.debugFrame = {
   args = {
   args = {
     [1] = 'User:Locke/Sandbox/Listing'
     [1] = 'The Legend of Zelda Locations'
   }
   }
}
}

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