Module:Command: Difference between revisions

From Modded Wiki
Jump to navigation Jump to search
Correctly support optional parameters
mNo edit summary
 
(31 intermediate revisions by 9 users not shown)
Line 1: Line 1:
local p = {}
local p = {}
function p.cmd( f )
function p.cmd( f )
local args = f:getParent().args
local args = f
local syntax = mw.loadData( 'Module:Command/Syntax' )
if f == mw.getCurrentFrame() then
local command
args = f:getParent().args
end
--if args.be then
--local syntax = mw.loadData( 'Module:Command/SyntaxBE' )
--else
local syntax = mw.loadData( 'Module:Command/Syntax')
--end
local fullCommand
local commandName = args[1]:match( '^%s*/?([^%s]+)' ):lower()
local params = {}
local command = {}
args[1] = mw.text.trim( args[1] )
--getparams
if args[1]:find( '%s' ) or not syntax[args[1]] then
for i, v in ipairs( args ) do
command = { args[1]:match( '^([^%s]-)%s(.+)$' ) }
if not args[i+1] and v == '...' then
fullCommand = true
if #command == 0 then
elseif i > 1 or v:match( '^%s*/?(.+)' ):lower() ~= commandName then
command = { args[1], args[2] }
table.insert( params, mw.text.trim( v ) )
end
end
end
end
if not command then
 
command = { args[1] }
local needFormat = false
if ( fullCommand or args[2] or args[1]:match('?') ) and syntax['command'..commandName] then
needFormat = true
end
end
command[1] = command[1]:lower()
 
