:wikitext(titleText)
else
row:tag('th')
:addClass('summary')
:attr('scope', 'row')
:css('text-align', textAlign)
:wikitext(titleText)
end
else
if (isSerial) then
row:tag('td')
:addClass('summary')
:attr('rowspan', numberOfParameterGroups)
:css('text-align', textAlign)
:wikitext(titleText)
else
row:tag('td')
:addClass('summary')
:css('text-align', textAlign)
:wikitext(titleText)
end
end  
nonNilParams = nonNilParams + 1
end  
-- 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 = string.match(episodeNumber, "^%w+")
row:tag('th')
:attr('scope', 'row')
:attr('rowspan', numberOfParameterGroups)
:attr('id', epID and 'ep' .. epID or '')
:css('text-align', '')
:wikitext(episodeText)
end  
---
Local function which is used to extract the text from the EpisodeNumber or EpisodeNumber2
parameters 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 == '') then
return tableEmptyCellModule._main({})
else  
local episodeNumber1
local episodeNumber2  
-- Used for double episodes that need a visual "–"" or "<hr />"" added.
local divider  
episodeNumber = episodeNumber:gsub('%s*<br%s*/?%s*>%s*', '<hr />')  
if (episodeNumber:match('^(%w+)%s*<hr */%s*>%s*(%w+)$')) then
episodeNumber1, 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 elements
episodeNumber1, episodeNumber2 = episodeNumber:match('^(%w+)%s*<hr */%s*>.-<hr */%s*>%s*(%w+)$')
divider = "<hr />"
elseif (mw.ustring.match(episodeNumber, '^(%w+)%s*[%s%-–/&]%s*(%w+)$')) then
episodeNumber1, episodeNumber2 = mw.ustring.match(episodeNumber, '^(%w+)%s*[%s%-–/&]%s*(%w+)$')
divider = "–"
else
episodeNumber1, episodeNumber2 = mw.ustring.match(episodeNumber, '^(%w+)%s*[%s%-–/&].-[%s%-–/&]%s*(%w+)$') -- 3 or more elements
divider = "–"
end  
if (not episodeNumber1) then
return episodeNumber
elseif (not episodeNumber2) then
return string.match(episodeNumber, '%w+')
else
return episodeNumber1 .. divider .. episodeNumber2
end
end
end  
-- Local function which is used to create EpisodeNumber2 and EpisodeNumber3 cells.
local function _createEpisodeNumberCellSecondary(episodeValue, numberOfParameterGroups)
if (episodeValue) then
local episodeText = getEpisodeText(episodeValue)  
if (nonNilParams == 0) then
createTableRowEpisodeNumberHeader(episodeValue, numberOfParameterGroups, episodeText)
else
createTableData(episodeText, numberOfParameterGroups, "")
end  
nonNilParams = nonNilParams + 1  
end
end  
-- Local function which is used to create seconday episode number cells.
local function createEpisodeNumberCellSecondary(args, numberOfParameterGroups)
_createEpisodeNumberCellSecondary(args.EpisodeNumber2, numberOfParameterGroups)
_createEpisodeNumberCellSecondary(args.EpisodeNumber3, numberOfParameterGroups)
end  
-- Local function which is used to create an EpisodeNumber cell.
local function createEpisodeNumberCell(args, numberOfParameterGroups)
if (args.EpisodeNumber) then
local episodeText = getEpisodeText(args.EpisodeNumber)
createTableRowEpisodeNumberHeader(args.EpisodeNumber, numberOfParameterGroups, episodeText)
nonNilParams = nonNilParams + 1
end
end  
-- 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 do
args = extractDataFromNumberedSerialArgs(args, i, numberOfParameterGroups, title)
createCells(args, true, i, onInitialPage, title, numberOfParameterGroups)
if (i ~= numberOfParameterGroups) then
row = row:done -- Use done to close the 'tr' tag in rowspaned rows.
:tag('tr')
:css('background', topColor)
end
end
end  
-- Local function which is used to retrieve the NumParts value.
local function getnumberOfParameterGroups(args)
for k, v in ipairs(cellNameList) do
local numberedParameter = v .. "_" .. 1
if (args[numberedParameter]) then
parameterGroupCells[v] = true
if not firstParameterGroupCell then
firstParameterGroupCell = k
end
end
end  
if (hasValue(args.NumParts)) then
return args.NumParts, true
else
return 1, false
end
end  
-- Local function which is used to retrieve the Top Color value.
local function getTopColor(args, rowColorEnabled, onInitialPage)
local episodeNumber = mathModule._cleanNumber(args.EpisodeNumber) or 1
if (args.TopColor) then
if (string.find(args.TopColor, "#")) then
return args.TopColor
else
return '#' .. args.TopColor
end
elseif (rowColorEnabled and onInitialPage and mathModule._mod(episodeNumber, 2) == 0) then
return '#E9E9E9'
elseif (onInitialPage and args.ShortSummary) then
return '#F2F2F2'
else
return 'inherit'
end
end  
-- Local function which is used to retrieve the Row Color value.
local function isRowColorEnabled(args)
local rowColorEnabled = yesNoModule(args.RowColor, false)  
if (args.RowColor and string.lower(args.RowColor) == 'on') then
rowColorEnabled = true
end  
return rowColorEnabled
end  
-- Local function which is used to retrieve the Line Color value.
local function getLineColor(args)
-- Default color to light blue
local lineColor = args.LineColor or 'CCCCFF'  
-- Add # to color if necessary, and set to default color if invalid
if (htmlColor[lineColor] == nil) then
lineColor = '#' .. (mw.ustring.match(lineColor, '^[%s#]*([a-fA-F0-9]*)[%s]*$') or '')
if (lineColor == '#') then
lineColor = '#CCCCFF'
end
end  
return lineColor
end  
-- 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  
-- Only sublist had anything about hiding, so only it needs to even check
if (sublist) then
onInitialPage = mw.uri.anchorEncode(pageTitle) == mw.uri.anchorEncode(initiallistTitle)
-- avoid processing ghost references
if (not onInitialPage) then
args.ShortSummary = nil
end
else
if (initiallistTitle == "") then
onInitialPage = true
else
onInitialPage = mw.uri.anchorEncode(pageTitle) == mw.uri.anchorEncode(initiallistTitle)
end
end  
return onInitialPage
end  
-- Local function which does the actual main process.
local function _main(args, sublist)