跳转到内容

模組:CNBUS/sandbox

本页使用了标题或全文手工转换
维基百科,自由的百科全书

这是本页的一个历史版本,由TimWu007留言 | 贡献2021年12月19日 (日) 15:53编辑。这可能和当前版本存在着巨大的差异。

-- 声明模块本体
local p = {
	NO_DATA = '(暂缺)',
	DEFAULT_SPACE = ' ',
}

-- 导入城市数据
local function _loadSystemData(city)
	local system_data = nil
	local err_text = nil
	if city ~= nil and city ~= "" then
		local state
		state, ro_system_data = pcall(mw.loadData, "Module:CNBUS/"..city)
		if state then
			system_data = setmetatable( {}, { __index = ro_system_data });	-- 转换为可读写的table
			system_data.locName = {}
			for i1, t1 in pairs(system_data.location) do
				for _, k1 in pairs(t1) do
					system_data.locName[k1] = t1[1]
				end
			end
			system_data.compName = {}
			for i2, t2 in pairs(system_data.company) do
				for _, k2 in pairs(t2) do
					system_data.compName[k2] = t2[1]
				end
			end
		else
			err_text = mw.ustring.format('[\[Module:CNBUS]\]不存在“%s”的公交系统数据', city)
		end
	else
		err_text = mw.ustring.format('“city”参数为空,请输入城市代码')
	end
	return system_data, err_text
end

local function _isEmpty(var)
	if var == '' then var = nil end
	return not var
end

-- 导入路线数据
local function _loadLineData(datapath)
	local city_data = nil
	local err_text = nil
	local state
	state, city_data = pcall(mw.loadData, datapath)
	if not state then
		err_text = mw.ustring.format("资料模块[\[%s]\]出现错误,请前往检查", datapath)
	end
	return city_data, err_text
end

-- {{巴士公司色块}}
function p._internalColorbox(compname, city)
	local sys = _loadSystemData(city)						-- 加载系统数据
	str = compname
	len = #str
	if sys.compName[compname] then
		box_output = string.format('width=1%% bgcolor=%s', sys.colors[sys.compName[compname]])
	elseif len > 18 or compname == "multi" then				-- 公司名超过六个字为联营
		box_output = string.format('width=1%% bgcolor=%s', sys.colors['multi'])	
	else
		box_output = string.format('width=1%% bgcolor=%s', sys.colors['other'])
	end
	return box_output
end

-- 仅输出颜色
function p._internalColor(compname, city)
	local sys = _loadSystemData(city)						-- 加载系统数据
	str = compname
	len = #str
	if sys.compName[compname] then
		color = sys.colors[sys.compName[compname]]
	elseif len > 18 or compname == "multi" then				-- 公司名超过六个字为联营
		color = sys.colors['multi']
	else
		color = sys.colors['other']
	end
	return color
end

-- 处理起讫点中出现的跨粤文维基百科的链接模板({{tsl|zh-yue|...}})
function p._internalTsllink(name)
	if _isEmpty(name) then
		str = p.DEFAULT_SPACE
	else
		str = name --[[
		if string.find(name, "tsl") then
			start = string.find(name, "{")
			en3 = string.find(name, "}", start)
			en1 = string.find(name, "|", start+13)
			arg1 = string.sub(name, start+13, en1-1)
			en2 = string.find(name, "|", en1+1)
			arg2 = string.sub(name, en1+1, en2-1)
			arg3 = string.sub(name, en2+1, en3-1) 
			no1 = string.sub(name, 0, start-1)
			fi1 = string.find(name, "{", en2+1)
			if fi1 == nil then			-- 只引用一次tsl
				no2 = string.sub(name, en3+2, string.len(name))
				str = no1..mw.getCurrentFrame():expandTemplate{title = "ly", args = {arg2, arg1, arg3}}..no2
			else 						-- 引用两次tsl
				start1 = string.find(name, "{", en3)
				no2 = string.sub(name, en3+2, start1-1)
				en4 = string.find(name, "|", start1+13)
				arg4 = string.sub(name, start1+13, en4-1)
				en5 = string.find(name, "|", en4+1)
				arg5 = string.sub(name, en4+1, en5-1)
				en6 = string.find(name, "}", start1)
				arg6 = string.sub(name, en5+1, en6-1) 
				no3 = string.sub(name, en6+2, string.len(name))
				str = no1..mw.getCurrentFrame():expandTemplate{title = "ly", args = {arg2, arg1, arg3}}..no2..mw.getCurrentFrame():expandTemplate{title = "ly", args = {arg5, arg4, arg6}}..no3
			end
		end ]]
	end
	return str
