Naar inhoud springen

Module:Opvolgende stations

Uit Wikipedia, de vrije encyclopedie

Documentatie voor deze module kan aangemaakt worden op de volgende pagina: Module:Opvolgende stations/doc

local p = {}
--Lua code made by Eru aimed at presenting preceding and following subway stations, sorted by geographical order and by service/line number/name. 
--For time being, still in bêta. Original code at https://commons.wikimedia.org/wiki/Module:Adjacent_stations
--If any requests or comments, please add them to (where?)
--Adapted by JB63 for nlwiki infoboxes

-- default params

local defaultLang = mw.language.getContentLanguage().code
local defaultLink = 'nlwiki' -- modify to your local wiki, like frwiki
local size_logo = 24
local logo_inv = 1
local showdebug = false
local ignoreCoordinate = false
local linkback
local showsource = false--parameter to help present sources, if they are present in Wikidata. Make sure false for frwiki as they do not want sources in that table
local with_bearing=true--parameter to help decide to calculate with bearing or with classic line direction method (false)

-- module loading

local function loadModule(name, name2)
	local exist, res = pcall(require, name)
	if not exist then
		exist, res = pcall(require, name2)
	end
	return exist and res
end
local wikidata
if defaultLink == 'eowiki' or defaultLink == 'wikidata' or defaultLink == 'ptwiki' or defaultLink == 'nlwiki' then -- too much incompatibilities in [[Module:Wikidata]]
	wikidata = loadModule( 'Module:Wikidata frwiki' ) -- original code at https://fr.wikipedia.org/wiki/Module:Wikidata
	wikidata.getReferences = nil
	wikidata.sourceStr = nil
else
	wikidata = loadModule( 'Module:Wikidata' ) -- original code at https://fr.wikipedia.org/wiki/Module:Wikidata or https://commons.wikimedia.org/wiki/Module:Wikidata
end

local tools = loadModule( 'Module:Wikidata/Tools' ) -- original code at https://commons.wikimedia.org/wiki/Module:Wikidata/Tools
local TNT = require 'Module:TNT' -- https://www.mediawiki.org/wiki/Module:TNT

-- compatiblity of [[Module:Wikidata]] on various wiki

wikidata.formatEntity = wikidata.formatEntity -- frwiki
	or wikidata._getLabel -- commons
wikidata.getId = wikidata.getId -- frwiki
	or ( tools and tools.getId ) -- commons
wikidata.getFormattedQualifiers = wikidata.getFormattedQualifiers -- frwiki
	or wikidata.formatStatementQualifiers -- commons
wikidata.sourceStr = wikidata.sourceStr -- frwiki
	or function( sources, hashes ) -- commons
	return sources
end
wikidata.stringTable = wikidata.stringTable -- commons
	or wikidatafr.stringTable -- eowiki
wikidata.getClaims = wikidata.getClaims -- commons
	or wikidatafr.getClaims -- eowiki

-- private functions

local function getMessage(key, ...)
	return TNT.formatInLanguage(defaultLang, 'I18n/Template:Stations-voisines.tab', key, {...}) -- loading of https://commons.wikimedia.org/wiki/Data:I18n/Template:Stations-voisines.tab
end
--from https://commons.wikimedia.org/wiki/Module:Bearing
require ('strict');

local function bearing (from_lat, from_long, to_lat, to_long)
	if not (to_lat and to_long) then
		return nil
	end
	local from_lat_rad = math.rad (from_lat);									-- convert degree inputs to radians
	local from_long_rad = math.rad (from_long);
	local to_lat_rad = math.rad (to_lat);
	local to_long_rad = math.rad (to_long);
	
	local delta_long_rad = to_long_rad - from_long_rad;
	local x = math.cos (to_lat_rad) * math.sin (delta_long_rad);
	local y = (math.cos (from_lat_rad) * math.sin (to_lat_rad)) - (math.sin (from_lat_rad) * math.cos (to_lat_rad) * math.cos (delta_long_rad));
	local beta = math.atan2 (x, y);												-- result in radians
	beta = math.deg (beta);														-- convert to degrees
	return (0.0 > beta) and (beta + 360.0) or beta;								-- when beta is negative, add 360 degrees to make a positive bearing
end

--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]


-- from [[fr:Module:Outils]]

local function trim( texte )
	if type( texte ) == 'string' and texte ~= '' then
		texte = texte:gsub( '^%s*(%S?.-)%s*$', '%1' )
		if texte ~= '' then
			return texte
		end
	end
	return nil
end

local function validTextArg( args, name, ... )
	local texte = trim( args[name] )
	if texte then
		return texte
	end
	if select( '#', ... ) > 0 then
		return validTextArg( args, ... )
	end
	return nil
end

local function extractArgs ( frame )
	if type( frame.getParent ) == 'function' then
		local args = frame:getParent().args
		for k,v in pairs( frame.args ) do
			args[k] = v;
		end
		return args
	else
		return frame
	end
end

-- from [[fr:Module:Wikidata]]

local function getMainId(claim)
	return wikidata.getId(claim.mainsnak)
end

local function entityId(entity)
	if type(entity) == 'string' then
		return entity
	elseif type(entity) == 'table' then
		return entity.id
	end
end

