Jump to content

Module:Formatting: Difference between revisions

From The Petit Planet Wiki
No edit summary
No edit summary
Line 4: Line 4:
local lib = require('Module:Feature')
local lib = require('Module:Feature')
local search = lib.inArray
local search = lib.inArray
local nw = mw.text.nowiki


function p.main(frame)
function p.main(frame)
Line 11: Line 10:
removeBlanks = false
removeBlanks = false
})
})
local main = args['text'] or args[1]
-- helper function to parse params
local label = args['label'] or args[2] or ''
function FP(arr, val, def, noBlk)
local r_s,r_e,b,i,u_s,u_e,v_s,v_e = '','','','','','','',''
local param = nil
if main == nil then error('A value must be given') end
for _, v in ipairs(arr) do
local nw = mw.text.nowiki
if param == nil and args[v]~=nil then
local out = mw.html.create(lib.ternary(args.NC,'span','code'))
param = val and args[v] or v
if args.block then
end
out:addClass('code-block' .. lib.ternary(main:find('Infobox'),'-table',''))
if not noBlk then
end
args[v]=nil
 
end
--check what to add, leave variable blank if option wasn't enabled
end
if (args['ref'] or args['r']) then
return param or def
r_s = '<ref>'
r_e = '</ref>'
end
if (args['bold'] or args['b']) then
b = "'''"
end
if (args['italic'] or args['i']) then
i = "''"
end
if (args['underline'] or args['u']) then
u_s = '<u>'
u_e = '</u>'
end
if (args['variable'] or args['v']) then
main = tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(nw(main)))
end
if lib.isNotEmpty(label) and (args['variable-label'] or args['vl']) then
label = tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(nw(label)))
end
end


-- Define variables
local prefix = r_s .. b .. i .. u_s
local main = args[1]; assert(main, 'A value must be given'); main = {main, main}
local suffix = u_e .. i .. b .. r_e
local label = FP({'label', 2}, true, '', true); label = {label, label}
local mode = FP({'link', 'l', 'external-link', 'el', 'template', 't'}) or 'plain'
local ret  = FP({'_Ybr_', '_Yn_', '_Y_'}) or 'none'
local spc  = FP({'block'}) or 'inline'
local lprs = FP({'let_parse'}) ~= nil
local code = FP({'NC'}) == nil
local var  = FP({'variable', 'v'}) ~= nil
local esc  = FP({'nowiki', 'nw'}) and nw or (function(a)return a end)
local infobox = FP({'_infobox'}) ~= nil or main[1]:find('Infobox')
local content -- for actual render storage
local final = mw.html.create()
local out  = final:tag('span')
:addClass(table.concat({
'custom-formatting-code',
code and '' or 'custom-formatting-plain',
spc=='block' and ('code-block' .. lib.ternary(infobox,'-table','')) or ''
}, ' '))
-- Define defaults
local joint = ' yields: '
local _d = {
if args['no_joint'] then joint = ' ' end
['pipe'] = '|',
['open'] = ({
if args['_Ybr_'] then
['link'] = '[[', ['l'] = '[[',
joint = joint .. '<br />'
['external-link'] = '[', ['el'] = '[',
elseif args['_Yn_'] then
['template'] = '{{', ['t'] = '{{',
joint = joint .. '\n'
['plain'] = ''
end
})[mode],
['close'] = ({
['link'] = ']]', ['l'] = ']]',
['external-link'] = ']', ['el'] = ']',
['template'] = '}}', ['t'] = '}}',
['plain'] = ''
})[mode],
['join'] = ((
FP({'no_joint'}) or
((mode=='t' or mode=='template') and infobox)
) and '')
or ({
['_Ybr_'] = ' yields:<br>',
['_Yn_'] = ' yields:\n',
['_Y_'] = ' yields: ',
['none'] = ''
})[ret],
ref = FP({'ref', 'r'}) and {'<ref>', '</ref>'} or {'',''},
bold = FP({'bold', 'b'}) and {'<b>', '</b>'} or {'',''},
italic = FP({'italic', 'i'}) and {'<i>', '</i>'} or {'',''},
under = FP({'underline', 'u'}) and {'<u>', '</u>'} or {'',''},
}
_d.prefix = table.concat({ FP({'prefix'},true,''), _d.ref[1], _d.bold[1], _d.italic[1], _d.under[1] }):gsub('{_SP_}', ' '):gsub('{_NL_}', '\n')
_d.suffix = table.concat({ _d.under[2], _d.italic[2], _d.bold[2], _d.ref[2], FP({'suffix'},true,''), }):gsub('{_SP_}', ' '):gsub('{_NL_}', '\n')