end

-- 生成一条路线的一列表格内容
function p._internalList(no, style, city, loc, time, vehicle, image)
	local sys, err_text = _loadSystemData(city)			-- 加载系统数据
	if not err_text and sys.locName[loc] then
		sysloc = sys.locName[loc]						-- sysloc为拼音
		loc = sys.titlename[sysloc]						-- loc为简体
		d, err_text = _loadLineData(sys.data[sysloc])	-- 加载线路数据
	elseif not err_text then
		err_text = mw.ustring.format("[\[Module:CNBUS/%s]\]中未包含“%s”的资料模块", city, loc)
	end
	
	table_output = mw.html.create('tr')
	
	if err_text then
		no = "错误"
	elseif _isEmpty(no) then
		no = "无输入"
		err_text = mw.ustring.format("请输入线路[\[%s巴士路线列表|编号]\]", loc)
	elseif not d[no] then
		err_text = mw.ustring.format("[\[%s]\]中未包含这条[\[%s巴士路线列表|%s]\]的线路", sys.data[sysloc], loc, loc)
	elseif d[no].note and mw.ustring.match(d[no].note, "已停[办辦]") then
		if _isEmpty(d[no].suspend) then
			err_text = "本线已停办,请移除"
		else
			err_text = mw.ustring.format("本线自%s起停办,请移除", d[no].suspend)
		end
		no = d[no].code
	elseif d[no].note and (d[no].note == "暂停服务" or d[no].note == "暫停服務") then
		if _isEmpty(d[no].suspend) then 
			err_text = "本线已暂停服务"
		else
			err_text = mw.ustring.format("本线自%s起暂停服务", d[no].suspend)
		end
		no = d[no].code
	else
		data_color = p._internalColor(d[no].company, city)			-- 获取颜色
		data_ep1 = d[no].endpoint1 or ""
		data_ep2 = d[no].endpoint2 or data_ep1
		--[[ p._internalTsllink(d[no].endpoint1)				-- 处理起讫点1可能出现的{{tsl|zh-yue}}
		if _isEmpty(d[no].endpoint2) then
			data_ep2 = data_ep1
		else
			data_ep2 = p._internalTsllink(d[no].endpoint2)			-- 处理起讫点2可能出现的{{tsl|zh-yue}}
		end]]
		if _isEmpty(d[no].endpoint3) then							-- 部分双向高峰快线:去程终点和返程起点不同
			data_ep3 = nil 											-- 处理起讫点3可能出现的{{tsl|zh-yue}}
		else
			data_ep3 = p._internalTsllink(d[no].endpoint3)
		end
		if time == "yes" then
		--if time and mw.ustring.match(time, "[Yy][Ee][Ss]") then
			if not _isEmpty(d[no].time1) then data_ep1 = data_ep1..[[<br>]]..d[no].time1 end
			if not _isEmpty(d[no].time2) then data_ep2 = data_ep2..[[<br>]]..d[no].time2 end
			if not _isEmpty(d[no].time3) and data_ep3 then data_ep3 = data_ep3..[[<br>]]..d[no].time3 end
		end
		if _isEmpty(d[no].direction) then
            if _isEmpty(d[no].endpoint2) then
			    data_direction = "↺"
            else
			    data_direction = "⇆"
            end
        elseif not _isEmpty(d[no].direction1) then			-- 部分线路的第二个方向
			if data_ep3 then								-- 部分线路去程终点和返程起点不同
				data_direction = d[no].direction..'<hr>'..d[no].direction1
				data_ep2 = data_ep2..'<hr>'..data_ep3
			else 
				data_direction = d[no].direction..'<br>'..d[no].direction1
			end
		else
			data_direction = d[no].direction
        end
        
		data_note = d[no].note or ""

		-- BRT样式(广州、中山)
		if style == "BRT" and _isEmpty(d[no].brt_b) then				-- 不是BRT路线
			err_text = "本线并非[\[快速公交系统|BRT线路]\]"
		elseif style == "BRT" and not _isEmpty(d[no].brt_b) then		-- BRT样式:单向路线(一列,广州)
			
			data_brt_b_in = p._internalTsllink(d[no].brt_b_in)
			data_brt_b_out = p._internalTsllink(d[no].brt_b_out)
			if not _isEmpty(d[no].brt_a) then
				data_brt_a_in = p._internalTsllink(d[no].brt_a_in)
				data_brt_a_out = p._internalTsllink(d[no].brt_a_out)
				data_brtin = data_brt_a_in..'<hr>'..data_brt_b_in
				data_brtout = data_brt_a_out..'<hr>'..data_brt_b_out
				data_brtno = d[no].brt_a..'<hr>'..d[no].brt_b
				data_direction = "→<hr>←"
			else
				data_brtin = data_brt_b_in
				data_brtout = data_brt_b_out
				data_brtno = d[no].brt_b
			end
			data_company = d[no].company or ""
			if not _isEmpty(d[no].brt_info) then
				if not _isEmpty(data_note) then
					data_note = data_note..[[;]]..d[no].brt_info
				else
					data_note = data_note..d[no].brt_info
				end
			end
			table_output
				:tag('td')
					:attr('width', '1%')
					:attr('bgcolor', data_color)
					:done()
				:tag('td')
					:tag('b')
						:wikitext(d[no].code)
						:done()
					:done()
				:tag('td')
					:attr('align', 'right')
					:wikitext(data_ep1)
					:done()
				:tag('td')
					:wikitext(data_direction)
					:done()
				:tag('td')
					:attr('align', 'left')
					:wikitext(data_ep2)
					:done()
				:tag('td')
					:wikitext(data_brtin)
					:done()
				:tag('td')
					:wikitext(data_brtout)
					:done()
				:tag('td')
					:wikitext(data_brtno)
					:done()
				:tag('td')
					:wikitext(data_company)
		-- 非BRT样式
		else
			table_output
				:tag('td')
					:attr('width', '1%')
					:attr('bgcolor', data_color)
					:done()
				:tag('td')
					:tag('b')
						:wikitext(d[no].code)
						:done()
					:done()
				:tag('td')
					:attr('align', 'right')
					:wikitext(data_ep1)
					:done()
				:tag('td')
					:attr('nowrap', 'true')
					:wikitext(data_direction)
					:done()
				:tag('td')
					:attr('align', 'left')
					:wikitext(data_ep2)
					:done()
			if style ~= "nofa" and style ~= "nocofa" then
				data_fare = d[no].fare or ""
				table_output
					:tag('td')
						:wikitext(data_fare)
			end
			if style ~= "noco" and style ~= "nocofa" then				-- 不显示公司栏(noco、nocofa)
				data_company = d[no].company or ""
				table_output
					:tag('td')
						:wikitext(data_company)
			end
			if vehicle == "yes" then						-- 配车信息(惠州)
				data_vehicle = d[no].vehicle or ""
				table_output
					:tag('td')
						:wikitext(data_vehicle)
			end
		end
		if image == "yes" and not _isEmpty(d[no].image) then
			if not _isEmpty(d[no].note) then
				data_note = data_note..'<br>'..d[no].image
			else
				data_note = d[no].image
			end
		end
		table_output
			:tag('td')
				:attr('align', 'left')
				:wikitext(data_note)
			:allDone()
			:newline()
	end
	if err_text then						-- 输出错误信息
		table_output
			:tag('td')
				:attr('width', '1%')
				:done()
			:tag('td')
				:tag('b')
					:wikitext(mw.ustring.format("%s", no))
					:done()
				:done()
			:tag('td')
				:attr('colspan', 3)
				:wikitext(mw.ustring.format("%s", err_text))
			:allDone()
			:newline()
	end
	return table_output
