Module:Sandbox/Bon

From OpenStreetMap Wiki
Jump to navigation Jump to search
-- The following module, intended to be used inside a table, creates all table rows needed to represent a public transport service line,
-- its variants and its routes along with its mapping progress, update, etc.

local getArgs = require('Module:Arguments').getArgs

local p = {}

-- local translation = require('Module:Sandbox/Bon/Translations').translations
local translation = {}

translation['en'] = {
	name = 'name',		-- line name
	colour = 'colour',	-- line colour
	var = 'var',		-- variant
	varL = 'varL',		-- length of the variant
	upd = 'upd',		-- last update
	chk = 'chk',		-- last check
	tags = 'tags',		-- other tags
	notes = 'notes'		-- notes
	}

translation['it'] = {
	name = 'nome',		-- nome linea
	colour = 'colore',	-- colore linea
	var = 'var',		-- variante
	varL = 'Lvar',		-- lunghezza variante
	upd = 'agg',		-- aggiornamento
	chk = 'con',		-- controllo
	tags = 'tag',		-- altri tag
	notes = 'note'		-- note
	}


local function setLang(frame,args)
	langCode = mw.text.trim(lang or args.lang or 'en')					-- +local
	if not translation[langCode] then
		local fallbacks_table = mw.language.getFallbacksFor(langCode)
		for _, fb_code in ipairs(fallbacks_table) do
			if translation[fb_code] then langCode = fb_code break end
		end
	end
	Wlang = mw.getLanguage(langCode)									-- +local
	if not mw.language.isSupportedLanguage(langCode) then
		local fallbacks_table = mw.language.getFallbacksFor(langCode)
		for _, fb_code in ipairs(fallbacks_table) do
			if mw.language.isSupportedLanguage(fb_code) then
				Wlang = mw.getLanguage(fb_code) break
			end
		end
	end
	return langCode, Wlang
end

local function translateArgs(frame,args)
	local tl_langCode, Wlang = setLang(frame,args)
	local tl_table = translation[langCode]
	local backtl_table = {}
	for k,v in pairs(tl_table) do
		backtl_table[v] = k
	end
	
	for loc_argkey in pairs(args) do
		local argkey = backtl_table[loc_argkey] or backtl_table[mw.text.split(loc_argkey,'1')[1]] or nil
		if argkey then
			args[argkey] = args[loc_argkey]
		end
	end
	local i = 2
	while args[tl_table['var']..i] do
		for loc_argkey in pairs(args) do
			local loc_argname_parts = mw.text.split(loc_argkey,tostring(i))
			local argkey = backtl_table[loc_argname_parts[1]] or nil
			if argkey and loc_argname_parts[2] == '' then
				args[argkey..i] = args[loc_argkey]
			end
		end
		i = i + 1
	end
	return Wlang
end


local setParams = {
	
	general =
		function(frame, args, dateFormat, rP, nrP)
			local dF = dateFormat or 'j F Y'
			local rep_P = rP or frame.args[1] or 3
			local nrep_P = nrP or frame.args[2] or 1
			return dF, rep_P, nrep_P
		end,
	
	network =
		function(frame, args, network, operator)
			local nw = network or args.network or nil
			local op = operator or args.operator or nil
			return nw, op
		end,
	
	line =
		function(frame, args)
			local Lref = args[1] or ''
			local Lname = args.name or nil
			local Lcolour = args.colour ~= '' and args.colour or nil
			local Lnotes = args.notes or nil
			return Lref, Lname, Lcolour, Lnotes
		end,
	
	variants =
		function(frame, args)
			local Vlabel = {}
			local Vlength = {}
			local Vupdate = {}
			local Vcheck = {}
			local Vtags = {}
			Vlabel[1] = args.var or args.var1 or nil
			Vupdate[1] = args.upd or args.upd1 or nil
			Vcheck[1] = args.chk or args.chk1 or nil
			Vtags[1] = args.tags or args.tags1 or nil
			if Vlabel[1] then
				Vlength[1] = tonumber(args.varL or args.varL1 or 2)
				local i = 2
				while args['var'..i] do
					Vlabel[i] = args['var'..i]
					Vlength[i] = tonumber(args['varL'..i] or 2)
					Vupdate[i] = args['upd'..i] or nil
					Vcheck[i] = args['chk'..i] or nil
					Vtags[i] = args['tags'..i] or nil
					i = i + 1
				end
				local n_var = #Vlabel
			end
			return Vlabel, Vlength, Vupdate, Vcheck, Vtags, n_var
		end,
	
	routes =
		function(frame, args, rP, nrP)
			local rep_P = rP or frame.args[1] or 3
			local nrep_P = nrP or frame.args[2] or 1
			local Rroute = {}
			local Rrel = {}
			local Rprogr = {}
			local i,j = 1, nrep_P + 1
			while args[j] or args[j+1] do
				Rroute[i] = tostring(args[j] or '')
				Rrel[i] = mw.text.trim(args[j+1] or '')
				Rprogr[i] = tostring(args[j+2] or '')
				i = i + 1
				j = j + rep_P
			end
			local n_routes = #Rroute
			return Rroute, Rrel, Rprogr, n_routes
		end
	
}


