Module:Sandbox/RedWolf
Appearance
local p = {}
--local wd = require('Module:Wd')
local titled_coords = require('Module:Titled_coords')
-- Information about a mountain from Module arguments and Wikidata.
local Mountain = { rank, page, name, eid, elevation, elevation_wd,
prominence , range, fa, coords, notes }
-- Runtime options about what information to display
local Options = { showFA = false, showCoord = false, showTCoord = false,
showNotes = false, showRank = false, showRange = false}
-- Wikidata properties
local WD_PROPERTIES = {
elevation = "P2044",
prominence = "P2660",
mtn_range = "P4552",
coords = "P625",
sig_event = "P793",
pt_in_time = "P585"
}
local QID_FIRST_ASCENT = "Q1194369"
local errors
-- Split a string based on a separator
local function split(istring, sep)
-- if sep is null, set it as comma
if sep == nil then sep = ',' end
local t = {}
for str in string.gmatch(istring, '([^'..sep..']+)')
do
table.insert(t, str)
end
return t
end
-- Extract raw elevation/prominence value
local function extractRaw(value)
local i, i1, i2, n
if value == nil then return -1 end
i = string.find(value, " metre")
if i then
n = string.sub(value, 1, i-1):gsub(',', '')
else
n = -1
end
return n
end
-- Call {{elevation_cells} to format the values
local function getElevationCells(frame, elev, unit) --23
if frame.expandTemplate then
return frame:expandTemplate{title='elevation_cells', args= { elev, unit}}
end
return "{{elevation_cells|" .. elev .. "|" .. unit .. "}}"
end
local function getPage(name)
local parts = split(name,"|")
local page = parts[1]
local n = string.find(page, "%[%[")
if n then
page = string.sub(page,3)
end
n = string.find(page, "%]%]")
if n then
page = string.sub(page,1,n-1)
end
return page
end
local function getWD(frame, eid, name, flag)
if not frame.preprocess then
return "{{Wikidata|property|" .. name .. "|eid=" .. eid .. "}}"
end
local args = "property|"
if flag then args = args .. flag .. "|" end
args = args .. name .. "|eid=" .. eid
local invoke = "{{#invoke:Wd|" .. args .. "}}"
local value = frame:preprocess(invoke)
mw.log(invoke .. " => " .. value)
return value
end
local function getWD(frame, eid, name)
return getWD(frame, eid, name, nil)
end
local function getWDLinked(frame, eid, name)
return getWD(frame, eid, name, "linked")
end
local function getWDRaw(frame, eid, name)
return getWD(frame, eid, name, "raw")
end
-- Get an entity's property from Wikidata
local function getWDProperty(frame, eid, name, linked)
mw.log("eid=" .. eid .. " name=" .. name)
--[[ local stmts = mw.wikibase.getBestStatements(eid, name)
if stmts ~= nil then
mw.logObject(stmts)
for i=1,#stmts do
mw.log("stmts["..i.."]="..stmts[i]);
end
end ]]
if frame.preprocess then
local args = "property|"
if linked then args = args .. "linked|" end
args = args .. name .. "|eid=" .. eid
local invoke = "{{#invoke:Wd|" .. args .. "}}"
local value = frame:preprocess(invoke)
mw.log(invoke .. " => " .. value)
return value
end
return "{{Wikidata|property|" .. name .. "|eid=" .. eid .. "}}"
end
-- if frame.expandTemplate then
-- local args = { ['1'] = name, ['page'] = page }
-- return wd._property({eid, args})
-- local args = { ['1'] = 'property', ['2'] = name, ['page'] = page }
-- return frame:expandTemplate{title='Wikidata', args= args}
local function getCoords(frame, eid)
return getWD(frame, eid, WD_PROPERTIES.coords, nil)
end
local function getTitledCoords(frame, eid, title)
local raw_coords = getWDRaw(frame, eid, WD_PROPERTIES.coords)
local invoke = "{{#invoke:Titled_coords|main|" .. raw_coords .. "|" .. title .. "}}"
--local fmt_coords = frame:preprocess(invoke)
mw.log(invoke .. " => " .. fmt_coords)
return "????"
--return fmt_coords
end
local function getElevation(frame, eid)
value = getWD(frame, eid, WD_PROPERTIES.elevation)
return extractRaw(value)
end
local function getFirstAscent(frame, eid)
if frame.preprocess == nil then return "????" end
local names = WD_PROPERTIES.sig_event .. "|" .. QID_FIRST_ASCENT .. "|" .. WD_PROPERTIES.pt_in_time
local value = frame:preprocess("{{#invoke:Wd|property|qualifier|" .. names .. "|eid=" .. eid .. "}}")
mw.log("FA value = " .. value)
if value == "" then
mw.log("No FA found for eid=" .. eid)
return " "
end
-- Find date such as: 10 July 1913
local i1, i2 = string.find(value, "%(%d+%s%a*%s%d%d%d%d%)")
if i1 then
--mw.log("i1="..i1)
local date = string.sub(value, i1+1, i2-1)
mw.log("FA date = " .. date)
local len = string.len(date)
local year = string.sub(date, len-4, len)
return year
end
-- Find date with just the year; e.g. (2025)
i1, i2 = string.find(value, "%(%d+%)")
if i1 then
local year = string.sub(value, i1+1, i2-1)
return year
end
return "FA date format unknown"
end
-- get prominence from Wikidata
local function getProminence(frame, eid)
local prom = getWD(frame, eid, WD_PROPERTIES.prominence, nil)
return extractRaw(prom)
end
-- get mountain range from Wikidata
local function getRange(frame, eid)
return getWDLinked(frame, eid, WD_PROPERTIES.mtn_range)
end
-- generate table header
local function header(options, unit)
local unit_1, unit_2
if unit == nil or unit == "" then
unit = 'm'
end
if unit == 'm' then unit_1 = 'm'; unit_2 = 'ft'
else unit_1 = 'ft'; unit_2 = 'm'
end
local s = '{| class="wikitable sortable"\n!'
if options.showRank then s = s .. " align=\"left\" rowspan=2|Rank||" end
s = s .. "rowspan=2|Mountain/Peak ||colspan=2|Elevation ||colspan=2| Prominence "
if options.showRange then s = s .. "||rowspan=2| Subrange" end
if options.showFA then s = s .. "||rowspan=2| FA " end
if options.showCoord then s = s .. "||rowspan=2| Coordinates" end
if options.showNotes then s = s .. "||rowspan=2| Notes" end
s = s .. "\n|-\n"
s = s .. '!' .. unit_1 .. '||' .. unit_2 .. '||' .. unit_1 .. '||' .. unit_2 .. "\n"
return s
end
local function finish()
return "|}"
end
--[[ Process run options
rank - show ranking
range - show mountain range or subrange from WD
fa - show first ascent (year only) from WD
coords - show coordinates from WD
tcoords - show titled coordinates from WD
notes - show notes
]]
local function processOptions(runOptions)
local o = Options
if runOptions == nil then return o end
mw.log("runOptions=" .. runOptions)
local parts = split(runOptions, ",")
for i=1,#parts do
option = parts[i]
mw.log("option=" .. option)
if option == "rank" then o.showRank = true end
if option == "fa" then o.showFA = true end
if option == "coords" then o.showCoord = true end
if option == "tcoords" then o.showTCoord = true end
if option == "range" then o.showRange = true end
if option == "notes" then o.showNotes = true end
end
return o
end
local function processLine(frame, options, line)
local parts, n
local name, elev, page, notes
-- argument contains elevation, page link and notes
parts = split(line, ",")
if #parts < 3 then
local m = "<br/>Bad format on argument (<nowiki>" .. line .. "</nowiki>) -- skipped"
errors = errors .. m
mw.log(m)
return nil
end
local mtn = Mountain
elev = parts[1]
name = parts[2]
if name then
page = getPage(name)
mw.log("name = " .. name .. ";page = " .. page)
else
mw.log("name is null")
return nil
end
mtn.name = name
mtn.page = page
mtn.elevation = elev;
if options.showNotes then
notes = parts[3]
n = string.find(notes, "\n")
if n then
notes = string.sub(notes, 1, n-1)
end
mtn.notes = notes
end
local eid = mw.wikibase.getEntityIdForTitle(page)
mw.log("page="..page .. ",eid=" .. eid)
mtn.eid = eid
mtn.elevation_wd = getElevation(frame, eid)
mtn.prominence = getProminence(frame, eid)
if options.showRange then
mtn.range = getRange(frame, eid)
end
if options.showFA then
mtn.fa = getFirstAscent(frame, eid)
end
if options.showCoord then
mtn.coords = getCoords(frame, eid)
end
if options.showTCoord then
mtn.coords = getTitledCoords(frame, eid, page)
end
return mtn
end
local function processRange(ranges, mtn)
local found = false;
local range = mtn.range
for k,v in pairs(ranges) do
if v == range then
found = true; break
end
end
if not found then
mw.log("Adding range " .. range)
table.insert(ranges, range)
else
local i1, i2 = string.find(range, "|")
if i1 then
name = string.sub(range, i1+1)
else
local len = string.len(range)
name = string.sub(range, 3, len-2)
end
mtn.range = name
end
end
function p.list(frame) -- 34
local debug = false
local rank_number = 0
local last_elev = ""
errors = ""
local unit = frame.args[1]
local options = processOptions(frame.args[2])
local output = header(options, unit)
local ranges = {}
for i=3,999,1 do
line = frame.args[i]
if line == nil then break end
mw.log("line=" .. line)
local mtn = processLine(frame, options, line)
if mtn then
if options.showRank and last_elev ~= mtn.elevation then
rank_number = rank_number + 1
mtn.rank = rank_number
last_elev = mtn.elevation
end
if options.showRange then
processRange(ranges, mtn)
end
elev_cells = getElevationCells(frame, mtn.elevation, unit)
prom = mtn.prominence
if prom ~= nil and prom ~= "-1" and prom ~= "" then
prom_cells = getElevationCells(frame, prom, unit)
else
prom_cells = " || "
end
mw.log("elev=" .. mtn.elevation ..";elev_wd="..mtn.elevation_wd)
if options.showNotes and mtn.elevation ~= mtn.elevation_wd then
local mm = "<br/><font color=green>Local/WD elevations mismatch: " .. "\"" .. mtn.elevation .. "\"".. "/\"" .. mtn.elevation_wd.. "\"</font>"
mtn.notes = mtn.notes .. mm
end
local s = "|-\n|"
if options.showRank then s = s .. "align=center|" .. mtn.rank .. "||" end
s = s .. mtn.name .. '\n|' .. elev_cells .. '\n|' .. prom_cells .. '\n|'
if options.showRange then s = s .. '|' .. mtn.range .. '\n' end
if options.showFA then s = s .. '|' .. mtn.fa .. '\n' end
if options.showCoord or options.showTCoord then s = s .. '|' .. mtn.coords .. '\n' end
if options.showNotes then s = s .. '|' .. mtn.notes .. '\n' end
output = output .. s
end
end -- for
output = output .. finish()
if debug then
output = "</br><nowiki>"..output.."</nowiki>".."\n"..output
end
if string.len(errors) > 0 then
output = output .. "<font color=red>" .. errors .. "</font>"
end
return output
end
--[[
Test via Preview Window Debug console
print(p.test())
]]
function p.test()
local frame = mw.getCurrentFrame()
-- if frame then mw.logObject(frame) end
-- local frame = {}
frame.args = {}
frame.args[1] = 'm'
frame.args[2] = "rank,range,fa,xcoords,xnotes"
frame.args[3] = "3954,[[Mount Robson]],Highest point in the Canadian Rockies\n"
frame.args[4] = "3747,[[Mount Columbia (Canada)|Mount Columbia]],Highest point in [[Alberta]]"
frame.args[5] = "3246,[[Apex Mountain (Chaba Icefield)|Apex Mountain]],Named for its location in the centre of the Clemenceau Icefield"
frame.args[6] = "3246,[[Mount Smythe (Alberta)|Mount Smythe]],Named for an English mountaineer"
frame.args[7] = ""
frame.args[8] = " "
return p.list(frame)
end
function p.test2()
local s = '<a href="/wiki/Rainbow_Range_(Rocky_Mountains)" title="Rainbow Range (Rocky Mountains)">Rainbow Range</a>'
--local i1,i2 = string.find(s,"%>(.*)%<%/a%>")
local i1,i2 = string.find(s,"%b><")
if i1 then
mw.log("i1=" .. i1 .. " i2=" .. i2)
mw.log(string.sub(s,i1+1,i2-1))
else
mw.log("not found")
end
end
return p
--[[
{| class="wikitable sortable"
|- bgcolor="#ffffcc"
! align="left" rowspan=2|Rank||rowspan=2|Mountain/Peak ||colspan=2|Elevation ||colspan=2| Prominence ||rowspan=2| Subrange
!rowspan=2| FA ||rowspan=2| Notes ||rowspan=2| References
|-
!m || ft || m || ft
|-
|align=center|1||Mount Robson
|{{elevation_cells|3,959|m}}|{{elevation_cells|2829|m}}||Rainbow Range
|1913||Highest point in the Canadian Rockies|| <ref name=robson/>
]]