Модуль:Рейтинги альбома

Реализует {{Рейтинги альбома}}.


-- This module implements [[Template:Album ratings]].

local mTableTools = require('Module:TableTools')
local yesno = require('Module:Yesno')
local p = {}

local function makeCell(html, s)
	html
		:tag('td')
			:wikitext(s)
end

local function makeRow(review, score)
	local row = mw.html.create('tr')
	makeCell(row, review)
	makeCell(row, score)
	return row
end

local function makeHeaderRow(header, class, scope)
	local row = mw.html.create('tr')
	row
		:tag('th')
			:attr('scope', scope ~= false and 'colgroup' or nil)
			:attr('colspan', 2)
			:addClass(class)
			:wikitext(header)
	return row
end

local function makeRatingHeaderRow()
	local row = mw.html.create('tr')
	row
		:addClass('ts-Рейтинги_альбома-ratingHeader')
		:tag('th')
			:attr('scope', 'col')
			:wikitext('Источник')
			:done()
		:tag('th')
			:attr('scope', 'col')
			:wikitext('Оценка')
	return row
end

local function getArgPermutations(args, prefix, num, suffix)
	local langEnObj = mw.language.new('en')
	local prefixUpper = langEnObj:ucfirst(prefix)
	local suffixUpper = langEnObj:ucfirst(suffix)
	return args[prefix .. num .. suffix] or
		args[prefixUpper .. num .. suffix] or
		args[prefix .. num .. suffixUpper] or
		args[prefixUpper .. num .. suffixUpper]
end

local function findSortText(wikitext)
	-- Simplified wikitext parser that returns a value that can be used for
	-- sorting.
	wikitext = mw.text.killMarkers(wikitext)
	-- Replace piped links with their display values
	wikitext = wikitext:gsub('%[%[[^%]]*|([^%]]-)%]%]', '%1')
	-- Replace non-piped links with their display values
	wikitext = wikitext:gsub('%[%[([^%]]-)%]%]', '%1')
	-- Strip punctuation
	wikitext = wikitext:gsub('%p', '')
	-- Trim whitespace
	wikitext = wikitext:gsub('^%s*', ''):gsub('%s*$', '')
	return wikitext
end

function p._main(args)
	local root = mw.html.create()
	local tableRoot = root:tag('table')
	
	local align = args.align
	local width = args.width
	local state = args['состояние'] or args['state']
	local title = args.title or args['заголовок']
	local subtitle = args.subtitle or args['подзаголовок']

	-- Table base
	tableRoot
		:addClass('wikitable')
		:addClass('ts-Рейтинги_альбома')
		:addClass( (align == 'left') and 'floatleft' or 'floatright' )
		:css('width', width)
		:tag('th')
			:attr('scope', 'colgroup')
			:attr('colspan', 2)
			:addClass('bright')
			:tag('div')
				:addClass('ts-Рейтинги_альбома-mainHeader-content')
				:wikitext(title or 'Рецензии')
		
	
	if state ~= 'plain' then
		if state == 'collapsed' then 
			state = 'mw-collapsed'
		end
		tableRoot
			:addClass('mw-collapsible')
			:addClass(state)
	end

	-- Subtitle
	if subtitle then
		tableRoot:node(makeHeaderRow(subtitle, nil, false))
	end

	-- Aggregate rows
	local aggregateNums = mTableTools.affixNums(args, 'aggregate')
	if args.MC or args.ADM or #aggregateNums > 0 then
		tableRoot:node(makeHeaderRow('Совокупная оценка', 'highlight', true))
		tableRoot:node(makeRatingHeaderRow())

		-- Assemble all of the aggregate scores
		local aggregates = {}
		if args.MC then
			table.insert(aggregates, {
				name = '[[Metacritic]]',
				sort = 'Metacritic',
				score = args.MC,
			})
		end
		if args.ADM then
			table.insert(aggregates, {
				name = '[[AnyDecentMusic?]]',
				sort = 'AnyDecentMusic?',
				score = args.ADM,
			})
		end
		for i, num in ipairs(aggregateNums) do
			local name = args['aggregate' .. num]
			local sort = findSortText(name)
			local score = args['aggregate' .. num .. 'score']
			table.insert(aggregates, {
				name = name,
				sort = sort,
				score = score,
			})
		end

		-- Sort the aggregates
		if not args.aggregatenosort then
			table.sort(aggregates, function (t1, t2)
				return t1.sort < t2.sort
			end)
		end

		-- Add the aggregates to the HTML
		for i, t in ipairs(aggregates) do
			tableRoot:node(makeRow(t.name, t.score))
		end
	end

	-- Review rows
	local reviewNums = mTableTools.affixNums(args, 'rev')
	local _reviewNums = mTableTools.affixNums(args, 'ист')
	for i, v in ipairs(_reviewNums) do
		reviewNums[#reviewNums + 1] = v
	end
	mTableTools.removeDuplicates(reviewNums)
	table.sort(reviewNums)
	
	local reviewNumsForeign = mTableTools.affixNums(args, 'ин')
	local reviewNumsRu = mTableTools.affixNums(args, 'рус')
	
	local duplicateScores = false
	tableRoot:node(makeHeaderRow('Оценки критиков', 'highlight', true))
	tableRoot:node(makeRatingHeaderRow())
	for _, num in ipairs(reviewNums) do
		local review = args['ист' .. num] or args['rev' .. num]
		local score = args['рейт' .. num] or getArgPermutations(args, 'rev', num, 'score')
		tableRoot:node(makeRow(review, score))
	end
	
	if #reviewNumsRu > 0 then
		tableRoot:node(makeHeaderRow('Русскоязычные издания', 'ts-Рейтинги_альбома-subheader', true))
		for _, num in ipairs(reviewNumsRu) do
			tableRoot:node(makeRow(args['рус' .. num], args['русрейт' .. num]))
		end
	end
	
	if #reviewNumsForeign > 0 then
		tableRoot:node(makeHeaderRow('Иноязычные издания', 'ts-Рейтинги_альбома-subheader', true))
		for _, num in ipairs(reviewNumsForeign) do
			tableRoot:node(makeRow(args['ин' .. num], args['инрейт' .. num]))
		end
	end

	return tostring(root)
end

function p.main(frame)
	local args = require('Module:Arguments').getArgs(frame, {
		wrappers = 'Шаблон:Рейтинги альбома'
	})
	local templatestyles = frame:extensionTag{
		name = 'templatestyles',
		args = { src = 'Модуль:Рейтинги альбома/styles.css' }
	}
	return templatestyles .. p._main(args)
end

return p