Module:Sandbox/RedWolf

--[[

This module builds a wiki table that lists information pertinent to mountains. This module accomodates up to 996 lines

of mountains where each line consists of the elevation, wiki-linked name and optional notes information. This

module uses the wiki-linked name to find its corresponding Wikidata item (eid) and then retrieve the following

information from Wikidata: elevation, prominence, isolation, range, first ascent, country, coordinates

]]

local p = {}

--local wd = require('Module:Wd')

local Titled_coords = require('Module:Titled_coords')

local newBuffer = require('Module:OutputBuffer')

-- Wikidata properties

local WD_PROPERTIES = {

elevation = "P2044",

prominence = "P2660",

mtn_range = "P4552",

coords = "P625",

sig_event = "P793",

pt_in_time = "P585",

isolation = "P2659",

country = "P17"

}

-- Table column titles for easier translation

local COL_TITLES = {

rank = "Rank",

name = "Mountain / Peak",

elev = "Elevation",

prom = "Prominence",

isoltn = "Isolation",

range = "Subrange",

fa = "FA",

coords = "Coordinates",

country = "Country",

custom = "Notes"

}

-- ** Runtime Option names **

local OPT_NAMES = {

NAME = "name",

RANK = "rank",

PROM = "prom",

ISOLTN = "isolation",

RANGE = "range",

FA = "fa",

COORDS = "coords",

TCOORDS= "tcoords",

CUSTOM1= "custom1",

CUSTOM2= "custom2",

COUNTRY= "country",

ORDER = "order",

DEBUG = "debug"

}

local RANK_ORDER = { ELEV = "E", PROM = "P"}

local UNITS = {

METRE = "m", FEET = "ft",

KILOMETRE = "km", MILE = "mi"

}

-- Runtime options about what information to display

local Options = { debug = false, test = false, showFA = false, showProm = false,

showCoord = false, showTCoord = false, rankOrder = RANK_ORDER.ELEV,

showRank = false, showRange = false, showIsolation = false,

showCountry = false, showCustom1 = false, showCustom2 = false }

-- Information about a mountain from Module arguments and Wikidata.

local Mountain = { rank, page, name, eid, elevation, elevation_wd = 0, prominence,

range = "", isolation = "", fa = "", coords, custom, country }

local QID_FIRST_ASCENT = "Q1194369"

local FA_UNKNOWN = "Unk"

local FA_ERROR = "????"

local FS = "^" -- field separator

local NBSP = " "

local COL_TITLE_SEP = ":" -- do not use "="

local OPTIONS_SEP = ","

local NEWLINE = "\n"

local BR_NEWLINE ="
"..NEWLINE

local TD = '|'

local errors, dbgout

local function debug(msg)

mw.log(msg)

dbgout = dbgout .. msg .. BR_NEWLINE

end

local function debugv(var, value)

local s = var .. "=" .. value

mw.log(s)

dbgout = dbgout .. s .. BR_NEWLINE

end

local function addError(msg)

errors = errors .. msg .. BR_NEWLINE

debug(msg)

end

local function errorFont(value)

return "" .. value .. ""

end

-- Split a string based on a separator

local function split(istring, sep)

-- if sep is null, use default

if sep == nil then sep = FS end

local t = {}

for str in string.gmatch(istring, '([^'..sep..']+)') do

table.insert(t, str)

end

return t

end

-- Strip newline character at end --

local function stripNewline(value)

local n = string.find(value, NEWLINE)

if n then

return string.sub(value, 1, n-1)

end

return value

end

-- Extract raw elevation/prominence/isolation value

local function extractRaw(value)

local i, i1, i2, n

local units = { " metre", " feet", " kilometre" }

if value == nil then return -1 end

i = string.find(value, " metre")

if i then

-- remove thousands separator while we are it

return string.sub(value, 1, i-1):gsub(',', '')

end

i = string.find(value, "feet")

if i then

return string.sub(value, 1, i-1):gsub(',', '')

end

i = string.find(value, " kilometre")

if i then

return string.sub(value, 1, i-1):gsub(',', '')

end

return -1

end

