Mô đun:WikiProject banner

require('strict')
local p = {}
local sandbox-- = '/sandbox' -- BE SURE TO COMMENT OUT this definition when deploying to live
local cfg = mw.loadData('Module:WikiProject banner/config' .. (sandbox or ))
local auxiliary = cfg.auxiliary_module .. (sandbox or )
local args_module = require('Module:Arguments')
local mbox = require('Module:Message box').main
local yesno = require('Module:Yesno')
local frame = mw.getCurrentFrame()
local lang = mw.getLanguage(cfg.language)
local current_title = mw.title.getCurrentTitle()
local parameter_format = function(parameter, value)
	return frame:expandTemplate{title='para', args={parameter, value or }}
end
local wikilink = function(link, display)
	if link then
		return display and ..display.. or ..link..
	else
		return display or 
	end
end
local display_error = function(text)
	local span = mw.html.create('div')
		:addClass('error')
		:wikitext(text)
	return tostring(span)	
end
local image = function(image_name, size, alt, position)
	return image_name and 'alt=' .. alt or )
		.. 
end
local if_exists = function(target, fallback) -- function to add wikilink if target exists
	local title = mw.title.new(target)
	if title and title.exists then
		return wikilink(target)
	else
		return fallback or target
	end
end
local importance_mask = function(raw_importance, scale, banner_name, pagetype, class)
---------------------------
-- Importance mask --------
---------------------------
local importance
if scale=='inline' then -- pass importance without change
	importance = raw_importance
elseif scale=='subpage' then
	local custom_mask = banner_name:subPageTitle('importance')
	if custom_mask.exists and #custom_mask:getContent()>1 then -- pass to custom importance mask
		importance = mw.text.trim(frame:expandTemplate{
			title = custom_mask.prefixedText,
			args = {
				importance = raw_importance or '¬',
				class = class,
				pagetype = pagetype
			}
		})
	end
elseif raw_importance then-- standard importance scale
	importance = cfg.importance.na
	if pagetype=='article' or pagetype=='set index article' or pagetype=='redirect' or pagetype=='draft' then
		local mask = cfg.importance.mask
		if maskraw_importance:lower() then -- valid importance specified
			importance = maskraw_importance:lower()
		elseif pagetype=='article' or pagetype=='set index article' then -- unspecified or invalid importance, use "Unknown" for articles
			importance = cfg.importance.unknown
		end
	end
end
return importance
end
---------------------------
-- Quality class mask -----
---------------------------
p.readarticleclass = function(options, page) -- used by _main and also Module:Banner shell
	page = page or current_title.prefixedText
	local get_parameter_value = require('Module:Template parameter value').getParameter
	local success, result = get_parameter_value(page, cfg.banner_shell.redirects, 'class', options)
	return success and result
	-- returns FALSE if banner shell template does not exist on page
	-- returns BLANK if class parameter is not defined or is defined blank
	-- otherwise returns class parameter
end
p.class_mask = function(class, title, FQS, pagetype, article)
	local resolveFQSgrade = function(class)
		return FQS and lang:ucfirst(class) or 'NA'
	end
	local out
	title = title or mw.title.getCurrentTitle()
	local ns = title.namespace
	class = class:match('^%s*(.-)%s*$'):lower()
	if pagetype=='redirect' or pagetype=='soft redirect' then
		out = resolveFQSgrade('redirect')
	elseif pagetype=='disambiguation page' then
		out = resolveFQSgrade('disambig')
	elseif article or pagetype=='article' or pagetype=='set index article' then
		if pagetype=='set index article' then
			out = 'List'
		elseif class=='start' or class=='stub' then -- Ucfirst
			out = lang:ucfirst(class)
		elseif class=='b' or class=='c' or class=='fa' or class=='fl' or class=='a' or class=='ga' then -- Upper-case
			out = class:upper()
		elseif class=='list' or class=='sia' or class=='si' or class=='sl' then-- List
			out = 'List'
		else
			out =  -- unassessed
		end
	elseif ns==7 or ns==711 then -- File talk
		if class=='fm' then
			out = 'FM'
		else
			out = resolveFQSgrade('file')
		end
	else
	    local grade = cfg.quality.ns_to_classns or 'NA'
		out = resolveFQSgrade(grade)
	end
	return out
end
local page_assessment = function(project, class, importance) -- add PageAssessments parser function
	local assessment = table.concat({project, class or , importance or },'|')
	frame:preprocess()
end
local bubble = function(text, conflict, style)
	local out = mw.html.create('span')
		:addClass('wpb-header-bubbles')
		:addClass(style)
		:addClass(conflict and 'conflict' or nil)
		:wikitext(text)
	return tostring(out)