local function overpass_api_link_builder()
	local network = Nnetwork
	local operator = Noperator
	if not (network or operator) then
		return nil
	end
	l = 'https://overpass-api.de/api/sketch-line?'
	if network then
		network = mw.text.trim(network)
		network = mw.ustring.gsub(network, ' ', '+')
		l = l..'&network='..network
	end
	if Lref then
		local ref = mw.text.trim(Lref)
		ref = mw.ustring.gsub(ref, ' ', '+')
		l = l..'&ref='..ref
	end
	if operator then
		operator = mw.text.trim(operator)
		operator = mw.ustring.gsub(operator, ' ', '+')
		l = l..'&operator='..operator
	end
	return l
end

local function other_links()
end

local cells = {
	line = function(ref, length, name, hasVar)
		local s = '\n|-\n|rowspan='..length
		if hasVar
			then s = s..' style="width:6.5em; border-right:none; text-align:center; font-size:120%; font-weight:bold"| '
			else s = s..' colspan=2 style="width:6.5em; text-align:center; font-size:120%; font-weight:bold"|' end
		s = s..Lref
		if name then
			s = s..'<br/><span style="font-size:65%">'..name..'</span>' end
		return s
	end,
	
	var = function(label, length, isFirstVar)
		local s = ''
		if not isFirstVar then s = '\n|-' end
		s = s..'\n|rowspan='..length..' style="border-left:none; text-align:center; font-style:italic"|'..label
		return s
	end,
	
	route = function ()
	end,
	
	relation = function ()
	end,
	
	rel_and_route = function(relation, route, isFirstRoute, ref)
		local s = ''
		if isFirstRoute then
			s = '<span class="anchor" id="'..(ref or '')..'"></span>'
		end
		s = s..'\n|'..mw.getCurrentFrame():expandTemplate{ title = 'RelationIconLink', args = { relation } }..' '..route
		return s
	end,
	
	progress = function(progress_state, display_text)
		local s
		if display_text then
			s = '\n|'..mw.getCurrentFrame():expandTemplate{ title = 'Progress', args = { progress_state, text = display_text } }
			else s = '\n|'..mw.getCurrentFrame():expandTemplate{ title = 'Progress', args = { progress_state } }
		end
		return s
	end,
	
	update_and_check = function(length, update_date, check_date, langObj, dateFormat)
		local s = '\n|rowspan='..length..' style="text-align:center" data-sort-value="'..(check_date or update_date or '')..'" | '
		if update_date then
			s = s..langObj:formatDate(dateFormat, update_date) end
		if check_date then
			s = s..'<br/> [[File:Yes check.svg|10px]] <span style="font-size:75%">'..langObj:formatDate(dateFormat, check_date)..'</span>'
		end
		return s
	end,
	
	other_tags = function(length, tags, colour)
		local s = '\n|rowspan='..length..' style="vertical-align:top"| '
		if colour then
			s = s..mw.getCurrentFrame():expandTemplate { title = 'Tag', args = { 'colour', '', colour } }
			..' '..mw.getCurrentFrame():expandTemplate { title = 'Color sample', args = { colour } }
			if tags then s = s..'<br/>' end
		end
		if tags
		then s = s..tags end
		return s
	end,
	
	links = function(length, links)	-- links = { link1, link2,... } or { {link1, label1}, {link2,label2},... }
		local s = '\n|rowspan='..length..'| '
		if not links then return s end
		for i,l in ipairs(links) do
			if type(l) == 'table' then
				s = s..'['..l[1]..' '..l[2]..'] '
				else s = s..'['..l..' '..i..'] '
			end
		end
		return s
	end,
	
	notes = function(length, notes)
		local s = '\n|rowspan='..length..'|'..(notes or '')
		return s
	end
}