end

-- 列表模板
function p.list(frame)
	local bb = frame.args
	local ret = p._internalList(bb.code, bb.format, bb.city, bb.loc, bb.time, bb.vehicle, bb.image)
	return ret
end

-- 生成一条路线的一列简单表格内容
function p._internalSimpList(no, city, loc)
	local sys = _loadSystemData(city)			-- 加载系统数据
	local sysloc = sys.locName[loc]				-- sysloc为拼音
	local loc = sys.titlename[sysloc]			-- loc为简体
	local path = sys.data
	local d = _loadLineData(sysloc, path)		-- 加载路线数据
	if not d[no] then
		err_text = mw.ustring.format("(错误:%s中未包含这条[\[%s巴士路线列表|%s]\]的线路)", sys.data[sysloc], loc, loc)
	elseif mw.ustring.match(d[no].note, "已停[办辦]") then
		if _isEmpty(d[no].suspend) then
			err_text = "(本线已停办,请移除)"
		else
			err_text = mw.ustring.format("(本线自%s起停办,请移除)", d[no].suspend)
		end
		no = d[no].code
	elseif mw.ustring.match(d[no].note, "[暂暫]停服[务務]") then
		if _isEmpty(d[no].suspend) then 
			err_text = "(本线已暂停服务)"
		else
			err_text = mw.ustring.format("(本线自%s起暂停服务)", d[no].suspend)
		end
		no = d[no].code
	else
		data_ep1 = p._internalTsllink(d[no].endpoint1)		-- 处理起讫点1可能出现的{{tsl|zh-yue}}
		if _isEmpty(d[no].endpoint2) then
			data_ep2 = data_ep1								-- 未填入endpoint2默认为循环线
		else
			data_ep2 = p._internalTsllink(d[no].endpoint2)	-- 处理起讫点2可能出现的{{tsl|zh-yue}}
		end
		if _isEmpty(d[no].direction) then					-- 部分线路省略了方向
            if _isEmpty(d[no].endpoint2) then				-- 未填入endpoint2默认为循环线
			    data_direction = "↺"
            else
			    data_direction = "⇆"
            end
		elseif not _isEmpty(d[no].direction1) then			-- 部分线路的第二个方向
			if not  _isEmpty(d[no].endpoint3) then			-- 部分线路去程终点和返程起点不同
				data_direction = d[no].direction..'<hr>'..d[no].direction1
				data_ep2 = data_ep2..'<hr>'..p._internalTsllink(d[no].endpoint3)		-- 处理起讫点3可能出现的{{tsl|zh-yue}}
			else 
				data_direction = d[no].direction..'<br>'..d[no].direction1
			end
		else
			data_direction = d[no].direction
		end
		data_note = d[no].note or ""
	end
	local table_output = mw.html.create()
	if err_text then
		table_output
			:tag('tr')
				:tag('td')
					:attr('align', 'center')
					:tag('b')
						:wikitext(mw.ustring.format("%s", no))
						:done()
					:done()
				:tag('td')
					:attr('colspan', 3)
					:attr('align', 'center')
					:tag('i')
						:wikitext(mw.ustring.format("%s", err_text))
	else
		table_output
			:tag('tr')
				:tag('td')
					:attr('align', 'right')
					:tag('b')
						:wikitext(mw.ustring.format("%s", d[no].code))
						:done()
					:done()
				:tag('td')
					:attr('align', 'right')
					:wikitext(data_ep1)
					:done()
				:tag('td')
					:attr('align', center)
					:attr('nowrap', 'true')
					:wikitext(data_direction)
					:done()
				:tag('td')
					:attr('align', 'left')
					:wikitext(data_ep2)
					:done()
				:tag('td')
					:attr('align', 'left')
					:wikitext(data_note)
	end
	return table_output