-- Variable formatting
--create result as internal link
if var then main[2] = '(('..main[2]..'))' end
if (args['link'] or args['l']) then
if FP({'variable-label', 'vl'})~=nil and lib.isNotEmpty(label[2]) then label[2] = '(('..label[2]..'))' end
if lib.isNotEmpty(label) then
out
--create result as plain text
:wikitext(nw(prefix),nw('[['),p.variableFormat(main),nw('|'),p.variableFormat(label),nw(']]'),nw(suffix))
if mode == 'plain' then
else
out:wikitext(
out
nw(_d.prefix),
:wikitext(nw(prefix),nw('[['),p.variableFormat(main),nw(']]'),nw(suffix))
esc(main[2]),
nw(_d.suffix)
)
if ret ~= 'none' or not code then
content = frame:preprocess(table.concat({
_d.prefix,
main[1],
_d.suffix
}))
end
end
if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
--create result as wiki link
local content = b .. i .. u_s  .. '[[' .. main .. '|' .. (lib.isNotEmpty(label) and label) or main .. ']]' .. u_e .. i .. b
elseif search({'link', 'l'}, mode) then
if (args['ref'] or args['r']) then
out:wikitext(
return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
nw(_d.prefix),
else
nw(_d['open']),
return tostring(out) .. joint .. content
esc(main[2]),
end
lib.isEmpty(label[2]) and '' or
(nw(_d.pipe) .. esc(label[2])),
nw(_d['close']),
nw(_d.suffix)
)
if ret ~= 'none' or not code then
content = frame:preprocess(table.concat({
_d.prefix,
main[1],
(
label[1]=='' and ''
or (_d.pipe .. label[1])
),
_d.suffix
}))
end
end


--create result as external link
--create result as external link
elseif search({'external-link', 'el'}, mode) then
elseif (args['external-link'] or args['el']) then
out:wikitext(
if lib.isNotEmpty(label) then
nw(_d.prefix),
out
nw(_d['open']),
:wikitext(nw(prefix),nw('['),p.variableFormat(nw(mw.text.unstrip(main))),' ',p.variableFormat(label),nw(']'),nw(suffix))
nw(main[2]),
else
lib.isEmpty(label[2]) and '' or
out
(' ' .. esc(label[2])),
:wikitext(nw(prefix),nw('['),p.variableFormat(nw(mw.text.unstrip(main))),nw(']'),nw(suffix))
nw(_d['close']),
nw(_d.suffix)
)
if ret ~= 'none' or not code then
content = frame:preprocess(table.concat({
_d.prefix,
main[1],
(
label[1]=='' and ''
or (' ' .. label[1])
),
_d.suffix
}))
end
end
elseif search({'template', 't'}, mode) then
if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
local content = b .. i .. u_s  .. '[' .. main .. ' ' .. label .. ']' .. u_e .. i .. b
if (args['ref'] or args['r']) then
return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
else
return tostring(out) .. joint .. content
end
end
 