local function addLinkBack(str, id, property)
	if not id or id == '' then
		id = wikidata.getEntityIdForCurrentPage()
	end
	if not id then
		return str
	end
	if type(property) == 'table' then
		property = property[1]
	end
	
	id = entityId(id)

	local class = ''
	if property then
		class = 'wd_' .. string.lower(property)
	end
	local icon = '[[File:Blue pencil.svg|%s|10px|baseline|class=noviewer|link=%s]]'--pencil icon to help modify Wikidata
	local title = 'zie waarde in wikidata' --getMessage('see-wikidata-value')
	local url = mw.uri.fullUrl('d:' .. id, 'uselang=nl')
	url.fragment = property -- ajoute une #ancre si paramètre "property" défini
	url = tostring(url)
	local v = mw.html.create('span')
		:addClass(class)
		:wikitext(str)
		:tag('span')
			:addClass('noprint wikidata-linkback')
			:wikitext(icon:format(title, url))
		:allDone()
	return tostring(v)
end

-- from [[commons:Module:Wikidata]]

local function getQualifiers(statement, qualifs, params)
	if not statement.qualifiers then
		return nil
	end
	local vals = {}
	for i, j in pairs(qualifs) do
		j = string.upper(j)
		if statement.qualifiers[j] then
			local inserted = false
			if statement.qualifiers[j][1].datatype == 'monolingualtext' then
				local in_preferred_lang
				for _, language in ipairs(fb.fblist(params.lang or defaultlang, true)) do
					for _, snak in ipairs(statement.qualifiers[j]) do
						if isInLanguage(snak, language) then
							in_preferred_lang = snak
							break
						end
					end
					if in_preferred_lang then
						break
					end
				end
				if in_preferred_lang then
					table.insert(vals, in_preferred_lang)
					inserted = true
				end
			end
			if not inserted then
				for _, snak in pairs(statement.qualifiers[j]) do
					table.insert(vals, snak)
				end
			end
		end
	end
	if #vals == 0 then
		return nil
	end
	return vals
end

wikidata.getReferences = wikidata.getReferences or function(statement)
	local cite = loadModule( 'Module:Cite' )
	local isSpecial = wikidata.isSpecial or ( tools and tools.isSpecial )
	if not isSpecial or not cite or not statement.references then
		return ''	
	end
	local frame = mw.getCurrentFrame()
	local sourcestring = ''
	for i, ref in pairs(statement.references) do
		local s
		if ref.snaks.P248 then
			for j, source in pairs(ref.snaks.P248) do
				if not isSpecial(source) then
					local page
					if ref.snaks.P304 and not isSpecial(ref.snaks.P304[1]) then
						page = ref.snaks.P304[1].datavalue.value
					end
					s = cite.citeitem('Q' .. source.datavalue.value['numeric-id'], lang, page)
					s = frame:extensionTag('ref', s)
					sourcestring = sourcestring .. s
				end
			end
		elseif ref.snaks.P854 and not isSpecial(ref.snaks.P854[1]) then
			s = frame:extensionTag('ref', wikidata.formatSnak(ref.snaks.P854[1], {}))
			sourcestring = sourcestring .. s
		end
	end
	return sourcestring
end

-- public functions
function p.Lijn_info (id, onlyLineService, filter, rows)
    if not id then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	local argsData = { entity = id, property = 'P197' }
	if onlyLineService then
		argsData.qualifier = { 'P1192', 'P81' } -- ligne or service
		argsData.qualifiervalue = onlyLineService
	end
	--localisation principale
	local mainCoordinate = ( not ignoreCoordinate ) and wikidata.stringTable( { entity = id, property = 'P625', numval = 1 } )
	if mainCoordinate and #mainCoordinate > 0 then -- si des coordonnées pour la présente station sont présentes / if coordinates are present for the current subway
		mainCoordinate = mainCoordinate[ 1 ]
	end
    local function Split(s, delimiter)
        result = {};
        for match in (s..delimiter):gmatch("(.-)"..delimiter) do
            table.insert(result, match);
        end
        return result;
    end
    local claims = wikidata.getClaims( argsData )
	local function getClaimDetail( claim )
		claim.lineid = wikidata.getId( claim.currentline )
		claim.lineName = wikidata.formatSnak( claim.currentline, { link = defaultLink } )
		if not claim.lineName or claim.lineName == '-' then -- no value
			claim.lineName = ''
		end
		local routenumber = wikidata.formatStatements( { entity = claim.lineid, property = 'P1671', numval = 1 } )
		if routenumber then
			claim.sortKey = tonumber( routenumber ) -- 570000
				or tonumber( tostring( routenumber:gsub( ' ', '' ) ) ) -- 655 000
				or routenumber:upper() -- KBS 566
		else
			claim.sortKey = claim.lineName:upper()
		end
        claim.xq = 0
        claim.yq = 0
        if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td colspan="3">----------</td></tr><tr><td>'..(#rows +1)..'</td><td>Modaliteit</td><td>'..claim.lineName..'</td></tr>' end
        --Modaliteitsdetectie
        local soort = wikidata.getClaims( { entity = claim.lineid, property = 'P31' } ) --is het metro/voorstad/treindienst ?
        claim.soort = '-'
        if soort and #soort > 0 then
            for _, modaliteit in ipairs( soort ) do
                local fltr = wikidata.formatStatement( modaliteit, { link = defaultLink } ):upper()    
                if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..fltr..'</td><td></td><td>'..claim.soort..'</td></tr>' end
                if string.find(fltr,'RINGLIJN') then claim.yq = 1 end 
                if string.find(fltr,'VOORSTAD') and claim.xq < 7 then claim.soort = 'S' claim.xq = 7 end
                if string.find(fltr,'TREINSERIE') and claim.xq < 4 then claim.soort = 'P' claim.xq = 4 end
                if string.find(fltr,'TREINDIENST') and claim.xq < 4 then claim.soort = 'P' claim.xq = 4 end
                if string.find(fltr,'LUCHTHAVENTREIN') and claim.xq < 7 then claim.soort = 'P' claim.xq = 7 end
                if string.find(fltr,'REIZIGERSTREIN') and claim.xq < 7 then claim.soort = 'P' claim.xq = 7 end 
                if string.find(fltr,'METRO') and claim.xq < 7 then claim.soort = 'M' claim.xq = 7 end 
                if string.find(fltr,'LIGHT') and claim.xq < 5 then claim.soort = 'L' claim.xq = 5 end  
                if string.find(fltr,'LICHT') and claim.xq < 5 then claim.soort = 'L' claim.xq = 5 end 
                if string.find(fltr,'SNELTRAM') and claim.xq < 5 then claim.soort = 'L' claim.xq = 5 end     
                if string.find(fltr,'S-TREIN') and claim.xq < 3 then claim.soort = 'S' claim.xq = 3 end
                if string.find(fltr,'VOORMALIGE') and claim.xq < 7 then claim.soort = 'X' claim.xq = 7 end
                if string.find(fltr,'OPGEHEVEN') and claim.xq < 7 then claim.soort = 'X' claim.xq = 7 end
                if string.find(fltr,'HOOFD') and claim.xq < 7 then claim.soort = 'H' claim.xq = 7 end
                if string.find(fltr,'NEVEN') and claim.xq < 7 then claim.soort = 'H' claim.xq = 7 end
                if string.find(fltr,'HOGE') and claim.xq < 7 then claim.soort = 'H' claim.xq = 7 end
                if string.find(fltr,'SPOORLIJN') and claim.xq < 4 then claim.soort = 'H' claim.xq = 4 end
               
                if claim.lineName == 'Docklands Light Railway' then claim.soort = 'X' end --niet netjes om een concrete waarde uit te sluiten maar gezien de vervuiling in wikidata onontkoombaar 
