Module:Infobox television season name/sandbox2 explained

require('strict')local match = require("Module:String")._match

local p =

--- Returns a formatted link to the list of episodes article.--- @param listOfEpisodesArticle string--- @return stringlocal function getListOfEpisodesLink(listOfEpisodesArticle) local listOfEpisodesPage = mw.title.new(listOfEpisodesArticle, 0) if listOfEpisodesPage and listOfEpisodesPage.exists and listOfEpisodesPage.redirectTarget ~= mw.title.getCurrentTitle then return string.format("List of episodes", listOfEpisodesArticle) endend

--- Returns an article link.--- @param article string The article's title.--- @param pipedLink string The piped link.--- @return stringlocal function getArticleLink(article, pipedLink) if not pipedLink or pipedLink

"" then return "" .. article .. "" end return "" .. pipedLink .. ""end

--- Returns the show name and season number from a title.--- @param showName string The show's title.--- @return nil | number | string, nil | number | stringlocal function getShowNameAndSeasonNumberFromShowName(showName) local _, _, showNameModified, seasonNumber = string.find(showName, "(.*)%s+(%d+)$") return showNameModified, seasonNumberend

--- Returns the current season number from the disambiguation.--- @param disambiguation string The article's disambiguation.--- @return stringlocal function getCurrentSeasonNumberFromDisambiguation(disambiguation) return match(disambiguation, "%d+", 1, -1, false, "")end

--- Returns the type of word used for "season" in the title.------ The returned value can be one of three options: "season", "series", "story arc" or "specials".--- @param title string The article's title.--- @return stringlocal function getSeasonType(title) for _, seasonType in pairs do if string.find(title, seasonType) then return seasonType end end return "season"end

--- Returns the season number from the title.--- @param title string The article's title.--- @return string | nillocal function getSeasonNumber(title) return match(title, "%d+", 1, -1, false, "")end

--- Returns the disambiguation from the title.--- @param title string The article's title.--- @return string | nillocal function getDisambiguation(title) local disambiguation = match(title, "%s%((.-)%)", 1, -1, false, "") if disambiguation and disambiguation

"" then return nil end return disambiguationend

--- Returns the title without its disambiguation.--- @param title string The article's title.--- @return string | nillocal function getTitleWithoutDisambiguation(title) local disambiguation = getDisambiguation(title) if disambiguation then return string.gsub(title, "%(" .. disambiguation .. "%)", "") end return titleend

--- Returns the TV program's disambiguation.--- @param disambiguation string The disambiguation used in the season's article title.--- @return stringlocal function getTVProgramDisambiguation(disambiguation) if not disambiguation then return "" end

-- Check if the disambiguation is normal 'season #' or 'series #'. -- If so, remove disambiguation. if string.match(disambiguation, "^season %d*$") or string.match(disambiguation, "^series %d*$") then return "" end

local disambiguationStyle = " (%s)" -- Check if the disambiguation is extended and has 'TV series' and isn't just season #. -- Only leave the TV series disambiguation, not including the season #. -- Example: Teenage Mutant Ninja Turtles (1987 TV series, season 5) will return '1987 TV series'. if string.find(disambiguation, "TV series") then local shortDisambiguation, _ = disambiguation:match("^(.*),") if shortDisambiguation then return string.format(disambiguationStyle, shortDisambiguation) end end

-- Check if the disambiguation is extended with country adjective. -- Example: The Office (American season 2) will return "American season 2". -- Keep only country adjective. local countryDisambiguation = disambiguation:match("^(.*) season %d*") or disambiguation:match("^(.*) series %d*") local data = mw.loadData("Module:Country adjective") local valid_result = data.getCountryFromAdj[countryDisambiguation] -- Check if the country adjective is valid. if valid_result then -- Add 'TV series' suffix return string.format(disambiguationStyle, countryDisambiguation .. " TV series") end

-- Not a known disambiguation style. Use whatever was used in the title or manually added. -- Note: might not be a valid style link. return string.format(disambiguationStyle, disambiguation)end

--- Returns the show's name from the title.--- @param title string The article's title.--- @return stringlocal function getShowName(title) local name, _ = mw.ustring.gsub(title, "season %d*$", "") name, _ = mw.ustring.gsub(name, "series %d*$", "") name, _ = mw.ustring.gsub(name, "specials", "") name, _ = mw.ustring.gsub(name, "story arc %d*$", "") name = string.match(name, "^%s*(.-)%s*$") -- Trim spaces. return nameend