elseif (args['template'] or args['t']) then
local SPECIAL = {'_Y_','_Ybr_','_Yn_','let_parse','block','t','template','NC','ref','r','b','boid','i','italic','u','underline','v','variable'}
local yieldargs = {}
local yieldargs = {}
local pre = main[1]
local pre = main
local t_prefix = lib.split(pre, ':')[1]
if not main:find('User:') then
if not lib.inArray({'User', 'U', 'Project', 'Petit Planet Wiki'}, t_prefix) then
pre = 'Template:' .. main
pre = 'Template:' .. pre
end
end
out:wikitext(
main = '[[' .. pre .. '|' .. main:gsub(' ','&nbsp;') .. ']]'
nw(_d.prefix),
 
nw(_d['open']),
'[[', pre, '|', main[2]:gsub(' ','&nbsp;'), ']]'
)
--template call with params
--template call with params
if p.checkParams(args) then
if p.checkParams(args,SPECIAL) then
--open fake template call
out
:wikitext(nw(prefix),nw('{{'),main)
local param = 1
local param = 1
while (args['V'..param] or args['v'..param] or args['P' .. param] or args['p' .. param] or args[param+1]) do
while (args['v'..param] or args['P' .. param] or args['p' .. param] or args[param+1]) do
local _p = FP({'V'..param, 'v'..param, 'P' .. param, 'p' .. param, param+1}, nil, nil, true)
--variable input format
local _v = FP({'V'..param, 'v'..param, 'P' .. param, 'p' .. param, param+1}, true)
if args['v'..param] then
local sett = {
local parse = p.parseParam(args['v'..param])
p      = _p,
 
v      = _v,
if args.block then
cmmt  = FP({_p..'_comment'}, true),
out:wikitext('<br />')
prefix = FP({_p..'_pref'}, true) or (spc=='block' and '<br>') or '',
end
suffix = FP({_p..'_suff'}, true) or '',
 
parse = lprs or search({'V', 'P'}, (tostring(_p):sub(1,1))),
--named param format
var    = var or search({'V', 'v'}, (tostring(_p):sub(1,1))),
if parse.value then
param = p.parseParam(_v, _p)
out
}
:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing),'= ',tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(p.NewLineAllow(parse.value, args.let_parse))))
out:wikitext(sett.prefix)
 
if sett.cmmt then
--unnamed param format
out:wikitext('<br>((!-- ', nw(sett.cmmt), ' --))<br>')
else
out
:wikitext(nw('|'),tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(p.NewLineAllow(parse.name, args.let_parse))))
end
args['v' .. param] = nil
 
--fixed input format
elseif (args['p' .. param] or args[param+1]) then
local value = args['p' .. param] or args[param+1]
local parse = p.parseParam(value)
 
if args.block then
out:wikitext('<br />')
end
 
--named param format
if parse.value then
yieldargs[parse.name] = mw.text.unstrip(parse.value)
out
:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing),'= ',p.NewLineAllow(p.variableFormat(parse.value), args.let_parse))
 
--unnamed param format
else
yieldargs[param] = mw.text.unstrip(parse.name)
out
:wikitext(nw('|'),p.NewLineAllow(p.variableFormat(parse.name), args.let_parse))
end
--set values to nil for yield to ignore them
if args['p' .. param] then args['p' .. param] = nil end
if args[param+1] then args[param+1] = nil end
--fixed input format, default let parse
elseif args['P' .. param] then
local value = args['P' .. param]
local parse = p.parseParam(value)
 
if args.block then
out:wikitext('<br />')
end
 
--named param format
if parse.value then
yieldargs[parse.name] = mw.text.unstrip(parse.value)
out
:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing), '= ', p.NewLineAllow(p.variableFormat(parse.value), true))
 
--unnamed param format
else
yieldargs[param] = mw.text.unstrip(parse.name)
out
:wikitext(nw('|'),p.NewLineAllow(p.variableFormat(parse.name), true))
end
--set values to nil for yield to ignore them
args['P' .. param] = nil
end
end
out:wikitext(nw(_d.pipe))
 
