Модуль:Список серий

Документация

Документацию смотри на странице шаблонов {{Таблица эпизодов}} и {{Список серий}}

require('strict')local p = {}local tableEmptyCellModule = require('Модуль:Пустая ячейка таблицы')local colorContrastModule = require('Модуль:Color contrast')local htmlColor = mw.loadData('Модуль:Color contrast/colors')local delinkModule = require('Модуль:Delink')local yesNoModule = require('Модуль:Yesno')local mathModule = require('Модуль:Math')local lower = mw.ustring.lowerlocal match = mw.ustring.matchlocal find = mw.ustring.findlocal gsub = mw.ustring.gsublocal sub = mw.ustring.sublocal len = mw.ustring.lenlocal rowlocal nonNilParams = 0local cellValueTBA = falselocal trackingCategories = '[[Категория:Википедия:Статьи использующие шаблон cписок серий]]'local trackingCategoryList = {['air_dates']='[[Категория:Википедия:Списки эпизодов с неоформленной датой показа]]',['alt_air_dates']='[[Категория:Википедия:Списки эпизодов с неверно оформленной датой показа]]',['faulty_line_colors']='[[Категория:Википедия:Списки эпизодов с неверным цветом границ]]',['non_compliant_line_colors']='[[Категория:Википедия:Списки эпизодов с неверным цветом границ]]',['default_line_colors']='[[Категория:Википедия:Списки эпизодов с неверным цветом границ]]',['row_deviations']='[[Категория:Википедия:Списки эпизодов с отклонениями строк]]',['invalid_top_colors']='[[Категория:Википедия:Потенциально нечитаемые таблицы эпизодов]]',['tba_values']='[[Категория:Википедия:Списки эпизодов с незаполненными ячейками]]',['nonmatching_numbered_parameters']='[[Категория:Википедия:Списки эпизодов с неверными параметрами]]',['raw_unformatted_storyteleplay']='[[Категория:Википедия:Списки эпизодов с неоформленными сюжетом или телесценарием]]'}local cellNameList = {'Aux1', 'Столбец1','DirectedBy', 'Режиссёр', 'Режиссер','WrittenBy', 'Сценарист','Aux2', 'Столбец2','Aux3', 'Столбец3','OriginalAirDate', 'ДатаПоказа','AltDate', 'ДатаПоказа2','Guests', 'Гости','MusicalGuests', 'Персоны','ProdCode', 'ПродКод','Viewers', 'Зрителей','Aux4', 'Столбец4'}-- Список взаимоисключающих параметровlocal excludeList = {['Guests']='Aux1', ['Гости']='Столбец2',['MusicalGuests']='Aux2', ['Персоны']='Столбец3'}-- Список ячеек, имеющих группы параметровlocal parameterGroupCells = {}local firstParameterGroupCelllocal parameterGroupCellsAny = false-- Список параметров заголовка для списков с несколькими названиями.local titleList = {'Title', 'Название','RTitle', 'НазваниеПрим','AltTitle', 'Название2','RAltTitle', 'Название2Прим','NativeTitle', 'НазваниеОригинал','TranslitTitle', 'НазваниеТранслит'}-- Локальная функция для получения номера эпизода или производственного кода,-- без какого-либо дополнительного текста.local function idTrim(val, search)local valFind = find(val, search)if not valFind thenreturn valendreturn sub(val, 0, valFind - 1)end-- Локальная функция для проверки того, что параметр имеет значение.local function hasValue(param)if param and param:find('%S') thenreturn trueendend-- Локальная функция для создания транслитерации.local function langSpan(translitNativeTitle, langCode)local line = mw.html.create('span')if hasValue(langCode) thenline:attr('lang', langCode):attr('xml:lang', langCode):css('font-style', 'normal'):wikitext(translitNativeTitle)endreturn tostring(line)end-- Локальная функция для создания аббревиатурыlocal function abbr(text, title)local abbr = mw.html.create('abbr')abbr:attr('title', title):wikitext(text)return tostring(abbr)end-- Локальная функция для создания ячейки Таблицы эпизодов.local function createTableData(text, rowSpan, textAlign)if rowSpan and tonumber(rowSpan) > 1 thenrow:tag('td'):attr('rowspan', rowSpan):wikitext(text)elserow:tag('td'):css('text-align', textAlign):wikitext(text)endend-- Локальная функция для добавления отслеживающей категории  на страницу.local function addTrackingCategory(category)trackingCategories = trackingCategories .. categoryend-- Локальная функция для создания Краткого Содержания.local function createShortSummaryRow(args, lineColor, linetop)local shortSummary = args.ShortSummary or args['КраткоеСодержание']-- исправление Краткого Содержанияif hasValue(shortSummary) and (match(shortSummary, '^[*:;#]') or match(shortSummary, '^{|')) thenshortSummary = '<span></span>\n' .. shortSummaryendif hasValue(shortSummary) and match(shortSummary, '\n[*:;#]') thenshortSummary = shortSummary .. '\n<span></span>'endif linetop thenshortSummary = nilendlocal shortSummaryCell = mw.html.create('td')shortSummaryCell:addClass('description'):css('border-bottom', 'solid 3px ' .. lineColor):attr('colspan', nonNilParams):newline():wikitext(shortSummary)local cell = mw.html.create('tr')cell:addClass('expand-child'):node(shortSummaryCell)if linetop thenlocal lencell = len(cell)cell = sub(cell, 1, lencell - 10)endreturn tostring(cell)end-- Локальная функция для добавления отслеживающей категории при проблемах с цветом.local function addTopColorTrackingCategories(args)local topColor = args.TopColor or args['ЦветСтроки']if hasValue(topColor) or '#eaecf0' thenaddTrackingCategory(trackingCategoryList['row_deviations'])-- Проверка контрастности в соответствии с [[ВП:ЦВЕТ]].local textContrastRatio = colorContrastModule._ratio{topColor, 'black', ['error']=0}local linkContrastRatio = colorContrastModule._ratio{'#0B0080', topColor, ['error']=0}local visitedLinkContrastRatio = colorContrastModule._ratio{topColor, '#0645AD', ['error']=0}if textContrastRatio < 4.5 or linkContrastRatio < 3 or visitedLinkContrastRatio < 3 thenaddTrackingCategory(trackingCategoryList['invalid_top_colors'])endendend-- Локальная функция для добавления отслеживающей категории при проблемах с цветом границы.local function addLineColorTrackingCategories(args)local lineColor = args.LineColor or args['ЦветГраницы']  --  or '#a2a9b1'if hasValue(lineColor) thenlocal blackContrastRatio = colorContrastModule._ratio{lineColor, 'black', ['error']=0}local whiteContrastRatio = colorContrastModule._ratio{'white', lineColor, ['error']=0}if lineColor == '' thenaddTrackingCategory(trackingCategoryList['faulty_line_colors'])elseif blackContrastRatio < 3 and whiteContrastRatio < 3 thenaddTrackingCategory(trackingCategoryList['non_compliant_line_colors'])endelseaddTrackingCategory(trackingCategoryList['default_line_colors'])endend-- Локальная функция для удаления вики-ссылок из повторяющейся информации в ячейках.local function removeWikilinks(args, v)return delinkModule._delink({args[v]})end-- Локальная функция для установки текста пустой ячейки либо 'TBD' - to be announced, либо  'н/д' - нет данных.local function setTBDStatus(args, awaitingText, expiredText)local year, day, month, secondslocal originalAirDate = args.OriginalAirDate or args['ДатаПоказа']if not hasValue(originalAirDate) thenreturn tableEmptyCellModule._main({alt_text=awaitingText, title_text=awaitingText})endoriginalAirDate = gsub(originalAirDate, '&nbsp;', ' ')originalAirDate = gsub(originalAirDate, '[%[%]]', '')if match(originalAirDate, '{{[Ss]tart date') or match(originalAirDate, '-') thenoriginalAirDate = gsub(originalAirDate, '[-%s|]+', ' ')year, month, day = match(originalAirDate, '(%d+) (%d+) (%d+)')elseif match(originalAirDate, ',') thenmonth, day, year = match(originalAirDate, '([%a%A]+) (%d+), (%d+)')elseif match(originalAirDate, '[./]') thenoriginalAirDate = gsub(originalAirDate, '[%s./|]+', ' ')day, month, year = match(originalAirDate, '(%d+) (%d+) (%d+)')elseoriginalAirDate = gsub(originalAirDate, '[-%s.,/|]+', ' ')day, month, year = match(originalAirDate, '(%d+) ([%a%A]+) (%d+)')endif not day thenreturn tableEmptyCellModule._main({alt_text='TBD'})end-- Список месяцев.local monthList = {['января']=1, ['январь']=1, ['january']=1, ['1']=1, ['01']=1, 1,['февраля']=2, ['февраль']=2, ['february']=2, ['2']=2, ['02']=2, 2,['марта']=3, ['март']=3, ['march']=3, ['3']=3, ['03']=3, 3,['апреля']=4, ['апрель']=4, ['april']=4, ['4']=4, ['04']=4, 4,['мая']=5, ['май']=5, ['may']=5, ['5']=5, ['05']=5, 5,['июня']=6, ['июнь']=6, ['june']=6, ['6']=6, ['06']=6, 6,['июля']=7, ['июль']=7, ['july']=7, ['7']=7, ['07']=7, 7,['августа']=8, ['август']=8, ['august']=8, ['8']=8, ['08']=8, 8,['сентября']=9, ['сентябрь']=9, ['september']=9, ['9']=9, ['09']=9, 9,['октября']=10, ['октябрь']=10, ['october']=10, ['10']=10, 10,['ноября']=11, ['ноябрь']=11, ['november']=11, ['11']=11, 11,['декабря']=12, ['декабрь']=12, ['december']=12, ['12']=12, 12}local monthnumber = monthList[lower(month)]if not monthnumber thenerror('Неверный месяц ' .. month)endseconds = os.time() - os.time({year=year, month=monthnumber, day=day, hour=0, min=0, sec=0})-- 60 * 60 * 24 * 7 * 4 = 2419200 секунд в 4-х неделяхif seconds >= 2419200 thenreturn tableEmptyCellModule._main({alt_text=expiredText, title_text=expiredText})endreturn tableEmptyCellModule._main({alt_text=awaitingText, title_text=awaitingText})end-- Local function which is used to create an empty cell.local function createEmptyCell(args, v, unsetParameterGroup)local originalAirDate = args.OriginalAirDate or args['ДатаПоказа']local directedByAll = 'DirectedBy Режиссёр Режиссер'local writtenByAll = 'WrittenBy Сценарист'local viewersAll = 'Viewers Зрителей'if unsetParameterGroup thenargs[v] = tableEmptyCellModule._main({alt_text='н/д'})elseif find(viewersAll, v) and hasValue(originalAirDate) thenargs[v] = setTBDStatus(args, 'TBD', 'н/д')elseif find(directedByAll, v) or find(writtenByAll, v) thenargs[v] = setTBDStatus(args, 'TBA', 'Неизвестно')elseargs[v] = tableEmptyCellModule._main({})endend-- Air dates that don't use {{Start date}}local function checkUsageOfDateTemplates(args, v, onInitialPage, title)local originalAirDateAll = 'OriginalAirDate ДатаПоказа'local altDateAll = 'AltDate ДатаПоказа2'if find(originalAirDateAll, v)and hasValue(args[v])and match(args[v], '%d%d%d%d')and not match(args[v], '2C2C2C')and not find(args[v], 'dtstart')and onInitialPageand title.namespace == 0thenaddTrackingCategory(trackingCategoryList['air_dates'])end-- Alternate air dates that do use {{Start date}}if find(altDateAll, v)and hasValue(args[v])and find(args[v], 'dtstart')and onInitialPageand title.namespace == 0thenaddTrackingCategory(trackingCategoryList['alt_air_dates'])endend--[[Local function which is used to extract datafrom the numbered serial parameters (Title1, Aux1, etc.), and then convert them touse the non-numbered parameter names (Title, Aux).The function returns the args as non-numbered prameter names.]]local function extractDataFromNumberedSerialArgs(args, i, numberOfParameterGroups, title)local prodCodeAll = 'ProdCode ПродКод'for _, v in ipairs(cellNameList) dolocal parameter = vlocal numberedParameter = v .. '_' .. ilocal excludeParameter = excludeList[parameter] or 'NULL' .. parameterlocal excludeNumberParameter = (excludeList[numberedParameter] or 'NULL' .. parameter) .. '_' .. iif not hasValue(args[numberedParameter]) and not hasValue(args[excludeNumberParameter])and hasValue(parameterGroupCells[parameter]) and not hasValue(args[excludeParameter])thenif find(prodCodeAll, v) thencreateEmptyCell(args, parameter, true)elseargs[parameter] = ''endif title.namespace == 0 thenaddTrackingCategory(trackingCategoryList['nonmatching_numbered_parameters'])endelseif hasValue(args[numberedParameter]) and not hasValue(args[excludeNumberParameter]) thenargs[parameter] = args[numberedParameter]endendreturn argsend--[[Local function which is used to create column cells.EpisodeNumber, EpisodeNumber2 and Title are created in different functionsas they require some various if checks.See:-- createEpisodeNumberCell()-- createEpisodeNumberCellSecondary()-- createTitleCell()]]local function createCells(args, isSerial, currentRow, onInitialPage, title, numberOfParameterGroups)local prodCodeAll = 'ProdCode ПродКод'local writtenByAll = 'WrittenBy Сценарист'local aux1All = 'Aux1 Столбец1'for k, v in ipairs(cellNameList) doif args[v] then-- Set empty cells to TBA/TBDif args[v] == '' thencreateEmptyCell(args, v, false)elseif find(writtenByAll, v) and title.namespace == 0 thenif (find(args[v], "''Сюжет")or find(args[v], "''Сценарий")or find(args[v], "''Телесценарий")or find(args[v], "''Телепередача")or find(args[v], "''Передача"))and not find(args[v], '8202')then-- &#8202; is the hairspace added through {{StoryTeleplay}}addTrackingCategory(trackingCategoryList['raw_unformatted_storyteleplay'])endend-- If serial titles need to be centered and not left, then this should be removed.local textAlign = 'center'if find(aux1All, v) and isSerial thentextAlign = 'left'endlocal thisRowspanif firstParameterGroupCell and k < firstParameterGroupCell thenthisRowspan = numberOfParameterGroupselsethisRowspan = 1endif currentRow == 1 or (currentRow > 1 and k >= (firstParameterGroupCell or 0)) thencreateTableData(args[v], thisRowspan, textAlign)endnonNilParams = nonNilParams + 1checkUsageOfDateTemplates(args, v, onInitialPage, title)endif args[v] == 'TBA' thencellValueTBA = trueendendend--[[Local function which is used to create the Title cell text.The title text will be handled in the following way:Line 1: <Title><RTitle> (with no space between)Line 2: <AltTitle><RAltTitle> (with no space between) ORLine 2: Transcription: <TranslitTitle> (<Language>: <NativeTitle>)<RAltTitle> (with space between first two parameters)If <Title> or <RTitle> are empty,then the values of line 2 will be placed on line 1 instead.--]]local function createTitleText(args)local title = args.Title or args['Название']local rTitle = args.RTitle or args['НазваниеПрим']local altTitle = args.AltTitle or args['Название2']local rAltTitle = args.RAltTitle or args['Название2Прим']local nativeTitle = args.NativeTitle or args['НазваниеОригинал']local translitTitle = args.TranslitTitle or args['НазваниеТранслит']local nativeTitleLangCode = args.NativeTitleLangCode or args['КодЯзыка']local titleString = ''local isCellPresent = falselocal useSecondLine = falselocal lineBreakUsed = false-- «Заголовок в кавычках». Если пустой, то без кавычек.if title thenisCellPresent = trueif hasValue(title) then-- НазваниеtitleString = "&#171;'''" .. title .. "'''&#187;"useSecondLine = trueendendif rTitle thenisCellPresent = trueif hasValue(rTitle) thentitleString = titleString .. rTitleuseSecondLine = trueendend-- Surround the AltTitle/TranslitTitle with quotes; No quotes if empty.if altTitle or translitTitle thenisCellPresent = trueif useSecondLine thentitleString = titleString .. '<br>'lineBreakUsed = trueendif hasValue(altTitle) then-- Название2titleString = titleString .. "&#171;''" .. altTitle .. "''&#187;"elseif hasValue(translitTitle) thentitleString = titleString .. abbr('транслит.', 'транслитерация названия') .. '.: &#171;'if hasValue(nativeTitleLangCode) thentitleString = titleString .. langSpan(translitTitle, nativeTitleLangCode) .. '&#187;'elsetitleString = titleString .. translitTitle .. '&#187;'endendendif nativeTitle thenisCellPresent = trueif hasValue(nativeTitle) thenif useSecondLine and not lineBreakUsed thentitleString = titleString .. '<br>'endtitleString = titleString .. ' (' .. abbr('ориг.', 'оригинальное название') .. '.: 'if hasValue(nativeTitleLangCode) thentitleString = titleString .. langSpan(nativeTitle, nativeTitleLangCode) .. ')'elsetitleString = titleString .. nativeTitle .. ')'endendendif rAltTitle thenisCellPresent = trueif hasValue(rAltTitle) thenif useSecondLine and not lineBreakUsed thentitleString = titleString .. '<br>'endtitleString = titleString .. rAltTitleendendreturn titleString, isCellPresentend--[[Local function which is used to extract datafrom the numbered title parameters (Title1, RTitle2, etc.), and then convert them touse the non-numbered prameter names (Title, RTitle).The function returns two results:-- The args parameter table.-- A boolean indicating if the title group has data.]] --local function extractDataFromNumberedTitleArgs(args, i)local nextGroupValid = falsefor _, v in ipairs(titleList) dolocal parameter = vlocal numberedParameter = v .. '_' .. iargs[parameter] = args[numberedParameter]if not nextGroupValid and hasValue(args[numberedParameter]) thennextGroupValid = trueendendreturn args, nextGroupValidend-- Local function which is used to process the multi title list.local function processMultiTitleList(args, numberOfParameterGroups)local nativeTitleLangCode = args.NativeTitleLangCode or args['КодЯзыка']local titleText = ''local isCellPresent = falselocal isFirstTitleGroup = true -- Ячейка заголовка создана хотя бы один раз и не создается повторно, если другие заголовки пусты.for i=1, numberOfParameterGroups dolocal args, nextGroupValid = extractDataFromNumberedTitleArgs(args, i)if nextGroupValid thenif not isFirstTitleGroup thentitleText = titleText .. '<hr>'endlocal titleTextRow = createTitleText(args)titleText = titleText .. titleTextRowisFirstTitleGroup = falseelseif isFirstTitleGroup thentitleText, isCellPresent = createTitleText(args)end-- Valid titles have to be in succession (#1, #2, #3 and not #1, #4 #5), so exit for loop if next group is empty.return titleText, isCellPresentendendreturn titleTextend-- Local function which is used to create a Title cell.local function createTitleCell(args, numberOfParameterGroups, multiTitleListEnabled, isSerial)local titleText, isCellPresentif multiTitleListEnabled thentitleText, isCellPresent = processMultiTitleList(args, numberOfParameterGroups)elsetitleText, isCellPresent = createTitleText(args)endif not isCellPresent thenreturn nilendlocal textAlign = 'left'-- If Title is blank, then set Raw Title to TBAif not hasValue(titleText) thentitleText = tableEmptyCellModule._main({})textAlign = 'left'end-- If title is the first cell, create it with a !scope='row'if nonNilParams == 0 thenif isSerial thenrow:tag('th'):addClass('summary'):attr('scope', 'row'):attr('rowspan', numberOfParameterGroups):css('text-align', textAlign):wikitext(titleText)elserow:tag('th'):addClass('summary'):attr('scope', 'row'):css('text-align', textAlign):wikitext(titleText)endelseif isSerial thenrow:tag('td'):addClass('summary'):attr('rowspan', numberOfParameterGroups):css('text-align', textAlign):wikitext(titleText)elserow:tag('td'):addClass('summary'):css('text-align', textAlign):wikitext(titleText)endendnonNilParams = nonNilParams + 1end-- Local function which is used to create a table row header for either the-- EpisodeNumber or EpisodeNumber2 column cells.local function createTableRowEpisodeNumberHeader(episodeNumber, numberOfParameterGroups, episodeText)local epID = match(episodeNumber, '^%w+')row:tag('th'):attr('scope', 'row'):attr('rowspan', numberOfParameterGroups):attr('id', epID and 'ep' .. epID or ''):css('text-align', 'center'):wikitext(episodeText)end--[[Local function which is used to extract the text from the EpisodeNumber or EpisodeNumber2parameters and format them into a correct MoS compliant version.Styles supported:-- A number range of two numbers, indicating the start and end of the range,seperated by an en-dash (–) with no spaces in between.Example: '1 - 2' -> '1–2'; '1-2-3' -> '1–3'.-- An alphanumeric or letter range, similar to the above.Example: 'A - B' -> 'A–B'; 'A-B-C' -> 'A–C'.Example: 'A1 - B1' -> 'A1–B1'; 'A1-B1-C1' -> 'A1–C1'.-- A number range of two numbers, indicating the start and end of the range,seperated by a visual <hr> (divider line).-- An alphanumeric or letter range, similar to the above.]] --local function getEpisodeText(episodeNumber)if episodeNumber == '' thenreturn tableEmptyCellModule._main({})elselocal episodeNumber1, episodeNumber2-- Used for double episodes that need a visual '–' or '<hr>' added.local dividerepisodeNumber = episodeNumber:gsub('%s*<br%s*/?%s*>%s*', '<hr>')if episodeNumber:match('^(%w+)%s*<hr */%s*>%s*(%w+)$') thenepisodeNumber1, episodeNumber2 = episodeNumber:match('^(%w+)%s*<hr */%s*>%s*(%w+)$')divider = '<hr>'elseif episodeNumber:match('^(%w+)%s*<hr */%s*>.-<hr */%s*>%s*(%w+)$') then -- 3 or more elementsepisodeNumber1, episodeNumber2 = episodeNumber:match('^(%w+)%s*<hr */%s*>.-<hr */%s*>%s*(%w+)$')divider = '<hr>'elseif match(episodeNumber, '^(%w+)%s*[%s%-–/&]%s*(%w+)$') thenepisodeNumber1, episodeNumber2 = match(episodeNumber, '^(%w+)%s*[%s%-–/&]%s*(%w+)$')divider = '–'elseepisodeNumber1, episodeNumber2 = match(episodeNumber, '^(%w+)%s*[%s%-–/&].-[%s%-–/&]%s*(%w+)$') -- 3 or more elementsdivider = '–'endif not episodeNumber1 thenreturn episodeNumberelseif not episodeNumber2 thenreturn match(episodeNumber, '%w+')elsereturn episodeNumber1 .. divider .. episodeNumber2endendend-- Local function which is used to create EpisodeNumber2 and EpisodeNumber3 cells.local function _createEpisodeNumberCellSecondary(episodeValue, numberOfParameterGroups)if episodeValue thenlocal episodeText = getEpisodeText(episodeValue)if nonNilParams == 0 thencreateTableRowEpisodeNumberHeader(episodeValue, numberOfParameterGroups, episodeText)elsecreateTableData(episodeText, numberOfParameterGroups, 'center')endnonNilParams = nonNilParams + 1endend-- Local function which is used to create seconday episode number cells.local function createEpisodeNumberCellSecondary(args, numberOfParameterGroups)local episodeNumber2 = args.EpisodeNumber2 or args['НомерЭпизода2']local episodeNumber3 = args.EpisodeNumber3 or args['НомерЭпизода3']_createEpisodeNumberCellSecondary(episodeNumber2, numberOfParameterGroups)_createEpisodeNumberCellSecondary(episodeNumber3, numberOfParameterGroups)end-- Local function which is used to create an EpisodeNumber cell.local function createEpisodeNumberCell(args, numberOfParameterGroups)local episodeNumber = args.EpisodeNumber or args['НомерЭпизода']if episodeNumber thenlocal episodeText = getEpisodeText(episodeNumber)createTableRowEpisodeNumberHeader(episodeNumber, numberOfParameterGroups, episodeText)nonNilParams = nonNilParams + 1endend-- Local function which is used to create a single row of cells.-- This is the standard function called.local function createSingleRowCells(args, numberOfParameterGroups, multiTitleListEnabled, onInitialPage, title)createEpisodeNumberCell(args, 1)createEpisodeNumberCellSecondary(args, 1)createTitleCell(args, numberOfParameterGroups, multiTitleListEnabled, false)createCells(args, false, 1, onInitialPage, title, numberOfParameterGroups)end-- Local function which is used to create a multiple row of cells.-- This function is called when part of the row is rowspaned.-- Current use is for Doctor Who serials.local function createMultiRowCells(args, numberOfParameterGroups, onInitialPage, title, topColor)createEpisodeNumberCell(args, numberOfParameterGroups)createEpisodeNumberCellSecondary(args, numberOfParameterGroups)createTitleCell(args, numberOfParameterGroups, false, true)for i=1, numberOfParameterGroups doargs = extractDataFromNumberedSerialArgs(args, i, numberOfParameterGroups, title)createCells(args, true, i, onInitialPage, title, numberOfParameterGroups)if i ~= numberOfParameterGroups thenrow = row:done()-- Use done() to close the 'tr' tag in rowspaned rows.:tag('tr'):css('background', topColor)endendend-- Local function which is used to retrieve the NumParts value.local function getnumberOfParameterGroups(args)local numParts = args.NumParts or args['КоличествоЧастей']for k, v in ipairs(cellNameList) dolocal numberedParameter = v .. '_' .. 1if args[numberedParameter] thenparameterGroupCells[v] = trueif not firstParameterGroupCell thenfirstParameterGroupCell = kendendendif hasValue(numParts) thenreturn numParts, trueelsereturn 1, falseendend-- Local function which is used to retrieve the remainder value after x has been divided by ylocal function mathMod(x, y)local ret = x % yif not (0 <= ret and ret < y) thenret = 0endreturn retend-- Local function which is used to retrieve the Top Color value.local function getTopColor(args, rowColorEnabled, onInitialPage)local episodeNumber = args.EpisodeNumber or args['НомерЭпизода']local topColor = args.TopColor or args['ЦветСтроки']local shortSummary = args.ShortSummary or args['КраткоеСодержание']local episodeNumber = mathModule._cleanNumber(episodeNumber) or 1if topColor thenif find(topColor, '#') thenreturn topColorelsereturn '#' .. topColorendelseif (rowColorEnabled and onInitialPage and mathMod(episodeNumber, 2) == 0) thenreturn '#E9E9E9'elseif onInitialPage and shortSummary thenreturn '#F2F2F2'elsereturn 'inherit'endend-- Локальная функция, которая используется для включения чередования цвета строк.local function isRowColorEnabled(args)local rowColor = args.RowColor or args['ЧередованиеЦвета']return yesNoModule(rowColor, nil)end-- Local function which is used to retrieve the Line Color value.local function getLineColor(args)-- Default color to light bluelocal lineColor = args.LineColor or args['ЦветГраницы'] or 'CCCCFF'-- Add # to color if necessary, and set to default color if invalidif not htmlColor[lineColor] thenlineColor = '#' .. (match(lineColor, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '')if lineColor == '#' thenlineColor = '#CCCCFF'endendreturn lineColorend-- Local function which is used to check if the table is located on the page-- currently viewed, or on a transcluded page instead.-- If it is on a transcluded page, the episode summary should not be shown.local function isOnInitialPage(args, sublist, pageTitle, initiallistTitle)-- This should be the only check needed, however, it was previously implemented with two templates-- with one of them not requiring an article name, so for backward compatability, the whole sequence is kept.local onInitialPage = false-- Only sublist had anything about hiding, so only it needs to even checkif sublist thenlocal pageTitleMatch = match(pageTitle, 'Список эпизодов', 1) -- Результат: Список эпизодов или nilif not initiallistTitle and pageTitleMatch == 'Список эпизодов' then -- Автоопределение страницы 'Список эпизодов ...'onInitialPage = trueelseif hasValue(initiallistTitle) thenonInitialPage = mw.uri.anchorEncode(pageTitle) == mw.uri.anchorEncode(initiallistTitle)endendreturn onInitialPageend-- Local function which does the actual main process.local function _main(args, sublist, linetop)local title = mw.title.getCurrentTitle()local title2 = args.Title_2 or args['Название_2']local pageTitle = title.textlocal initiallistTitle = args['1'] or ''local shortSummary = args.ShortSummary or args['КраткоеСодержание']-- Is this list on the same page as the page directly calling the template?local onInitialPage = isOnInitialPage(args, sublist, pageTitle, initiallistTitle)-- Need just this parameter removed if blank, no othersif not hasValue(shortSummary) thenshortSummary = nilendlocal lineColor = getLineColor(args)local rowColorEnabled = isRowColorEnabled(args)local topColor = getTopColor(args, rowColorEnabled, onInitialPage)local root = mw.html.create() -- Create the root mw.html object to returnrow = root:tag('tr')-- Create the table row and store it globally:addClass('vevent'):css('text-align', 'center'):css('background', topColor)local numberOfParameterGroups, multiTitleListEnabled = getnumberOfParameterGroups(args)if multiTitleListEnabled and not title2 thencreateMultiRowCells(args, numberOfParameterGroups, onInitialPage, title, topColor)elsecreateSingleRowCells(args, numberOfParameterGroups, multiTitleListEnabled, onInitialPage, title)end-- add these categories only in the mainspace and only if they are on the page where the template is usedif onInitialPage and title.namespace == 0 thenaddLineColorTrackingCategories(args)addTopColorTrackingCategories(args)endif cellValueTBA and title.namespace == 0 thenaddTrackingCategory(trackingCategoryList['tba_values'])endlocal pageTitleMatch = match(pageTitle, 'Список эпизодов', 1)if pageTitleMatch == 'Список эпизодов' or title.namespace ~= 0 thentrackingCategories = ''end-- Do not show the summary if this is being transcluded on the initial list page-- Do include it on all other listsif not onInitialPage and shortSummary thenlocal bottomWrapper = createShortSummaryRow(args, lineColor)return tostring(root) .. tostring(bottomWrapper) .. trackingCategorieselseif linetop thenlocal bottomWrapper = createShortSummaryRow(args, lineColor)local bottomWrapperLen = len(bottomWrapper)local bottomWrapperEnd = sub(bottomWrapper, 1, bottomWrapperLen - 10)return tostring(root) .. tostring(bottomWrapperEnd) .. trackingCategorieselsereturn tostring(root) .. trackingCategoriesendend-- Local function which handles both module entry points.local function main(frame, sublist, linetop)local getArgs = require('Модуль:Arguments').getArgslocal args-- Most parameters should still display when blank, so don't remove blanksif sublist thenargs = getArgs(frame, {removeBlanks=false, wrappers='Шаблон:Список серий/sublist'})elseif linetop thenargs = getArgs(frame, {removeBlanks=false, wrappers='Шаблон:Список серий/шапка'})elseargs = getArgs(frame, {removeBlanks=false, wrappers='Шаблон:Список серий'})endreturn _main(args, sublist, linetop)end---------------------------------------------------------------------------------- Экспорт--------------------------------------------------------------------------------function p.sublist(frame)return main(frame, true, false)endfunction p.linetop(frame)return main(frame, false, true)endfunction p.list(frame)return main(frame, false, false)endreturn p