-- Call {{elevation_cells} to format the values

local function getElevationCells(frame, elev, unit)

if frame.expandTemplate then

return frame:expandTemplate{title='elevation_cells', args= { elev, unit}}

end

return "{{elevation_cells|" .. elev .. "|" .. unit .. "}}"

end

local function getProminenceCells(frame, prom)

return frame:expandTemplate{title='convert', args= { prom, "km", "mi", disp='table', sortable='on'}}

end

local function stripBrackets(value)

local stripped = value;

-- strip leading brackets if found

local n = string.find(stripped, "%[%[")

if n then

stripped = string.sub(stripped, 3)

end

-- strip trailing brackets if found

n = string.find(stripped, "%]%]")

if n then

stripped = string.sub(stripped,1,n-1)

end

if stripped then return stripped

else return value end

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 getPageTitle(name)

local title

local parts = split(name,"|")

if parts[2] then

title = stripBrackets(parts[2])

else

title = stripBrackets(parts[1])

end

mw.log("name="..name..";title="..title)

return title

end

--[[

Retrieve a entity's property value from Wikidata. Unfortunately

the interface only supports one property at a time.

]]

local function getWD(frame, eid, name, cmdFlag, multiple)

if not frame.preprocess then

return "{{Wikidata|property|" .. name .. "|eid=" .. eid .. "}}"

end

local args

if not multiple then args = "property|" else args = "properties|" end

if cmdFlag then args = args .. cmdFlag .. "|" end

args = args .. name .. "|eid=" .. eid

local invoke = "{{#invoke:Wd|" .. args .. "}}"

local value = frame:preprocess(invoke)

mw.log(invoke .. " => " .. value)

return value

end

-- Get a wiki linked property value

local function getWDLinked(frame, eid, name)

return getWD(frame, eid, name, "linked", false)

end

-- Get the raw value of a property value

local function getWDRaw(frame, eid, name)

return getWD(frame, eid, name, "raw", false)

end

-- Get an entity's property from Wikidata

local function getWDProperty(frame, eid, name, linked)

debug("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 ]]

-- call Module:Wd using template syntax

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)

debug(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 stripCoords(wdCoords)

--debugv("wdCoords", wdCoords)

if Options.test then -- this only shows up in console test mode

local stripped = string.gsub(wdCoords, "\"`UNIQ%-%-templatestyles%-%d+%-QINU`\"", "")

--debugv("stripped", stripped)

return stripped

end

return wdCoords

end

local function getCountry(frame, eid)

local value = getWD(frame, eid, WD_PROPERTIES.country, nil, true)

return value

end

-- get location coordinates

local function getCoords(frame, eid)

local wdCoords = getWDLinked(frame, eid, WD_PROPERTIES.coords)

return stripCoords(wdCoords)

end

-- Call Module:Titled_coords to get titled coordinates

local function getTitledCoords(frame, eid, page)

local title = getPageTitle(page)

local raw_coords = getWDRaw(frame, eid, WD_PROPERTIES.coords)

local fmt_coords = Titled_coords.build(raw_coords, title, "")

debug(fmt_coords .. " => " .. fmt_coords)

return stripCoords(fmt_coords)

end

local function getElevation(frame, eid)

local value = getWD(frame, eid, WD_PROPERTIES.elevation, nil)

return extractRaw(value)

end

local function getFirstAscent(frame, eid)

if frame.preprocess == nil then return FA_ERROR 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 .. "}}")

debugv("FA value", value)

if value == "" then

debugv("No FA found for eid", eid)

return FA_UNKNOWN

end

-- FA deliberately set to unknown value

if string.find(value, "(unknown)") then

debugv("FA unknown for eid", eid)

return FA_UNKNOWN

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)