local function make_var(ref, label, length, update, check, Rroute, Rrel, Rprogr, Ri, colour, tags, notes, Wlang, dateFormat, isFirstVar)
		-- (line = { ref, colour}, var = { label, length, update, check, tags}, routes = { { Rroute, Rrel, Rprogr }, Ri }, general = { Wlang, dateFormat }, isFirstVar)
	local s = ''
	s = s..cells.var(label, length, isFirstVar)
	s = s..cells.rel_and_route(Rrel[Ri], Rroute[Ri], Ri==1, ref)
	s = s..cells.progress(Rprogr[Ri])
	s = s..cells.update_and_check(length, update, check, Wlang, dateFormat)
	s = s..cells.other_tags(length, tags, colour)
	if isFirstVar then
		s = s..cells.links(#Rroute)
		s = s..cells.notes(#Rroute, notes)
	end
	for i=1,length-1 do
		s = s..'\n|-'
		s = s..cells.rel_and_route(Rrel[Ri+i], Rroute[Ri+i])
		s = s..cells.progress(Rprogr[Ri+i])
	end
	return s
end

local function make_line()	--( line = { ref, ... })
	local s = ''
	local Ri = 1
	s = s..cells.line(Lref, n_routes, Lname, Vlabel[1])
	if Vlabel[1] then
		for Vi in ipairs(Vlabel) do
			s = s..make_var(Lref, Vlabel[Vi], Vlength[Vi], Vupdate[Vi], Vcheck[Vi], Rroute, Rrel, Rprogr, Ri, Lcolour, Vtags[Vi], Lnotes, Wlang, dateFormat, Vi==1)
			Ri = Ri + Vlength[Vi]
		end
	else
		s = s..cells.rel_and_route(Rrel[1], Rroute[1], true, Lref)
		s = s..cells.progress(Rprogr[1])
		s = s..cells.update_and_check(n_routes, Vupdate[1], Vcheck[1], Wlang, dateFormat)
		s = s..cells.other_tags(n_routes, Vtags[1], Lcolour)
		s = s..cells.links(n_routes)
		s = s..cells.notes(n_routes, Lnotes)
		Ri = Ri + 1
		for i=2,n_routes do
			s = s..'\n|-'
			s = s..cells.rel_and_route(Rrel[i], Rroute[i])
			s = s..cells.progress(Rprogr[i])
		end
	end
	return s
end

function p.generic(frame)
	local args = getArgs(frame, {
		trim = false,
		removeBlanks = false,
		frameOnly = false,
		parentOnly = false,
		parentFirst = true,
		readOnly = false,
		noOverwrite = false
	})
	
	translateArgs(frame,args)
	dateFormat, rP, nrP = setParams.general(frame, args)
	Nnetwork, Noperator = setParams.network(frame, args)
	Lref, Lname, Lcolour, Lnotes = setParams.line(frame, args)
	Vlabel, Vlength, Vupdate, Vcheck, Vtags, n_var = setParams.variants(frame, args)
	Rroute, Rrel, Rprogr, n_routes = setParams.routes(frame, args, rP, nrP)
	
	local s = make_line()
	return s
end


return p