Bước tới nội dung

Mô đun:Road data/parser/sandbox

Bách khoa toàn thư mở Wikipedia
local p = {} -- Package to be exported-- Change to "" upon deployment.local moduleSuffix = "/sandbox"local parserHooksModuleName = "Module:Road data/parser/hooks" .. moduleSuffix-- Local library aliaseslocal format = string.formatlocal gsub = mw.ustring.gsublocal upper = mw.ustring.upper----- Substitution pattern based on passed arguments-- Syntax: [param|value|match|mismatch]-- where--  param is the parameter name to be tested--  value is the value to test against argument; if empty, the argument is--    tested for existence--  match is the string to be substituted if the argument matches value--  mismatch is the string to be substituted if the argument does not match--    the value-- These arguments may not contain "[", "|", or "]".local prepattern = "%[(%w+)%|([^%[|%]]*)%|([^%[|%]]*)%|([^%[|%]]*)%]"----- Parameter substitution pattern-- Syntax: %param%-- where param is the name of the parameter whose value is to be substituted-- in place of %param%.local pattern = "%%(%w+)%%"----- Perform substitutions.-- @param #string formatStr The string the be substituted-- @param #table args The arguments passed to this modulelocal function subst(formatStr, args)	---	-- Perform a substitution based on passed argument.	-- @param #string param The parameter name to be tested	-- @param #string value The value to test against argument; if empty,	-- 		the argument is tested for existence	-- @param #string ifmatch The resulting string if the argument matches	-- 		`value`	-- @param #string ifmismatch The resulting string if the argument does not	-- 		match `value`	-- @return #string either `ifmatch` or `ifmismatch`, based on the test	local function testArgs(param, value, ifmatch, ifmismatch)		local arg = args[param] or ''		if value ~= '' then			return arg == value and ifmatch or ifmismatch		else			return arg ~= '' and ifmatch or ifmismatch		end	end	-- argument-test substitutions	local preprocessed = gsub(formatStr, prepattern, testArgs)	-- parameter substitutions	return (gsub(preprocessed, pattern, args))	-- gsub returns number of matches as second value.	-- The enclosing parens discards it.end----- Determine whether a given title exists on Wikipedia.-- @param #string name The title, e.g., article name and file name,-- 		without namespace prefix-- @param #string key The name of the entry being translated.-- @return #boolean `true` if the title exists, false otherwiselocal function titleExists(name, key)	if name == '' then return false end	local namespaceModule = mw.loadData('Module:Road data/parser/namespace')	-- Retrieve the namespace for `key`.	local namespace = namespaceModule[key] or 0	local title = mw.title.new(name, namespace);	return title.existsend----- Determine whether titles exist on Wikipedia.-- @param value A string or a table containing strings of titles to be checked-- 		against-- @param #string key The name of the entry being translated.-- @return #boolean `true` if all titles exist, false otherwiselocal function ifexists(value, key)	local valueType = type(value)	if valueType == "table" then		-- If `value` is a table, recursively check the existence		-- for each element within the table.		for _,entry in pairs(value) do			if not ifexists(entry, key) then return false end		end		return true	end	-- Otherwise, `value` is a string, so check the existence for that string.	return titleExists(value, key)end----- Perform a translation on a given entry.-- @param entry An entry to be translated; may be any non-function type.-- 		A table may be a parser hook specification, a switch table, or an-- 		ordinary value table.  Translations are applied recursively.-- @param #table args The arguments passed to this module-- @param #string key The name of the entry being translated.-- @return The translated entrylocal function translate(entry, args, key)	if type(entry) == "string" then		return subst(entry, args) -- Substitute arguments as necessary.	elseif type(entry) ~= "table" then		return entry	elseif entry.hook then		-- This entry is a parser hook.		-- Requires: Parser hook must have hook field.		local hook = entry.hook		local parserHooksModule = require(parserHooksModuleName)		local hookFunction = parserHooksModule[hook]			or error("Hook '" .. hook .. "' does not exist", 0)		return translate(hookFunction(entry, args), args, key)	elseif entry.arg or entry.undefined or entry.default then		-- This entry is a switch table.		-- Requires: Switch table must have		--           arg, undefined, or default fields		--           but not hook field.		local arg = args[entry.arg or "route"]		if entry[arg] then return translate(entry[arg], args, key) end		if arg == nil and entry.undefined ~= nil then			-- result for unspecified argument			return translate(entry.undefined, args, key)		end		-- default result for mismatch		local defaultValue = translate(entry.default, args, key)		if defaultValue and entry.ifexists then			-- Check existence.			if ifexists(defaultValue, key) then return defaultValue end			-- Failed existence check results in fallback value (default to nil).			return entry.otherwise and translate(entry.otherwise, args, key) or nil		else			return defaultValue		end	else		-- This entry is a value table.		-- Process each table element.		local result = {}		for key,elem in pairs(entry) do			result[key] = translate(elem, args, key)		end		return result	endend----- Retrieve an entry from a data module based on a given type and key.-- @param #string module The name of the data module to be fetched-- @param type The key for the type table within the loaded table-- @param key The key for the entry within the type table-- @return fetchedTable[type][key] if specified, where `fetchedTable` is the-- 		table fetched from `module`, nil otherwiselocal function getTypeData(module, type, key)	-- Attempt to fetch the given data module.	local success, moduleData = pcall(mw.loadData, module)	if not success then return false, moduleData end -- Module could not be loaded	-- The type table defaults to empty-key table if undefined.	local typeTable = moduleData[type] or moduleData['']	-- Fallback table is the empty-key table, with the empty table as default.	local defaultTable = moduleData[''] or {}	if typeTable then		local alias = typeTable.alias		if alias and alias.module and alias.type then			-- The type table is an alias table.			-- Recursively fetch the aliased type data.			local aliasedModule = "Module:Road data/strings/" .. alias.module			local aliasedType = alias.type			return getTypeData(aliasedModule, aliasedType, key)		end		return true, typeTable[key] or defaultTable[key] or nil	else		return true, nil	endend----- Determine the module name for the lookup by country and state.-- @param #table args The arguments passed to this module-- @return #string The module name to be fetchedlocal function getModuleName(args)	-- countries with submodules for states or provinces	local stateCountries = {USA = true, CAN = true}	local state = upper(args.state or '')	local country	if args.country then		country = upper(args.country)	else		-- Recover the country from the given state or province.		local countryModule = mw.loadData("Module:Road data/countrymask")		country = countryModule[state] or 'UNK'	end	if stateCountries[country] and state ~= '' then		-- Submodule within the country exists.		return format("Module:Road data/strings/%s/%s", country, state)	end	return format("Module:Road data/strings/%s", country)end----- Fetch the entry from the appropriate module, and return that entry-- substituted with appropriate values.-- @param #table args The arguments to be used for lookup and substitutions-- @param #string key The key for the entry within the type table-- @param #string type (optional) The key for the type table within the fetched-- 		module; defaults to args.type-- @param #string moduleName (optional) The name of the module to be fetched;-- 		defaults to the module determined by country and state-- @return The substituted entryfunction p.parser(args, key, type, moduleName)	-- Determine module name, if not given.	local dataModuleName = moduleName or getModuleName(args)	-- Fetch the entry from the module.	local success, formatStr = getTypeData(dataModuleName, type or args.type, key)	if not success then return false, formatStr end	-- Translate the entry.	return translate(formatStr, args, key)endreturn p