--named param only
if type(sett.param.name) == 'string' and sett.param.name ~= sett.p then
out
:tag('b'):wikitext(nw(sett.param.name)):done()
:wikitext(string.rep('&nbsp;',sett.param.spacing),'=&nbsp;')
end
out:wikitext(
sett.var and '((' or '',
p.NewLineAllow(sett.param.value, sett.parse),
sett.var and '))' or ''
)
out:wikitext(sett.suffix)
-- store param value
yieldargs[sett.param.name] = mw.text.unstrip(sett.param.value)
--increase count for the next 'while' loop
--increase count for the next 'while' loop
param = param + 1
param = param + 1
Line 200: Line 183:
for n,v in pairs(args) do
for n,v in pairs(args) do
if (n ~= 1) then
if (n ~= 1 and not search(SPECIAL,n)) then
out:wikitext(
(spc=='block' and '<br>') or '',
nw(_d.pipe),'<b>',nw(n),'</b> = ',
p.NewLineAllow(v, lprs)
)
yieldargs[n] = mw.text.unstrip(v)
yieldargs[n] = mw.text.unstrip(v)
if args.block then
out:wikitext('<br />')
end
out:wikitext(nw('|'),'<b>',p.variableFormat(nw(n)),'</b> = ',p.NewLineAllow(p.variableFormat(v),args.let_parse))
end
end
end
end
if args.block then
out:wikitext('<br />')
end
--close fake template call and all the selected items
out
:wikitext(nw('}}'),nw(suffix))
--template call without params
else
out
:wikitext(nw(prefix),nw('{{'),main,nw('}}'),nw(suffix))
end
end
out:wikitext((spc=='block' and '<br>') or '', nw(_d['close']), nw(_d.suffix))


-- auto template result for examples
--auto fake template usage for examples
if ret~='none' or not code then
if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
content = _d.prefix .. frame:expandTemplate{title = main[1], args = yieldargs} .. _d.suffix
frame = frame or mw.getCurrentFrame()
local param = 1
local content = b .. i .. u_s .. frame:expandTemplate{title = (args['text'] or args[1]),args = yieldargs} .. u_e .. i .. b
if args.block then
joint = '<br />' .. joint
end
if (args['ref'] or args['r']) then
return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
else
if main:find('Infobox') then
return content .. tostring(out)
else
return tostring(out) .. joint .. content
end
end
end
end
end
 
--create plain text result
if content and (ret ~= 'none' or not code) then
else
if content:find('<ref') then
if (args['nowiki'] or args['nw']) then
local c_p,c_r,c_s = string.match(content, '^(.-)<ref>(.-)</ref>(.-)$')
out
content = c_p .. frame:extensionTag{ name = 'ref', content = c_r } .. c_s
:wikitext(nw(prefix),p.variableFormat(nw(main)),nw(suffix))
else
out
:wikitext(nw(prefix),p.variableFormat(main),nw(suffix))
end
end
if ret ~= 'none' then
if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
if infobox then
local content = b .. i .. u_s  .. main .. u_e .. i .. b
final = mw.html.create()
if (args['ref'] or args['r']) then
:wikitext(content)
return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
:node(final)
else
else
final:wikitext(
return tostring(out) .. joint .. content
(spc=='block' and '<br>' or ' '),
_d.join,
content
)
end
end
elseif not code then
out:addClass('custom-formatting-nested')
final:tag('span'):addClass('custom-formatting-resulting'):wikitext(content)
end
end
end
end
 
-- Parse keywords
--return completed result
final = tostring(final):gsub('{_SP_}', ' '):gsub('{_NL_}', '\n')
return tostring(out)
final = p.variableFormat(final)
 
return final
end
end


function p.parseParam(param, pName)
function p.parseParam(param)
local tmp = param
    local tmp = param
local name, value, spacing = '','',1
    local name, value, spacing = '','',' '
 
-- the parameter's name is anything to the left of the first equals sign;
    -- the parameter's name is anything to the left of the first equals sign;
-- the equals sign can be escaped, for wikis that don't have [[Template:=]]
    -- the equals sign can be escaped, for wikis that don't have [[Template:=]]
if tmp:find('=') then
    if tmp:find('=') then
name, spacing, value = string.match(tmp,'^(.-)(%s*)=%s*(.-)$')
        name, spacing, value = string.match(tmp,'^(.-)(%s*)=%s*(.-)$')
