跳转到内容

模組:RouteSequence

被永久保护的模块
维基百科,自由的百科全书

这是本页的一个历史版本,由Siyuwj留言 | 贡献2016年6月6日 (一) 01:14编辑。这可能和当前版本存在着巨大的差异。

local p = {
	STATION_SEPARATOR = ' - ',
	DEFAULT_STATION_SUFFIX = '站',
	BLOCK_ALIGN_PATTERN = '##BLOCK_ALIGN##',
	BLOCK_START = '&#32;&lt;&#32;<div style="display:inline-block; text-align: ##BLOCK_ALIGN##; vertical-align:middle;">',
	BLOCK_START_PURE = '<div style="display:inline-block; text-align: ##BLOCK_ALIGN##; vertical-align:middle;">',
	BLOCK_LINE_SEPARATOR = '<br />',
	BLOCK_END = '</div>&#32;&gt;&#32;',
	BLOCK_END_PURE = '</div>'
}

p.sep_translate = {
	['%%dash%%'] = '&ndash;',
	['%%rarrow%%'] = '→',
	['%%larrow%%'] = '←',
	['%%darrow%%'] = '↔',
	['%%ldarrow%%'] = '⇐',
	['%%rdarrow%%'] = '⇒',
	['%%ddarrow%%'] = '⇔'
}

p.station_suffix = p.DEFAULT_STATION_SUFFIX

function p.truncateEnds(s, l)
	if l == nil then l = 1 end
	return string.sub(s, l + 1, string.len(s) - l)
end

function p.appendStyle(s, a)
	s = mw.text.trim(s)
	if s == '' then
		return a
	elseif string.find(s, ';$') ~= nil then
		return s .. ' ' .. a
	else
		return s .. '; ' .. a
	end
end

function p.marshalStation(station_link, station_name, style)
	if style == nil or mw.text.trim(style) == '' then
		return '[[' .. station_link .. '|' .. station_name .. ']]'
	else
		return '[[' .. station_link .. '|<span style="' .. style .. '">' .. station_name .. '</span>]]'
	end
end

function p.parseLink(station_link, style, system_data)
	local station_name, match
	local prefix, suffix
	local link_name_split

	prefix = ''
	suffix = ''
	if string.find(station_link, "^%$.+%$$") ~= nil then
		return p.truncateEnds(station_link)
	elseif string.find(station_link, "^s.+s$") ~= nil then
		station_link = p.truncateEnds(station_link)
		prefix = '<s>'
		suffix = '</s>'
	elseif string.find(station_link, "^g.+g$") ~= nil then
		station_link = p.truncateEnds(station_link)
		style = p.appendStyle(style, 'color: gray')
	elseif string.find(station_link, "^'''.+'''$") ~= nil then
		station_link = p.truncateEnds(station_link, 3)
		prefix = "'''"
		suffix = "'''"
	elseif string.find(station_link, "^''.+''$") ~= nil then
		station_link = p.truncateEnds(station_link, 2)
		prefix = "''"
		suffix = "''"
	end

	if system_data ~= nil and system_data.stationNames[station_link] ~= nil then
		for _idx, station_repr in ipairs(mw.text.split(system_data.stationNames[station_link], '#')) do
			if string.find(station_repr, '|') ~= nil then
				link_name_split = mw.text.split(station_repr, '|')
				break
			end
		end
	else
		link_name_split = mw.text.split(station_link, '!')
	end

	if table.getn(link_name_split) == 1 then
		station_name, match = string.gsub(station_link, p.station_suffix .. ' +%(.+%)$', '')
		if match == 0 then
			station_name, match = string.gsub(station_link, p.station_suffix .. '$', '')
		end
		if match == 0 then
			station_name = station_link
			station_link = station_link .. p.station_suffix
		end
	else
		station_link = link_name_split[1]
		station_name = link_name_split[2]
	end
	
	return prefix .. p.marshalStation(station_link, station_name, style) .. suffix
end

function p.splitStationExpr(station)
	local new_split = {}
	local last_element, cur_element
	local station_split = mw.text.split(station, '#')

	for i, spart in ipairs(station_split) do
		if i > 1 and string.sub(last_element, string.len(last_element), string.len(last_element)) == '&' then
			table.remove(new_split)
			cur_element = last_element .. '#' .. spart
		else
			cur_element = spart
		end
		table.insert(new_split, cur_element)
		last_element = cur_element
	end
	return new_split
end

