Module:Args: Difference between revisions
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 | ||
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] | 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