end

--if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..fltr..'</td><td>omgezet:</td><td>'..claim.soort..'</td></tr>' end
           
        end
        if claim.soort == '-' then
            --claim.soort = 'P'
        end      
    local staziuns = wikidata.getClaims( { entity = claim.lineid, property = 'P527' } ) --opsomming van de stations
	end --einde functie claimdetails
 
    if claims and #claims > 0 then --stations gevonden
		-- récupération des données de bases et de tri des lignes / recovery of basic data and line sorting
		local newClaims = { }
		local defaultSortKey = 1
		for _, claim in ipairs( claims ) do
			claim.defaultSortKey = defaultSortKey
			defaultSortKey = defaultSortKey + 1
			local currentlines = getQualifiers( claim, { 'P1192', 'P81' }, { } ) -- ligne or service
			if currentlines and #currentlines > 0 then
				for _,currentline in ipairs( currentlines ) do
					local newClaim = mw.clone( claim )
					newClaim.currentline = currentline
					getClaimDetail( newClaim )
                    if not onlyLineService or onlyLineService == newClaim.lineid then
						if filter == 'Y' or filter == 'Z' or filter == newClaim.soort then
                            newClaims[ #newClaims + 1 ] = newClaim
                        end
					end
                    if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..newClaim.soort..'</td><td>'..newClaim.lineName..'</td><td>'..#newClaims..'</td></tr>' end
				end
			else
				claim.lineName = ''
				claim.sortKey = claim.lineName:upper()
				newClaims[ #newClaims + 1 ] = claim
			end
		end

		table.sort( newClaims,
			function( c1, c2 )
				if c1.sortKey == c2.sortKey then
					return c1.defaultSortKey < c2.defaultSortKey
				elseif type( c1.sortKey ) == 'number' and type( c2.sortKey ) == 'number' then
					return c1.sortKey < c2.sortKey
				else
					return tostring( c1.sortKey ) < tostring( c2.sortKey )
				end
			end
		)

		-- doorloop de gevonden stations
		local lineDetail = { }
        local destinaziuns = { } 
        local zulu = 0 
        local zxa='-'
        local zxb='-'
        local terminusDirection = { }
        local terminusDirections = { }
        local kant
        local nba = "Voir l'élément Wikidata correspondant" --verwijzing voor niet bestaand artikel op nlwiki
        local aaw = "Article sur Wikipédia en" -- verwijzing naar artikel op andere wiki.
        local zelf = wikidata.formatEntity( id , { link = defaultLink } )
        local toev = false
        for _, claim in ipairs( newClaims ) do
            
			-- nieuwe lijn
            if claim.lineName ~= lineDetail.name then
               if lineDetail.name ~= nil then
                     local streep = true 
                     if terminusDirections and #terminusDirections > 0 then
                     for _, terminusDirection in ipairs( terminusDirections ) do
                       if zulu>0 then
                           zulu=zulu-1 
                           local destinaziun = ''
                           if terminusDirection=='-' then destinaziun='-' end
                           if terminusDirection=='*qxl' then destinaziun='*qxl' end
                           if terminusDirection=='*qxr' then destinaziun='*qxr' end
                           if destinaziun=='' then destinaziun = wikidata.formatStatement( terminusDirection, { link = defaultLink }  ) end
                           if lineDetail.logolink == nil then lineDetail.logolink = zelf end   
                           if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>richting: </td><td>'..destinaziun..'</td><td>'..destinaziuns[destinaziun]..'</td></tr>' end
                           local logoslot=0           
                           local eind='[['            
                           if lineDetail.logo then
                              if destinaziuns[zelf] == 'zulu' then destinaziuns[zelf] = 'Eindpunt~~' end
			                  for _, logo in ipairs( lineDetail.logo ) do 
                                 if destinaziuns[destinaziun]~='zulu' and destinaziuns[destinaziun]~=nil then
                                   
                                     if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..logo..'</td><td>'..string.upper(logo)..'</td><td>'..logoslot..'</td></tr>' end
                                     local str=destinaziuns[destinaziun]
                                     if destinaziun=='*qxl' or destinaziun=='*qxr' then str=str..'~~' end
                                     local fermeda=''
                                     local memo = destinaziun 
                                     local k=0 
                                     local cc=true
                                     for i = 1, #str do
                                         k= k + 1
                                         local c = str:sub(i,i)
                                         if c =='~' then 
                                            if cc==false then cc=true else cc=false end
                                            if k==#str or cc==true then
                                               if memo=='-' then memo='Stopt niet in de richting' end 
                                               if memo=='*qxr' then memo='[[wijzerzin|Met de klok mee]]' end 
                                               if memo=='*qxl' then memo='[[tegenwijzerzin|Tegen de klok in]]' end  
                                               memo = string.gsub(memo,nba,'Zie overeenkomstige gegevenskaart in Wikidata')
                                               memo = string.gsub(memo,aaw,'Artikel op wikipedia in het')
                                               fermeda = string.gsub(fermeda,nba,'Zie overeenkomstige gegevenskaart in Wikidata')  
                                               fermeda = string.gsub(fermeda,aaw,'Artikel op wikipedia in het')
                                               if fermeda == 'Eindpunt' or string.find(fermeda,'Artikel op wikipedia in het') or string.find(fermeda,'Zie overeenkomstige gegevenskaart in Wikidata') then eind='' end

                                               local l=0
                                               local links=''
                                               local rechts=''
                                               local lees=0
                                               for l = 1, #memo do
                                                   local d = memo:sub(l,l)
                                                   if lees==0 then links=links..d end
                                                   if lees==1 then rechts=rechts..d end
                                                   if d=='|' then lees=1 end
                                                   if string.upper(rechts)=="STATION " then rechts='' end
                                                   if string.upper(links)=="STATION " and lees==0 then links=eind end   
                                               end

                                               memo = links..rechts

                                               l=0
                                               links=''
                                               rechts=''
                                               lees=0
                                               for l = 1, #fermeda do
                                                   local d = fermeda:sub(l,l)
                                                   if lees==0 then links=links..d end
                                                   if lees==1 then rechts=rechts..d end
                                                   if d=='|' then lees=1 end
                                                   if string.upper(rechts)=="STATION " then rechts='' end
                                                   if string.upper(links)=="STATION " and lees==0 then links=eind end   
                                               end

                                               fermeda = links..rechts


zxa = '<tr><td style="width:32px">[[Bestand:' ..logo .. '|' .. size_logo .. ' px'..lineDetail.logolink..']]</td><td style="width:116px">' ..memo.. '</td><td style="width:116px">' ..fermeda.. '</td></tr>'

                                            if zxa ~= zxb then
                                               if streep then rows[ #rows + 1] = '<tr><td colspan="3"><hr></td></tr>' end
                                               rows[ #rows + 1] = zxa
                                               zxb = zxa 
                                               streep = false
                                            end  
                                            fermeda = ''
                                            memo = destinaziun 
                                            end
                                         else
                                            if cc==true then fermeda = fermeda..c
                                            else
                                               if c =='*' then memo='' end 
                                               memo = memo..c 
                                            end
                                         end
                                     end
                                 end  
                              end
                           end
                       end
                       
                    end
                  end    
				end 
				zulu=0
                
                lineDetail = { }
			    destinaziuns = { }
                local textLine = {''} 
			    lineDetail.name = claim.lineName
               
			    lineDetail.logo = wikidata.stringTable( { entity = claim.lineid, property = 'P154' } )

                if zulu==0 then
                   if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td colspan="3"><hr></td></tr>' end
                   if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td colspan="3">Nieuwe lijn</td></tr>' end
                end
                   
                if #lineDetail.logo==0 and claim.soort=='H' then
                   logo_inv=logo_inv+1
                   if logo_inv>1 then logo_inv=0 end
                   if logo_inv==0 then lineDetail.logo[#lineDetail.logo + 1]='ERTMSmodeUN.svg' end
                   if logo_inv==1 then lineDetail.logo[#lineDetail.logo + 1]='ERTMSmodeUN.svg' end
                   -- Aiga railtransportation 25.svg
                end

                if #lineDetail.logo==0 and claim.soort=='P' then
                   logo_inv=logo_inv+1
                   if logo_inv>1 then logo_inv=0 end
                   if logo_inv==0 then lineDetail.logo[#lineDetail.logo + 1]='Aiga railtransportation inv.svg' end
                   if logo_inv==1 then lineDetail.logo[#lineDetail.logo + 1]='Aiga railtransportation inv.svg' end
                end

                if #lineDetail.logo==0 and claim.soort=='L' then
                   lineDetail.logo[#lineDetail.logo + 1]='Tram logo Basel.png'
                end 

                local rijzijde = wikidata.getClaims( { entity = claim.lineid, property = 'P5658' } ) --rijden ze links of rechts ?
                if rijzijde and #rijzijde > 0 then
                   for _, rz in ipairs( rijzijde ) do
                       kant = wikidata.formatStatement( rz, { link = defaultLink }  )    
                       if string.find(kant,'links') then kant = 'links' end
                       if string.find(kant,'rechts') then kant = 'rechts' end                    
                   end
                end

                if claim.yq==0 then
                   terminusDirections = wikidata.getClaims( { entity = claim.lineid, property = 'P559'} ) -- verzamel de eindpunten van de lijn
                else --ringlijn heeft geen eindpunten
                   terminusDirections={ }
                   terminusDirections[#terminusDirections+1]='*qxr'
                   terminusDirections[#terminusDirections+1]='*qxl'
                end 
                local ep = 0
                local bz=''
			    if terminusDirections and #terminusDirections > 0 then
                   ep = #terminusDirections
                   for _, terminusDirection in ipairs( terminusDirections ) do
                      if zulu<#terminusDirections then 
                          local destinaziun 
                          if claim.yq==0 then
                             destinaziun = wikidata.formatStatement( terminusDirection, { link = defaultLink }  )
                             if string.find(destinaziun,':Q') then 
                             if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba eindpunt: </td><td>'..destinaziun..'</td><td></td></tr>' end
                             
                             local vervang=''
                             local cd = true
                             for i = 1, #destinaziun do
                                local c = destinaziun:sub(i,i)
                                if c == 'Q' then vervang='' end
                                if c == '|' then cd = false  end
                                if cd==true then vervang=vervang..c end                    
                             end
                             if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba eindpunt: </td><td>'..destinaziun..'</td><td></td></tr>' end
                             if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba id: </td><td>'..vervang..'</td><td></td></tr>' end
                             local vervangers = wikidata.getClaims( { entity = vervang, property = 'P2789' } ) --is er een alternatief ?
                             if vervangers and #vervangers > 0 then
                                for _, bestaand in ipairs( vervangers ) do
                                   local vervanger = wikidata.formatStatement( bestaand, { link = defaultLink } )
                                   if not string.find(vervanger,':Q') then 
                                      destinaziuns[vervanger] = 'zulu'
                                      terminusDirections[#terminusDirections+1]=bestaand
                                   end
                                end
                             end
                             end 
                             
                             destinaziuns[destinaziun] = 'zulu'
                          else 
                             destinaziun = terminusDirection
                             destinaziuns[destinaziun] = 'zulu' 
                          end
                             zulu = zulu +1
                             
                             if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..zulu..'</td><td>'..bz..'</td><td>'..destinaziun..'</td></tr>' end
                       end                       
                   end
                   terminusDirections[#terminusDirections+1]='-' --stopt hier niet
                end
                local destinaziun ='-'
                zulu = zulu +1
                destinaziuns[destinaziun] = 'zulu' 
                if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>einde nieuwe lijn</td><td></td><td>'..ep..' eindpunten</td></tr>' end 
                if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td colspan="3">Opvolgende stations op      deze lijn</td></tr>' end
           end --einde nieuwe lijn
       
 
           local station = wikidata.formatStatement( claim, { link = defaultLink }  )
           if string.find(station,':Q') then 
              if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba opvolgend: </td><td>'..station..'</td><td></td></tr>' end
              local vervang=''
              local cd = true
              for i = 1, #station do
                 local c = station:sub(i,i)
                 if c == 'Q' then vervang='' end
                 if c == '|' then cd = false  end
                 if cd==true then vervang=vervang..c end                    
              end
              if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba opvolgend: </td><td>'..station..'</td><td></td></tr>' end
              if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba id: </td><td>'..vervang..'</td><td></td></tr>' end
              local vervangers = wikidata.getClaims( { entity = vervang, property = 'P2789' } ) --is er een alternatief ?
              if vervangers and #vervangers > 0 then
                 for _, bestaand in ipairs( vervangers ) do
                    local vervanger = wikidata.formatStatement( bestaand, { link = defaultLink } )
                    if not string.find(vervanger,':Q') then station = vervanger
                 end
              end
          end
       end


if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>gevonden</td><td></td><td>'..station..'</td></tr>' end

           local destination = wikidata.getFormattedQualifiers( claim, { 'P5051' , 'P560' }, { conjtype = getMessage( 'or', ' ' ), link = defaultLink } )
           local via = wikidata.getFormattedQualifiers( claim, { 'P2825' }, { conjtype = getMessage( 'and' ), link = defaultLink } )
           local vix=''
           local bz=''
           local bibu = wikidata.getFormattedQualifiers( claim, { 'P5051' , 'P560' }, { conjtype = getMessage( 'or', ' ' ), link = defaultLink } )
                
           if bibu ~= nil and bibu ~='' then --met de klok mee/tegen de klok in afleiden van combinatie links/rechts rijden en buitenste/binnenste spoor
                   
              
                      if string.find(bibu,'binnen') then bz = 'bi' end
                      if string.find(bibu,'buiten') then bz = 'bu' end                    
                      if kant ~= nil and kant ~='' then
                        if bz == 'bi' then
                           if kant == 'links' then vix='*qxl' end
                           if kant == 'rechts' then vix='*qxr' end
                        end
                        if bz == 'bu' then
                           if kant == 'links' then vix='*qxr' end
                           if kant == 'rechts' then vix='*qxl' end
                        end
                      end   
                      destinaziuns[vix]=station
                      if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>ringlijn</td><td></td><td>'..vix..'</td></tr>' end
           end
                
           if claim.currentline ~= nil then
           local str = wikidata.formatSnak( claim.currentline, { link = defaultLink } )
           local logolink =''
           local logoq = ''  
           local cc=true
           local ll=true 
           for i = 1, #str do
               local c = str:sub(i,i)
               if c =='|' then cc=false end
               if cc then
                   if c ~='[' then 
                       logolink = logolink..c
                   end
               end
               if c=='(' or logoq ~='' then logoq = logoq..c end
               if logoq == '([[:' then ll=false end
           end
           if filter == 'Z' then rows[ #rows + 1 ] = logolink end
           
           if ll then 
                 lineDetail.logolink = '|link='..logolink
           else
                 lineDetail.logolink = ''
           end
           if station == nil or station =='' then station='station' end
           if via ~= nil and via ~='' then
               via='~<br><small>via: '..via..'</small>'
           else 
               via='~'
           end
           
           if destination ~= nil and destination ~='' then
               if not string.find(destination,':Q') then 
                    if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>naar: </td><td>'..destination..'</td><td></td></tr>' end
               else
                   local vervang=''
                   local cd = true
                   for i = 1, #destination do
                      local c = destination:sub(i,i)
                      if c == 'Q' then vervang='' end
                      if c == '|' then cd = false  end
                      if cd==true then vervang=vervang..c end
                    
                   end
                   if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>nba: </td><td>'..destination..'</td><td></td></tr>' end
                   if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>vervanger: </td><td>'..vervang..'</td><td></td></tr>' end
                   local vervangers = wikidata.getClaims( { entity = vervang, property = 'P2789' } ) --is er een alternatief ?
                   if vervangers and #vervangers > 0 then
                      for _, bestaand in ipairs( vervangers ) do
                         local vervanger = wikidata.formatStatement( bestaand, { link = defaultLink } )
                         if not string.find(vervanger,':Q') then destination = vervanger end
                      end
                   end
               end 
               local destinaziun='' 
               if destination=='-' then
                   destinaziun='-'
                   destinaziuns[destinaziun]=station..'~'; 
                   if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>Stopt niet in de richting </td><td>'..destinaziuns[destinaziun]..'</td><td></td></tr>' end     
               end 
               if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>naar: </td><td>'..destination..'</td><td></td></tr>' end
               local j = 0
               local cc=false
               
               if destination == zelf then --afvangen ringlijnen met "eindpunten", kan niet in het echt maar in wikidata komen deze gevallen voor.
                   destinaziun = zelf 
                   if destinaziuns[destinaziun] ~= nil and destinaziuns[destinaziun] ~='' then
                       if destinaziuns[destinaziun]=='zulu' then
                           destinaziuns[destinaziun]=station..via..'~'
                       else
                           destinaziuns[destinaziun]=destinaziuns[destinaziun]..station..via..'~'
                       end
                   end
                   destinaziun=''
                   cc=false
               end
               for i = 1, #destination do
                   local c = destination:sub(i,i)
                   if c =='[' then
                       cc=true
                       j = 0
                   end
                   if cc then
                       if c ==']' then j= j+1 end  
                       if j<3 then
                           destinaziun = destinaziun..c
                       end
                       if j==2 then
                           if destinaziuns[destinaziun] ~= nil and destinaziuns[destinaziun] ~='' then
                               if destinaziuns[destinaziun]=='zulu' then
                                   destinaziuns[destinaziun]=station..via..'~'
                               else
                                   destinaziuns[destinaziun]=destinaziuns[destinaziun]..station..via..'~'
                               end
                           end
                           --if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..destinaziun..'</td><td>'..destinaziuns[destinaziun]..'</td><td></td></tr>' end
                           destinaziun=''
                           cc=false
                       end
                    end
                 end
              end
           end
          
        end --einde doorloop gevonden stations

        if lineDetail.name ~= nil then
                  local streep = true 
				  if terminusDirections and #terminusDirections > 0 then
                     for _, terminusDirection in ipairs( terminusDirections ) do
                       if zulu>0 then
                           zulu=zulu-1 
                           local destinaziun = ''
                           if terminusDirection=='-' then destinaziun='-' end
                           if terminusDirection=='*qxl' then destinaziun='*qxl' end
                           if terminusDirection=='*qxr' then destinaziun='*qxr' end
                           if destinaziun=='' then destinaziun = wikidata.formatStatement( terminusDirection, { link = defaultLink }  ) end
                           if lineDetail.logolink == nil then lineDetail.logolink = zelf end   
                           if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>richting: </td><td>'..destinaziun..'</td><td>'..destinaziuns[destinaziun]..'</td></tr>' end
                                               
                           if lineDetail.logo then
                              local eind='[['
                              if destinaziuns[zelf] == 'zulu' then destinaziuns[zelf] = 'Eindpunt~~' end
			                  for _, logo in ipairs( lineDetail.logo ) do 
                                 if destinaziuns[destinaziun]~='zulu' and destinaziuns[destinaziun]~=nil then
                                     
                                     local str=destinaziuns[destinaziun]
                                     if destinaziun=='*qxl' or destinaziun=='*qxr' then str=str..'~~' end
                                     local fermeda=''
                                     local memo = destinaziun 
                                     local k=0 
                                     local cc=true
                                     for i = 1, #str do
                                         k= k + 1
                                         local c = str:sub(i,i)
                                         if c =='~' then 
                                            if cc==false then cc=true else cc=false end
                                            if k==#str or cc==true then
                                               if memo=='-' then memo='Stopt niet in de richting' end 
                                               if memo=='*qxr' then memo='[[wijzerzin|Met de klok mee]]' end 
                                               if memo=='*qxl' then memo='[[tegenwijzerzin|Tegen de klok in]]' end  
                                               memo = string.gsub(memo,nba,'Zie overeenkomstige gegevenskaart in Wikidata')
                                               memo = string.gsub(memo,aaw,'Artikel op wikipedia in het')
                                               fermeda = string.gsub(fermeda,nba,'Zie overeenkomstige gegevenskaart in Wikidata')  
                                               fermeda = string.gsub(fermeda,aaw,'Artikel op wikipedia in het')
                                               if fermeda == 'Eindpunt' or string.find(fermeda,'Artikel op wikipedia in het') or string.find(fermeda,'Zie overeenkomstige gegevenskaart in Wikidata') then eind='' end
                                               local l=0
                                               local links=''
                                               local rechts=''
                                               local lees=0
                                               for l = 1, #memo do
                                                   local d = memo:sub(l,l)
                                                   if lees==0 then links=links..d end
                                                   if lees==1 then rechts=rechts..d end
                                                   if d=='|' then lees=1 end
                                                   if string.upper(rechts)=="STATION " then rechts='' end
                                                   if string.upper(links)=="STATION " and lees==0 then links=eind end   
                                               end

                                               memo = links..rechts

                                               l=0
                                               links=''
                                               rechts=''
                                               lees=0
                                               for l = 1, #fermeda do
                                                   local d = fermeda:sub(l,l)
                                                   if lees==0 then links=links..d end
                                                   if lees==1 then rechts=rechts..d end
                                                   if d=='|' then lees=1 end
                                                   if string.upper(rechts)=="STATION " then rechts='' end
                                                   if string.upper(links)=="STATION " and lees==0 then links=eind end   
                                               end

                                               fermeda = links..rechts

zxa = '<tr><td style="width:32px">[[Bestand:' ..logo .. '|' .. size_logo .. ' px'..lineDetail.logolink..']]</td><td style="width:116px">' ..memo.. '</td><td style="width:116px">' ..fermeda.. '</td></tr>'

                                            if zxa ~= zxb then
                                               if streep then rows[ #rows + 1 ] = '<tr><td colspan="3"><hr></td></tr>' end
                                               rows[ #rows + 1] = zxa
                                               zxb = zxa 
                                               streep = false
                                            end  
                                            fermeda = ''
                                            memo = destinaziun 
                                            end
                                         else
                                            if cc==true then fermeda = fermeda..c
                                            else
                                               if c =='*' then memo='' end 
                                               memo = memo..c 
                                            end
                                         end
                                     end
                                 end  
                              end
                           end
                       end
                       
                    end
                  end    
						end
local lb = ''
	    if linkback ~= '-' and #rows>2 then
           rows[ #rows + 1 ] = '<tr><td colspan="3"><hr></td></tr>'
		   lb = '[[d:' .. id  .. '#P197|<small>Brongegevens in Wikidata aanpassen</small>]]'
		   rows[ #rows + 1 ] = '|-'
		   rows[ #rows + 1 ] = '| class="noprint navigation-not-searchable tfoot" colspan="5" | ' .. lb
	    end
	    return true
	else
		return false
	end -- einde #claims>0

end

function p.Dienst_info( id, onlyLineService, filter, rows )
    if not id then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	local argsData = { entity = id, property = 'P197' }
	if onlyLineService then
		argsData.qualifier = { 'P1192', 'P81' } -- ligne or service
		argsData.qualifiervalue = onlyLineService
	end
	--localisation principale
	local mainCoordinate = ( not ignoreCoordinate ) and wikidata.stringTable( { entity = id, property = 'P625', numval = 1 } )
	if mainCoordinate and #mainCoordinate > 0 then -- si des coordonnées pour la présente station sont présentes / if coordinates are present for the current subway
		mainCoordinate = mainCoordinate[ 1 ]
	end
    local function Split(s, delimiter)
        result = {};
        for match in (s..delimiter):gmatch("(.-)"..delimiter) do
            table.insert(result, match);
        end
        return result;
    end
    local claims = wikidata.getClaims( argsData )
	local function getClaimDetail( claim )
		claim.lineid = wikidata.getId( claim.currentline )
		claim.lineName = wikidata.formatSnak( claim.currentline, { link = defaultLink } )
		if not claim.lineName or claim.lineName == '-' then -- no value
			claim.lineName = ''
		end
		local routenumber = wikidata.formatStatements( { entity = claim.lineid, property = 'P1671', numval = 1 } )
		if routenumber then
			claim.sortKey = tonumber( routenumber ) -- 570000
				or tonumber( tostring( routenumber:gsub( ' ', '' ) ) ) -- 655 000
				or routenumber:upper() -- KBS 566
		else
			claim.sortKey = claim.lineName:upper()
		end
        if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td colspan="3">----------</td></tr><tr><td>'..(#rows +1)..'</td><td>Modaliteit</td><td>'..claim.lineName..'</td></tr>' end
        --Modaliteitsdetectie
        local soort = wikidata.getClaims( { entity = claim.lineid, property = 'P31' } ) --is het metro/voorstad/treindienst ?
        claim.soort = '-'
        if soort and #soort > 0 then
            for _, modaliteit in ipairs( soort ) do
                local fltr = wikidata.formatStatement( modaliteit, { link = defaultLink }  ):upper()    
                if filter == 'Z' then rows[ #rows + 1 ] = '<tr><td>'..fltr..'</td><td></td><td>'..claim.soort..'</td></tr>' end
                if claim.soort == '-' then
                    if string.find(fltr,'METRO') then claim.soort = 'M' end 
                    if string.find(fltr,'LIGHT') then claim.soort = 'L' end  
                    if string.find(fltr,'LICHT') then claim.soort = 'L' end 
                    if string.find(fltr,'SNELTRAM') then claim.soort = 'L' end     
                    if string.find(fltr,'S-TREIN') then claim.soort = 'S' end
                    if string.find(fltr,'VOORSTAD') then claim.soort = 'S' end
                    if string.find(fltr,'HOOFD') then claim.soort = 'H' end
                    if string.find(fltr,'NEVEN') then claim.soort = 'H' end
                    if string.find(fltr,'HOGE') then claim.soort = 'H' end
                    if string.find(fltr,'SPOORLIJN') then claim.soort = 'H' end
                    if claim.soort == '-' then claim.soort = 'P' end      
                end
            end
        end
        
	end --einde functie claimdetails
 
    if claims and #claims > 0 then --stations gevonden
		-- récupération des données de bases et de tri des lignes / recovery of basic data and line sorting
		local newClaims = { }
		local defaultSortKey = 1
		for _, claim in ipairs( claims ) do
			local newClaim = mw.clone( claim )
			newClaim.currentline = claim.id
			getClaimDetail( newClaim )
			if not onlyLineService or onlyLineService == newClaim.lineid then
				if filter == 'Y' or filter == 'Z' or filter == newClaim.soort then
                    newClaims[ #newClaims + 1 ] = newClaim
                end
			end
            if filter == 'D' then rows[ #rows + 1 ] = '<tr><td>'..newClaim.soort..'</td><td>'..newClaim.lineName..'</td><td>'..#newClaims..'</td></tr>' end
		end
	
		table.sort( newClaims,
			function( c1, c2 )
				if c1.sortKey == c2.sortKey then
					return c1.defaultSortKey < c2.defaultSortKey
				elseif type( c1.sortKey ) == 'number' and type( c2.sortKey ) == 'number' then
					return c1.sortKey < c2.sortKey
				else
					return tostring( c1.sortKey ) < tostring( c2.sortKey )
				end
			end
		)
    end
end

function p.navigatie (id, filter, rows)
    if not id then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
	local argsData = { entity = id, property = 'P1192' }
	local lijst=''
		
	rows[ #rows + 1 ] = '{{Navigatie'
    rows[ #rows + 1 ] = '| titel = Stations van de [[metro van Helsinki]]'
    rows[ #rows + 1 ] = '| afb_rechts = [[Bestand:Helsingin metro logo.svg|20px|Logo metro Helsinki]]'
lijst='| inhoud = [[Kivenlahti]] · [[Espoonlahti]] · [[Soukka]] · [[Kaitaa]] · [[Finnoo]] · [[Matinkylä]] · [[Niittykumpu]] · [[Urheilupuisto (metrostation)|Urheilupuisto]] · [[Tapiola (metrostation)|Tapiola]] · [[Aalto-yliopisto]] · [[Keilaniemi]] · [[Koivusaari (metrostation)|Koivusaari]] · [[Lauttasaari (metrostation)|Lauttasaari]] · [[Ruoholahti (metrostation)|Ruoholahti]] · [[Kamppi (metrostation)|Kamppi]] · [[Rautatientori (metrostation)|Rautatientori]] · [[Helsingin yliopisto (metrostation)|Helsingin yliopisto]] · [[Hakaniemi (metrostation)|Hakaniemi]] · [[Sörnäinen]] · [[Kalasatama]] · [[Kulosaari (metrostation)|Kulosaari]] · [[Herttoniemi]] · [[Siilitie]] · [[Itäkeskus]]}}'
	rows[ #rows + 1 ] = lijst
    
    return table.concat( rows, '\n' )
end


function p.overzicht (id, filter, rows)
    if not id then
		id = mw.wikibase.getEntityIdForCurrentPage()
	end
    return 'stationslijst'
end

function p.main( frame )
	local rows = {}
	local args = extractArgs( frame )
	local id = validTextArg( args, 1, 'id', 'wikidata', 'entity' )
	local onlyLineService = validTextArg( args, 2, 'ligne', 'line', 'service' )
	linkback = validTextArg( args, 'linkback' )
	local ssource = validTextArg( args, 'showsource' )
	if ssource and ( ssource == '-' or ssource == 'non' or ssource == 'no' or ssource == 'false' ) then
		showsource = false
	end
    local filter = validTextArg( args, 5, 'mode', 'mode' ) or 'M' --parameter 5 modaliteit, verstekwaarde is M (metro). A=aansluitende stations, B=buslijn, T=tramlijn, L=sneltram/lightrail, M=metro, S=voorstadsdienst, V=treindienst, I=internationale trein
	local title = validTextArg( args, 'titre', 'title', 3 ) or ''
    if id and title == '' then
        title = wikidata.formatEntity( id , { link = defaultLink } )
		if linkback ~= '-' and defaultLink ~= 'wikidata' then
			title = addLinkBack( title, id, 'P197' )
			linkback = '-'
		end
	elseif title == '-' then
		title = ''
	end
    
	ignoreCoordinate = validTextArg( args, 'ignore coordinate', 'ignore coordonnées' )
	showdebug = validTextArg( args, 'debug' ) -- pour les tests uniquement / for testing only
    
    if filter ~= 'N' and filter ~= 'O' then 
	    rows[ #rows + 1 ] = '<table style="width:264px">'
        
        if filter ~= 'P' then
           rows[ #rows + 1 ] = '<tr><td style="width:32px">Lijn</td><td style="width:116px">Richting</td><td style="width:116px">Volgend station</td></tr>'
        else
           rows[ #rows + 1 ] = '<tr><td style="width:32px">Trein</td><td style="width:116px">Richting</td><td style="width:116px">Volgend station</td></tr>'
        end
	
        if filter ~= 'D' then
           local found = p.Lijn_info( id, onlyLineService, filter, rows )
        else
           local found = p.Dienst_info( id, onlyLineService, filter, rows )
        end  
    
	    if #rows>2 then
           rows[ #rows + 1 ] = '</table>'
           return table.concat( rows, '\n' )
	    else
		   return nil
        end
	end

    if filter == 'N' then
       return p.navigatie (id, filter, rows)
    end  
    
    if filter == 'O' then
       return p.overzicht (id, filter, rows)
    end   

end

-- p=string.gsub(p,'class="error"','class="error" style="display:none"')

return p