Редактирование: Модуль:Series overview
Перейти к навигации
Перейти к поиску
Примечание. Ваши правки будут показаны в статье только после их проверки участником с соответствующими правами.
Правка может быть отменена. Проверьте сравнение версий ниже и нажмите «Записать страницу».
Если отменяемые вами изменения не вандализм, пожалуйста, допишите причину в описании правки.
Текущая версия | Ваш текст | ||
Строка 12: | Строка 12: | ||
local SeriesOverview = {} | local SeriesOverview = {} | ||
function SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, key, cell | function SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, key, cell) | ||
local spanlength = 1 | local spanlength = 1 | ||
for i = cell+1, #SeasonEntries_ordered do | for i = cell+1, #SeasonEntries_ordered do | ||
local entry = SeasonEntries[SeasonEntries_ordered[i]] | local entry = SeasonEntries[SeasonEntries_ordered[i]] | ||
Строка 27: | Строка 21: | ||
else break end | else break end | ||
if not entry[key..'B'] then spanlength = spanlength + 1 | if not entry[key..'B'] then spanlength = spanlength + 1 | ||
else break end | |||
if not entry[key..'C'] then spanlength = spanlength + 1 | |||
else break end | else break end | ||
else | else | ||
if not entry[key] and (key == 'network' or (string.sub(key,0,3) == 'aux' and (not entry.special or entry.episodes)) | if not entry[key] and (key == 'network' or (string.sub(key,0,3) == 'aux' and (not entry.special or entry.episodes))) then | ||
spanlength = spanlength + 1 | spanlength = spanlength + 1 | ||
else break end | else break end | ||
Строка 89: | Строка 85: | ||
function SeriesOverview.new(frame, args) | function SeriesOverview.new(frame, args) | ||
args = args or {} | args = args or {} | ||
local categories = '' | local categories = '' | ||
local title = mw.title.getCurrentTitle() | local title = mw.title.getCurrentTitle() | ||
Строка 96: | Строка 90: | ||
-- Create series overview table | -- Create series overview table | ||
local root = mw.html.create( | local root = mw.html.create('table') | ||
local cellPadding = '0 8px' | local cellPadding = '0 8px' | ||
root | root | ||
Строка 104: | Строка 97: | ||
:addClass('plainrowheaders') | :addClass('plainrowheaders') | ||
:css('text-align', 'center') | :css('text-align', 'center') | ||
-- Caption | -- Caption | ||
if args.caption then | if args.caption then | ||
root:tag('caption'):wikitext( | root:tag('caption'):wikitext(args.caption) | ||
end | end | ||
-- Extract seasons info and place into a 3D array | -- Extract seasons info and place into a 3D array | ||
local SeasonEntries = {} | local SeasonEntries = {} | ||
Строка 150: | Строка 133: | ||
table.sort(SeasonEntries_ordered,SeriesOverview.series_sort) | table.sort(SeasonEntries_ordered,SeriesOverview.series_sort) | ||
local firstRow = | local firstRow = SeasonEntries[SeasonEntries_ordered[1]] | ||
-- Colspan calculation for information cells (0 = no info set) | -- Colspan calculation for information cells (0 = no info set) | ||
Строка 162: | Строка 145: | ||
-- Top info cell | -- Top info cell | ||
-- @ = string.char(64), A = string.char(65) | -- @ = string.char(64), A = string.char(65) | ||
local topInfoCell = numInfoCells > 0 and string.char(numInfoCells + (string.byte('A') - 1)) or ' | local topInfoCell = args.infoheader and (numInfoCells > 0 and string.char(numInfoCells + (string.byte('A') - 1)) or 'A') or '@' | ||
-- Headers | -- Headers | ||
do | do | ||
local headerRow = root:tag('tr') | |||
headerRow | |||
:css('text-align', 'center') | |||
-- Networks are included if the very first entry sets the first network | |||
local setNetwork = firstRow.network or firstRow.networkA | |||
local releasedBlurb = args.released and 'дата' or 'дата' | |||
-- Base series/season content on the format of the first date; Series = D M Y, Season = M D, Y | |||
local matchDMY = false | |||
local thisStart = firstRow.start or firstRow.startA | |||
if thisStart then | |||
if string.match(thisStart:gsub(" "," "), '(%d+)%s(%a+)%s(%d+)') then | |||
matchDMY = true | |||
end | end | ||
end | |||
-- | |||
if args | -- Season header | ||
headerRow:tag('th') | |||
:attr('scope', 'col') | |||
:attr('rowspan', allReleased and numInfoCells == 0 and 1 or 2) | |||
:attr('colspan', 2) | |||
:css('padding', cellPadding) | |||
:wikitext(args.seriesT or args.seasonT or (matchDMY and 'Эпизоды') or 'Сезон') | |||
-- Aux headers | |||
for i = string.byte('A'), string.byte('Z') do | |||
local param = 'aux' .. string.char(i) | |||
if args[param] then | |||
numAuxCells = numAuxCells + 1 | |||
headerRow:tag('th') | headerRow:tag('th') | ||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:css('padding', cellPadding) | :css('padding', cellPadding) | ||
:attr('rowspan', allReleased and 1 or 2) | :attr('rowspan', allReleased and numInfoCells == 0 and 1 or 2) | ||
:wikitext( | :wikitext(args[param]) | ||
end | end | ||
end | |||
-- | |||
-- Episodes header | |||
headerRow:tag('th') | |||
:attr('scope', 'col') | |||
:attr('rowspan', allReleased and numInfoCells == 0 and 1 or 2) | |||
:attr('colspan', 2) | |||
:css('padding', cellPadding) | |||
:wikitext('Эпизодов') | |||
-- Originally aired header | |||
headerRow:tag('th') | |||
:attr('scope', 'col') | |||
:attr('rowspan', allReleased and numInfoCells > 0 and 2 or 1) | |||
:attr('colspan', setNetwork and 3 or 2) | |||
:wikitext('Трансляция') | |||
-- Network subheader for released series | |||
if setNetwork and allReleased then | |||
headerRow:tag('th') | headerRow:tag('th') | ||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:attr('rowspan', allReleased and 1 or 2 | :attr('rowspan', allReleased and numInfoCells == 0 and 1 or 2) | ||
:css('padding', cellPadding) | :css('padding', cellPadding) | ||
:wikitext( | :wikitext('Телесеть') | ||
end | |||
-- Subheader row | |||
local subheaderRow = mw.html.create('tr') | |||
-- Info header | |||
if args.infoheader then | |||
headerRow:tag('th') | headerRow:tag('th') | ||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:attr(' | :attr('colspan', numInfoCells > 0 and numInfoCells or nil) | ||
:attr(' | :attr('rowspan', (allReleased and 1) or (numInfoCells > 0 and 1) or 2) | ||
:css('padding', cellPadding) | :css('padding', cellPadding) | ||
:wikitext(' | :wikitext(args.infoheader) | ||
end | |||
if not allReleased then | |||
-- First aired subheader | |||
subheaderRow:tag('th') | |||
:attr('scope', 'col') | |||
:wikitext('Премьера сезона') | |||
-- | -- Last aired subheader | ||
subheaderRow:tag('th') | |||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:wikitext('Финал сезона') | |||
-- Network subheader for aired series | |||
if setNetwork then | |||
-- Network subheader for | subheaderRow:tag('th') | ||
if setNetwork | |||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:css('padding', cellPadding) | :css('padding', cellPadding) | ||
:wikitext('Телесеть') | :wikitext('Телесеть') | ||
end | end | ||
end | |||
-- Information subheaders, only if the infoheader doesn't span down (i.e. 2+ info cells set) | |||
if topInfoCell ~= 'A' then | |||
for i = string.byte('A'), string.byte(topInfoCell) do | |||
local param = 'info' .. string.char(i) | |||
subheaderRow:tag('th') | subheaderRow:tag('th') | ||
:attr('scope', 'col') | :attr('scope', 'col') | ||
:css('padding', cellPadding) | |||
:wikitext(args[param]) | |||
end | end | ||
end | |||
-- Check for scenarios with an empty subheaderRow | |||
if not allReleased or numInfoCells > 0 then | |||
root:node(subheaderRow) | |||
end | end | ||
end | end | ||
Строка 297: | Строка 263: | ||
-- Season rows | -- Season rows | ||
do | do | ||
if args. | -- One row entries, only categorized in the mainspace | ||
-- | if title.namespace == 0 and #SeasonEntries == 1 then | ||
if args. | categories = categories .. '[[Category:Articles using Template:Series overview with only one row]]' | ||
end | |||
for X = 1, #SeasonEntries_ordered do | |||
local season, entry = SeasonEntries_ordered[X], SeasonEntries[SeasonEntries_ordered[X]] | |||
local splitSeason = entry.startA | |||
-- New season row | |||
local seasonRow = root:tag('tr') | |||
-- Dates | |||
local startDate = entry['start'] | |||
local endDate = entry['end'] | |||
-- First season row | |||
-- Coloured cell | |||
-- Add # to colors if necessary | |||
if entry.color ~= nil and HTMLcolor[entry.color] == nil then entry.color = '#'..(mw.ustring.match(entry.color, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '') end | |||
if entry.colorA ~= nil and HTMLcolor[entry.colorA] == nil then entry.colorA = '#'..(mw.ustring.match(entry.colorA, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '') end | |||
if entry.colorB ~= nil and HTMLcolor[entry.colorB] == nil then entry.colorB = '#'..(mw.ustring.match(entry.colorB, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '') end | |||
seasonRow:tag('td') | |||
:attr('scope','row') | |||
:attr('rowspan', ((splitSeason and entry.color) or (entry.colorA and entry.colorA == entry.colorB)) and 2 or nil) | |||
:css('background',entry.colorA or entry.color) | |||
:css('width','10px') | |||
-- Season number link | |||
seasonRow:tag('td') | |||
:attr('rowspan', splitSeason and 2 or nil) | |||
:attr('colspan', entry.special and not entry.episodes and 3+numAuxCells or 1) | |||
:wikitext(entry.link and '[[' .. entry.link .. '|' .. (entry.linkT or season) .. ']]' or (entry.linkT or season)) | |||
-- Aux cells | |||
for i = string.byte('A'), string.byte('Z') do | |||
local param = 'aux' .. string.char(i) | |||
if entry[param] or entry[param..'A'] then | |||
local thisCell = SeriesOverview.season_cell(entry[param] or entry[param..'A'], frame) | |||
:attr('scope', 'col') | |||
:attr('rowspan', SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, param, X)) | |||
:css('padding', cellPadding) | |||
seasonRow:node(thisCell) | |||
end | |||
end | |||
-- Episodes | |||
if entry.episodes then | |||
local thisCell = SeriesOverview.season_cell(entry.episodes, frame) | |||
:attr('colspan', splitSeason and 1 or 2) | |||
:attr('rowspan', splitSeason and 2 or nil) | |||
seasonRow:node(thisCell) | |||
elseif not entry.special then | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
infoCell | |||
:attr('colspan', splitSeason and 1 or 2) | |||
:attr('rowspan', splitSeason and 2 or nil) | |||
seasonRow:node(infoCell) | |||
end | |||
-- Episodes for first half of split season | |||
if splitSeason then | |||
if entry.episodesA then | |||
local thisCell = SeriesOverview.season_cell(entry.episodesA, frame) | |||
seasonRow:node(thisCell) | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
seasonRow:node(infoCell) | |||
end | |||
end | |||
-- Start date | |||
if entry.startA or startDate then | |||
local thisCell = SeriesOverview.season_cell(entry.startA or startDate, frame) | |||
:attr('colspan', ((not entry.special and endDate == 'start') or (entry.special and not endDate)) and 2 or 1) | |||
:css('padding',cellPadding) | |||
seasonRow:node(thisCell) | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}}) | |||
infoCell:css('padding',cellPadding) | |||
seasonRow:node(infoCell) | |||
if title.namespace == 0 then | |||
categories = categories .. '[[Category:Articles using Template:Series overview with empty start date]]' | |||
end | |||
end | |||
-- End date | |||
if not allReleased and endDate ~= 'start' and ((entry.special and endDate) or not entry.special) then | |||
if entry.endA or endDate then | |||
local thisCell = SeriesOverview.season_cell(entry.endA or endDate, frame) | |||
:css('padding',cellPadding) | |||
seasonRow:node(thisCell) | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
infoCell:css('padding',cellPadding) | |||
seasonRow:node(infoCell) | |||
end | |||
end | end | ||
-- | -- Network | ||
if | if entry.network or entry.networkA then | ||
local thisCell = SeriesOverview.season_cell(entry.networkA or entry.network, frame) | |||
:attr('rowspan', SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, 'network', X)) | |||
seasonRow:node(thisCell) | |||
end | end | ||
-- | -- Information | ||
for i = string.byte('A'), string.byte(topInfoCell) do | |||
local param = 'info' .. string.char(i) | |||
local infoParam = entry[param .. 'A'] or entry[param] | |||
if infoParam then | |||
-- Cells with {{N/A|...}} already expanded | |||
if string.sub(infoParam,1,5) == 'style' then | |||
if entry[param] | local infoCell = SeriesOverview.series_attributes(infoParam) | ||
infoCell:attr('rowspan', (splitSeason and entry[param]) and 2 or nil) | |||
seasonRow:node(infoCell) | |||
else | |||
-- Unstyled content info cell | |||
local thisCell = SeriesOverview.season_cell(infoParam, frame) | |||
:attr('rowspan', (splitSeason and entry[param]) and 2 or nil) | |||
seasonRow:node(thisCell) | |||
end | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
infoCell:attr('rowspan', (splitSeason and entry[param]) and 2 or nil) | |||
seasonRow:node(infoCell) | |||
end | end | ||
end | end | ||
for | -- Second season row for split seasons | ||
if splitSeason then | |||
-- Second row | |||
local seasonRowB = root:tag('tr') | |||
-- Coloured cell | |||
if not entry.color and entry.colorB and entry.colorA ~= entry.colorB then | |||
seasonRowB:tag('td') | |||
:attr('scope','row') | |||
:css('background',entry.colorB) | |||
:css('width','10px') | |||
end | |||
-- | -- Aux cells | ||
for i = string.byte('A'), string.byte('Z') do | for i = string.byte('A'), string.byte('Z') do | ||
local param = ' | local param = 'aux' .. string.char(i) | ||
if entry[param] then | if entry[param..'B'] then | ||
local thisCell = SeriesOverview.season_cell(entry[param .. 'B'], frame) | |||
:attr('scope', 'col') | |||
:attr('rowspan', SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, param, X)) | |||
:css('padding', cellPadding) | |||
seasonRowB:node(thisCell) | |||
end | |||
end | |||
-- Episodes for first half of split season | |||
if entry.episodesB then | |||
local thisCell = SeriesOverview.season_cell(entry.episodesB, frame) | |||
seasonRowB:node(thisCell) | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
infoCell:css('padding',cellPadding) | |||
seasonRowB:node(infoCell) | |||
end | end | ||
-- | -- Start date | ||
if entry.startB then | |||
local thisCell = SeriesOverview.season_cell(entry.startB, frame) | |||
:attr('colspan',entry.endB == 'start' and 2 or 1) | |||
:css('padding',cellPadding) | |||
seasonRowB:node(thisCell) | |||
else | |||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | |||
infoCell:css('padding',cellPadding) | |||
seasonRowB:node(infoCell) | |||
end | |||
-- End date | |||
if not allReleased and entry.endB ~= 'start' then | |||
local thisCell = SeriesOverview.season_cell(entry | if entry.endB then | ||
local thisCell = SeriesOverview.season_cell(entry.endB, frame) | |||
:css('padding', | :css('padding',cellPadding) | ||
seasonRowB:node(thisCell) | |||
else | else | ||
local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | local infoCell = SeriesOverview.series_attributes( frame:expandTemplate{title='N/A',args={'TBA'}} ) | ||
infoCell:css('padding', | infoCell:css('padding',cellPadding) | ||
seasonRowB:node(infoCell) | |||
end | end | ||
end | |||
-- Network | |||
if entry.networkB then | |||
local thisCell = SeriesOverview.season_cell(entry.networkB, frame) | |||
:attr('rowspan', SeriesOverview.cellspan(SeasonEntries, SeasonEntries_ordered, 'network', X)) | |||
seasonRowB:node(thisCell) | |||
end | |||
-- Information | |||
for i = string.byte('A'), string.byte('Z') do | |||
local param = 'info' .. string.char(i) | |||
if entry[param .. 'B'] then | |||
local thisCell = SeriesOverview.season_cell(entry[param .. 'B'], frame) | |||
seasonRowB:node(thisCell) | |||
end | end | ||
end | |||
end -- End 'if' splitSeason | |||
end -- End 'for' SeasonEntries_ordered | |||
end | |||
end -- End ' | |||
end -- End ' | |||
end -- End 'do' season rows | end -- End 'do' season rows | ||
return | return tostring(root) .. categories | ||
end | end | ||