--escape space and split args
if args[2] and syntax[args[1]] then
if #params == 1 and ( not args[2] or args[2] == '...' ) and params[1]:find( '%s' ) then
local fullCommand
params[1] = params[1]:match( '^[^%s]+%s(.+)' )
for _, v in ipairs( args ) do
if v == '...' then
if needFormat then
fullCommand = true
params[1] = params[1]:gsub( '\\\\', '\\' ):gsub( '\\"', '\"' ):gsub( "\\'", '\'' ):gsub( '(@[aesprcv])%s+(%[)', '%1%2' )
while(true) do
local startPos, endPos = params[1]:find( "'[^']-'" )
local startPosn, endPosn = params[1]:find('"[^"]-"')
if startPosn and startPos and startPosn < startPos then
startPos, endPos = startPosn, endPosn
end
if not startPos then
startPos, endPos = params[1]:find( '"[^"]+"' )
if not startPos then
startPos, endPos = params[1]:find( '%b[]' )
if not startPos then
startPos, endPos = params[1]:find( '%b{}' )
if not startPos then
startPos, endPos = params[1]:find( '&lt;!%-%- Command %-%->.+&lt;!%-%- /Command %-%->' )
end
end
end
end
if startPos then
params[1] = params[1]:sub( 1, startPos - 1 ) ..
params[1]:sub( startPos, endPos ):gsub('%[','〈lsqb〉'):gsub('%]','〈rsqb〉'):gsub('{','&#123;'):gsub('}','&#125;'):gsub("'",'〈apos〉'):gsub('"','〈quot〉'):gsub( '%s', '〈space〉' ) ..
params[1]:sub( endPos + 1 )
else
break
end
end
end
params = mw.text.split( params[1], '%s+' )
end
end
end
local arg = 1
function parseParams( params, sub )
if needFormat then
local param = 0
function parseParams( defaultParams )
local section = {}
local section = {}
local hasValue
local hasValue
for i, v in ipairs( params ) do
local prefix
for i, v in pairs( defaultParams or {} ) do
if type( v ) == 'table' then
if type( v ) == 'table' then
local subSection, subHasValue = parseParams( v, true )
param = param + 1
if subHasValue then
for k,j in pairs(v) do
hasValue = true
v = j
prefix = k
break
end
end
table.insert( section, subSection )
if params[param] and params[param] ~= '' and params[param]~='?' then
else
hasValue = false
arg = arg + 1
for k,j in pairs(v) do
if j == params[param] or j:match('<.+>') then
-- Skip "..." arg
table.insert(section, params[param])
if args[arg] and args[arg] == '...' then
hasValue=true
arg = arg + 1
if k=='redirect' then
param = param - 1
table.insert(section, parseParams(syntax[j:match('<(.+)>')]))
else
table.insert(section, parseParams(syntax[prefix..j]))
end
break
end
end
if not hasValue then
params = {}
break
end
else
params = {}
local option = {}
local swap
for _,j in pairs(v) do
if fullCommand then
swap = {j,parseParams(syntax[prefix..j])}
table.insert(option, table.concat(swap,' '))
else
table.insert(option, j)
end
end
table.insert(section, '('..table.concat(option, '|')..')')
end
end
elseif i == 'redirect' then
if args[arg] then
if params[param+1] then
hasValue = true
table.insert(section, parseParams(syntax[v]))
args[arg] = mw.text.trim( args[arg] )
elseif v:match("^command$") then
if args[arg] ~= '' and args[arg] ~= '?' then
table.insert(section, "-> ''"..v.."''")
args[arg] = args[arg]:gsub( '<', '&lt;' )
else
table.insert( section, args[arg] )
table.insert(section, "-> ''"..v:match('command(.+)').."''")
end
end
end
if not section[i] then
else
table.insert( section, v )
param = param + 1
if params[param] and params[param] ~= '' and params[param] ~= '?' then
table.insert(section,params[param])
else
table.insert(section, v)
end
end
end
if not fullCommand and not params[param+1] then
break
end
end
end
end
section = table.concat( section, ' ' )
section = table.concat( section, ' ' )
if section == '' then
section = nil
end
if sub and not hasValue then
return section
if fullCommand then
end
section = '(' .. section .. ')'
else
command = { parseParams( syntax['command'..commandName] ) }
section = nil
-- Add any extra parameters not defined in the syntax
if #params > param then
for i, v in ipairs( params ) do
if i > param then
table.insert( command, v )
end
end
end
end
return section, hasValue
end
end
else
command[2] = parseParams( syntax[syntax[command[1]]] or syntax[command[1]] )
command = params
end
end
if args.link then
if args.link then
if args.link:lower() ~= 'none' then
if args.link:lower() ~= 'none' then
command[1] = '[[' .. args.link .. '|' .. command[1] .. ']]'
commandName = '[[' .. args.link .. '|' .. commandName .. ']]'
end
end
else
else
command[1] = '[[Commands#' .. command[1] .. '|' .. command[1] .. ']]'
commandName = '[[Commands/' .. commandName .. '|' .. commandName .. ']]'
end
end
table.insert( command, 1, commandName )
local slash = '/'
local slash = '/'
Line 87: Line 173:
end
end
local attr
local attr = ''
if args.long == '1' then
if args.long then
attr = 'style="display:block;padding:0.8em 1em;margin-bottom:0.4em;word-wrap:break-word"'
attr = 'style="display: flex; padding: 0.8em 1em; margin-bottom: 0.4em; word-warp: break-word;"'
else
attr = 'class="nowrap"'
end
end
return '<code ' .. attr .. '>' .. slash .. table.concat( command, ' ' ) .. '</code>'
local result = table.concat( command, ' ' ):gsub( '〈space〉', ' ' ):gsub('〈lsqb〉', '%['):gsub('〈rsqb〉', '%]'):gsub('〈apos〉',"'"):gsub('〈quot〉','"')
-- Don't encode if told not to or if there is a sub-command
if args.escape ~= '0' then
result = result:gsub( '<', '&lt;' ):gsub( '&lt;(!%-%- Command %-%->)&lt;','<%1<'):gsub( '&lt;/code>&lt;(!%-%- /Command %-%->)','</code><%1')
end
result = '<!-- Command --><code ' .. attr .. '><span>' .. slash .. result .. '</span></code><!-- /Command -->'
    if needFormat then
        result = result .. '[[Category:Pages using deprecated command module]]'
    end
    return result
end
end
return p
return p

Latest revision as of 14:34, 1 May 2024

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