debugv("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

addError("Unknown FA date format for eid " .. eid .. ": " .. value)

return FA_ERROR

end

-- *** get topgraphic isolation from Wikidata ***

local function getIsolation(frame, eid)

local isoltn = getWD(frame, eid, WD_PROPERTIES.isolation, nil)

return extractRaw(isoltn)

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. We want it wiki-linked for

-- the first occurrence of it in the output.

local function getRange(frame, eid)

return getWDLinked(frame, eid, WD_PROPERTIES.mtn_range)

end

-- generate table header

local function genHeader(options, unit)

local unit_1, unit_2

if unit == nil or unit == "" then

unit = UNITS.METRE

end

if unit == UNITS.METRE then unit_1 = UNITS.METRE; unit_2 = UNITS.FEET

else unit_1 = UNITS.FEET; unit_2 = UNITS.METRE

end

local s = "

class=\"wikitable sortable\"\n!"

if options.showRank then

s = s .. " align=\"left\" rowspan=2|" ..COL_TITLES.rank .. "

"

end

s = s .. "rowspan=2|" .. COL_TITLES.name

if options.showCountry then s = s .. "

rowspan=2|" .. COL_TITLES.country end

if options.showCustom1 then s = s .. "

rowspan=2|" .. COL_TITLES.custom end

s = s .. "

colspan=2|" .. COL_TITLES.elev

if options.showProm then s = s .. "

colspan=2|" .. COL_TITLES.prom end

if options.showIsolation then s = s .. "

colspan=2|" .. COL_TITLES.isoltn end

if options.showRange then s = s .. "

rowspan=2|" .. COL_TITLES.range end

if options.showFA then s = s .. "

rowspan=2|" .. COL_TITLES.fa end

if options.showCustom2 then s = s .. "

rowspan=2|" .. COL_TITLES.custom end

if options.showCoord or options.showTCoord then s = s .. "

rowspan=2|" .. COL_TITLES.coords end

s = s .. "\n

\n"

s = s .. '!' .. unit_1 .. '

' .. unit_2 -- elevation cells

if options.showProm then s = s .. '

' .. unit_1 .. '' .. unit_2 end

if options.showIsolation then

local iso_u1, iso_u2

if unit == UNITS.METRE then iso_u1 = UNITS.KILOMETRE; iso_u2 = UNITS.MILE

else iso_u1 = UNITS.MILE; iso_u2 = UNITS.KILOMETRE

end

s = s .. '

' .. iso_u1 .. '' .. iso_u2

end

s = s .. NEWLINE

return s

end

local function finish()

return "

" -- table end

end

local function handleCustomOption(n, options, columnTitle)

if columnTitle then

COL_TITLES.custom = columnTitle

end

if n == 1 then options.showCustom1 = true else options.showCustom2 = true end

end

--[[ Process run options

rank - show ranking

name - override default name column title

elev - show elevation

prom - show prominence

isolation - show isolation

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

custom[1|2]- show custom field (e.g. Notes)

country - show country

debug - generate debug information

]]

local function processOptions(runOptions)

local o = Options

if runOptions == nil then return o end

runOptions = stripNewline(runOptions)

debugv("runOptions", runOptions)

local parts = split(runOptions, OPTIONS_SEP)

for i=1,#parts do

option = parts[i]

debugv("option", option)

-- Strip out column title if given for an option

local colTitle

local n = string.find(option, COL_TITLE_SEP)

if n then

colTitle = string.sub(option, n+1)

debugv("colTitle", colTitle)

option = string.sub(option, 1, n-1)

end

local valid_option = true

if option == OPT_NAMES.RANK then o.showRank = true

elseif option == OPT_NAMES.PROM then o.showProm = true

elseif option == OPT_NAMES.FA then o.showFA = true

elseif option == OPT_NAMES.PROM then o.showProm = true

elseif option == OPT_NAMES.ISOLTN then o.showIsolation = true

elseif option == OPT_NAMES.COORDS then

o.showCoord = true

if colTitle then COL_TITLES.coords = colTitle end

elseif option == OPT_NAMES.TCOORDS then

o.showTCoord = true

if colTitle then COL_TITLES.coords = colTitle end

elseif option == OPT_NAMES.RANGE then

o.showRange = true

if colTitle then COL_TITLES.range = colTitle end

elseif option == OPT_NAMES.CUSTOM1 then

handleCustomOption(1, o, colTitle)

elseif option == OPT_NAMES.CUSTOM2 then

handleCustomOption(2, o, colTitle)

elseif option == OPT_NAMES.COUNTRY then o.showCountry = true

elseif option == OPT_NAMES.NAME then

if colTitle then COL_TITLES.name = colTitle end

elseif option == OPT_NAMES.ORDER then

if colTitle and colTitle == "prom" then

o.rankOrder = RANK_ORDER.PROM

end

elseif option == OPT_NAMES.DEBUG then o.debug = true

else

addError("Unknown option: " .. option)

valid_option = false

end

end

return o

end

-- ** Process a mountain line **

local function processLine(frame, options, line)

local parts, n, name, elev, page, custom, has_custom

-- argument contains elevation, page link and custom value

parts = split(line, FS)

if #parts == 2 then

has_custom = false

elseif #parts < 3 then

local m = "
Bad format on argument (" .. line .. ") -- skipped"

errors = errors .. m

mw.log(m)

return nil

else

has_custom = true

end

local mtn = Mountain

elev = parts[1] -- "m" or "ft"

name = parts[2] -- wiki-linked name

if name then

page = getPage(name)

debug("name = " .. name .. ";page = " .. page)

else

debug("name is null")

return nil

end

mtn.name = name

mtn.page = page

mtn.eid = nil

mtn.elevation = elev;

mtn.elevation_wd = 0

mtn.prominence = nil

mtn.isolation = nil

mtn.range = ""

mtn.fa = ""

if options.showCustom1 or options.showCustom2 then

if has_custom then

custom = stripNewline(parts[3])

debugv("custom", custom)

else

custom = NBSP

end

mtn.custom = custom

end

-- Get the Wikidata entity id

local eid = mw.wikibase.getEntityIdForTitle(page)

if not eid then

debug("Cannot find entity id for page " .. page)

mtn.name = mtn.name .. BR_NEWLINE .. errorFont("Cannot find entity id")

return mtn

end

debug("page="..page .. ",eid=" .. eid)

mtn.eid = eid

mtn.elevation_wd = getElevation(frame, eid)

mtn.prominence = getProminence(frame, eid)

if options.showIsolation then

mtn.isolation = getIsolation(frame, eid)

debugv("mtn.isolation", mtn.isolation)

end

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, mtn.name)