--- Returns "true" if the given link is valid; nil otherwise.--- A link is valid in the following cases:--- -- A season article exists.--- -- A redirect exists to a season section.------ A link is invalid in the following cases:--- -- A season article or redirect do not exist.--- -- A redirect exists, but it is a general redirect and not for any specific season section.------ Note: Return values are not booleans as the returned value is used in template space.--- @param title string The article's title.--- @return string | nillocal function isLinkValid(title) local article = mw.title.new(title)

-- Article or redirect do not exist; Not a valid link. if not article or not article.exists then return nil end

local redirectTarget = article.redirectTarget

-- Article exists and is not a redirect; Valid link. if not redirectTarget then return "true" end

local fullLink = redirectTarget.fullText local isSection = fullLink:find("#")

-- Article is a section redirect; Valid link. if isSection then return "true" end

-- Article is a general redirect; Not a valid link. return nilend

--- Returns a season article title and a piped link.------ The following are the supported season naming styles:--- -- Style: --- Example: Lost season 2.--- Example: Doctor Who series 2.--- -- Style: ( TV series) --- Example: The Office (American TV series) season 2.--- Example: Teenage Mutant Ninja Turtles (1987 TV series) season 2--- Example: X Factor (British TV series) series 2.--- Example: Love Island (British TV series) series 2--- -- Style: ( TV series) --- Example: Love Island (2015 TV series) series 2--- -- Style: ( )--- Example: Big Brother 2 (American season).

--- @param title string The article's title.--- @param seasonNumberDiff number The number difference between the current season and the other season.--- @return string, stringlocal function getArticleTitleAndPipedLink(title, seasonNumberDiff) local seasonType = getSeasonType(title) local seasonNumber = getSeasonNumber(title) if tonumber(seasonNumber)

nil then return "", nil end seasonNumber = seasonNumber + seasonNumberDiff local modifiedTitle = string.gsub(title, "%d+$", seasonNumber) local pipedLink = seasonType:gsub("^%l", string.upper) .. " " .. seasonNumber

local disambiguation = getDisambiguation(title) -- Titles such as "Big Brother 2 (American season) and Teenage Mutant Ninja Turtles (1987 TV series) season 2". if disambiguation then local titleWithoutDisambiguation = string.gsub(title, disambiguation, "_DAB_") modifiedTitle = string.gsub(titleWithoutDisambiguation, "%d+", seasonNumber) modifiedTitle = string.gsub(modifiedTitle, "_DAB_", disambiguation) return modifiedTitle, pipedLink

-- Titles such as "Big Brother Brasil 2". elseif not string.find(title, seasonType) then return modifiedTitle, nil

-- Invalid usages of TV series articles with the television season infobox. elseif disambiguation and string.find(disambiguation, "TV series") and not (string.find(disambiguation, ", season") or string.find(disambiguation, ", series")) then return "", nil

-- Standard titles such as "Lost season 1". else return modifiedTitle, pipedLink endend

--- Returns the article's title either from args (usually from /testcases) or from the page itself.--- @param frame table The frame invoking the module.--- @return stringlocal function getTitle(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame) if args.italic_title then return "no" end local title = args.title if not title then title = mw.title.getCurrentTitle.text end return titleend

--- Returns "true" if the given season link is valid; nil otherwise.--- @param frame table The frame invoking the module.--- @param seasonNumberDiff number The number difference between the current season and the other season.--- @return string | nillocal function isSeasonLinkValid(frame, seasonNumberDiff) local title = getTitle(frame) local articleTitle, _ = getArticleTitleAndPipedLink(title, seasonNumberDiff) return isLinkValid(articleTitle)end

--- Returns a season article link.--- @param frame table The frame invoking the module.--- @param seasonNumberDiff number The number difference between the current season and the other season.--- @return stringlocal function getSeasonArticleLink(frame, seasonNumberDiff) local title = getTitle(frame) local articleTitle, pipedLink = getArticleTitleAndPipedLink(title, seasonNumberDiff) return getArticleLink(articleTitle, pipedLink)end

