Module:Args: Difference between revisions

From Zelda Dungeon Wiki
Jump to navigation Jump to search
Want an adless experience? Log in or Create an account.
(change fromPageContent to use expandInto instead of parseInto, and trim whitespace from key and value)
(support value and table collisions in 'expand'; add fromFrame function)
Line 11: Line 11:
function Arg:val()
function Arg:val()
   return self.__value
   return self.__value
end
-- get the value at the given key of this Arg node
function Arg:get( key )
  return self[key] and self[key]:val()
end
end


Line 52: Line 57:
end
end


-- place the value in the right spot in the arg tree, determined by underscores in the key
function p.expandInto( args, key, value )
function p.expandInto( args, key, value )
   local first, rest = string.match( key, '^(.-)_(.*)$' )
   local first, rest = string.match( key, '^(.-)_(.*)$' )
Line 58: Line 64:


   if first then -- this is an internal node so insert children
   if first then -- this is an internal node so insert children
    -- note this will overwrite values in the case of { arg = 'val', arg_sub = 'val' }
     args[myKey] = type( args[myKey] ) == 'table' and args[myKey] -- already a table
     args[myKey] = type( args[myKey] ) == 'table' and args[myKey] or {}
      or args[myKey] and { __value = args[myKey] } -- move existing value into a new table
      or {} -- create new table
     p.expandInto( args[myKey], rest, value )
     p.expandInto( args[myKey], rest, value )
   else -- this is a leaf so set value
   else -- this is a leaf so set value
     args[myKey] = args[myKey] or value -- don't overwrite a table
     if type( args[myKey] ) == 'table' then args[myKey].__value = value
    else args[myKey] = value
    end
   end
   end
end
end


-- expand the arg tree for the given flattened args
function p.expand( args )
function p.expand( args )
   local expandedArgs = {}
   local expandedArgs = {}
Line 75: Line 85:
end
end


-- get the value at the given node, in case the node contains a table
function p.getValue( val )
  return type( val ) == 'table' and val.__value or val
end
-- expand the arg tree from the given frame and its parent
function p.fromFrame( frame )
  local parsedArgs = Arg.new()
  for k, v in pairs( frame.args ) do
    p.expandInto( parsedArgs, k, v )
  end
  local parentFrame = frame:getParent()
  if parentFrame and parentFrame.args then
    for k, v in pairs (parentFrame.args ) do
      p.expandInto( parsedArgs, k, v )
    end
  end
  return parsedArgs
end
-- parse and expand the arg tree for the given template on the given page
function p.fromPageContent( content, templateName )
function p.fromPageContent( content, templateName )
   templateName = templateName or 'Properties'
   templateName = templateName or 'Properties'

Revision as of 20:40, June 26, 2020

Documentation for this module may be created at Module:Args/doc

local Arg = {}
Arg.__index = Arg

function Arg.new( value )
  return setmetatable( {
    __value = value
  }, Arg )
end

-- get the Arg node's value, if it has one
function Arg:val()
  return self.__value
end

-- get the value at the given key of this Arg node
function Arg:get( key )
  return self[key] and self[key]:val()
end

-- get the values of the Arg node's direct children
-- this is used to re-flatten/unwrap a particular piece of an Arg tree
function Arg:values()
  local vals = {}
  for k, v in pairs( self ) do
    if type( v ) == 'table' and v.val then
      vals[k] = v:val()
    end
  end

  return vals
end

local p = {}

function insertInto( tbl, key, value )
  local first, rest = string.match( key, '^(.-)_(.*)$' )
  local myKey = first or key
  myKey = tonumber( myKey ) or myKey

  -- make sure the node exists
  if not tbl[myKey] then tbl[myKey] = Arg.new() end

  if first then -- this is an internal node so insert children
    insertInto( tbl[myKey], rest, value )
  else -- this is a leaf so set value
    tbl[myKey].__value = value
  end
end

function p.parse( args )
  local parsedArgs = Arg.new()
  for k, v in pairs( args ) do
    insertInto( parsedArgs, k, v )
  end

  return parsedArgs
end

-- place the value in the right spot in the arg tree, determined by underscores in the key
function p.expandInto( args, key, value )
  local first, rest = string.match( key, '^(.-)_(.*)$' )
  local myKey = first or key
  myKey = tonumber( myKey ) or myKey

  if first then -- this is an internal node so insert children
    args[myKey] = type( args[myKey] ) == 'table' and args[myKey] -- already a table
      or args[myKey] and { __value = args[myKey] } -- move existing value into a new table
      or {} -- create new table
    p.expandInto( args[myKey], rest, value )
  else -- this is a leaf so set value
    if type( args[myKey] ) == 'table' then args[myKey].__value = value
    else args[myKey] = value
    end
  end
end

-- expand the arg tree for the given flattened args
function p.expand( args )
  local expandedArgs = {}
  for k, v in pairs( args ) do
    p.expandInto( expandedArgs, k, v )
  end

  return expandedArgs
end

-- get the value at the given node, in case the node contains a table
function p.getValue( val )
  return type( val ) == 'table' and val.__value or val
end

-- expand the arg tree from the given frame and its parent
function p.fromFrame( frame )
  local parsedArgs = Arg.new()

  for k, v in pairs( frame.args ) do
    p.expandInto( parsedArgs, k, v )
  end

  local parentFrame = frame:getParent()
  if parentFrame and parentFrame.args then
    for k, v in pairs (parentFrame.args ) do
      p.expandInto( parsedArgs, k, v )
    end
  end

  return parsedArgs
end

-- parse and expand the arg tree for the given template on the given page
function p.fromPageContent( content, templateName )
  templateName = templateName or 'Properties'
  local parsedArgs = {}

  local templateContents = string.match( content, '{{%s*' .. templateName .. '%s*|%s*(.-)%s*}}' )

  if templateContents then
    for prop in mw.text.gsplit( templateContents, '%s*|%s*' ) do
      local k, v = unpack( mw.text.split( prop, '%s*=%s*' ) )
      p.expandInto( parsedArgs, k, v )
    end
  end

  return parsedArgs
end

return p