Difference between revisions of "Module:Road data/parser"

From blackwiki
Jump to navigation Jump to search
blackwiki>Happy5214
(Never ifexists-test empty strings)
blackwiki>Happy5214
(Redoing ifexists functionality)
Line 8: Line 8:
 
local pattern = "%%(%w+)%%"
 
local pattern = "%%(%w+)%%"
  
local function parser(formatStr, args)
+
local function parser(formatStr, args, form)
 +
local function ifexists(name)
 +
local title
 +
if form == 'shield' then
 +
title = mw.title.new(name, 'Media')
 +
else
 +
title = mw.title.new(name, 0)
 +
end
 +
return title.exists
 +
end
 
local function testArgs(test, equals, ifexists, ifnot)
 
local function testArgs(test, equals, ifexists, ifnot)
 
if equals ~= '' then
 
if equals ~= '' then
Line 16: Line 25:
 
end
 
end
 
end
 
end
 +
local formatTable = {}
 
-- Recursively dig into tables that could be parser hooks or argument tables.
 
-- Recursively dig into tables that could be parser hooks or argument tables.
 
local function formatStrInTable(formatStr)
 
local function formatStrInTable(formatStr)
 
if type(formatStr) ~= "table" then return formatStr end
 
if type(formatStr) ~= "table" then return formatStr end
 +
formatTable = formatStr
 
local hook = formatStr.hook
 
local hook = formatStr.hook
 
if hook then
 
if hook then
Line 32: Line 43:
 
if not formatStr or formatStr == '' then return '' end
 
if not formatStr or formatStr == '' then return '' end
 
local preprocessed = gsub(formatStr, prepattern, testArgs)
 
local preprocessed = gsub(formatStr, prepattern, testArgs)
local final = gsub(preprocessed, pattern, args)
+
local parsedStr = gsub(preprocessed, pattern, args)
return trim(final)
+
local final = trim(parsedStr)
 +
if formatTable.ifexists then
 +
local exists = ifexists(final)
 +
if exists then
 +
return final
 +
else
 +
return parser(formatTable.otherwise, args, form)
 +
end
 +
end
 +
return final
 
end
 
end
  
Line 58: Line 78:
 
if typeTable then
 
if typeTable then
 
return part and typeTable[form][part] or typeTable[form]
 
return part and typeTable[form][part] or typeTable[form]
else
 
return ''
 
end
 
end
 
 
local function ifexists(name, form)
 
local title
 
if form == 'shield' then
 
title = mw.title.new(name, 'Media')
 
else
 
title = mw.title.new(name, 0)
 
end
 
if title.exists then
 
return name
 
 
else
 
else
 
return ''
 
return ''
Line 83: Line 89:
 
local formatStr = formatString(args, form, part)
 
local formatStr = formatString(args, form, part)
 
if not formatStr or formatStr == '' then return nil end
 
if not formatStr or formatStr == '' then return nil end
local parsedStr = parser(formatStr, args)
+
local parsedStr = parser(formatStr, args, form)
if type(formatStr) == 'table' and formatStr.ifexists and parsedStr ~= '' then
+
return parsedStr
return ifexists(parsedStr, form)
 
else
 
return parsedStr
 
end
 
 
end
 
end
  
 
return p
 
return p

Revision as of 10:35, 8 March 2014

Documentation for this module may be created at Module:Road data/parser/doc

local p = {}
local format = string.format
local gsub = mw.ustring.gsub
local trim = mw.text.trim
local upper = mw.ustring.upper

local prepattern = "%[(%w+)%|(.*)%|(.*)%|(.*)%]"
local pattern = "%%(%w+)%%"

local function parser(formatStr, args, form)
	local function ifexists(name)
		local title
		if form == 'shield' then
			title = mw.title.new(name, 'Media')
		else
			title = mw.title.new(name, 0)
		end
		return title.exists
	end
	local function testArgs(test, equals, ifexists, ifnot)
		if equals ~= '' then
			if args[test] == equals then return ifexists else return ifnot end
		else
			if args[test] and args[test] ~= '' then return ifexists else return ifnot end
		end
	end
	local formatTable = {}
	-- Recursively dig into tables that could be parser hooks or argument tables.
	local function formatStrInTable(formatStr)
		if type(formatStr) ~= "table" then return formatStr end
		formatTable = formatStr
		local hook = formatStr.hook
		if hook then
			local hooksModule = require "Module:Road data/parser/hooks"
			local hookFunction = hooksModule[hook] or error("Hook '" .. hook .. "' does not exist", 0)
			return formatStrInTable(hookFunction(formatStr, args))
		else
			local arg = args[formatStr.arg or "route"]
			return formatStrInTable(formatStr[arg] or formatStr.default)
		end
	end
	formatStr = formatStrInTable(formatStr)
	if not formatStr or formatStr == '' then return '' end
	local preprocessed = gsub(formatStr, prepattern, testArgs)
	local parsedStr = gsub(preprocessed, pattern, args)
	local final = trim(parsedStr)
	if formatTable.ifexists then
		local exists = ifexists(final)
		if exists then
			return final
		else
			return parser(formatTable.otherwise, args, form)
		end
	end
	return final
end

local function formatString(args, form, part)
	local stateCountries = {USA = true, CAN = true}
	local state = upper(args.state or '')
	local country
	if args.country then
		country = upper(args.country)
	else
		local countryModule = mw.loadData("Module:Road data/countrymask")
		country = countryModule[state] or 'UNK'
	end
	local typeArg = args.type
	local module
	if stateCountries[country] then
		module = format("Module:Road data/strings/%s/%s", country, state)
	else
		module = format("Module:Road data/strings/%s", country)
	end
	local success, moduleData = pcall(mw.loadData, module)
	if not success then return '' end
	local typeTable = moduleData[typeArg] or moduleData['']
	if typeTable then
		return part and typeTable[form][part] or typeTable[form]
	else
		return ''
	end
end

function p.parser(passedArgs, form, part)
	local args = {state = passedArgs.state, type = passedArgs.type, route = passedArgs.route, 
	              denom = passedArgs.denom, county = passedArgs.county, dab = passedArgs.dab,
	              country = passedArgs.country, township = passedArgs.township}
	local formatStr = formatString(args, form, part)
	if not formatStr or formatStr == '' then return nil end
	local parsedStr = parser(formatStr, args, form)
	return parsedStr
end

return p