跳转到内容

模块:剧集列表

维基百科,自由的百科全书
local p = {}
local episodes = {}

local titleList = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"}
local localColSpan = 0
local localRowSpan = 0
local summaryRow = false

function episodes.headerRow(text, style, rowStyle, colspan, rowspan)
	local row = mw.html.create("th")
	
	if checknil(text) then
		localColSpan = localColSpan + 1
		row
		   :attr("colspan", (colspan or "1"))
		   :attr("rowspan", (rowspan or tostring(localRowSpan-1)))
		   :cssText("padding:.2em .5em;"..(rowStyle or "")..(style or ""))
		   :wikitext(text)
		return row
	end
	
	return
end

function episodes.baseSummaryRow(text, lineColor)
	local row = mw.html.create("td")
	
	if text ~= "" then
		local summaryDiv = mw.html.create('div') -- Copy and edited from the [[en:Module:Episode list]]
				:css("max-width", "90vw")
				:css("position", "sticky")
				:css("left", "0.2em")
				:newline()
				:wikitext(text)
		
		row:addClass("description")
		   :attr("colspan", 30)
		   :css("padding", ".5em")
		   :css("text-align", "left")
		   :css("background", "var(--background-color-base, transparent)")
		   :css("color", "var(--color-base)")
		   :css("white-space", "normal")
		   :css("border-bottom", ".3em solid "..(lineColor or "#aaa"))
		   :node(summaryDiv)
		return mw.html.create("tr"):node(row)
	end

	return
end

function episodes.titleRow(text, subtitle, nativeTitle, rowStyle, style, subtitleStyle, colspan, rowspan)
	local row = mw.html.create("td")
	
	if summaryRow then text = "<strong>"..text.."</strong>" end
	if checknil(subtitle) then 
		text = text .. "<br /><small style=\"color:gray;" ..(checknil(subtitleStyle) and subtitleStyle or "").. "\"><em>" ..subtitle.. "</em></small>"
	end
	if checknil(nativeTitle) then
		text = text .. "<br />-{(" ..nativeTitle.. ")}-"
	end
	
	if checknil(text) then
		row:attr("colspan", colspan)
		   :attr("rowspan", (summaryRow and "1" or (rowspan or "1")))
		   :css("text-align", "left")
		   :css("padding", ".2em .5em")
		   :css("line-height", "1.2")
		   :cssText((rowStyle or "")..(style or ""))
		   :wikitext(text)
		return row
	end
	
	return
end

function episodes.multipleTitleRow(text, subtitle, nativeTitle, style, rowStyle, subtitleStyle, colspan, rowspan)
	local row = mw.html.create()
	
	if checknil(text) then
		row:node(episodes.titleRow(
		   	text, subitle, 
		   	nativeTitle, style,
		   	rowStyle, subtitleStyle, 
		   	colspan, rowspan
		   )):addClass("Title-EX")
			 :attr("scope", "row")
			 :css("height", "2em")
		return row
	end

	return
end

function episodes.chapterRow(text, style, rowStyle, lineColor)
	local row = mw.html.create("th")
	
	if checknil(text) then
		if (lineColor or "") ~= "" then row:css("border-bottom-color", lineColor) end
		row:attr("colspan", (colspan or "25"))
		   :cssText((rowStyle or "")..(style or ""))
		   :wikitext(text)
		return row
	end

	return
end

function episodes.baseRow(tableclass, class, text, style, rowStyle, colspan, rowspan)
	local row = mw.html.create(tableclass or "td")

	-- Check text
	if text == "TBA" or text == "待公布" then -- {{TBA}} template
		text = "待公布"
		style = "background: #DDF; vertical-align: middle;"..(style == nil and style or "")
	elseif text == "TBD" or text == "待定" then -- {{TBD}} template
		text = "待定"
		style = "background: #FFD; vertical-align: middle;"..(style == nil and style or "")
	elseif text == "N/A" or text == "不適用" or text == "不适用" or text == "-" then -- {{N/A}} template
		if text ~= "-" then text = "不適用" end
		if class ~= nil then class = "table-na skin-invert"..(class.." " or "") end
		style = "background: var(--background-color-disabled-subtle, #ececec); color: var(--color-disabled, #2c2c2c); vertical-align: middle; font-size: smaller;"..(style == nil and style or "")
	end

	if checknil(text) then
		localColSpan = localColSpan + 1
		if summaryRow then 
			if localRowSpan > 0 then rowspan = tostring(localRowSpan-1)
			else rowspan = "1" end
		end
		if string.find(text or "", "data-temp=\"spml\"", 0, true) ~= nil then -- {{spml}} template fixed
			text = text:gsub("、", "<span style='user-select: none'>、</span>")
			text = "<span style='white-space:normal'>"..text.."</span>"
		end
		row
		   :addClass(class)
		   :attr("scope", "col")
		   :attr("colspan", (colspan or "1"))
		   :attr("rowspan", rowspan or tostring(localRowSpan-1))
		   :css("text-align", "center")
		   :cssText("padding:.2em .5em;"..(rowStyle or "")..(style or ""))
		   :wikitext(text)
		return row
	end

	return ""
end