--- Returns "true" if the season link for the next season is valid; nil otherwise.--- @param frame table The frame invoking the module.--- @return string | nilfunction p.isNextSeasonLinkValid(frame) return isSeasonLinkValid(frame, 1)end

--- Returns "true" if the season link for the previous season is valid; nil otherwise.--- @param frame table The frame invoking the module.--- @return string | nilfunction p.isPrevSeasonLinkValid(frame) return isSeasonLinkValid(frame, -1)end

--- Returns "true" if the season link for the previous or next season is valid; nil otherwise.--- @param frame table The frame invoking the module.--- @return string | nilfunction p.isPrevOrNextSeasonLinkValid(frame) if p.isPrevSeasonLinkValid(frame)

"true" then return "true" end return p.isNextSeasonLinkValid(frame)end

--- Returns the next season article title.--- @param frame table The frame invoking the module.--- @return stringfunction p.getNextSeasonArticle(frame) return getSeasonArticleLink(frame, 1)end

--- Returns the previous season article title.--- @param frame table The frame invoking the module.--- @return stringfunction p.getPrevSeasonArticle(frame) return getSeasonArticleLink(frame, -1)end

--- Returns the type of season word used - "season" or "series".--- @param frame table The frame invoking the module.--- @return stringfunction p.getSeasonWord(frame) local title = getTitle(frame) title = getTitleWithoutDisambiguation(title) local seasonType = getSeasonType(title) return seasonTypeend

--- Returns an instance if title qualifies or a blank string.

--- @param frame table--- @return stringfunction p.getItalicTitle(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame) -- If italic_title is set then "no" is the only valid value. -- Don't set an italic title. if args.italic_title then return "" end

local title = getTitle(frame) title = getShowName(getTitleWithoutDisambiguation(title))

-- If the infobox is used on List of articles don't set an italic title. -- TODO: this can be fixed in the future but current usages use a manual display title. if string.find(title, "List of") then return "" end

return frame:expandTemplateend

--- Returns the text used for the |above= field of the infobox.------ @param frame table--- @return stringfunction p.getAboveTitle(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame) local title = getTitle(frame) title = getShowName(getTitleWithoutDisambiguation(title)) return titleend

--- Returns the text used for the |subheader= field of the infobox.------ The text is returned in the format of "Season #" or "Series #",--- depending on either what the article disambiguation uses, or on the manually entered parameters of the infobox.--- @param frame table The frame invoking the module.--- @return string | nilfunction p.getSubHeader(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame)

local seasonType local seasonNumber if args.season_number then seasonType = "Season" seasonNumber = args.season_number elseif args.series_number then seasonType = "Series" seasonNumber = args.series_number end

if not seasonNumber then local title = getTitle(frame) local titleWithoutDisambiguation = getTitleWithoutDisambiguation(title) seasonNumber = getSeasonNumber(titleWithoutDisambiguation) seasonType = getSeasonType(titleWithoutDisambiguation) -- For pages like "Doctor Who specials (2008–2010)". if seasonType

"specials" then local disambiguation = getDisambiguation(title) or "" return disambiguation .. " " .. seasonType end seasonType = seasonType:sub(1, 1):upper .. seasonType:sub(2) end

if seasonNumber and seasonNumber ~= "" then return seasonType .. " " .. seasonNumber end

return nilend

--- Returns a formatted link to the list of episodes article.------ The returned link is in the style of:--- [List of <series name> <disambiguation, if present> episodes <range, if present>|List of episodes]------ The link will only return if the page exists.--- @param frame table The frame invoking the module.--- @return string | nilfunction p.getListOfEpisodes(frame) local getArgs = require("Module:Arguments").getArgs local args = getArgs(frame)

if args.link then -- Parameter should be unformatted. if string.find(args.link, "%[") then local delink = require("Module:Delink")._delink args.link = delink({args.link, wikilinks = "target"}) end return getListOfEpisodesLink(args.link) end local title = getTitle(frame) local showName = getShowName(getTitleWithoutDisambiguation(title)) if showName then local disambiguation = getDisambiguation(title) if disambiguation then disambiguation = " (" .. disambiguation .. ")" end local listOfEpisodesArticle = string.format("List of %s%s episodes", showName, disambiguation or "") return getListOfEpisodesLink(listOfEpisodesArticle) end end return p]