end

if options.showCountry then

mtn.country = getCountry(frame, eid)

end

return mtn

end

-- Process a mountain range. Only display the linked range once.

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

debug("Adding range " .. range)

table.insert(ranges, range)

else

local i1, i2 = string.find(range, "|")

if i1 then

local ei = string.len(range) - 2 -- strip ending brackets

name = string.sub(range, i1+1, ei)

else

local len = string.len(range)

name = string.sub(range, 3, len-2)

end

mtn.range = name

end

end

-- *** Main entry point ***

function p.list(frame)

local debug_on = false

local rank_number = 0

local last_elev, last_prom = ""

local same_rank = 0

errors = ""; dbgout = ""

--debugv("args[1]", frame.args[1])

--debugv("args[2]", frame.args[2])

--debugv("args[3]", frame.args[3])

local unit = frame.args[1]

local options = processOptions(frame.args[2])

if options.showCoord and options.showTCoord then

return "

" .. errorFont("Can only specify one of coords or tcoords") .. "

"

end

-- Create the output buffer and add the table header

local getBuffer, print, printf = newBuffer()

print(genHeader(options, unit))

local ranges = {}

local rankOrderElev = options.rankOrder == RANK_ORDER.ELV

-- Main processing loop

for i=3,502,1 do

local prom_cells, isoltn_cells

local line = frame.args[i]

if line == nil then break end

debugv("line", line)

local mtn = processLine(frame, options, line)

if mtn then -- only do if no error

if options.showRank then

if rankOrderElev then

if last_elev ~= mtn.elevation then

rank_number = rank_number + 1 + same_rank

mtn.rank = rank_number

last_elev = mtn.elevation

same_rank = 0

else

same_rank = same_rank + 1

end

else -- ranked by prominence

if last_prom ~= mtn.prominence then

rank_number = rank_number + 1 + same_rank

mtn.rank = rank_number

last_prom = mtn.prominence

same_rank = 0

else

same_rank = same_rank + 1

end

end

end

if options.showRange and mtn.eid then

processRange(ranges, mtn)

end

local elev_cells = getElevationCells(frame, mtn.elevation, unit)

local prom = mtn.prominence

if prom ~= nil and prom ~= -1 and prom ~= "" then

prom_cells = getElevationCells(frame, prom, unit)

else

prom_cells = " || "

end

if options.showIsolation then

local isoltn = mtn.isolation

if isoltn and isoltn ~= -1 and isoltn ~= "" then

isoltn_cells = getProminenceCells(frame, mtn.isolation)

else

isoltn_cells = " || "

end

debugv("isoltn_cells", isoltn_cells)

end

debug("elev=" .. mtn.elevation ..";elev_wd="..mtn.elevation_wd)

if (options.showCustom1 or options.showCustom2) and mtn.elevation_wd ~= 0 and mtn.elevation ~= mtn.elevation_wd then

local mm = "
Local/WD elevations mismatch: " .. "\"" .. mtn.elevation .. "\"".. "/\"" .. mtn.elevation_wd.. "\""

mtn.custom = mtn.custom .. mm

end

print("|-\n|")

if options.showRank then print("align=center|" .. mtn.rank .. "||") end

print(mtn.name)

if options.showCountry then printf("\n|%s", mtn.country) end

printf("\n|%s\n", elev_cells)

if options.showProm then printf("|%s\n", prom_cells) end

if options.showIsolation then printf(TD .. "%s\n", isoltn_cells) end

if options.showRange then printf(TD .. "%s\n", mtn.range) end

if options.showFA then printf(TD .. "%s\n", mtn.fa) end

if options.showCustom2 then printf(TD .. "%s\n", mtn.custom) end

if options.showCoord or options.showTCoord then printf(TD .. "%s\n", mtn.coords) end

end

end -- for

print(finish())

if debug_on then