end
p._main = function(args, raw_args, demo_page, banner_name, inactive)
---------------------------
-- Initialise parameters --
---------------------------
local project = args.PROJECT or 'PROJECT'
local project_name = args.PROJECT_NAME or 'WikiProject ' .. project
local project_link = mw.title.new(args.PROJECT_LINK or 'Wikipedia:' .. project_name)
local pagetype = demo_page==true and 'article' or require('Module:Pagetype')._main({
	page = demo_page,
	dab = 'disambiguation page',
	sia = 'set index article',
	draft = 'draft'
})
local article = pagetype=='article' or pagetype=='set index article'
local rows, nested_ratings, task_forces, notes, categories, taskforce_categories = {}, {}, {}, {}, {}, {}
local add_category = function(category, key)
	if category and category~='none' then
		table.insert(categories, {category = category, key = key})
	end
end
local parse_pt = function(text) -- function to replace _PAGETYPE_ with the actual page type
	local ptype = article and 'article' or pagetype -- display "article" for articles otherwise page type
	return text and text:gsub('_PAGETYPE_', ptype)
end
for arg_name, arg_value in pairs(args) do
	local tf_match = mw.ustring.match(arg_name,'^tf (%d+)$')
	local note_match = mw.ustring.match(arg_name,'^note (%d+)$')
	if tf_match and yesno(arg_value, true) then
		table.insert(task_forces, tf_match)
	elseif note_match and yesno(arg_value, true) then
		table.insert(notes, note_match)
	else
		local tf, cat = mw.ustring.match(arg_name,'^tf (%d+) cat (%d+)$')
		if tf and yesno(arg_value, true) then
			if not taskforce_categoriestf then -- initialise table
				taskforce_categoriestf = {}
			end
			table.insert(taskforce_categoriestf, cat)
		end
	end
end
table.sort(task_forces, function (x, y) return tonumber(x) '
	)
	warning = warning .. mbox('ombox', {
		image = '40px',
		type = cfg.subst_warning.type_,
		text = text,
	}) .. cfg.subst_warning.categories
end
---------------------------
-- Primary image/text -----
---------------------------
local primary_image = function(image_name, size)
	local cell = mw.html.create('td')
	if image_name and image_name~= then
		cell:addClass('mbox-image wpb-image')
			:wikitext(image(image_name, size, cfg.image.alt))
	else
		cell:addClass('mbox-empty-cell')
	end
	return cell
end
local portal = args.PORTAL
local portal_box = portal and frame:expandTemplate{title='Portal', args={portal}} or 
local main_text = portal_box .. parse_pt(args.MAIN_TEXT or cfg.main_text:format(
	project_link.prefixedText,
	project_name,
	args.MAIN_ARTICLE and if_exists(args.MAIN_ARTICLE) or if_exists(project, project .. ' articles'),
	project_link.talkPageTitle.prefixedText
))
local image_left_size = args.IMAGE_LEFT_SIZE or cfg.image.default_size
local metadata = function(class, data)
	return mw.html.create('span')
		:addClass(class)
		:wikitext(data)
end
local text_cell = mw.html.create('td')
	:addClass('mbox-text')
	:wikitext(main_text)
	:tag('span')
		:addClass('metadata wpb-metadata')
		:node(metadata('wpb-project', project))
		:node(metadata('wpb-project_link', project_link.prefixedText))
		:node(metadata('wpb-banner_name', banner_name.prefixedText))
		:node(metadata('wpb-assessment_cat', assessment_cat))
	:done()
local primary_row = mw.html.create('tr')
	:node(primary_image(args.IMAGE_LEFT, image_left_size))
	:node(text_cell)
	:node(primary_image(args.IMAGE_RIGHT, args.IMAGE_RIGHT_SIZE or cfg.image.default_size))
table.insert(rows, primary_row)
---------------------------
-- Banner shell checks ----
---------------------------
local title = demo_page and demo_page~=true and mw.title.new(demo_page) or current_title
local article_class = p.readarticleclass({ignore_subtemplates=true}, title.prefixedText)
if article_class then -- banner shell exists
	local special_chars = '(%%%(%)%.%+%-%*%?%%%^%$)'
	local banner_name_escaped = banner_name.text
	local page_content = require('Module:Wikitext Parsing').PrepareText(title:getContent()) -- get content of current page
	local content_without_shell
	for capture in mw.ustring.gmatch(page_content, '%b{}') do -- look for possible templates on page
		for _, redirect in ipairs(cfg.banner_shell.redirects) do
			if mw.ustring.find(capture, '^}$') then -- found a banner shell
				banner_name_escaped = banner_name_escaped:gsub(special_chars, '%%%1') -- escape each special character
				capture = capture:gsub(special_chars, '%%%1')
				content_without_shell = mw.ustring.gsub(page_content, capture, ) -- remove banner shell content from page content
			end
			if content_without_shell then break end
		end
		if content_without_shell then break end
	end
	local template_outside_shell
	if content_without_shell and mw.ustring.find(content_without_shell, '