function episodes.listrow(args, id, text, dtext)
	local htext = "td"
	if id == 1 then
		htext = "th"
	elseif id == 2 then
		return episodes.titleRow(
			args["Title"], args["Subtitle"],
			args["NativeTitle"], args["TitleStyle"],
			args.Style, args["SubtitleStyle"],
			args["TitleColSpan"], args["TitleRowSpan"]
		)
	elseif id == 3 then
		return episodes.multipleTitleRow(
			args["Title"..text], args["Subtitle"..text],
			args["NativeTitle"..text], args["Title"..text.."Style"],
			args.Style, args["Subtitle"..text.."Style"],
			args["Title"..text.."ColSpan"], args["Title"..text.."RowSpan"]
		)
	elseif id == -1 then
		return episodes.headerRow(
			(args[text] or dtext), args[text.."Style"],
			args.Style, args[text.."ColSpan"],
			args[text.."RowSpan"]
		)
	end
	return episodes.baseRow(
		htext, args[text.."Class"], 
		args[text], args[text.."Style"], 
		args.Style, args[text.."ColSpan"], 
		args[text.."RowSpan"]
	)
end

function checknil(data)
	return ((data or "") ~= "")
end

function episodes.base(args)
	args = args or {}

	local base = mw.html.create("tr")
	summaryRow = checknil(args.Summary) and (not checknil(args.SubtitleOf) or (checknil(args.SubtitleOf) and mw.title.getCurrentTitle().text ~= args.SublistOf))
	
	if args.Chapter then
		base:node(episodes.chapterRow(args.Chapter, args.ChapterStyle, args.Style, args.ChapterColSpan))
		return base
	end
	
	base
		:node(episodes.listrow(args, -1, "Header0"))
		:node(episodes.listrow(args, -1, "Header1"))
	
	if checknil(args["TitleA"]) then
		localRowSpan = localRowSpan + 1
		for i=1,6 do 
			if checknil(args["Title"..titleList[i]]) then 
				localRowSpan = localRowSpan + 1
			end
		end
	else localRowSpan = 0 end

	if args["Number"] ~= "!INVISIBLE" then
		base:node(episodes.listrow(args, (summaryRow and 1 or 0), "Number"))
	end
	
	if checknil(args["TitleA"]) then
		base:node(episodes.listrow(args, 3, "A"))
	elseif args["Title"] ~= "!INVISIBLE" then
		base:node(episodes.listrow(args, 2, ""))
	end

	for i=0,20 do
		base:node(episodes.listrow(args, 0, "Aux"..i))
		if mw.title.getCurrentTitle().text ~= args.SublistOf then
			if i%5 == 0 then
				for j=0+6*((i-5)/5),5+6*((i-5)/5) do
					base:node(episodes.listrow(args, 0, "SubAux"..i))
				end
			end
		end
	end

	if checknil(args["TitleA"]) then
		for i=2,6 do
			if checknil(args["Title"..titleList[i]]) then
				base:tag("tr"):node(episodes.listrow(args, 3, titleList[i]))
			end
		end
	end
	
	if summaryRow then 
		base:tag("tr"):node(episodes.baseSummaryRow(args.Summary, args.LineColor))
	end
		
    return base
end

function episodes.header(args)
	args = args or {}
	
	local header = mw.html.create((args.ExcludeTableTag and "tr" or "table"))
	
	if not args.ExcludeTableTag then
		header
		  :addClass("wikitable")
		  :addClass("wikiepisodetable")
		  :css("border-collapse", "collapse")
		  :css("border-spacing", "0")
		  :cssText(args.TableStyle)
	end
	
	if (args.Caption or "") ~= "" then
		header:tag("caption")
			  :cssText(args.CaptionStyle)
			  :wikitext(args.Caption)
	end
		  
	local headerRow = header:tag("tr")
	
	headerRow
		     :cssText("border-bottom: .3em solid " .. (args.LineColor or "#aaa"))
			 :node(episodes.listrow(args, -1, "Header0"))
			 :node(episodes.listrow(args, -1, "Header1"))
	if args["Number"] ~= "!INVISIBLE" then
		headerRow:node(episodes.listrow(args, -1, "Number" , "#"))
	end
	if args["Title"] ~= "!INVISIBLE" then
		headerRow:node(episodes.listrow(args, -1, "Title" , "劇集標題"))
	end
	for i=0,20 do
		headerRow:node(episodes.listrow(args, -1, "Aux"..i))
		if mw.title.getCurrentTitle().text ~= args.SublistOf then
			if i%5 == 0 then
				for j=0+6*((i-5)/5),5+6*((i-5)/5) do
					headerRow:node(episodes.listrow(args, -1, "SubAux"..i))
				end
			end
		end
	end
    return tostring(mw.ustring.gsub(tostring(header), "</table>", ""))
end

function p.mainHeader(frame)
    local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
        wrappers = "Template:劇集列表/base/header"
    })
	return episodes.header(args)
end

function p.main(frame)
    local args = require('Module:Arguments').getArgs(frame, {
		removeBlanks = false,
        wrappers = "Template:劇集列表/base"
    })
	return episodes.base(args)
end

return p