printf("
%s\n")

end

if string.len(errors) > 0 then

printf("%s\n", errors)

end

if options.debug and string.len(dbgout) > 0 then

printf("
Debug output
\n%s
\n", dbgout)

end

return getBuffer('')

end

--[[

Test via Preview Window Debug console

print(p.test())

]]

function p._test(doDebug)

local frame = mw.getCurrentFrame()

-- if frame then mw.logObject(frame) end

-- local test_data = { {["e"]="3954",["p"]="Mount Robson",

-- ["n"]="Highest point in the Canadian Rockies"},

-- {["e"]="3747",["p"]="Mount Columbia",

-- ["n"]="Highest point in Alberta"}

-- }

local sep = ","

frame.args = {}

frame.args[1] = 'm'

frame.args[2] = OPT_NAMES.RANK..sep..

OPT_NAMES.RANGE..COL_TITLE_SEP.."Mtn Range"..sep..OPT_NAMES.FA

..sep..OPT_NAMES.PROM

--..sep..OPT_NAMES.ISOLTN

..sep..OPT_NAMES.TCOORDS

..sep..OPT_NAMES.CUSTOM2..COL_TITLE_SEP.."Additional info"

-- ..sep..OPT_NAMES.COUNTRY

-- ..sep..OPT_NAMES.ORDER..COL_TITLE_SEP.."prom"

if doDebug then frame.args[2] = frame.args[2] ..sep .. OPT_NAMES.DEBUG end

frame.args[3] = "3954"..FS.."Mount Robson"..FS.."Highest point in the Canadian Rockies"

frame.args[4] = "3448"..FS.."Mount Saint Elias"..FS.."Canada/US border"

frame.args[5] = "3310"..FS.."Mount Vaux"..FS.."Ottertail Range"

frame.args[6] = "3204"..FS.."Ghost Mountain"..FS..""

frame.args[7] = "2433"..FS.."Saddle Mountain"..FS

--[===[

frame.args[3] = "3954"..FS.."Mount Robson"..FS.."Highest point in the Canadian Rockies"

frame.args[4] = "3747"..FS.."Mount Columbia"..FS.."Highest point in Alberta"

frame.args[5] = "3731"..FS.."North Twin Peak"..FS.."Highest peak of The Twins Massif"

frame.args[6] = "3648"..FS.."Mount Clemenceau"..FS.."Named for Georges Clemenceau, premier of France during WWI"

frame.args[7] = "3619"..FS.."Mount Alberta"..FS.."Most difficult +11,000 climbing objective"

frame.args[8] = "3618"..FS.."Mount Assiniboine"..FS.."Highest point in the Southern Rockies"

frame.args[9] = "3612"..FS.."Mount Forbes"..FS.."Highest point within the confines of Banff Nat'l Park"

frame.args[10] = "3567"..FS.."Mount Goodsir"..FS.."Two major summits: South Tower and North Tower (lowest)"

frame.args[11] = "3556"..FS.."South Twin Peak"..FS.."Lowest peak of The Twins Massif"

frame.args[12] = "3543"..FS.."Mount Temple"..FS.."Highest point near Lake Louise"

frame.args[13] = "3425"..FS.."Resplendent Mountain"..FS.."tbd"

frame.args[14] = "3204"..FS.."Ghost Mountain"..FS..""

--]===]

-- frame.args[7] = ""

-- frame.args[8] = " "

--[[ Commented out

local fi = 3

for i=1,#test_data do

frame.args[fi] = test_data[i]["e"] .. FS .. test_data[i]["l"] .. FS .. test_data[i]["n"]

fi = fi + 1

end ]]

Options.test = true

return p.list(frame)

end

function p.testd()

return p._test(true)

end

function p.test()

return p._test(false)

end

function p.test2()

local s = 'Rainbow Range'

--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

function p.test3()

mw.log(stripBrackets("abc"))

mw.log(stripBrackets("def"))

mw.log(stripBrackets("Mount Victoria"))

mw.log("title=" .. getPageTitle("Mount Victoria"))

end

function p.testR()

local frame = mw.getCurrentFrame()

frame.args = {}

frame.args[1] = 'm'

frame.args[2] = "debug,fa,tcoords,custom2:Easiest route"

frame.args[3] = "3543"..FS.."Mount Temple"..FS.."Moderate scramble on SW face"

frame.args[4] = "3492"..FS.."Hungabee Mountain"..FS.."UIAA III 5.4 on West ridge"

frame.args[5] = "3464"..FS.."Mount Victoria"..FS.."UIAA II on SE ridge, South Summitend"

Options.test = true

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||

]]