Aller au contenu

Module:Bacasable

Une page de Wikipédia, l'encyclopédie libre.
Ceci est une version archivée de cette page, en date du 1 avril 2018 à 15:01 et modifiée en dernier par Hlm Z. (discuter | contributions). Elle peut contenir des erreurs, des inexactitudes ou des contenus vandalisés non présents dans la version actuelle.

 Documentation[créer] [purger]
local p = {}

-- * [pairs(args)] itère sur un couple (clé, valeur).
-- * [ipairs(args)] itère sur un couple (index, valeur) et ignore les clés,
--   s'arrète si valeur = nil.
-- * [mw.dumpObject(o)] et [ou mw.logObject(o)] affichent le contenu de o.

-- HtmlBuilder
local function creerEntete(html)
	html
		:tag('div')
			:addClass('entete')
			:wikitext('Entête')
end

function p.creerCorps(args)
	local res = mw.html.create('div'):addClass('infobox')
	creerEntete(res)

	return tostring(res)
end


-- Création d'bjet
local objet = {}

objet.__index = objet

function objet.creerObjet()
	local res = {a = 1, b = false, c}
	return setmetatable(res, objet)
end

function objet:setB(b)
	self.b = b
end

function objet.__tostring(t)
	return t.a .. tostring(t.b) .. tostring(t.c)
end

function p.main2()
	local o = objet.creerObjet()
	o:setB(true)

	return tostring(o)
end


-- Métatable
local mt = {}

mt.__index = mt

function mt:insert(...)
	table.insert(self, ...)
	return self
end

function mt:concat(...)
	return table.concat(self, ...)
end

function p.new(...)
	return setmetatable({...}, mt)
end

-- Test lambda
function p.estOrdonne(args, prefixe)
	local sections, groupes, listes = {}, {}, {}
	local indice
	for cle, _ in pairs(args) do
		indice = tostring(cle):match('^section(%d+)$')
		if indice then
			table.insert(res, tonumber(indice))
		end
	end
	table.sort(res)
	
	indice = 1
	for cle, val in pairs(res) do
		if indice ~= val then
			return false
		end
		indice = indice + 1
	end

	return f(res), #res ~= 0
end

-- Gestion des arguments
local checkType = require('libraryUtil').checkType
	
local function foncDefaut(_, val)
	local res = mw.text.trim(val)
	if res == '' then
		return nil
	end
	return res
end

