Module:Discographie
Aller à la navigation
Aller à la recherche
La documentation pour ce module peut être créée à Module:Discographie/doc
-- Ce module implémente les modèles {{Discographie des albums}} et {{Discographie des chansons}}. -- luacheck: globals mw local p = {} local cfg = { header = 'Liste des titres, avec positions dans les classements', headerWithAll = ', ventes cumulées et certifications', headerWithSale = ' et ventes cumulées', headerWithCertif = ' 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' } } local 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 fields = { args = args, cfg = cfg, isAlbumType = classType == 'album', root = mw.html.create('table') :addClass('wikitable') :css('text-align', 'center'), chartNums = getArgNums(args, cfg.prefix.chart), existsSale = #getArgNums(args, cfg.prefix.sale) > 0, existsCertif = #getArgNums(args, 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 self.existsSale and cfg.header .. cfg.headerWithAll or self.existsCertif and cfg.header .. cfg.headerWithCertif or self.existsSale and cfg.header .. cfg.headerWithSale 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 match in text:gmatch('([^;]+)') do table.insert(res, mw.text.trim(match)) end end return res end function Discography:buildRow(titleNum, args, prefix, css) local root = mw.html.create('tr') -- Create title column. local text = args[prefix.title .. titleNum] .. optionTitle(args[prefix.option .. titleNum]) createTag(root, 'td', text, {}, css) -- Create album details column. -- Album type only. local text = args[prefix.details .. titleNum] text = text and '\n' .. text createTagIf(self.isAlbumType, root, 'td', text, {}, css) -- Create year column only if the previous yearn is not found. -- Song type only. local attr = { rowspan = args[prefix.yearn .. titleNum] or 1 } local text = args[prefix.year .. titleNum] createTagIf(text and not self.isAlbumType, root, 'td', text, attr) -- Create chart position columns. local positions = splitBySemicolon(args[prefix.position .. titleNum]) for chartNum = 1, #self.chartNums do root:tag('td'):wikitext(positions[chartNum] or '—'):done() end -- Create optional sale column. local text = args[prefix.sale .. titleNum] text = text and '\n' .. text createTagIf(self.existsSale, root, 'td', text, {}, css) -- Create optional certification column. local text = args[prefix.certif .. titleNum] text = text and '\n' .. text createTagIf(self.existsCertif, root, 'td', text, {}, css) -- Create album column only if the previous yearn is not found. -- Song type only. local attr = { rowspan = args[prefix.albumn .. titleNum] or 1 } local text = args[prefix.album .. titleNum] createTagIf(text and not self.isAlbumType, root, 'td', text, attr) return root end function Discography:buildContent() local args = self.args local prefix = self.cfg.prefix local css = { ['text-align'] = 'left' } for _, titleNum in pairs(getArgNums(args, prefix.title)) do local currentRoot = self:buildRow(titleNum, args, prefix, css) 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 local cleanArgs = {} for k, v in pairs(argsParent) do if type(k) == 'string' and v ~= '' then cleanArgs[k] = mw.text.trim(v) end end return p._main(cleanArgs, frame.args[1]) end return p