Module:Road data/parser/hooks

< Module:Road data‎ | parser
Revision as of 05:40, 16 July 2021 by Zoran (talk | contribs) (Pywikibot 6.4.0)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This module includes hook functions that provide extra functionality to Module:Road data/parser and its associated string modules.

Basics

Each hook is simply a function stored in the p package table exported by this module. Each function accepts two arguments:

  • parameters: The table in the string module that references the hook. In this example, this argument would be the table stored in the shield field of the type table (from Module:Road data/strings/USA/KY):

<syntaxhighlight lang="lua"> KY["KY 1966"] = {shield = {hook = "split",

                          split = 100,
                          below = "Elongated circle %route%.svg", 
                          above = "Circle sign %route%.svg"},
                link = KY.KY.link,
                abbr = KY.KY.abbr}

</syntaxhighlight>

  • args: The arguments originally passed to the parser.

Hooks may modify the argument table by simply setting a new key as equal to a computed value. Modifying existing values is allowed, but discouraged.

The return value of a hook is an ordinary format string, which may be computed within the function or pulled from the parameters argument. Generally, if the hook does not compute the format string to be returned, the hook should return parameters.default, which should equal a format string.

Hooks

split

This hook determines the format string to be used by the parser based on whether the route number is above or below a particular number.

Parameters:

  • split: The number on which to split.
  • below: The format string to use if the route number is below split.
  • above: The format string to use if the route number is equal to or above split.

splitlen

This hook operates in a similar fashion to split, but tests the length of the route number instead of its value.

Parameters:

  • split: The length on which to split.
  • below: The format string to use if the route number's length is below split.
  • above: The format string to use if the route number's length is equal to or above split.

between

This hook determines the format string to be used by the parser based on whether the route number is between two given numbers.

Parameters:

  • lower: The lower limit of the test (inclusive).
  • upper: The upper limit of the test (exclusive).
  • yes: The format string to use if the route number is between lower and upper.
  • no: The format string to use if the route number is not between lower and upper.

mask

This hook adds an argument to the args table based on the result of applying a supplied mask to a particular argument.

Parameters:

  • base: The argument to be masked.
  • masked: The key used to store the mask result in the args table.
  • mask: The name of the module to be used as a mask, without the "Module:" prefix. The module must return a table which maps a base argument to the value stored in the masked field of args.
  • default: The format string to be processed by the parser. This string may reference the argument stored in args by this hook.

padroute

This hook zero-pads the route number so that the route number has a particular number of digits.

Parameters:

  • paddedLength: The length to which the route number should be zero-padded.
  • default: The format string to be processed by the parser. This string may reference the zero-padded route number as the paddedRoute argument.

lowercase

This hook converts the route "number" to lowercase.

Parameters:

  • default: The format string to be processed by the parser. This string may reference the lowercased route number as the lowercase argument.

startswith

This hook determines whether a particular argument starts with any of the given patterns, and returns the value associated with the matching pattern.

Parameters:

  • base: The argument to test.
  • startPatterns: Key-value pairs of starting patterns and the values to return if a match is found.
  • default: The value to return if no match is found.

local p = {}

local parserModuleName = "Module:Road data/parser" -- SANDBOX REFERENCE

function p.split(parameters, args)
	local route = tonumber(string.match(args.route, "%d+")) or 0
	if route < parameters.split then
		return parameters.below
	else
		return parameters.above
	end
end

function p.splitlen(parameters, args)
	local route = args.route
	if #route < parameters.split then
		return parameters.below
	else
		return parameters.above
	end
end

function p.between(parameters, args)
	local lower = parameters.lower
	local upper = parameters.upper
	local route = tonumber(string.match(args.route, "%d+")) or 0
	if route < lower or route >= upper then
		return parameters.no
	else
		return parameters.yes
	end
end

function p.mask(parameters, args)
	local baseParam = parameters.base
	local maskedParam = parameters.masked
	local maskModule = "Module:" .. parameters.mask
	local mask = mw.loadData(maskModule)
	args[maskedParam] = mask[args[baseParam]]
	return parameters.default
end

function p.padroute(parameters, args)
	local route = args.route
	local paddedLength = parameters.paddedLength
	args.paddedRoute = string.format("%0" .. tostring(paddedLength) .. "d", route)
	return parameters.default
end

function p.lowercase(parameters, args)
	local route = args.route
	args.lowercase = string.lower(route)
	return parameters.default
end

--[[
For the first element (pattern, action) in .actions such that
args[.base] begins with pattern, return action.
If no such element exists, return .default (nil if unspecified).
]]
function p.beginswith(parameters, args)
	local baseParam = parameters.base
	local actions = parameters.actions
	local arg = args[baseParam]
	for pattern,action in pairs(actions) do
		if mw.ustring.sub(arg, 1, mw.ustring.len(pattern)) == pattern then
			return action
		end
	end
	return parameters.default
end

--[[
For the first element (pattern, action) in .actions such that
require(Module:Road data/parser).parser(args, .entry, .path, .kind)
matches pattern as a regular expression, return action.
If no such element exists, return .default (nil if unspecified).

.path and .kind are optional.
]]
function p.match(parameters, args)
	local parserModule = require(parserModuleName)
	local parser = parserModule.parser

	local entry = parameters.entry
	local path = parameters.path
	local kind = parameters.kind
	local actions = parameters.actions
	local value = parser(args, entry, path, kind)
	for pattern,action in pairs(actions) do
		if mw.ustring.match(value, pattern) then
			return action
		end
	end
	return parameters.default
end

function p.iso3166Sub(parameters, args)
	local country = args.country
	local subParam = parameters.sub
	local subCode = args[subParam]

	local iso3166Module = require("Module:ISO 3166")
	args.iso3166Sub = iso3166Module.luaname{country, subCode}
	return parameters.default
end

return p