if string.len(spacing) == 0 then spacing = 1 else spacing = string.len(spacing) end
        if string.len(spacing) == 0 then spacing = 1 else spacing = string.len(spacing) end
else
    else
name = type(pName)=='number'
    name = tmp
and (pName-1)
    value = false
or tonumber((pName:gsub('[^%d]+', '')))
    end
value = tmp
    return {
end
    name = name,
return {
    value = value,
name = name,
    spacing = spacing
value = value,
    }
spacing = spacing
}
end
end


Line 273: Line 272:
while (textin:find('%(%(') and textin:find('%)%)')) do
while (textin:find('%(%(') and textin:find('%)%)')) do
local textrp = string.match(textin,'%(%((.-)%)%)')
local textrp = string.match(textin,'%(%((.-)%)%)')
textin = textin:gsub('%(%(.-%)%)',tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(textrp)),1)
textin = textin:gsub('%(%(.-%)%)',tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(mw.text.nowiki(textrp))),1)
end
end
return textin
return textin
end
end


function p.checkParams(args)
function p.checkParams(args,SPECIAL)
for n,v in pairs(args) do
for n,v in pairs(args) do
if (n ~= 1 and v~=nil) then
if (n ~= 1 and not search(SPECIAL,n)) then
return true
return true
end
end
Line 288: Line 287:


--helper function to allow new line format in template calls in block format, as directly allowing makes the <code> container break
--helper function to allow new line format in template calls in block format, as directly allowing makes the <code> container break
function p.NewLineAllow(str, parse)
function p.NewLineAllow(str,parse)
local container = mw.html.create()
local container = mw.html.create()
local nw = mw.text.nowiki
local nw = mw.text.nowiki
if str:find('[\n\r]') then
if str:find('[\n\r]') then
str = str:gsub('[\n\r]', '¤¤¤'):gsub('¤¤¤$', '')
str = str:gsub('[\n\r]', '¤¤¤')
local splitstr = mw.text.split(str, '¤¤¤', true )
local splitstr = mw.text.split(str, '¤¤¤', true )
for i,v in ipairs(splitstr) do
for i,v in ipairs(splitstr) do
Line 299: Line 298:
container:wikitext(v)
container:wikitext(v)
if i ~= #splitstr then
if i ~= #splitstr then
container:wikitext('<br>')
container:wikitext('<br />')
end
end
end
end

Revision as of 10:50, 9 November 2025

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

-- Source: https://genshin-impact.fandom.com/wiki/Module:Formatting

