Module:OsmPageTitleParser

local p = {} local data = mw.loadData('Module:OSM Constants')

-- Module_talk:OsmPageTitleParser/testcases has many test cases showing how to use this module -- Simple debugging: -- =p.parseTitle(mw.title.new('Key:test')).key

-- A wrapper to return the parse results. See p.parseTitleToObj function p.parseTitle(title) local result = {} p.parseTitleToObj(result, title) return result end

-- given a title string in a form of (lang-code:)?(tag|key):(tagkey)(=tagvalue)? -- tries to parse it into language (object), key, and optional value strings -- We have to do it manually because Lua regex support is not that great -- The actual tag and key prefixes are ignored. Value will be nil if no equal sign. -- The output result object will always get the language unless title is nil, -- but no other values will be set unless successfuly parsed -- Params: title object,  result table to get the results -- Returns true if parsed, false otherwise function p.parseTitleToObj(result, title) if not title then return false end

local language, prefix, tagkey, tagvalue

-- if this is one of the known language namespaces, do not allow more language codes local ns = title.namespace / 2 * 2 ns = ns - ns % 2 -- treat talk pages as their corresponding main pages local langCode = data.nsToLangCodeMap[ns] if langCode then language = mw.getLanguage(langCode) end

local keyvalue for _, val in ipairs(mw.text.split(title.text, ':', true)) do   if not prefix then -- this could be the language code or the prefix (tag or key) local lval = string.lower(val) if lval == 'tag' or lval == 'key' then prefix = lval elseif not language and (data.customLangCodes[lval] or mw.language.isSupportedLanguage(lval)) then -- mw.getLanguage will creat an object even if the language is not supported language = mw.getLanguage(lval) else -- unrecognized, there was no tag or key as first or second part break end else -- combine the values back into a single string after we found the prefix if keyvalue then keyvalue = keyvalue .. ':' .. val else keyvalue = val end end end

if keyvalue then -- now split the keyvalue into key and (optional) value tagkey, tagvalue = p.splitKeyValue(keyvalue) if not tagkey and not tagvalue then keyvalue = nil end end

if not language then result.language = mw.language.getContentLanguage else result.language = language end

if keyvalue then result.key = tagkey if tagvalue then result.value = tagvalue end return true else return false end end

-- given a key=value string, split it into two parts and return both -- if there is no equal sign, return key and nil value function p.splitKeyValue(keyvalue) if not keyvalue then return end local tagkey, tagvalue local eqlSignPos = mw.ustring.find(keyvalue, '=', 1, true) if not eqlSignPos then tagkey = keyvalue else local keyvalLen = mw.ustring.len(keyvalue) if eqlSignPos > 1 then tagkey = mw.ustring.sub(keyvalue, 1, eqlSignPos - 1) tagvalue = mw.ustring.sub(keyvalue, eqlSignPos + 1) end end return tagkey, tagvalue end

-- Given a language code, returns proper title prefix: -- empty string for English, all caps for the namespaces, first letter cap for rest function p.langPrefix(langCode) langCode = langCode and mw.ustring.lower(langCode) or '' if not langCode or langCode == '' or langCode == 'en' then return '' end for _,v in pairs(data.nsToLangCodeMap) do	 if v == langCode then return string.upper(langCode) .. ':'	 end end return mw.getContentLanguage:ucfirst(langCode) .. ':' end

return p