Module:form of/templates: Difference between revisions
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
local export = {} | local export = {} | ||
local debug_track_module = "Module:debug/track" | |||
local form_of_module = "Module:form of" | local form_of_module = "Module:form of" | ||
local functions_module = "Module:fun" | local functions_module = "Module:fun" | ||
| Line 17: | Line 18: | ||
local pairs = pairs | local pairs = pairs | ||
local require = require | local require = require | ||
local boolean_param = {type = "boolean"} | |||
-- FIXME: Finish [[Module:format utilities]]. | -- FIXME: Finish [[Module:format utilities]]. | ||
| Line 24: | Line 27: | ||
--[==[ | --[==[ | ||
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==] | Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==] | ||
local function debug_track(...) | |||
debug_track = require(debug_track_module) | |||
return debug_track(...) | |||
end | |||
local function decode_entities(...) | local function decode_entities(...) | ||
| Line 135: | Line 142: | ||
[[Module:form of]], which contains the underlying implementing code and is meant to be called from other modules. | [[Module:form of]], which contains the underlying implementing code and is meant to be called from other modules. | ||
]==] | ]==] | ||
-- Add tracking category for PAGE when called from TEMPLATE. The tracking category linked to is | |||
-- [[Wiktionary:Tracking/form of/TEMPLATE/PAGE]]. If TEMPLATE is omitted, the tracking category is of the form | |||
-- [[Wiktionary:Tracking/form of/PAGE]]. | |||
local function track(page, template) | |||
debug_track("form of/" .. (template and template .. "/" or "") .. page) | |||
end | |||
| Line 141: | Line 155: | ||
-- Named params not controlling link display | -- Named params not controlling link display | ||
["cat"] = {list = true, sublist = "comma without whitespace", flatten = true}, | ["cat"] = {list = true, sublist = "comma without whitespace", flatten = true}, | ||
["notext"] = | ["notext"] = boolean_param, | ||
["sort"] = true, | ["sort"] = true, | ||
["enclitic"] = true, | ["enclitic"] = true, | ||
-- FIXME! The following should only be available when withcap=1 in invocation args or when withencap=1 and the | -- FIXME! The following should only be available when withcap=1 in invocation args or when withencap=1 and the | ||
-- language is "en". Before doing that, need to remove all uses of nocap= in other circumstances. | -- language is "en". Before doing that, need to remove all uses of nocap= in other circumstances. | ||
["nocap"] = | ["nocap"] = boolean_param, | ||
["addl"] = true, -- additional text to display at the end, before the closing </span> | ["addl"] = true, -- additional text to display at the end, before the closing </span> | ||
["pagename"] = true, -- for testing, etc. | ["pagename"] = true, -- for testing, etc. | ||
| Line 182: | Line 196: | ||
end | end | ||
-- Need to do what [[Module:parameters]] does to string arguments from parent_args as we're running this | -- Need to do what [[Module:parameters]] does to string arguments from parent_args as we're running this | ||
| Line 225: | Line 226: | ||
end | end | ||
--[=[ | |||
Modify `params` in-place by adding parameters that control the link to the main entry and any base lemmas. `term_param` | |||
is the number of the param specifying the main entry itself; `term_param` + 1 will be the display text, and `term_param` | |||
+ 2 will be the gloss, unless `no_numbered_gloss` is given. The base lemma parameters are determined by attempting to | |||
load language-specific data for the language of the page; this comes from |lang= if `compat` is given, else from |1=. | |||
]=] | |||
local function add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat, no_numbered_gloss) | local function add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat, no_numbered_gloss) | ||
local base_lemma_params | local base_lemma_params | ||
if not iargs.nolink and not iargs.linktext then | if not iargs.nolink and not iargs.linktext then | ||
-- Numbered params controlling link display | |||
if iargs.with_multiple_parts then | |||
params[term_param] = {list = true, allow_holes = true} | |||
else | |||
params[term_param + 1] = {alias_of = "alt"} | |||
if not no_numbered_gloss then | |||
params[term_param + 2] = {alias_of = "t"} | |||
end | |||
params[term_param] = true | |||
end | |||
base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat) | base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat) | ||
end | end | ||
| Line 239: | Line 255: | ||
if iargs.withdot then | if iargs.withdot then | ||
params.dot = true | params.dot = true | ||
params.nodot = | params.nodot = boolean_param | ||
end | end | ||
| Line 247: | Line 263: | ||
if not iargs.withcap then | if not iargs.withcap then | ||
params.cap = | params.cap = boolean_param | ||
ignored_tracked_params.nocap = iargs.withencap and "non-english" or "always" | ignored_tracked_params.nocap = iargs.withencap and "non-english" or "always" | ||
end | end | ||
| Line 336: | Line 352: | ||
default = iargs.lang or "und" | default = iargs.lang or "und" | ||
} | } | ||
-- Error to catch most uses of old-style parameters for {{contraction of}}. (FIXME: Remove eventually.) | |||
if iargs.with_multiple_parts then | |||
if ine(parent_args[term_param + 2]) and not ine(parent_args[term_param + 1]) and not ine(parent_args.tr2) and not ine(parent_args.ts2) | |||
and not ine(parent_args.t2) and not ine(parent_args.gloss2) and not ine(parent_args.g2) | |||
and not ine(parent_args.alt2) then | |||
error(("You specified a term in %s= and not one in %s=. You probably meant to use t= to specify a gloss instead. " | |||
.. "If you intended to specify two terms, put the second term in %s=."):format(term_param + 2, term_param + 1, | |||
term_param + 1)) | |||
end | |||
if not ine(parent_args[term_param + 1]) and not ine(parent_args.alt2) and not ine(parent_args.tr2) and not ine(parent_args.ts2) | |||
and ine(parent_args.g2) then | |||
error(("You specified a gender in g2= but no term in %s=. You were probably trying to specify two genders for " | |||
.. "a single term. To do that, put both genders in g=, comma-separated."):format(term_param + 1)) | |||
end | |||
end | |||
local base_lemma_params = add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat, | local base_lemma_params = add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat, | ||
| Line 345: | Line 377: | ||
require("Module:parameters").process(parent_args, params) | require("Module:parameters").process(parent_args, params) | ||
but in addition it does the following: | but in addition it does the following: | ||
(1) Supplies default values for unspecified parent arguments as specified in | (1) Supplies default values for unspecified parent arguments as specified in DEFAULTS, which consist of specs of the | ||
form "ARG=VALUE". These are added to the parent arguments prior to processing, so boolean and number parameters | |||
will process the value appropriately. | |||
(2) Removes parent arguments specified in IGNORESPECS, which consist either of bare argument names to remove, or | |||
(2) Removes parent arguments specified in IGNORESPECS, which consist either | list-argument names to remove of the form "ARG:list". | ||
(3) Tracks the use of any parent arguments specified in TRACKED_PARAMS, which is a set where the keys are arguments | |||
as they exist after processing (hence numeric arguments should be numbers, not strings) and the values should be | |||
(3) Tracks the use of any parent arguments specified in TRACKED_PARAMS, which | boolean true. | ||
]=]-- | ]=]-- | ||
local defaults = iargs.def | local defaults = iargs.def | ||
| Line 417: | Line 446: | ||
end | end | ||
local | local param_mods_with_conj, param_mods_without_conj | ||
local function | local function get_param_mods(with_conj) | ||
if not | if with_conj then | ||
if not param_mods_with_conj then | |||
param_mods_with_conj = require(parameter_utilities_module).construct_param_mods { | |||
{group = {"link", "q", "l", "ref"}}, | |||
{param = "conj", set = allowed_conj_set, overall = true}, | |||
} | } | ||
end | |||
return param_mods_with_conj | |||
else | |||
if not param_mods_without_conj then | |||
param_mods_without_conj = require(parameter_utilities_module).construct_param_mods { | |||
{group = {"link", "q", "l", "ref"}}, | |||
-- Override lit= to have a separate overall value | |||
{param = "lit", separate_no_index = true}, | |||
} | |||
end | |||
return param_mods_without_conj | |||
end | end | ||
end | end | ||
| Line 433: | Line 473: | ||
args = process_params(parent_args, params) | args = process_params(parent_args, params) | ||
else | else | ||
local m_param_utils = require(parameter_utilities_module) | |||
terms, args = m_param_utils. | if iargs.with_multiple_parts then | ||
terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { | |||
params = params, | |||
param_mods = get_param_mods(false), | |||
raw_args = parent_args, | |||
termarg = term_param, | |||
track_module = "form of" .. (template and "/" .. template or ""), | |||
lang = compat and "lang" or 1, | |||
sc = "sc.default", | |||
parse_lang_prefix = true, | |||
default_separator = " +‎ ", | |||
special_separators = {[";"] = " or "}, | |||
} | |||
else | |||
terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params { | |||
params = params, | |||
param_mods = get_param_mods("with conj"), | |||
raw_args = parent_args, | |||
termarg = term_param, | |||
track_module = "form of" .. (template and "/" .. template or ""), | |||
lang = compat and "lang" or 1, | |||
sc = "sc", | |||
parse_lang_prefix = true, | |||
make_separate_g_into_list = true, | |||
splitchar = ",", | |||
subitem_param_handling = "last", | |||
} | |||
end | |||
end | end | ||
local lang = args[compat and "lang" or 1] | local lang = args[compat and "lang" or 1] | ||
-- Tracking for certain user-specified params. This is generally used for | |||
-- parameters that we accept but ignore, so that we can eventually remove | |||
-- all uses of these params and stop accepting them. | |||
if ignored_tracked_params then | |||
for ignored_tracked_param, condition in pairs(ignored_tracked_params) do | |||
if parent_args[ignored_tracked_param] and (condition ~= "non-english" or lang:getCode() ~= "en") then | |||
track("arg/" .. ignored_tracked_param, template) | |||
track("arg/" .. ignored_tracked_param) | |||
end | |||
end | |||
end | |||
-- Determine categories for the page, including tracking categories | -- Determine categories for the page, including tracking categories | ||
| Line 480: | Line 535: | ||
local function add_term_tracking_categories(term) | local function add_term_tracking_categories(term) | ||
-- add tracking category if term is same as page title | -- add tracking category if term is same as page title | ||
if term and mw. | if term and mw.loadData("Module:headword/data").pagename == lang:stripDiacritics(term) then | ||
insert(categories, "Forms linking to themselves") | insert(categories, "Forms linking to themselves") | ||
end | end | ||
| Line 498: | Line 553: | ||
lemmas = iargs.linktext | lemmas = iargs.linktext | ||
else | else | ||
if | if iargs.with_multiple_parts then | ||
lemmas = terms | |||
else | |||
lemmas = terms.terms | |||
end | |||
if not lemmas[1] then | |||
if mw.title.getCurrentTitle().nsText == "Template" then | if mw.title.getCurrentTitle().nsText == "Template" then | ||
lemmas[1] = { | |||
lang = lang, | lang = lang, | ||
term = "term" | term = "term" | ||
| Line 508: | Line 568: | ||
end | end | ||
end | end | ||
for _, termobj in ipairs( | for _, termobj in ipairs(lemmas) do | ||
if termobj.term then | if termobj.term then | ||
add_term_tracking_categories(termobj.term) | add_term_tracking_categories(termobj.term) | ||
| Line 516: | Line 576: | ||
-- changed it. Hopefully nothing depended on the old behavior. | -- changed it. Hopefully nothing depended on the old behavior. | ||
end | end | ||
end | end | ||
local enclitics, enclitic_conj | local enclitics, enclitic_conj | ||
if args.enclitic then | if args.enclitic then | ||
local enclitics_obj = parse_terms_with_inline_modifiers("enclitic", args.enclitic, get_param_mods("with conj"), | |||
local enclitics_obj = parse_terms_with_inline_modifiers("enclitic", args.enclitic, | lang) | ||
enclitics = enclitics_obj.terms | enclitics = enclitics_obj.terms | ||
enclitic_conj = enclitics_obj.conj | enclitic_conj = enclitics_obj.conj | ||
| Line 532: | Line 590: | ||
local param = base_lemma_param_obj.param | local param = base_lemma_param_obj.param | ||
if args[param] then | if args[param] then | ||
local base_lemmas_obj = parse_terms_with_inline_modifiers(param, args[param], | |||
local base_lemmas_obj = parse_terms_with_inline_modifiers(param, args[param], | get_param_mods("with conj"), lang) | ||
insert(base_lemmas, { | insert(base_lemmas, { | ||
paramobj = base_lemma_param_obj, | paramobj = base_lemma_param_obj, | ||
| Line 556: | Line 614: | ||
end | end | ||
local conj | |||
if iargs.with_multiple_parts then | |||
conj = false -- signals to use 'separator' field | |||
else | |||
conj = terms and terms.conj or iargs.conj | |||
end | |||
local lemma_data = { | local lemma_data = { | ||
lang = lang, | lang = lang, | ||
args = args, | args = args, | ||
lemmas = lemmas, | lemmas = lemmas, | ||
conj = | conj = conj, | ||
enclitics = enclitics, | enclitics = enclitics, | ||
enclitic_conj = enclitic_conj, | enclitic_conj = enclitic_conj, | ||
| Line 566: | Line 630: | ||
categories = categories, | categories = categories, | ||
posttext = posttext, | posttext = posttext, | ||
lit = iargs.with_multiple_parts and args.lit.default or nil, | |||
} | } | ||
| Line 573: | Line 638: | ||
args.nodot and "" or args.dot or iargs.withdot and "." or "" | args.nodot and "" or args.dot or iargs.withdot and "." or "" | ||
) | ) | ||
if | if not lemma_data.categories[1] then | ||
return text | return text | ||
end | end | ||
| Line 586: | Line 651: | ||
-- Invocation parameters shared between form_of_t(), tagged_form_of_t() and inflection_of_t(). | -- Invocation parameters shared between form_of_t(), tagged_form_of_t() and inflection_of_t(). `calling_func` is the | ||
local function get_common_invocation_params() | -- invoking function ("form_of_t", "tagged_form_of_t" or "inflection_of_t"), for handling parameters shared by two but | ||
-- not all three invoking functions. | |||
local function get_common_invocation_params(calling_func) | |||
local iparams = { | |||
["term_param"] = {type = "number"}, | ["term_param"] = {type = "number"}, | ||
["lang"] = true, -- To be used as the default code in params. | ["lang"] = true, -- To be used as the default code in params. | ||
| Line 596: | Line 663: | ||
["def"] = {list = true}, | ["def"] = {list = true}, | ||
["conj"] = {set = allowed_conj_set, default = "and"}, | ["conj"] = {set = allowed_conj_set, default = "and"}, | ||
["withcap"] = | ["withcap"] = boolean_param, | ||
["withencap"] = | ["withencap"] = boolean_param, | ||
["withdot"] = | ["withdot"] = boolean_param, | ||
["nolink"] = | ["nolink"] = boolean_param, | ||
["linktext"] = true, | ["linktext"] = true, | ||
["posttext"] = true, | ["posttext"] = true, | ||
| Line 605: | Line 672: | ||
["lemma_is_sort_key"] = true, | ["lemma_is_sort_key"] = true, | ||
} | } | ||
if calling_func ~= "inflection_of_t" then | |||
iparams.with_multiple_parts = boolean_param | |||
end | |||
return iparams | |||
end | end | ||
local function should_ucfirst_text(args, iargs, lang) | local function should_ucfirst_text(args, iargs, lang) | ||
return args.cap or (iargs.withcap or iargs.withencap and | local code = lang:getCode() | ||
return args.cap or (iargs.withcap or iargs.withencap and code == "en" or code == "mul") and not args.nocap | |||
end | end | ||
| Line 624: | Line 696: | ||
: Numbered param holding the term linked to. Other numbered params come after. Defaults to 1 if invocation or template | : Numbered param holding the term linked to. Other numbered params come after. Defaults to 1 if invocation or template | ||
param {{para|lang}} is present, otherwise 2. | param {{para|lang}} is present, otherwise 2. | ||
; {{para|with_multiple_parts|1}} | |||
: If specified, higher numbered parameters above the numbered param in {{para|term_param}} specify additional parts out | |||
of which the term was constructed, for use by templates like {{tl|contraction of}}. (If not specified, the parameter | |||
at <code><var>term_param</var> + 1</code> is the display form, same as {{para|alt}}, and the parameter at | |||
at <code><var>term_param</var> + 2</code> is the gloss, same as {{para|t}}.) | |||
; {{para|lang}} | ; {{para|lang}} | ||
: Default language code for language-specific templates. If specified, no language code needs to be specified, and if | : Default language code for language-specific templates. If specified, no language code needs to be specified, and if | ||
| Line 642: | Line 719: | ||
: One or more default values to supply for template args. For example, specifying {{para|def|2=tr=-}} causes the default | : One or more default values to supply for template args. For example, specifying {{para|def|2=tr=-}} causes the default | ||
for template param {{para|tr}} to be `-`. Actual template params override these defaults. | for template param {{para|tr}} to be `-`. Actual template params override these defaults. | ||
; {{para|withcap}} | ; {{para|withcap|1}} | ||
: Capitalize the first character of the text preceding the link, unless template param {{para|nocap}} is given. | : Capitalize the first character of the text preceding the link, unless template param {{para|nocap}} is given. | ||
; {{para|withencap}} | ; {{para|withencap|1}} | ||
: Capitalize the first character of the text preceding the link if the language is English and template param | : Capitalize the first character of the text preceding the link if the language is English and template param | ||
{{para|nocap}} is not given. | {{para|nocap}} is not given. | ||
; {{para|withdot}} | ; {{para|withdot|1}} | ||
: Add a final period after the link, unless template param {{para|nodot}} is given to suppress the period, or | : Add a final period after the link, unless template param {{para|nodot}} is given to suppress the period, or | ||
{{para|dot}} is given to specify an alternative punctuation character. | {{para|dot}} is given to specify an alternative punctuation character. | ||
; {{para|nolink}} | ; {{para|nolink|1}} | ||
: Suppress the display of the link. If specified, none of the template params that control the link | : Suppress the display of the link. If specified, none of the template params that control the link | ||
({{para|<var>term_param</var>}}, {{para|<var>term_param</var> + 1}}, {{para|<var>term_param</var> + 2}}, {{para|t}}, | ({{para|<var>term_param</var>}}, {{para|<var>term_param</var> + 1}}, {{para|<var>term_param</var> + 2}}, {{para|t}}, | ||
| Line 667: | Line 744: | ||
: Category to add the page to if the primary entry linked to doesn't exist. The language name will automatically be | : Category to add the page to if the primary entry linked to doesn't exist. The language name will automatically be | ||
prepended. | prepended. | ||
; {{para|lemma_is_sort_key}} | ; {{para|lemma_is_sort_key|1}} | ||
: If the user didn't specify a sort key, use the lemma as the sort key (instead of the page itself). | : If the user didn't specify a sort key, use the lemma as the sort key (instead of the page itself). | ||
]==] | ]==] | ||
function export.form_of_t(frame) | function export.form_of_t(frame) | ||
local iparams = get_common_invocation_params() | local iparams = get_common_invocation_params("form_of_t") | ||
iparams[1] = {required = true} | iparams[1] = {required = true} | ||
local iargs = process_params(frame.args, iparams) | local iargs = process_params(frame.args, iparams) | ||
| Line 679: | Line 756: | ||
if next(iargs.cat) then | if next(iargs.cat) then | ||
params.nocat = | params.nocat = boolean_param | ||
end | end | ||
| Line 698: | Line 775: | ||
end | end | ||
end | end | ||
-- This returns two values, which we pass up to the caller. | |||
return format_form_of { | return format_form_of { | ||
text = text, lemmas = lemma_data.lemmas, conj = lemma_data.conj, enclitics = lemma_data.enclitics, | lang = lemma_data.lang, text = text, lemmas = lemma_data.lemmas, conj = lemma_data.conj, | ||
enclitics = lemma_data.enclitics, base_lemmas = lemma_data.base_lemmas, lemma_face = "term", | |||
lit = lemma_data.lit, posttext = lemma_data.posttext | |||
} | |||
end | end | ||
} | } | ||
| Line 721: | Line 800: | ||
-- Named params not controlling link display | -- Named params not controlling link display | ||
-- Always included because lang-specific categories may be added | -- Always included because lang-specific categories may be added | ||
params.nocat = | params.nocat = boolean_param | ||
params.p = true | params.p = true | ||
params.POS = {alias_of = "p"} | params.POS = {alias_of = "p"} | ||
| Line 776: | Line 855: | ||
argument, simplifying template code. | argument, simplifying template code. | ||
; {{para|term_param}} | ; {{para|term_param}} | ||
; {{para|with_multiple_parts|1}} | |||
; {{para|lang}} | ; {{para|lang}} | ||
; {{para|sc}} | ; {{para|sc}} | ||
| Line 781: | Line 861: | ||
; {{para|ignore}}, {{para|ignore2}}, ... | ; {{para|ignore}}, {{para|ignore2}}, ... | ||
; {{para|def}}, {{para|def2}}, ... | ; {{para|def}}, {{para|def2}}, ... | ||
; {{para|withcap}} | ; {{para|withcap|1}} | ||
; {{para|withencap}} | ; {{para|withencap|1}} | ||
; {{para|withdot}} | ; {{para|withdot|1}} | ||
; {{para|nolink}} | ; {{para|nolink|1}} | ||
; {{para|linktext}} | ; {{para|linktext}} | ||
; {{para|posttext}} | ; {{para|posttext}} | ||
; {{para|noprimaryentrycat}} | ; {{para|noprimaryentrycat}} | ||
; {{para|lemma_is_sort_key}} | ; {{para|lemma_is_sort_key|1}} | ||
: All of these are the same as in {form_of_t()}. | : All of these are the same as in {form_of_t()}. | ||
]==] | ]==] | ||
function export.tagged_form_of_t(frame) | function export.tagged_form_of_t(frame) | ||
local iparams = get_common_invocation_params() | local iparams = get_common_invocation_params("tagged_form_of_t") | ||
iparams[1] = {list = true, required = true} | iparams[1] = {list = true, required = true} | ||
iparams.split_tags = true | iparams.split_tags = true | ||
| Line 842: | Line 922: | ||
; {{para|ignore}}, {{para|ignore2}}, ... | ; {{para|ignore}}, {{para|ignore2}}, ... | ||
; {{para|def}}, {{para|def2}}, ... | ; {{para|def}}, {{para|def2}}, ... | ||
; {{para|withcap}} | ; {{para|withcap|1}} | ||
; {{para|withencap}} | ; {{para|withencap|1}} | ||
; {{para|withdot}} | ; {{para|withdot|1}} | ||
; {{para|nolink}} | ; {{para|nolink|1}} | ||
; {{para|linktext}} | ; {{para|linktext}} | ||
; {{para|posttext}} | ; {{para|posttext}} | ||
; {{para|noprimaryentrycat}} | ; {{para|noprimaryentrycat}} | ||
; {{para|lemma_is_sort_key}} | ; {{para|lemma_is_sort_key|1}} | ||
: All of these are the same as in {form_of_t()}. | : All of these are the same as in {form_of_t()}. | ||
]==] | ]==] | ||
function export.inflection_of_t(frame) | function export.inflection_of_t(frame) | ||
local iparams = get_common_invocation_params() | local iparams = get_common_invocation_params("inflection_of_t") | ||
iparams.preinfl = {list = true} | iparams.preinfl = {list = true} | ||
iparams.postinfl = {list = true} | iparams.postinfl = {list = true} | ||