function p.gestionArgs(frame, options)
	checkType('gestionArgs', 1, frame, 'table', true)
	checkType('gestionArgs', 2, options, 'table', true)
	options = options or {}
	local res = {}

	if type(frame.args) == 'table'
	and type(frame.getParent) == 'function' then
		local argsFrame = frame.args or {}
		local argsParent = frame:getParent().args or {}
		-- Récupération unique des arguments passés via [#invoke].
		if options.argsFrame then
			res = argsFrame
		-- Récupération unique des arguments de la page qui a appelé [#invoke].
		elseif options.argsParent then
			res = argsParent
		-- Récupération de la totalité des arguments reçus via [#invoke].
		else

			for cle, val in pairs(argsParent) do
				res[cle] = val
			end
						for cle, val in pairs(argsFrame) do
				res[cle] = val
			end
		end
	else
		return frame
	end

	local foncIter = foncDefaut
	if type(options.foncIter) == 'function'
	or type(options.foncIter) == 'boolean' and not options.foncIter then
		foncIter = options.foncIter
	end
	if foncIter then
		for cle, val in pairs(res) do
			res[cle] = foncIter(cle, val)
		end
	end

	return res
end


local o = {}
o.__index = o

function o.Palette(args)
	local html = mw.html.create('div')
		:addClass('palette mw-collapsible')
	local etat = args['état']

	-- Configuration du paramètre [état].
	if etat == 'fermé' then
		res:addClass('mw-collapsed')
	elseif etat == 'ouvert' then
		res:addClass('mw-uncollapsed')
	end

	return setmetatable({ html = html, args = args }, o)
end

function o:test()
	local res = mw.html.create('p')
	local args = self.args

	res:wikitext('Lorem : ' .. args.lorem)
	self.html:node(res)
	return self
end

function o:test2()
	local res = mw.html.create('p')
	local args = self.args
	
	res:wikitext('Ipsum : ' .. args.ipsum)
	self.html:node(res)
	return self
end

function o.__tostring(o)
	return tostring(o.html)
end

local function gestionArgs(frame)
	local args = {}
	local argsParent = frame:getParent().args

	-- Paramètres vides interprétés par Lua.
	for cle, val in pairs(argsParent) do
		if val ~= '' then
			args[cle] = mw.text.trim(val)
		end
	end

	return args
end

function p.main2(frame)
	local args = p.gestionArgs(frame)
	--[[local palette = o.Palette(args)
	palette
		:test()
		:test2()

	return palette]]--
	return mw.dumpObject(args)
end

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

local cfg = {
	header = 'Liste des titres, avec positions dans les classements',
	headerWithCertif = 'Liste des titres, avec positions dans les classements et certifications',
	title = 'Titre',
	details = "Détails de l'album",
	year = 'Année',
	position = 'Meilleure position',
	sale = 'Ventes',
	certif = '[[Disque de certification|Certifications]]',
	album = 'Album',
	footer = "« — » indique que le titre n'est pas sorti ou classé dans le pays.",
	prefix = {
		chart = 'pays',
		ref = 'ref',

		title = 'titre',
		option = 'option',
		details = 'détails',
		year = 'année',
		yearn = 'annéen',
		position = 'position',
		sale = 'vente',
		certif = 'certif',
		album = 'album',
		albumn = 'albumn'
	}
}

function getArgNums(args, prefix)
	local nums = {}
	for k, _ in pairs(args) do
		local num = k:match('^' .. prefix .. '([1-9]%d*)$')
		if num then
			table.insert(nums, tonumber(num))
		end
	end
	table.sort(nums)
	return nums
end

local Discography = {}
Discography.__index = Discography

function Discography.new(args, cfg, classType)
	args = args or {}
	local cleanArgs = {}
	for k, v in pairs(args) do
		if type(k) == 'string' and v ~= '' then
			cleanArgs[k] = mw.text.trim(v)
		end
	end

	local fields = {
		isAlbumType = classType == 'album',
		args = cleanArgs,
		cfg = cfg,
		root = mw.html.create('table')
			:addClass('wikitable')
			:css('text-align', 'center'),
		chartNums = getArgNums(cleanArgs, cfg.prefix.chart),
		existsSale = #getArgNums(cleanArgs, cfg.prefix.sale) > 0,
		existsCertif = #getArgNums(cleanArgs, cfg.prefix.certif) > 0
	}
	return setmetatable(fields, Discography)
end

function Discography:__tostring()
	return tostring(self.root)
end

local function createTag(root, tag, text, attributes, styles)
	root:tag(tag):attr(attributes or {}):css(styles or {}):wikitext(text)
end

local function createTagIf(exist, root, tag, text, attributes, styles)
	if exist then createTag(root, tag, text, attributes, styles) end
end

function Discography:buildHeader()
	local args = self.args
	local cfg = self.cfg

	-- Create titles header.
	local titlesHeader = mw.html.create('tr')
	local attr = { scope = 'col', rowspan = '2' }
	local attrPosition = { scope = 'col', colspan = #self.chartNums }
	createTag(titlesHeader, 'th', cfg.title, attr)
	createTag(titlesHeader, 'th', self.isAlbumType and cfg.details or cfg.year, attr)
	createTag(titlesHeader, 'th', cfg.position, attrPosition)
	createTagIf(self.existsSale, titlesHeader, 'th', cfg.sale, attr)
	createTagIf(self.existsCertif, titlesHeader, 'th', cfg.certif, attr)
	createTagIf(not self.isAlbumType, titlesHeader, 'th', cfg.album, attr)

	-- Create charts header.
	local chartsHeader = mw.html.create('tr')
	local attr = { scope = 'col' }
	local css = { width = '2em', ['font-size'] = '90%' }
	for _, chartNum in pairs(self.chartNums) do
		local text = args[cfg.prefix.chart .. chartNum]
			.. '<br>'
			.. (args[cfg.prefix.ref .. chartNum] or '')
		createTag(chartsHeader, 'th', text, attr, css)
	end

	self.root
		:tag('caption')
		:wikitext(self.existsCertif and cfg.headerWithCertif or cfg.header)
		:done()
		:node(titlesHeader)
		:node(chartsHeader)
	return self
end

local function optionTitle(optionValue)
	if not optionValue then
		return ''
	end
	return '<br><span style="font-size:89%">(' .. optionValue .. ')</span>'
end

local function splitBySemicolon(text)
	local res = {}
	if text then
		for p in text:gmatch('([^; ]+)') do
			table.insert(res, p)
		end
	end
	return res
end

function Discography:buildAlbumRow(albumNum, args, prefix, css)
	local root = mw.html.create('tr')

	-- Create title column.
	local text = args[prefix.title .. albumNum]
		.. optionTitle(args[prefix.option .. albumNum])
	createTag(root, 'td', text, {}, css)

	-- Create album details column.
	local text = args[prefix.details .. albumNum]
	text = text and '\n' .. text
	createTag(root, 'td', text, {}, css)

	-- Create chart position columns.
	local positions = splitBySemicolon(args[prefix.position .. albumNum])
	for chartNum = 1, #self.chartNums do
		root:tag('td'):wikitext(positions[chartNum] or '—'):done()
	end

	-- Create optional sale column.
	local text = args[prefix.sale .. albumNum]
	text = text and '\n' .. text
	createTagIf(self.existsSale, root, 'td', text, {}, css)

	-- Create optional certification column.
	local text = args[prefix.certif .. albumNum]
	text = text and '\n' .. text
	createTagIf(self.existsCertif, root, 'td', text, {}, css)

	return root
end

function Discography:buildSongRow(songNum, args, prefix, css)
	local root = mw.html.create('tr')

	-- Create title column.
	local text = args[prefix.title .. songNum]
		.. optionTitle(args[prefix.option .. songNum])
	createTag(root, 'td', text, {}, css)

	-- Create year column only if the previous yearn is not found.
	local attr = { rowspan = args[prefix.yearn .. songNum] or 1 }
	local text = args[prefix.year .. songNum]
	createTagIf(text, root, 'td', text, attr)

	-- Create chart position columns.
	local positions = splitBySemicolon(args[prefix.position .. songNum])
	for chartNum = 1, #self.chartNums do
		root:tag('td'):wikitext(positions[chartNum] or '—'):done()
	end

	-- Create optional sale column.
	local text = args[prefix.sale .. songNum]
	text = text and '\n' .. text
	createTagIf(self.existsSale, root, 'td', text, {}, css)

	-- Create optional certification column.
	local text = args[prefix.certif .. songNum]
	text = text and '\n' .. text
	createTagIf(self.existsCertif, root, 'td', text, {}, css)

	-- Create album column only if the previous yearn is not found.
	local attr = { rowspan = args[prefix.albumn .. songNum] or 1 }
	local text = args[prefix.album .. songNum]
	createTagIf(text, root, 'td', text, attr)

	return root
end

function Discography:buildContent()
	local args = self.args
	local prefix = self.cfg.prefix
	local css = { ['text-align'] = 'left' }
	local buildRow = self.isAlbumType
		and function (albumNum)
			return self:buildAlbumRow(albumNum, args, prefix, css)
		end
		or function (songNum)
			return self:buildSongRow(songNum, args, prefix, css)
		end

	for _, titleNum in pairs(getArgNums(args, prefix.title)) do
		local currentRoot = buildRow(titleNum)
		self.root:node(currentRoot)
	end

	return self
end

function Discography:buildFooter()
	local rowNo = #self.chartNums
		+ (self.isAlbumType and 2 or 3)
		+ (self.existsCertif and 1 or 0)
		+ (self.existsSale and 1 or 0)
	self.root
		:tag('tr')
		:tag('td')
		:attr('colspan', rowNo)
		:css('font-size', '90%')
		:wikitext(self.cfg.footer)
		:done()
	return self
end

-- Access in the module space.
function p._main(args, classType)
	local discography = Discography.new(args, cfg, classType)
	return tostring(discography:buildHeader():buildContent():buildFooter())
end

-- Access outside the module space.
function p.main(frame)
	local argsParent = frame:getParent().args
	return p._main(argsParent, frame.args[1])
end

return p