end

-- 简单列表模板
function p.simplelist(frame)
	local ss = frame.args
	local ret = p._internalSimpList(ss.code, ss.city, ss.loc)
	return ret
end

-- 输出线路单项资料(惠州)
function p._internalCode(no, city, loc)
	local sys = _loadSystemData(city)			-- 加载系统数据
	local sysloc = sys.locName[loc]				-- sysloc为拼音
	local loc = sys.titlename[sysloc]			-- loc为简体
	local path = sys.data
	local d = _loadLineData(sysloc, path)		-- 加载路线数据
	if not d[no] then
		out = string.format("(错误:%s中无%s线)", sys.data[sysloc], no)
	elseif mw.ustring.match(d[no].note, "已停[办辦]") then
		out = string.format("(错误:%s已停办,请移除)", d[no].code)
	elseif mw.ustring.match(d[no].note, "[暂暫]停服[务務]") then
		out = string.format("(错误:%s暂停服务)", d[no].code)
	else
		out = d[no].code or no
	end
	return out
end

-- 极简列表模板(惠州)
function p.code(frame)
	local ss = frame.args
	local ret = p._internalCode(ss.code, ss.city, ss.loc)
	return ret
end

-- 生成表格表头
function p._internalTitle(style, city, loc, vehicle, time, image)
	local sys = _loadSystemData(city)				-- 加载系统数据
	local sysloc = sys.locName[loc]					-- sysloc为拼音
	local titleloc = sys.titlename[sysloc] or loc	-- loc为简体
	local listname = nil --sys.listname[sysloc] or nil
	local link_list
	
	if not _isEmpty(listname) then
		link_list = listname
	else
		if city == "ZZ" or city == "SU" or city == "BJ" or city == "CW" or city == "LYG" then
			link_list = mw.ustring.format('%s公交线路列表', titleloc)
		elseif city == "CQ" then
			link_list = mw.ustring.format('重庆公交线路列表 (%s)', titleloc)
		elseif city == "XA" then
			link_list = mw.ustring.format('%s市公交线路表', titleloc)
		elseif city == "ST" or city == "CZ" or city == "JY" then
			link_list = mw.ustring.format('%s公交路线列表', titleloc)
		elseif titleloc == "惠州" then
			link_list = '惠州公共交通线路表'
		else
			link_list = mw.ustring.format('%s巴士路线列表', titleloc)
		end
	end
	if mw.ustring.match(time, "[Yy][Ee][Ys]") then 
		title_route = "线路及运营时间"
	else
		title_route = "线路"
	end

	if mw.ustring.match(image, "[Yy][Ee][Ys]") then
		title_note = "图片及备注"
	else
		title_note = "备注"
	end
	
	local t = mw.html.create()
	if mw.ustring.match(style, "[Bb][Rr][Tt]") then
		t
			:tag('th')
				:attr('colspan', 2)
				:attr('width', '8.5%')
				:wikitext(mw.ustring.format('[\[%s|编号]\]',link_list))
				:done()
			:tag('th')
				:attr('colspan', 3)
				:attr('width', '25%')
				:wikitext(title_route)
				:done()
			:tag('th')
				:attr('width', '10.6%')
				:wikitext('驶入BRT通道')
				:done()
			:tag('th')
				:attr('width', '10.6%')
				:wikitext('驶出BRT通道')
				:done()
			:tag('th')
				:attr('width', '8.5%')
				:wikitext('BRT通道停靠站数')
				:done()
			:tag('th')
				:attr('width', '14.9%')
				:wikitext('运营商')
				:done()
			:tag('th')
				:attr('width', '21.3%')
				:wikitext(title_note)
		
	elseif mw.ustring.match(vehicle, "[Yy][Ee][Ys]") then								-- 显示运力(vehicle = yes)
		if style == "noco" then			-- 不显示公司栏(noco)
			t = '!colspan="2" width="12%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="8%"|收费!!width="19%"|运力!!width="19%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="20%"| || ||width="20%"| ||colspan="3"| '
		elseif style == "nofa" then								-- 不显示票价栏(nofa)
			t = '!colspan="2" width="12%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="8%"|运营商!!width="19%"|运力!!width="19%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="20%"| || ||width="20%"| ||colspan="3"| '
		elseif style == "nocofa" then							-- 不显示公司和票价栏(nocofa)
			t = '!colspan="2" width="13%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="21%"|运力!!width="20%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="22%"| || ||width="22%"| ||colspan="2"| '
		else													-- 显示公司和票价栏(默认)
			t = '!colspan="2" width="10%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="8%"|收费!!width="8%"|运营商!!width="18%"|运力!!width="18%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="18%"| || ||width="18%"| ||colspan="4"| '
		end
	else														-- 不显示运力
		t
			:tag('th')
				:attr('colspan', 2)
				:attr('width', width_code)
				:wikitext(mw.ustring.format('[\[%s|编号]\]', link_list))
			:tag('th')
				:attr('colspan', 3)
				:attr('width', width_route)
				:wikitext(title_route)
			:tag('th')
				:attr('width', width_col1)
				:wikitext(title_col1)
		--if style ~= "nocofa" then 未完成
		--	width_col2
			t	
				:tag('th')
					:attr('width', width_col2)
					:wikitext(title_col2)
			if style then
				t
					:tag('th')
						:attr('width', width_col3)
						:wikitext(title_note)
			end
		if style == "noco" then			-- 不显示公司栏(noco)
			t = '!colspan="2" width="14%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="10%"|收费!!width="22%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="25%"| || ||width="25%"| ||colspan="2"| '
		elseif style == "nofa" then						-- 不显示票价栏(nofa)
			t = '!colspan="2" width="14%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="11%"|运营商!!width="21%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="25%"| || ||width="25%"| ||colspan="2"| '
		elseif style == "nocofa" then					-- 不显示公司和票价栏(nocofa)
			t = '!colspan="2" width="16%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="24%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="28%"| || ||width="28%"| || '
		else											-- 显示公司和票价栏(默认)
			t = '!colspan="2" width="12%"|[['..link_list..'|编号]]!!colspan="3"|'..title_route..'!!width="8%"|收费!!width="10%"|运营商!!width="20%"|'..title_note..'\n|-style="background:#EAECF0" height=0\n|colspan="2"| ||width="23%"| || ||width="23%"| ||colspan="3"| '
		end
	end
	return t
end

-- Title模板
function p.title(frame)
	local tt = frame.args
	local ret = p._internalTitle(tt.format, tt.city, tt.loc, tt.vehicle, tt.time, tt.image)
	return ret
end

-- 色块模板
function p.colorbox(frame)
	local cc = frame.args
	local ret = p._internalColorbox(cc.company, cc.city)
	return ret
end

-- 颜色模板(新)
function p.color(frame)
	local cc = frame.args
	local ret = p._internalColor(cc.company, cc.city)
	return ret
end

return p