Module:parameters: Difference between revisions

No edit summary
m 1 revision imported
 
(3 intermediate revisions by 3 users not shown)
Line 180: Line 180:
sorted_pairs = require(table_module).sortedPairs
sorted_pairs = require(table_module).sortedPairs
return sorted_pairs(...)
return sorted_pairs(...)
end
local function split(...)
split = require(string_utilities_module).split
return split(...)
end
end


Line 252: Line 257:
   template page is visited; however, it is preferred to use `template_default` for this purpose, for clarity.
   template page is visited; however, it is preferred to use `template_default` for this purpose, for clarity.
; {template_default =}
; {template_default =}
: Specifies a default input value for absent or empty parameters only on template pages. Template pages are any page in
: Specifies a default input value for absent or empty parameters only on the template demo invocation (the invocation of
   the template space (beginning with `Template:`) except for documentation pages (those ending in `.../documentation`).
  the template that is displayed when the template page that implements the template is viewed). Template pages are
  This can be used to provide an example value for a non-required parameter when the template page is visited, without
   pages in template space that invoke (through {{tl|#invoke:}}) the module that implements the template and calls
   interfering with other uses of the template. Both `template_default` and `default` can be specified for the same
  [[Module:parameters]]. For example, the page [[Template:en-noun]] implements the {{tl|en-noun}} template, which in
  parameter. If this is done, `template_default` applies on template pages, and `default` on other pages. As an example,
  turn invokes [[Module:en-headword]], and is a template page for [[Module:en-headword]]. When the template page
  [[Template:en-noun]] is visited, the {{tl|#invoke:}} of the template's module is expanded as if the template were
  called without arguments, and the output is inserted at that point into the processed page. This output serves as a
  sort of demo of the template's functionality. `template_default` can be used to supply default values for use only in
  this demo. Since the template page may also contain other invocations of the same template (e.g. on the template's
  documentation page, which is typically transcluded into the template page itself), `template_default` does not apply
   if there are any arguments passed to the template or if the template is invoked on any other page but its own template
  page (which is checked by comparing the name of the invoking template to the current pagename). Both
  `template_default` and `default` can be specified for the same parameter. If this is done, `template_default` applies
  for the argumentless template invocation on the template page, and `default` in all other circumstances As an example,
   {{tl|cs-IPA}} uses the equivalent of {[1] = {default = "+", template_default = "příklad"}} to supply a default of
   {{tl|cs-IPA}} uses the equivalent of {[1] = {default = "+", template_default = "příklad"}} to supply a default of
   {"+"} for mainspace and documentation pages (which tells the module to use the value of the {{para|pagename}}
   {"+"} for mainspace and documentation pages (which tells the module to use the value of the {{para|pagename}}
Line 343: Line 357:
   constructing a {frame.args} table of arguments. This means that integers will be converted to numbers, but all other
   constructing a {frame.args} table of arguments. This means that integers will be converted to numbers, but all other
   arguments will remain as strings (e.g. {"1"} will be normalized to {1}, but {"foo"} and {"1.5"} will remain
   arguments will remain as strings (e.g. {"1"} will be normalized to {1}, but {"foo"} and {"1.5"} will remain
   unchanged). Note that Scribunto also trims parmeter names, following the same trimming method that this module
   unchanged). Note that Scribunto also trims parameter names, following the same trimming method that this module
   applies by default to all parameter types.
   applies by default to all parameter types.
:: This type is useful when one set of input arguments is used to construct a {params} table for use in a subsequent
:: This type is useful when one set of input arguments is used to construct a {params} table for use in a subsequent
Line 366: Line 380:
   [[Module:gender and number]]. Inline modifiers (`<q:...>`, `<qq:...>`, `<l:...>`, `<ll:...>` or `<ref:...>`) may be
   [[Module:gender and number]]. Inline modifiers (`<q:...>`, `<qq:...>`, `<l:...>`, `<ll:...>` or `<ref:...>`) may be
   attached to a gender/number spec.
   attached to a gender/number spec.
:; {type = "form of tags"}
:: The value is interpreted as an ampersand-separated list of grammar tags and converted into the correct format
  for passing as `tags` into `tagged_inflections()` in [[Module:form of]] (which is currently a list of strings).
  Splitting is always done by ampersands. This type should be used by for inflection qualifiers that act as
  grammar tags (typically specified using {{para|infl}}).
:; {type = function(val) ... end}
:; {type = function(val) ... end}
:: `type` may be set to a function (or callable table), which must take the argument value as its sole argument, and must
:: `type` may be set to a function (or callable table), which must take the argument value as its sole argument, and must
Line 386: Line 405:
   done in [[Module:headword/templates]].
   done in [[Module:headword/templates]].
; {set =}
; {set =}
: Require that the value of the parameter be one of the specified list of values (or omitted, if {required = true} isn't
: Require that the value of the parameter be one of the specified values (or omitted, if {required = true} isn't given).
  given). The values in the specified list should be strings corresponding to the raw parameter values except when
  Two formats are allowed; either a list of possible values can be supplied, or a table can be supplied where the keys
   {type = "number"}, in which case they should be numbers. A individual value in the list can also be an ''alias list'',
   are allowed values and the values are either `true` or a string naming a value found elsewhere in the table as a key.
   which is a list where the first value is the "canonical" value and the remainder are aliases. When one of the aliases
   In the latter case, the key is an alias and the value is the canonical value, and if the user uses the alias, it will
   is used, the resulting parameter field in the returned arguments structure will have the canonical value. The use of
   automatically be mapped to the canonical value. In such a case, the canonical value cannot itself be an alias. The use
   `set` is disallowed if {type = "boolean"} and causes an error to be thrown.
   of `set` is disallowed if {type = "boolean"} and causes an error to be thrown.
; {sublist =}
; {sublist =}
: The value of the parameter is a delimiter-separated list of individual raw values. The resulting field in `args` will
: The value of the parameter is a delimiter-separated list of individual raw values. The resulting field in `args` will
Line 455: Line 474:
   {"genders"} is also specified, and causes the resulting list to be flattened. Not currently compatible with
   {"genders"} is also specified, and causes the resulting list to be flattened. Not currently compatible with
   {allow_holes = true}.
   {allow_holes = true}.
; {replaced_by =}
: Specifies that the parameter is no longer valid, and has been replaced by some other mechanism. If the value of
  `replaced_by` is a string, it is the name of the new parameter to use instead. Use the `reason` tag to specify the
  reason why this change has been made, e.g.
  {reason = "for consistency with the corresponding parameter in other Romance-language headword templates"}. If the
  value of `replaced_by` is {false}, there is no replacement parameter. In this case, `instead` should be supplied
  with a description of what to do instead, e.g.
  {instead = "use an inline modifier on |2= such as <q:...>, <qq:...>, <l:...> or <ll:...>"}. You can also supply a
  justification in `reason` if you feel it is appropriate or necessary to do so.
; {reason =}
: When used in conjunction with `replaced_by`, specifies the reason for the parameter replacement.
; {instead =}
: When used in conjunction with {replaced_by = false}, specifies what to do instead of using the removed parameter.
; {demo = true}
; {demo = true}
: This is used as a way to ensure that the parameter is only enabled on the template's own page (and its documentation
: This is used as a way to ensure that the parameter is only enabled on the template's own page (and its documentation
Line 468: Line 500:


-- Returns true if the current page is a template or module containing the current {{#invoke}}.
-- Returns true if the current page is a template or module containing the current {{#invoke}}.
-- If the include_documentation argument is given, also returns true if the current page is either page's docuemntation page.
-- If the include_documentation argument is given, also returns true if the current page is either page's documentation page.
local own_page, own_page_or_documentation
local own_page, own_page_or_documentation
local function is_own_page(include_documentation)
local function is_own_page(include_documentation)
Line 515: Line 547:
msg, (processed_type == "string" or processed_type == "number") and processed or dump(processed)
msg, (processed_type == "string" or processed_type == "number") and processed or dump(processed)
)
)
end
-- Separate form of tags with ampersand (&).
local function split_tags_on_ampersand(tags)
return split(tags, "&")
end
end


Line 610: Line 647:


-- TODO: give ranges instead of long lists, if possible.
-- TODO: give ranges instead of long lists, if possible.
--[==[ func: export.params_list_error(params, msg)
Given a key-value table of raw parameters `params`, display an error message about all the parameters seen in the table.
The parameter names are displayed in sorted order. `msg` should be e.g. {"required"} or {"not used by this template"}.
This is used internally to display error messages about required or invalid parameters, and can be used for the same
purpose by code that processes its own parameters (e.g. if the `return_unknown` flag is specified to `process`).
]==]
local function params_list_error(params, msg)
local function params_list_error(params, msg)
local list, n = {}, 0
local list, n = {}, 0
Line 622: Line 665:
), 3)
), 3)
end
end
export.params_list_error = params_list_error


-- Helper function for use with convert_val_error(). Format a list of possible choices using `concat_list` and
-- Helper function for use with convert_val_error(). Format a list of possible choices using `concat_list` and
Line 829: Line 874:
-- FIXME: Should be able to pass in a parse_err function.
-- FIXME: Should be able to pass in a parse_err function.
return split_labels_on_comma(val)
return split_labels_on_comma(val)
end,
["form of tags"] = function(val, name, param)
return split_tags_on_ampersand(val)
end,
end,


Line 1,221: Line 1,270:
end
end
if not param.sublist and param.type ~= "genders" and param.type ~= "labels" and
if not param.sublist and param.type ~= "genders" and param.type ~= "labels" and
param.type ~= "references" and param.type ~= "qualifier" then
param.type ~= "references" and param.type ~= "qualifier" and param.type ~= "form of tags" then
process_error("For parameter %s, can only set `flatten` along with `sublist` or a list-generating type", name)
process_error("For parameter %s, can only set `flatten` along with `sublist` or a list-generating type", name)
end
end
Line 1,336: Line 1,385:
)
)
end
end
end
end
local replaced_by = param.replaced_by
if replaced_by then -- replaced_by can be `false`, which is OK
validate_name(replaced_by, "the replaced_by field of parameter ", name)
if replaced_by == name then
internal_process_error(
"parameter %s cannot be replaced by itself.",
name
)
end
local main_param = params[replaced_by]
-- Check that the replaced_by is set to a valid parameter.
if not (main_param == true or type(main_param) == "table") then
internal_process_error(
"parameter %s is set to be replaced by an invalid parameter.",
name
)
end
-- Can't be a replaced-by of a replaced-by.
if main_param ~= true then
local main_replaced_by = main_param.replaced_by
if main_replaced_by ~= nil then
internal_process_error(
"replaced_by cannot be set to another replaced-by parameter: parameter %s is set as replaced by %s, which is in turn replaced by %s. Set replaced_by for %s to %s.",
name, replaced_by, main_replaced_by, name, main_replaced_by
)
end
end
if param.instead ~= nil then
internal_process_error("the `instead` tag can only be given when `replaced_by` is set to `false`.")
end
elseif replaced_by == false then
if param.instead ~= nil and type(param.instead) ~= "string" then
internal_process_error(
"the `instead` tag must be a string, but saw %s.",
param.instead
)
end
end
if replaced_by ~= nil then
if param.reason ~= nil and type(param.reason) ~= "string" then
internal_process_error(
"the `reason` tag must be a string, but saw %s.",
param.reason
)
end
end
end
end
Line 1,449: Line 1,545:
end
end
else
else
if param.replaced_by == false then
process_error(
("Parameter %%s has been removed and is no longer valid%s.%s"):format(
param.reason and ", " .. param.reason or "",
param.instead and " Instead, " .. param.instead .. "." or ""),
name
)
elseif param.replaced_by then
process_error(
("Parameter %%s has been replaced by %%s%s."):format(
param.reason and ", " .. param.reason or ""),
name, param.replaced_by
)
end
if param.deprecated then
if param.deprecated then
track("deprecated parameter", name)
track("deprecated parameter", name)