function p.parseStation(station, style, system_data)
	local station_str
	local station_split, station_prefix, station_suffix
	
	station_split = p.splitStationExpr(station, '#')
	if table.getn(station_split) == 1 then
		station_prefix = ''
		station_expr = mw.text.trim(station_split[1])
		station_suffix = ''
	elseif table.getn(station_split) == 2 then
		station_prefix = mw.text.trim(station_split[1])
		station_expr = mw.text.trim(station_split[2])
		station_suffix = ''
	elseif table.getn(station_split) == 3 then
		station_prefix = mw.text.trim(station_split[1])
		station_expr = mw.text.trim(station_split[2])
		station_suffix = mw.text.trim(station_split[3])
	end
	station_link = p.parseLink(mw.text.trim(station_expr), style, system_data)
	station_str = ''
	 
	if station_prefix ~= '' then
		if string.find(station_suffix, ")$") ~= nil or string.find(station_suffix, "($") ~= nil or string.find(station_suffix, "</sub>$") ~= nil or string.find(station_suffix, "</sup>$") ~= nil or string.find(station_suffix, ":$") ~= nil then
			station_str = station_prefix
		else
			station_str = station_prefix .. '&#32;'
		end
	end
			
	station_str = station_str .. station_link

	if station_suffix ~= '' then
		if string.find(station_suffix, "^(") ~= nil or string.find(station_suffix, "^)") ~= nil or string.find(station_suffix, "^<sub>") ~= nil or string.find(station_suffix, "^<sup>") ~= nil then
			station_str = station_str .. station_suffix
		else
			station_str = station_str .. '&#32;' .. station_suffix
		end
	end

	if station_prefix ~= '' or station_suffix ~= '' then
		station_str = '<span class="nowrap">' .. station_str .. '</span>'
	end

	return station_str
end

function p.processRoute(route_str, gstyle, condition, system)
	if gstyle == nil then
		gstyle = ''
	end
	if condition == nil then
		condition = ''
	end
	
	local style = gstyle
	local out_style = gstyle
	
	local stations = mw.text.split(route_str, '~')
	local output_str = ''

	local condition = mw.text.trim(condition)
	local cond_expr, conds, cond, raw_cond
	local cond_met = true
	
	local gray_state = false
	
	local block_level = 0
	local block_align
	local station_index = 0

	local separator
	local next_separator = p.STATION_SEPARATOR
	local user_separator = p.STATION_SEPARATOR
	
	local system_data = nil
	if system ~= nil and mw.text.trim(system) ~= '' then
		system_data = mw.loadData("Module:RailSystems/" .. system)
	end

	for i, station in ipairs(stations) do
		station = mw.text.trim(station)
		if string.find(station, '^style *=') ~= nil then
			style = mw.text.trim(mw.text.split(station, '=')[2])
			if style == '' then
				style = gstyle
			end
		elseif string.find(station, '^con *=') ~= nil then
			cond_expr = mw.text.trim(mw.text.split(station, '=')[2])
			if cond_expr == '' then
				cond_met = true
			else
				conds = mw.text.split(cond_expr, '#')
				cond_met = false
				for i, cond in ipairs(conds) do
					raw_cond = mw.text.trim(cond)
					if string.find(raw_cond, '^- *') ~= nil then
						raw_cond = string.gsub(raw_cond, '^- *', '')
						if mw.text.trim(raw_cond) ~= condition then
							cond_met = true
							break
						end
					else
						if mw.text.trim(raw_cond) == condition then
							cond_met = true
							break
						end
					end
				end
			end
		elseif string.find(station, '^sep *=') ~= nil then
			separator = mw.text.trim(mw.text.split(station, '=')[2])
			if separator == '' then
				separator = p.STATION_SEPARATOR
			else
				for spatt, sep in pairs(p.sep_translate) do
					separator = string.gsub(separator, spatt, '&#32;' .. sep .. '&#32;')
				end
			end
			next_separator = separator
			user_separator = separator
		elseif station == 'blstart' then
			block_level = block_level + 1
			if station_index > 0 then
				next_separator = string.gsub(p.BLOCK_START, p.BLOCK_ALIGN_PATTERN, 'left')
			else
				next_separator = string.gsub(p.BLOCK_START_PURE, p.BLOCK_ALIGN_PATTERN, 'right')
			end
		elseif string.find(station, '^blstart *=') ~= nil then
			block_level = block_level + 1
			block_align = mw.text.trim(mw.text.split(station, '=')[2])
			if station_index > 0 then
				next_separator = string.gsub(p.BLOCK_START, p.BLOCK_ALIGN_PATTERN, block_align)
			else
				next_separator = string.gsub(p.BLOCK_START_PURE, p.BLOCK_ALIGN_PATTERN, block_align)
			end
		elseif station == 'blline' then
			next_separator = p.BLOCK_LINE_SEPARATOR
		elseif station == 'blend' then
			block_level = block_level - 1
			next_separator = p.BLOCK_END
		elseif station == 'gstart' then
			gray_state = true
		elseif station == 'gend' then
			gray_state = false
		elseif cond_met then
			station_index = station_index + 1
			if station_index > 1 or block_level > 0 then
				output_str = output_str .. next_separator
			end
			out_style = style
			if gray_state then
				out_style = p.appendStyle(style, 'color: gray')
			end
			output_str = output_str .. p.parseStation(station, out_style, system_data)
			next_separator = user_separator
		end
	end
	while block_level > 0 do
		block_level = block_level - 1
		output_str = output_str .. p.BLOCK_END_PURE
	end
	return output_str
end

function p.route(frame)
	local gstyle = frame.args['style']
	local route_str = frame.args['stations']
	local condition = frame.args['condition']
	local system = frame.args['system']

	p.station_suffix = mw.text.trim(frame.args['station_suffix'] or p.DEFAULT_STATION_SUFFIX)

	return p.processRoute(string.gsub(route_str, '\n', ''), gstyle, condition, system)
end
 
return p