Mô đun:Infobox television season name

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

local p = {}

--- Returns a formatted link to the list of episodes article.
--- @param listOfEpisodesArticle string
--- @return string
local 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("[[%s|Danh sách các tập phim]]", listOfEpisodesArticle)
	end
end

--- Trả về link bài viết.
--- @param article string Tiêu đề bài viết.
--- @param pipedLink string The piped link.
--- @return string
local function getArticleLink(article, pipedLink)
	if not pipedLink or pipedLink == "" then
		return "[[" .. article .. "]]"
	end
	return "[[" .. article .. "|" .. pipedLink .. "]]"
end

--- Trả về tên chương trình và số mùa từ từ tiêu đề.
--- @param showName string Tiêu đề chương trình.
--- @return nil | number | string, nil | number | string
local function getShowNameAndSeasonNumberFromShowName(showName)
	local _, _, showNameModified, seasonNumber = string.find(showName, "(.*)%s+(%d+)$")
	return showNameModified, seasonNumber
end

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

--- Returns the type of word used for "season" in the disambiguation.
---
--- The returned value can be one of three options: "season", "series", "story arc" or "specials".
--- @param disambiguation string The article's disambiguation.
--- @return string
local function getSeasonType(disambiguation)
	for _, seasonType in pairs({"season", "series", "story arc", "specials", "mùa", "phần"}) do
		if string.find(disambiguation, seasonType) then
			return seasonType
		end
	end
	return "season"
end

--- Returns the disambiguation without the "phim truyền hình (year)," part.
--- @param disambiguation string The article's disambiguation.
--- @return string
local function getShortDisambiguation(disambiguation)
	local shortDisambiguation, _ = string.gsub(disambiguation, "phim truyền hình %d+, ", "")
	return shortDisambiguation
end

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