local p = {}
function p.cmd( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	end
	--if args.be then
		--local syntax = mw.loadData( 'Module:Command/SyntaxBE' )
	--else
		local syntax = mw.loadData( 'Module:Command/Syntax')
	--end
	local fullCommand
	local commandName = args[1]:match( '^%s*/?([^%s]+)' ):lower()
	local params = {}
	local command = {}
	
	--getparams
	for i, v in ipairs( args ) do
		if not args[i+1] and v == '...' then
			fullCommand = true
		elseif i > 1 or v:match( '^%s*/?(.+)' ):lower() ~= commandName then
			table.insert( params, mw.text.trim( v ) )
		end
	end

	local needFormat = false
	if ( fullCommand or args[2] or args[1]:match('?') ) and syntax['command'..commandName] then
		needFormat = true
	end

	--escape space and split args
	if #params == 1 and ( not args[2] or args[2] == '...' ) and params[1]:find( '%s' ) then
		params[1] = params[1]:match( '^[^%s]+%s(.+)' )
		
		if needFormat then
		
			params[1] = params[1]:gsub( '\\\\', '&bsol;&bsol;' ):gsub( '\\"', '&bsol;&quot;' ):gsub( "\\'", '&bsol;&apos;' ):gsub( '(@[aesprcv])%s+(%[)', '%1%2' )
		
			while(true) do
				local startPos, endPos = params[1]:find( "'[^']-'" )
				local startPosn, endPosn = params[1]:find('"[^"]-"')
				if startPosn and startPos and startPosn < startPos then
					startPos, endPos = startPosn, endPosn
				end
				if not startPos then
					startPos, endPos = params[1]:find( '"[^"]+"' )
					if not startPos then
						startPos, endPos = params[1]:find( '%b[]' )
						if not startPos then
							startPos, endPos = params[1]:find( '%b{}' )
							if not startPos then
								startPos, endPos = params[1]:find( '&lt;!%-%- Command %-%->.+&lt;!%-%- /Command %-%->' )
							end
						end
					end
				end
				
				if startPos then
					params[1] = params[1]:sub( 1, startPos - 1 ) ..
						params[1]:sub( startPos, endPos ):gsub('%[','〈lsqb〉'):gsub('%]','〈rsqb〉'):gsub('{','&#123;'):gsub('}','&#125;'):gsub("'",'〈apos〉'):gsub('"','〈quot〉'):gsub( '%s', '〈space〉' ) ..
						params[1]:sub( endPos + 1 )
				else
					break
				end
			end
		
			params = mw.text.split( params[1], '%s+' )
		end
	end
	
	if needFormat then
		local param = 0
		function parseParams( defaultParams )
			local section = {}
			local hasValue
			local prefix
			for i, v in pairs( defaultParams or {} ) do
				if type( v ) == 'table' then
					param = param + 1
					for k,j in pairs(v) do
						v = j
						prefix = k
						break
					end
					if params[param] and params[param] ~= '' and params[param]~='?' then
						hasValue = false
						for k,j in pairs(v) do
							if j == params[param] or j:match('<.+>') then
								table.insert(section, params[param])
								hasValue=true
								if k=='redirect' then
									param = param - 1
									table.insert(section, parseParams(syntax[j:match('<(.+)>')]))
								else
									table.insert(section, parseParams(syntax[prefix..j]))
								end
								break
							end
						end
						if not hasValue then
							params = {}
							break
						end
					else
						params = {}
						local option = {}
						local swap
						for _,j in pairs(v) do
							if fullCommand then
								swap = {j,parseParams(syntax[prefix..j])}
								table.insert(option, table.concat(swap,' '))
							else
								table.insert(option, j)
							end
						end
						table.insert(section, '('..table.concat(option, '|')..')')
					end
				elseif i == 'redirect' then
					if params[param+1] then
						table.insert(section, parseParams(syntax[v]))
					elseif v:match("^command$") then
						table.insert(section, "-> ''"..v.."''")
					else
						table.insert(section, "-> ''"..v:match('command(.+)').."''")
					end
				else
					param = param + 1
					if params[param] and params[param] ~= '' and params[param] ~= '?' then
						table.insert(section,params[param])
					else
						table.insert(section, v)
					end
				end
				if not fullCommand and not params[param+1] then
					break
				end
			end
			
			section = table.concat( section, ' ' )
			if section == '' then
				section = nil
			end
			
			return section
		end
		
		command = { parseParams( syntax['command'..commandName] ) }
		
		-- Add any extra parameters not defined in the syntax
		if #params > param then
			for i, v in ipairs( params ) do
				if i > param then
					table.insert( command, v )
				end
			end
		end
	else
		command = params
	end
	
	if args.link then
		if args.link:lower() ~= 'none' then
			commandName = '[[' .. args.link .. '|' .. commandName .. ']]'
		end
	else
		commandName = '[[Commands/' .. commandName .. '|' .. commandName .. ']]'
	end
	table.insert( command, 1, commandName )
	
	local slash = '/'
	if args['/'] == '0' or args.slash == '0' then
		slash = ''
	end
	
	local attr = ''
	if args.long then
		attr = 'style="display: flex; padding: 0.8em 1em; margin-bottom: 0.4em; word-warp: break-word;"'
	end
	
	local result = table.concat( command, ' ' ):gsub( '〈space〉', ' ' ):gsub('〈lsqb〉', '%['):gsub('〈rsqb〉', '%]'):gsub('〈apos〉',"'"):gsub('〈quot〉','"')
	-- Don't encode if told not to or if there is a sub-command
	if args.escape ~= '0' then
		result = result:gsub( '<', '&lt;' ):gsub( '&lt;(!%-%- Command %-%->)&lt;','<%1<'):gsub( '&lt;/code>&lt;(!%-%- /Command %-%->)','</code><%1')
	end
	result = '<!-- Command --><code ' .. attr .. '><span>' .. slash .. result .. '</span></code><!-- /Command -->'
    if needFormat then
        result = result .. '[[Category:Pages using deprecated command module]]'
    end
    return result
end
return p