local p = {}
local lib = require('Module:Feature')
local search = lib.inArray

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		parentFirst = true,
		removeBlanks = false
	})
	local main = args['text'] or args[1]
	local label = args['label'] or args[2] or ''
	local r_s,r_e,b,i,u_s,u_e,v_s,v_e = '','','','','','','',''
	if main == nil then error('A value must be given') end
	local nw = mw.text.nowiki
	local out = mw.html.create(lib.ternary(args.NC,'span','code'))
	if args.block then
		out:addClass('code-block' .. lib.ternary(main:find('Infobox'),'-table',''))
	end

	--check what to add, leave variable blank if option wasn't enabled
	if (args['ref'] or args['r']) then
		r_s = '<ref>'
		r_e = '</ref>'
	end
	if (args['bold'] or args['b']) then
		b = "'''"
	end
	if (args['italic'] or args['i']) then
		i = "''"
	end
	if (args['underline'] or args['u']) then
		u_s = '<u>'
		u_e = '</u>'
	end
	if (args['variable'] or args['v']) then
		main = tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(nw(main)))
	end
	if lib.isNotEmpty(label) and (args['variable-label'] or args['vl']) then
		label = tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(nw(label)))
	end

	local prefix = r_s .. b .. i .. u_s
	local suffix = u_e .. i .. b .. r_e
	
	local joint = ' yields: '
	if args['no_joint'] then joint = ' ' end
	
	if args['_Ybr_'] then
		joint = joint .. '<br />'
	elseif args['_Yn_'] then
		joint = joint .. '\n'
	end

	--create result as internal link
	if (args['link'] or args['l']) then
		if lib.isNotEmpty(label) then
			out
				:wikitext(nw(prefix),nw('[['),p.variableFormat(main),nw('|'),p.variableFormat(label),nw(']]'),nw(suffix))
		else
			out
				:wikitext(nw(prefix),nw('[['),p.variableFormat(main),nw(']]'),nw(suffix))
		end
		if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
			local content = b .. i .. u_s  .. '[[' .. main .. '|' .. (lib.isNotEmpty(label) and label) or main .. ']]' .. u_e .. i .. b
			if (args['ref'] or args['r']) then
				return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
			else
				return tostring(out) .. joint .. content
			end
		end

	--create result as external link
	elseif (args['external-link'] or args['el']) then
		if lib.isNotEmpty(label) then
			out
				:wikitext(nw(prefix),nw('['),p.variableFormat(nw(mw.text.unstrip(main))),' ',p.variableFormat(label),nw(']'),nw(suffix))
		else
			out
				:wikitext(nw(prefix),nw('['),p.variableFormat(nw(mw.text.unstrip(main))),nw(']'),nw(suffix))
		end
		if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
			local content = b .. i .. u_s  .. '[' .. main .. ' ' .. label .. ']' .. u_e .. i .. b
			if (args['ref'] or args['r']) then
				return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
			else
				return tostring(out) .. joint .. content
			end
		end

	elseif (args['template'] or args['t']) then
		local SPECIAL = {'_Y_','_Ybr_','_Yn_','let_parse','block','t','template','NC','ref','r','b','boid','i','italic','u','underline','v','variable'}
		local yieldargs = {}
		local pre = main
		if not main:find('User:') then
			pre = 'Template:' .. main
		end
		main = '[[' .. pre .. '|' .. main:gsub(' ','&nbsp;') .. ']]'

		--template call with params
		if p.checkParams(args,SPECIAL) then
			
			--open fake template call
			out
				:wikitext(nw(prefix),nw('{{'),main)
			local param = 1
			while (args['v'..param] or args['P' .. param] or args['p' .. param] or args[param+1]) do
				--variable input format
				if args['v'..param] then
					local parse = p.parseParam(args['v'..param])

					if args.block then
						out:wikitext('<br />')
					end

					--named param format
					if parse.value then
						out
							:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing),'= ',tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(p.NewLineAllow(parse.value, args.let_parse))))

					--unnamed param format
					else
						out
							:wikitext(nw('|'),tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(p.NewLineAllow(parse.name, args.let_parse))))
					end
					args['v' .. param] = nil

				--fixed input format
				elseif (args['p' .. param] or args[param+1]) then
					local value = args['p' .. param] or args[param+1]
					local parse = p.parseParam(value)

					if args.block then
						out:wikitext('<br />')
					end

					--named param format
					if parse.value then
						yieldargs[parse.name] = mw.text.unstrip(parse.value)
						out
							:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing),'= ',p.NewLineAllow(p.variableFormat(parse.value), args.let_parse))

					--unnamed param format
					else
						yieldargs[param] = mw.text.unstrip(parse.name)
						out
							:wikitext(nw('|'),p.NewLineAllow(p.variableFormat(parse.name), args.let_parse))
					end
					
					--set values to nil for yield to ignore them
					if args['p' .. param] then args['p' .. param] = nil end
					if args[param+1] then args[param+1] = nil end
				--fixed input format, default let parse
				elseif args['P' .. param] then
					local value = args['P' .. param]
					local parse = p.parseParam(value)

					if args.block then
						out:wikitext('<br />')
					end

					--named param format
					if parse.value then
						yieldargs[parse.name] = mw.text.unstrip(parse.value)
						out
							:wikitext(nw('|'),'<b>',p.variableFormat(nw(parse.name)),'</b>',string.rep('&nbsp;',parse.spacing), '= ', p.NewLineAllow(p.variableFormat(parse.value), true))

					--unnamed param format
					else
						yieldargs[param] = mw.text.unstrip(parse.name)
						out
							:wikitext(nw('|'),p.NewLineAllow(p.variableFormat(parse.name), true))
					end
					
					--set values to nil for yield to ignore them
					args['P' .. param] = nil
				end

				--increase count for the next 'while' loop
				param = param + 1
			end
			
			for n,v in pairs(args) do
				if (n ~= 1 and not search(SPECIAL,n)) then
					yieldargs[n] = mw.text.unstrip(v)
					if args.block then
						out:wikitext('<br />')
					end
					out:wikitext(nw('|'),'<b>',p.variableFormat(nw(n)),'</b> = ',p.NewLineAllow(p.variableFormat(v),args.let_parse))
				end
			end

			if args.block then
				out:wikitext('<br />')
			end

			--close fake template call and all the selected items
			out
				:wikitext(nw('}}'),nw(suffix))

		--template call without params
		else
			out
				:wikitext(nw(prefix),nw('{{'),main,nw('}}'),nw(suffix))
		end

		--auto fake template usage for examples
		if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
			frame = frame or mw.getCurrentFrame()
			local param = 1
			local content = b .. i .. u_s .. frame:expandTemplate{title = (args['text'] or args[1]),args = yieldargs} .. u_e .. i .. b
			if args.block then
				joint = '<br />' .. joint
			end
			if (args['ref'] or args['r']) then
				return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
			else
				if main:find('Infobox') then
					return content .. tostring(out)
				else
					return tostring(out) .. joint .. content
				end
			end
		end

	--create plain text result
	else
		if (args['nowiki'] or args['nw']) then
			out
				:wikitext(nw(prefix),p.variableFormat(nw(main)),nw(suffix))
		else
			out
				:wikitext(nw(prefix),p.variableFormat(main),nw(suffix))
		end
		if (args['_Ybr_'] or args['_Y_'] or args['_Yn_']) then
			local content = b .. i .. u_s  .. main .. u_e .. i .. b
			if (args['ref'] or args['r']) then
				return tostring(out) .. joint .. frame:extensionTag{ name = 'ref', content = content}
			else
				return tostring(out) .. joint .. content
			end
		end
	end

	--return completed result
	return tostring(out)