--- Returns the TV program's disambiguation.
--- @param disambiguation string The disambiguation used in the season's article title.
--- @return string
local 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, "^mùa %d*$") or string.match(disambiguation, "^phần %d*$") then
		return ""
	end

	local disambiguationStyle = " (%s)"
	-- Check if the disambiguation is extended and has 'phim truyền hình' and isn't just season #.
	-- Only leave the TV series disambiguation, not including the season #.
	-- Example: Teenage Mutant Ninja Turtles (phim truyền hình 1987, mùa 5) will return 'phim truyền hình 1987'.
	if string.find(disambiguation, "phim truyền hình") 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("^(.*) mùa %d*") or disambiguation:match("^(.*) phần %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 string
local function getShowName(title)
	local name, _ = mw.ustring.gsub(title, "%s+%b()$", "")
	return name
end

--- 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 | nil
local 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 nil
end

--- Returns a season article title and a piped link.
---
--- The following are the supported season naming styles:
---	--  Style: <showName> (<seasonType> <seasonNumber>)
---		Example: Lost (season 2).
---		Example: Doctor Who (series 2).
---	--  Style: <showName> (<country> <seasonType> <seasonNumber>)
---		Example: The Office (American season 2).
---		Example: X Factor (British series 2).
---	--  Style: <showName> (<country> <seasonType>)
---		Example: Big Brother 2 (American season).
---	--  Style: <showName> (<year> TV series, <seasonType> <seasonNumber>)
---		Example: Teenage Mutant Ninja Turtles (1987 TV series, season 2)
---	--  Style: <showName> (<country> TV series, <seasonType> <seasonNumber>)
---		Example: Love Island (British TV series, series 2)
--- @param title string The article's title.
--- @param seasonNumberDiff number The number difference between the current season and the other season.
--- @return string, string
local function getArticleTitleAndPipedLink(title, seasonNumberDiff)
	local disambiguation = getDisambiguation(title)
	local shortDisambiguation
	local seasonType
	local seasonNumber
	local pipedLink = ""

	if disambiguation then
		shortDisambiguation = getShortDisambiguation(disambiguation)
		seasonType = getSeasonType(shortDisambiguation)
		seasonNumber = getCurrentSeasonNumberFromDisambiguation(shortDisambiguation)
		pipedLink = seasonType:gsub("^%l", string.upper) .. " "
	end

	local showName = getShowName(title)
	local showNameModified
	if not seasonNumber or seasonNumber == "" then
		-- Not a valid next/prev season link
		if not string.match(showName, "%s+(%d+)$") then
			return "", nil
		end

		showNameModified, seasonNumber = getShowNameAndSeasonNumberFromShowName(showName)
	end

	if tonumber(seasonNumber) == nil then
		return "", nil
	end

	seasonNumber = seasonNumber + seasonNumberDiff
	pipedLink = pipedLink .. seasonNumber

	-- Titles such as "Big Brother 1 (American season)""
	if showNameModified and disambiguation then
		return showNameModified .. " " .. seasonNumber .. " (" .. disambiguation .. ")", pipedLink

	-- Titles such as "Big Brother Brasil 1"
	elseif showNameModified then
		return showNameModified .. " " .. seasonNumber, nil

	-- Standard titles such as "Lost (season 1)"
	else
		local newDisambiguation, _ = string.gsub(disambiguation, "%d+$", seasonNumber)
		return showName .. " (" .. newDisambiguation .. ")", pipedLink
	end
end

--- 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 string
local function getTitle(frame)
	local getArgs = require("Module:Arguments").getArgs
	local args = getArgs(frame)
	local title = args.title

	if not title then
		title = mw.title.getCurrentTitle().text
	end
	return title
end

--- 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 | nil
local 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 string
local 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 | nil
function 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 | nil
function 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 | nil
function 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 string
function p.getNextSeasonArticle(frame)
	return getSeasonArticleLink(frame, 1)
end

--- Returns the previous season article title.
--- @param frame table The frame invoking the module.
--- @return string
function 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 string
function p.getSeasonWord(frame)
	local title = getTitle(frame)
	local disambiguation = getDisambiguation(title)
	if not disambiguation then
		return ""
	end

	local shortDisambiguation = getShortDisambiguation(disambiguation)
	local seasonType = getSeasonType(shortDisambiguation)
	if seasonType == "specials" then
		seasonType = "season"
	end

	return seasonType
end

--- Returns the relevant text for the sub-header field.
---
--- 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 | nil
function p.getInfoboxSubHeader(frame)
	local getArgs = require("Module:Arguments").getArgs
	local args = getArgs(frame)

	local seasonType
	local seasonNumber
	if args.season_number then
		seasonType = "Mùa"
		seasonNumber = args.season_number
	elseif args.series_number then
		seasonType = "Phần"
		seasonNumber = args.series_number
	end

	local title = getTitle(frame)
	local disambiguation = getDisambiguation(title)
	if not seasonNumber and disambiguation then
		local shortDisambiguation = getShortDisambiguation(disambiguation)

		seasonType = getSeasonType(shortDisambiguation)
		if seasonType == "specials" then
			return shortDisambiguation
		end
		seasonType = seasonType:sub(1, 1):upper() .. seasonType:sub(2)
		seasonNumber = getCurrentSeasonNumberFromDisambiguation(shortDisambiguation)
	end

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

	return nil
end

--- 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 | nil
function 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(title)

	if showName then
		local disambiguation = getDisambiguation(title)
		local TVProgramDisambiguation = getTVProgramDisambiguation(disambiguation)
		local listOfEpisodesArticle = string.format("Danh sách các tập phim %s%s", showName, TVProgramDisambiguation)
		return getListOfEpisodesLink(listOfEpisodesArticle)
	end
end

return p
Chúng tôi bán
Bài viết liên quan
Tổng quan Ginny - Illusion Connect
Tổng quan Ginny - Illusion Connect
Quy tắc và mệnh lệnh chỉ là gông cùm trói buộc cô. Và cô ấy được định mệnh để vứt bỏ những xiềng xích đó.
[Genshin Impact] Tại sao Eula lại hot đến vậy
[Genshin Impact] Tại sao Eula lại hot đến vậy
Bài viết sẽ tổng hợp mọi nội dung liên quan đến nhân vật mới Eula trong Genshin Impact
Tổng hợp tất cả nhân vật trong Overlord
Tổng hợp tất cả nhân vật trong Overlord
Danh sách các nhân vật trong Overlord
5 lọ kem chống nắng trẻ hóa làn da tốt nhất
5 lọ kem chống nắng trẻ hóa làn da tốt nhất
Nếu da đã bắt đầu xuất hiện dấu hiệu lão hóa, bạn nên tham khảo 5 lọ kem chống nắng sau