Jump to content

Module:Sandbox/RedWolf

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by RedWolf (talk | contribs) at 19:11, 27 January 2025 (syntax). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local p = {}
--local wd = require('Module:Wd')

Mountain = { rank, page, name, eid, elevation, elevation_wd, prominence , range, fa, coords, notes }
Options  = { showFA = false, showCoords = false, showNotes = false, showRank = false, showRange = false}

-- Wikidata properties
local WD_PROPERTIES = {
    elevation  = "P2044",
    prominence = "P2660",
    mtn_range  = "P4552",
    sig_event  = "P793",
    pt_in_time = "P585"
}
local QID_FIRST_ASCENT = "Q1194369"

local errors

-- Split a string based on a separator
local function split(inputstr, sep)
    -- if sep is null, set it as comma
    if sep == nil then sep = ',' end

    local t = {}
    for str in string.gmatch(inputstr, '([^'..sep..']+)') 
    do
        table.insert(t, str)
    end
    return t
end

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

-- Get an entity's property from Wikidata
local function getWDProperty(frame, eid, name) -- 45
    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
        --return frame:preprocess("{{#invoke:Wd|property|" .. name .. "|page=" .. page .. "}}")
        return frame:preprocess("{{#invoke:Wd|property|" .. name .. "|eid=" .. eid .. "}}")
--    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}
    end
    return "{{Wikidata|property|" .. name .. "|eid=" .. eid .. "}}"
end

local function getElevation(frame, eid)
    if frame.preprocess == nil then return "????" end

    value = getWDProperty(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

--    local i1, i2 = string.find(value, "%(%d%d%d%d%-%d%d%-%d%d%)")
    -- 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
    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 = getWDProperty(frame, eid, WD_PROPERTIES.prominence)
    return extractRaw(prom)
end

local function getRange(frame, eid)
    return getWDProperty(frame, eid, WD_PROPERTIES.mtn_range)
end

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.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
local function processOptions(runOptions)
mw.log("runOptions=" .. runOptions)
    local o = Options
    if runOptions == nil then return o end

    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.showCoords = 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 (" .. line .. ") -- 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

    return mtn
end

function p.list(frame) -- 34
    local debug = false

    errors = ""
    local unit  = frame.args[1]
    local rank_number = 0
    local last_elev = ""

    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
                last_elev = elev
            end
            mtn.rank = rank_number

            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 = "&nbsp;||&nbsp;"
            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|' .. mtn.range .. '\n|' .. mtn.fa .. '\n'
            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] = "xrank,range,fa,notesx"
    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,[[Mount Smythe (Alberta)|Mount Smythe]],Named for an English mountaineer"
    frame.args[6] = ""
    frame.args[7] = "&nbsp;"

    return p.list(frame)
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/>
]]