end

function p.parseParam(param)
    local tmp = param
    local name, value, spacing = '','',' '

    -- the parameter's name is anything to the left of the first equals sign;
    -- the equals sign can be escaped, for wikis that don't have [[Template:=]]
    if tmp:find('=') then
        name, spacing, value = string.match(tmp,'^(.-)(%s*)=%s*(.-)$')
        if string.len(spacing) == 0 then spacing = 1 else spacing = string.len(spacing) end
    else
    	name = tmp
    	value = false
    end
    return {
    	name = name,
    	value = value,
    	spacing = spacing
    }
end

function p.variableFormat(textin)
	while (textin:find('%(%(') and textin:find('%)%)')) do
		local textrp = string.match(textin,'%(%((.-)%)%)')
		textin = textin:gsub('%(%(.-%)%)',tostring(mw.html.create():tag("span"):addClass('variable'):wikitext(mw.text.nowiki(textrp))),1)
	end
	return textin
end

function p.checkParams(args,SPECIAL)
	for n,v in pairs(args) do
		if (n ~= 1 and not search(SPECIAL,n)) then
			return true
		end
	end
	return false
end

--helper function to allow new line format in template calls in block format, as directly allowing makes the <code> container break
function p.NewLineAllow(str,parse)
	local container = mw.html.create()
	local nw = mw.text.nowiki
	
	if str:find('[\n\r]') then
		str = str:gsub('[\n\r]', '¤¤¤')
		local splitstr = mw.text.split(str, '¤¤¤', true )
		for i,v in ipairs(splitstr) do
			if not parse then v = nw(v) end
			container:wikitext(v)
			if i ~= #splitstr then
				container:wikitext('<br />')
			end
		end
		return tostring(container)
	else
		if not parse then str = nw(str) end
		return str
	end
end

return p