Module:WikidataCoord

require('strict')

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

local patterns = {

'(%d+)°(%d+)'([%d%.]+)"([NS]),%s*(%d+)°(%d+)'([%d%.]+)"([EW])', -- if the returned data looks like 55°13'12"N, 23°17'17"E

'(%d+)°(%d+)'([NS]),%s*(%d+)°(%d+)'([EW])', -- if the returned data looks like 54°24'N, 25°25'E

'(%d+)°(%d+)[′\']([%d%.]+)[″\"]([NS]),?%s*(%d+)°(%d+)[′\']([%d%.]+)[″\"]([EW])', -- when args[1] is a dms string that uses quotes or primes

'(%d+)°(%d+)[′\']([NS]),?%s*(%d+)°(%d+)[′\']([EW])', -- when args[1] is a dms string that uses quotes or primes, bit shorter format

'(%d+%.?%d*)°([NS]),?%s*(%d+%.?%d*)°([EW])', -- when args[1] is a decimal degrees string

}

local params = {'display', 'format', 'name', 'notes'}; -- {{coord}} template paramters

--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Whether variable is set or not. A variable is set when it is not nil and not empty.

]]

local function is_set( var )

return not (var == nil or var == '');

end

--[[--------------------------< M A I N >----------------------------------------------------------------------

Template entry point. This function takes up to two unnamed positional parameters:

1 = coordinate string typically from a call to Wikidata like this: {{#property:P625|from=Q...}}

2 = coordinate parameters; see Template:Coord

Also takes the named parameters |display=, |format=, |name=, |notes= which it passes on to {{coord}}

Reformats the Wikidata coordinate string into unnamed parameters for {{coord}}

{{#invoke:WikidataCoord|main|{{#property:P625|from={{{1}}}}}|{{{2}}}|display={{{display}}}|format={{{format}}}|name={{{name}}}|notes={{{notes}}}}}

]]

local function main (frame)

local args = getArgs(frame);

local lat_long = {}; -- table of lat/long coords extracted from wikidata return

if not is_set (args[1]) then -- in case wikidata returns nothing (happens when Q... is wrong)

return '{{WikidataCoord}} – missing coordinate data'; -- error message and quit

else

for _, pattern in ipairs (patterns) do

lat_long[1], lat_long[2], lat_long[3], lat_long[4], lat_long[5], lat_long[6], lat_long[7], lat_long[8] =

mw.ustring.match (args[1], pattern)

if lat_long[1] then

break;

end

end

end

if not lat_long[1] then

return '{{WikidataCoord}} – malformed coordinate data'; -- wikidata returned something else

end

if is_set (args[2]) then -- coordinate parameters are in second unnammed positional parameter

table.insert (lat_long, args[2]); -- add coordinate parameters as next positional parameter after coordnates

end

for _, param in ipairs (params) do

if is_set (args[param]) then

lat_long[param] = args[param]; -- add the named parameters if they have a value

end

end

if args._debug then

return table.concat ({'{{coord|', table.concat (lat_long, '|' ), '}}'});

end

return frame:expandTemplate ({title = 'coord', args=lat_long}); -- invoke template {{coord}} with wikidata lat/long

end

--[[--------------------------< E X P O R T E D F U N C T I O N >--------------------------------------------

]]

return {main = main}