<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://test.st34an.tech/index.php?action=history&amp;feed=atom&amp;title=Module%3AForm_of%2Ftemplates</id>
	<title>Module:Form of/templates - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://test.st34an.tech/index.php?action=history&amp;feed=atom&amp;title=Module%3AForm_of%2Ftemplates"/>
	<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Form_of/templates&amp;action=history"/>
	<updated>2026-04-10T22:41:39Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://test.st34an.tech/index.php?title=Module:Form_of/templates&amp;diff=377&amp;oldid=prev</id>
		<title>Jsrs701: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Form_of/templates&amp;diff=377&amp;oldid=prev"/>
		<updated>2026-04-10T07:29:42Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 07:29, 10 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key mediawikidb:diff:1.41:old-376:rev-377 --&gt;
&lt;/table&gt;</summary>
		<author><name>Jsrs701</name></author>
	</entry>
	<entry>
		<id>https://test.st34an.tech/index.php?title=Module:Form_of/templates&amp;diff=376&amp;oldid=prev</id>
		<title>bob&gt;Juelos: Reverted edits by Juelos (talk) to last revision by Vaxjedi</title>
		<link rel="alternate" type="text/html" href="https://test.st34an.tech/index.php?title=Module:Form_of/templates&amp;diff=376&amp;oldid=prev"/>
		<updated>2024-09-06T14:21:02Z</updated>

		<summary type="html">&lt;p&gt;Reverted edits by &lt;a href=&quot;/index.php?title=Special:Contributions/Juelos&quot; title=&quot;Special:Contributions/Juelos&quot;&gt;Juelos&lt;/a&gt; (&lt;a href=&quot;/index.php?title=User_talk:Juelos&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User talk:Juelos (page does not exist)&quot;&gt;talk&lt;/a&gt;) to last revision by &lt;a href=&quot;/index.php?title=User:Vaxjedi&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User:Vaxjedi (page does not exist)&quot;&gt;Vaxjedi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local export = {}&lt;br /&gt;
&lt;br /&gt;
local m_form_of = require(&amp;quot;Module:form of&amp;quot;)&lt;br /&gt;
local m_params = require(&amp;quot;Module:parameters&amp;quot;)&lt;br /&gt;
local put_module = &amp;quot;Module:parse utilities&amp;quot;&lt;br /&gt;
local rfind = mw.ustring.find&lt;br /&gt;
local rmatch = mw.ustring.match&lt;br /&gt;
local rsplit = mw.text.split&lt;br /&gt;
local rgsplit = mw.text.gsplit&lt;br /&gt;
&lt;br /&gt;
-- Add tracking category for PAGE when called from TEMPLATE. The tracking category linked to is&lt;br /&gt;
-- [[Template:tracking/form-of/TEMPLATE/PAGE]]. If TEMPLATE is omitted, the tracking category is of the form&lt;br /&gt;
-- [[Template:tracking/form-of/PAGE]].&lt;br /&gt;
local function track(page, template)&lt;br /&gt;
	require(&amp;quot;Module:debug/track&amp;quot;)(&amp;quot;form-of/&amp;quot; .. (template and template .. &amp;quot;/&amp;quot; or &amp;quot;&amp;quot;) .. page)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Equivalent to list.extend(new_items) in Python. Appends items in `new_items` (a list) to `list`.&lt;br /&gt;
local function extend_list(list, new_items)&lt;br /&gt;
	for _, item in ipairs(new_items) do&lt;br /&gt;
		table.insert(list, item)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function get_script(sc, param_for_error)&lt;br /&gt;
	return sc and require(&amp;quot;Module:scripts&amp;quot;).getByCode(arg, param_for_error) or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Process parent arguments. This is similar to the following:&lt;br /&gt;
	require(&amp;quot;Module:parameters&amp;quot;).process(parent_args, params)&lt;br /&gt;
but in addition it does the following:&lt;br /&gt;
(1) Supplies default values for unspecified parent arguments as specified in&lt;br /&gt;
	DEFAULTS, which consist of specs of the form &amp;quot;ARG=VALUE&amp;quot;. These are&lt;br /&gt;
	added to the parent arguments prior to processing, so boolean and number&lt;br /&gt;
	parameters will process the value appropriately.&lt;br /&gt;
(2) Removes parent arguments specified in IGNORESPECS, which consist either&lt;br /&gt;
	of bare argument names to remove, or list-argument names to remove of the&lt;br /&gt;
	form &amp;quot;ARG:list&amp;quot;.&lt;br /&gt;
(3) Tracks the use of any parent arguments specified in TRACKED_PARAMS, which&lt;br /&gt;
	is a set-type table where the keys are arguments as they exist after&lt;br /&gt;
	processing (hence numeric arguments should be numbers, not strings)&lt;br /&gt;
	and the values should be boolean true.&lt;br /&gt;
]=]--&lt;br /&gt;
local function process_parent_args(template, parent_args, params, defaults, ignorespecs, tracked_params, function_name)&lt;br /&gt;
	if #defaults &amp;gt; 0 or #ignorespecs &amp;gt; 0 then&lt;br /&gt;
		local new_parent_args = {}&lt;br /&gt;
		for _, default in ipairs(defaults) do&lt;br /&gt;
			local defparam, defval = rmatch(default, &amp;quot;^(.-)=(.*)$&amp;quot;)&lt;br /&gt;
			if not defparam then&lt;br /&gt;
				error(&amp;quot;Bad default spec &amp;quot; .. default)&lt;br /&gt;
			end&lt;br /&gt;
			new_parent_args[defparam] = defval&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local params_to_ignore = {}&lt;br /&gt;
		local numbered_list_params_to_ignore = {}&lt;br /&gt;
		local named_list_params_to_ignore = {}&lt;br /&gt;
&lt;br /&gt;
		for _, ignorespec in ipairs(ignorespecs) do&lt;br /&gt;
			for ignore in rgsplit(ignorespec, &amp;quot;,&amp;quot;) do&lt;br /&gt;
				local param = rmatch(ignore, &amp;quot;^(.*):list$&amp;quot;)&lt;br /&gt;
				if param then&lt;br /&gt;
					if rfind(param, &amp;quot;^[0-9]+$&amp;quot;) then&lt;br /&gt;
						table.insert(numbered_list_params_to_ignore, tonumber(param))&lt;br /&gt;
					else&lt;br /&gt;
						table.insert(named_list_params_to_ignore,&lt;br /&gt;
							&amp;quot;^&amp;quot; .. require(&amp;quot;Module:utilities&amp;quot;).pattern_escape(param) .. &amp;quot;[0-9]*$&amp;quot;)&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					if rfind(ignore, &amp;quot;^[0-9]+$&amp;quot;) then&lt;br /&gt;
						ignore = tonumber(ignore)&lt;br /&gt;
					end&lt;br /&gt;
					params_to_ignore[ignore] = true&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		for k, v in pairs(parent_args) do&lt;br /&gt;
			if not params_to_ignore[k] then&lt;br /&gt;
				local ignore_me = false&lt;br /&gt;
				if type(k) == &amp;quot;number&amp;quot; then&lt;br /&gt;
					for _, lparam in ipairs(numbered_list_params_to_ignore) do&lt;br /&gt;
						if k &amp;gt;= lparam then&lt;br /&gt;
							ignore_me = true&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				else&lt;br /&gt;
					for _, lparam in ipairs(named_list_params_to_ignore) do&lt;br /&gt;
						if rfind(k, lparam) then&lt;br /&gt;
							ignore_me = true&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if not ignore_me then&lt;br /&gt;
					new_parent_args[k] = v&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		parent_args = new_parent_args&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local args = m_params.process(parent_args, params, nil, &amp;quot;form of/templates&amp;quot;, function_name)&lt;br /&gt;
&lt;br /&gt;
	-- Tracking for certain user-specified params. This is generally used for&lt;br /&gt;
	-- parameters that we accept but ignore, so that we can eventually remove&lt;br /&gt;
	-- all uses of these params and stop accepting them.&lt;br /&gt;
	if tracked_params then&lt;br /&gt;
		for tracked_param, _ in pairs(tracked_params) do&lt;br /&gt;
			if parent_args[tracked_param] then&lt;br /&gt;
				track(&amp;quot;arg/&amp;quot; .. tracked_param, template)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Split TAGSPECS (inflection tag specifications) on SPLIT_REGEX, which&lt;br /&gt;
-- may be nil for no splitting.&lt;br /&gt;
local function split_inflection_tags(tagspecs, split_regex)&lt;br /&gt;
	if not split_regex then&lt;br /&gt;
		return tagspecs&lt;br /&gt;
	end&lt;br /&gt;
	local inflection_tags = {}&lt;br /&gt;
	for _, tagspec in ipairs(tagspecs) do&lt;br /&gt;
		for tag in rgsplit(tagspec, split_regex) do&lt;br /&gt;
			table.insert(inflection_tags, tag)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return inflection_tags&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local term_param_mods = {&lt;br /&gt;
	t = {&lt;br /&gt;
		-- We need to store the &amp;lt;t:...&amp;gt; inline modifier into the &amp;quot;gloss&amp;quot; key of the parsed part, because that is what&lt;br /&gt;
		-- [[Module:links]] expects.&lt;br /&gt;
		item_dest = &amp;quot;gloss&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	gloss = {},&lt;br /&gt;
	tr = {},&lt;br /&gt;
	ts = {},&lt;br /&gt;
	g = {&lt;br /&gt;
		-- We need to store the &amp;lt;g:...&amp;gt; inline modifier into the &amp;quot;genders&amp;quot; key of the parsed part, because that is what&lt;br /&gt;
		-- [[Module:links]] expects.&lt;br /&gt;
		item_dest = &amp;quot;genders&amp;quot;,&lt;br /&gt;
		convert = function(arg, parse_err)&lt;br /&gt;
			return rsplit(arg, &amp;quot;,&amp;quot;)&lt;br /&gt;
		end,&lt;br /&gt;
	},&lt;br /&gt;
	id = {},&lt;br /&gt;
	alt = {},&lt;br /&gt;
	q = {},&lt;br /&gt;
	qq = {},&lt;br /&gt;
	lit = {},&lt;br /&gt;
	pos = {},&lt;br /&gt;
	sc = {&lt;br /&gt;
		convert = function(arg, parse_err)&lt;br /&gt;
			return get_script(arg, parse_err)&lt;br /&gt;
		end,&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function parse_terms_with_inline_modifiers(paramname, val, lang)&lt;br /&gt;
	local function generate_obj(term)&lt;br /&gt;
		return {lang = lang, term = term}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local retval&lt;br /&gt;
	-- Check for inline modifier, e.g. מרים&amp;lt;tr:Miryem&amp;gt;. But exclude HTML entry with &amp;lt;span ...&amp;gt;, &amp;lt;i ...&amp;gt;, &amp;lt;br/&amp;gt; or&lt;br /&gt;
	-- similar in it, caused by wrapping an argument in {{l|...}}, {{af|...}} or similar. Basically, all tags of&lt;br /&gt;
	-- the sort we parse here should consist of a less-than sign, plus letters, plus a colon, e.g. &amp;lt;tr:...&amp;gt;, so if&lt;br /&gt;
	-- we see a tag on the outer level that isn&amp;#039;t in this format, we don&amp;#039;t try to parse it. The restriction to the&lt;br /&gt;
	-- outer level is to allow generated HTML inside of e.g. qualifier tags, such as foo&amp;lt;q:similar to {{m|fr|bar}}&amp;gt;.&lt;br /&gt;
	if val:find(&amp;quot;&amp;lt;&amp;quot;) and not val:find(&amp;quot;^[^&amp;lt;]*&amp;lt;[a-z]*[^a-z:]&amp;quot;) then&lt;br /&gt;
		retval = require(put_module).parse_inline_modifiers(val, {&lt;br /&gt;
			paramname = paramname,&lt;br /&gt;
			param_mods = term_param_mods,&lt;br /&gt;
			generate_obj = generate_obj,&lt;br /&gt;
			splitchar = &amp;quot;,&amp;quot;,&lt;br /&gt;
		})&lt;br /&gt;
	else&lt;br /&gt;
		if val:find(&amp;quot;,&amp;lt;&amp;quot;) then&lt;br /&gt;
			-- this happens when there&amp;#039;s an embedded {{,}} template, as in [[MMR]], [[TMA]], [[DEI]], where an initialism&lt;br /&gt;
			-- expands to multiple terms; easiest not to try and parse the lemma spec as multiple lemmas&lt;br /&gt;
			retval = {val}&lt;br /&gt;
		elseif val:find(&amp;quot;,%s&amp;quot;) then&lt;br /&gt;
			retval = require(put_module).split_on_comma(val)&lt;br /&gt;
		else&lt;br /&gt;
			retval = rsplit(val, &amp;quot;,&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		for i, split in ipairs(retval) do&lt;br /&gt;
			retval[i] = generate_obj(split)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return retval&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local link_params = { &amp;quot;term&amp;quot;, &amp;quot;alt&amp;quot;, &amp;quot;t&amp;quot;, &amp;quot;gloss&amp;quot;, &amp;quot;sc&amp;quot;, &amp;quot;tr&amp;quot;, &amp;quot;ts&amp;quot;, &amp;quot;pos&amp;quot;, &amp;quot;id&amp;quot;, &amp;quot;lit&amp;quot; }&lt;br /&gt;
local link_param_set = {}&lt;br /&gt;
for _, param in ipairs(link_params) do&lt;br /&gt;
	link_param_set[param] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Modify PARAMS in-place by adding parameters that control the link to the&lt;br /&gt;
-- main entry. TERM_PARAM is the number of the param specifying the main&lt;br /&gt;
-- entry itself; TERM_PARAM + 1 will be the display text, and TERM_PARAM + 2&lt;br /&gt;
-- will be the gloss, unless NO_NUMBERED_GLOSS is given.&lt;br /&gt;
local function add_link_params(parent_args, params, term_param, no_numbered_gloss)&lt;br /&gt;
	for k, v in pairs(parent_args) do&lt;br /&gt;
		if type(k) == &amp;quot;string&amp;quot; then&lt;br /&gt;
			local base, num = k:match(&amp;quot;^([a-z]+)([0-9]+)$&amp;quot;)&lt;br /&gt;
			if base and link_param_set[base] then&lt;br /&gt;
				track(&amp;quot;multiple-lemmas&amp;quot;)&lt;br /&gt;
				error(&amp;quot;Support for the separate-parameter style of multiple lemmas in form-of templates is going away; use a comma-separated lemma param with inline modifiers&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- If no params for the second or higher term exist, use a simpler param setup to save memory.&lt;br /&gt;
	params[term_param + 1] = {alias_of = &amp;quot;alt&amp;quot;}&lt;br /&gt;
	if not no_numbered_gloss then&lt;br /&gt;
		params[term_param + 2] = {alias_of = &amp;quot;t&amp;quot;}&lt;br /&gt;
	end&lt;br /&gt;
	-- Numbered params controlling link display&lt;br /&gt;
	params[term_param] = {}&lt;br /&gt;
&lt;br /&gt;
	-- Named params controlling link display&lt;br /&gt;
	params[&amp;quot;gloss&amp;quot;] = {alias_of = &amp;quot;t&amp;quot;}&lt;br /&gt;
	params[&amp;quot;g&amp;quot;] = {list = true}&lt;br /&gt;
	for _, param in ipairs(link_params) do&lt;br /&gt;
		if param ~= &amp;quot;gloss&amp;quot; and param ~= &amp;quot;g&amp;quot; and param ~= &amp;quot;term&amp;quot; then&lt;br /&gt;
			params[param] = {}&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function add_base_lemma_params(parent_args, iargs, params, compat)&lt;br /&gt;
	-- Need to do what [[Module:parameters]] does to string arguments from parent_args as we&amp;#039;re running this&lt;br /&gt;
	-- before calling [[Module:parameters]] on parent_args.&lt;br /&gt;
	local function ine(arg)&lt;br /&gt;
		if not arg then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		arg = mw.text.trim(arg)&lt;br /&gt;
		return arg ~= &amp;quot;&amp;quot; and arg or nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local langcode = ine(parent_args[compat and &amp;quot;lang&amp;quot; or 1]) or iargs[&amp;quot;lang&amp;quot;] or &amp;quot;und&amp;quot;&lt;br /&gt;
	if m_form_of.langs_with_lang_specific_tags[langcode] then&lt;br /&gt;
		local langdata = mw.loadData(m_form_of.form_of_lang_data_module_prefix .. langcode)&lt;br /&gt;
		if langdata.base_lemma_params then&lt;br /&gt;
			for _, param in ipairs(langdata.base_lemma_params) do&lt;br /&gt;
				params[param.param] = {}&lt;br /&gt;
			end&lt;br /&gt;
			return langdata.base_lemma_params&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Given processed invocation arguments IARGS and processed parent arguments ARGS, as well as TERM_PARAM (the parent&lt;br /&gt;
argument specifying the first main entry/lemma) and COMPAT (true if the language code is found in args[&amp;quot;lang&amp;quot;] instead&lt;br /&gt;
of args[1]), return an object as follows:&lt;br /&gt;
{&lt;br /&gt;
	lang = LANG,&lt;br /&gt;
	lemmas = {LEMMA_OBJ, LEMMA_OBJ, ...},&lt;br /&gt;
	enclitics = {ENCLITIC_OBJ, ENCLITIC_OBJ, ...},&lt;br /&gt;
	base_lemmas = {BASE_LEMMA_OBJ, BASE_LEMMA_OBJ, ...},&lt;br /&gt;
	categories = {&amp;quot;CATEGORY&amp;quot;, &amp;quot;CATEGORY&amp;quot;, ...},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
* LANG is the language code;&lt;br /&gt;
* LEMMAS is a sequence of objects specifying the main entries/lemmas, as passed to full_link in [[Module:links]];&lt;br /&gt;
  however, if the invocation argument linktext= is given, it will be a string consisting of that text, and if the&lt;br /&gt;
  invocation argument nolink= is given, it will be nil;&lt;br /&gt;
* ENCLITICS is nil or a sequence of objects specifying the enclitics, as passed to full_link in [[Module:links]];&lt;br /&gt;
* BASE_LEMMA_OBJ is a sequence of objects specifying the base lemma(s), which are used when the lemma is itself a&lt;br /&gt;
  form of another lemma (the base lemma), e.g. a comparative, superlative or participle; each object is of the form&lt;br /&gt;
  { paramobj = PARAM_OBJ, lemmas = {LEMMA_OBJ, LEMMA_OBJ, ...} } where PARAM_OBJ describes the properties of the&lt;br /&gt;
  base lemma parameter (i.e. the relationship between the intermediate and base lemmas) and LEMMA_OBJ is of the same&lt;br /&gt;
  format of ENCLITIC_OBJ, i.e. an object suitable to be passed to full_link in [[Module:links]]; PARAM_OBJ is of the&lt;br /&gt;
  format { param = &amp;quot;PARAM&amp;quot;, tags = {&amp;quot;TAG&amp;quot;, &amp;quot;TAG&amp;quot;, ...} } where PARAM is the name of the parameter to {{inflection of}}&lt;br /&gt;
  etc. that holds the base lemma(s) of the specified relationship and the tags describe the relationship, such as&lt;br /&gt;
  {&amp;quot;comd&amp;quot;} or {&amp;quot;past&amp;quot;, &amp;quot;part&amp;quot;};&lt;br /&gt;
* CATEGORIES is the categories to add the page to (consisting of any categories specified in the invocation or&lt;br /&gt;
  parent args and any tracking categories, but not any additional lang-specific categories that may be added by&lt;br /&gt;
  {{inflection of}} or similar templates).&lt;br /&gt;
&lt;br /&gt;
This is a subfunction of construct_form_of_text().&lt;br /&gt;
]=]&lt;br /&gt;
local function get_lemmas_and_categories(iargs, args, term_param, compat, base_lemma_params)&lt;br /&gt;
	local lang = args[compat and &amp;quot;lang&amp;quot; or 1] or iargs[&amp;quot;lang&amp;quot;] or &amp;quot;und&amp;quot;&lt;br /&gt;
	lang = require(&amp;quot;Module:languages&amp;quot;).getByCode(lang, compat and &amp;quot;lang&amp;quot; or 1)&lt;br /&gt;
&lt;br /&gt;
	-- Determine categories for the page, including tracking categories&lt;br /&gt;
&lt;br /&gt;
	local categories = {}&lt;br /&gt;
&lt;br /&gt;
	if not args[&amp;quot;nocat&amp;quot;] then&lt;br /&gt;
		for _, cat in ipairs(iargs[&amp;quot;cat&amp;quot;]) do&lt;br /&gt;
			table.insert(categories, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. cat)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for _, cat in ipairs(args[&amp;quot;cat&amp;quot;]) do&lt;br /&gt;
		table.insert(categories, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. cat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Format the link, preceding text and categories&lt;br /&gt;
&lt;br /&gt;
	local function add_term_tracking_categories(term)&lt;br /&gt;
		-- add tracking category if term is same as page title&lt;br /&gt;
		if term and mw.title.getCurrentTitle().text == (lang:makeEntryName(term)) then&lt;br /&gt;
			table.insert(categories, &amp;quot;Forms linking to themselves&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		-- maybe add tracking category if primary entry doesn&amp;#039;t exist (this is an&lt;br /&gt;
		-- expensive call so we don&amp;#039;t do it by default)&lt;br /&gt;
		if iargs[&amp;quot;noprimaryentrycat&amp;quot;] and term and mw.title.getCurrentTitle().nsText == &amp;quot;&amp;quot;&lt;br /&gt;
			and not mw.title.new(term).exists then&lt;br /&gt;
			table.insert(categories, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. iargs[&amp;quot;noprimaryentrycat&amp;quot;])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local lemmas&lt;br /&gt;
&lt;br /&gt;
	if iargs[&amp;quot;nolink&amp;quot;] then&lt;br /&gt;
		lemmas = nil&lt;br /&gt;
	elseif iargs[&amp;quot;linktext&amp;quot;] then&lt;br /&gt;
		lemmas = iargs[&amp;quot;linktext&amp;quot;]&lt;br /&gt;
	else&lt;br /&gt;
		-- Only one lemma. We use a simpler structure in `args` to save memory.&lt;br /&gt;
		local term = args[term_param]&lt;br /&gt;
&lt;br /&gt;
		if not term and not args[&amp;quot;alt&amp;quot;] and not args[&amp;quot;tr&amp;quot;] and not args[&amp;quot;ts&amp;quot;] then&lt;br /&gt;
			if mw.title.getCurrentTitle().nsText == &amp;quot;Template&amp;quot; then&lt;br /&gt;
				term = &amp;quot;term&amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				error(&amp;quot;No linked-to term specified; either specify term, alt, translit or transcription&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		add_term_tracking_categories(term)&lt;br /&gt;
&lt;br /&gt;
		if term then&lt;br /&gt;
			lemmas = parse_terms_with_inline_modifiers(term_param, term, lang)&lt;br /&gt;
		else&lt;br /&gt;
			lemmas = {{ lang = lang }}&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- sc= but not invocation arg sc= should override inline modifier sc=.&lt;br /&gt;
		local sc&lt;br /&gt;
		if args[&amp;quot;sc&amp;quot;] then&lt;br /&gt;
			lemmas[1].sc = get_script(args[&amp;quot;sc&amp;quot;], &amp;quot;sc&amp;quot;)&lt;br /&gt;
		elseif not lemmas[1].sc and iargs[&amp;quot;sc&amp;quot;] then&lt;br /&gt;
			lemmas[1].sc = get_script(iargs[&amp;quot;sc&amp;quot;], &amp;quot;sc&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if #args[&amp;quot;g&amp;quot;] &amp;gt; 0 then&lt;br /&gt;
			local genders = {}&lt;br /&gt;
			for _, g in ipairs(args[&amp;quot;g&amp;quot;]) do&lt;br /&gt;
				extend_list(genders, rsplit(g, &amp;quot;,&amp;quot;))&lt;br /&gt;
			end&lt;br /&gt;
			lemmas[1].genders = genders&lt;br /&gt;
		end&lt;br /&gt;
		if args[&amp;quot;t&amp;quot;] then&lt;br /&gt;
			lemmas[1].gloss = args[&amp;quot;t&amp;quot;]&lt;br /&gt;
		end&lt;br /&gt;
		for _, param in ipairs(link_params) do&lt;br /&gt;
			if param ~= &amp;quot;sc&amp;quot; and param ~= &amp;quot;term&amp;quot; and param ~= &amp;quot;g&amp;quot; and param ~= &amp;quot;gloss&amp;quot; and param ~= &amp;quot;t&amp;quot; and&lt;br /&gt;
				args[param] then&lt;br /&gt;
				lemmas[1][param] = args[param]&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local enclitics&lt;br /&gt;
	if args.enclitic then&lt;br /&gt;
		enclitics = parse_terms_with_inline_modifiers(&amp;quot;enclitic&amp;quot;, args.enclitic, lang)&lt;br /&gt;
	end&lt;br /&gt;
	local base_lemmas = {}&lt;br /&gt;
	if base_lemma_params then&lt;br /&gt;
		for _, base_lemma_param_obj in ipairs(base_lemma_params) do&lt;br /&gt;
			local param = base_lemma_param_obj.param&lt;br /&gt;
			if args[param] then&lt;br /&gt;
				table.insert(base_lemmas, {&lt;br /&gt;
					paramobj = base_lemma_param_obj,&lt;br /&gt;
					lemmas = parse_terms_with_inline_modifiers(param, args[param], lang),&lt;br /&gt;
				})&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return {&lt;br /&gt;
		lang = lang,&lt;br /&gt;
		lemmas = lemmas,&lt;br /&gt;
		enclitics = enclitics,&lt;br /&gt;
		base_lemmas = base_lemmas,&lt;br /&gt;
		categories = categories,&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Construct and return the full definition line for a form-of-type template invocation, given processed invocation&lt;br /&gt;
-- arguments IARGS, processed parent arguments ARGS, TERM_PARAM (the parent argument specifying the main entry), COMPAT&lt;br /&gt;
-- (true if the language code is found in args[&amp;quot;lang&amp;quot;] instead of args[1]), and DO_FORM_OF, which is a function that&lt;br /&gt;
-- returns the actual definition-line text and any language-specific categories. The terminating period/dot will be&lt;br /&gt;
-- added as appropriate, the language-specific categories will be added to any categories requested by the invocation&lt;br /&gt;
-- or parent args, and then whole thing will be appropriately formatted.&lt;br /&gt;
--&lt;br /&gt;
-- DO_FORM_OF takes one argument, the return value of get_lemmas_and_categories() (an object describing the lemmas,&lt;br /&gt;
-- clitics, base lemmas and categories fetched).&lt;br /&gt;
--&lt;br /&gt;
-- DO_FORM_OF should return two arguments:&lt;br /&gt;
--&lt;br /&gt;
-- (1) The actual definition-line text, marked up appropriately with &amp;lt;span&amp;gt;...&amp;lt;/span&amp;gt; but without any terminating&lt;br /&gt;
--     period/dot.&lt;br /&gt;
-- (2) Any extra categories to add the page to (other than those that can be derived from parameters specified to the&lt;br /&gt;
--     invocation or parent arguments, which will automatically be added to the page).&lt;br /&gt;
local function construct_form_of_text(iargs, args, term_param, compat, base_lemma_params, do_form_of)&lt;br /&gt;
	local lemma_data = get_lemmas_and_categories(iargs, args, term_param, compat, base_lemma_params)&lt;br /&gt;
&lt;br /&gt;
	local form_of_text, lang_cats = do_form_of(lemma_data)&lt;br /&gt;
	extend_list(lemma_data.categories, lang_cats)&lt;br /&gt;
	local text = form_of_text .. (&lt;br /&gt;
		args[&amp;quot;nodot&amp;quot;] and &amp;quot;&amp;quot; or args[&amp;quot;dot&amp;quot;] or iargs[&amp;quot;withdot&amp;quot;] and &amp;quot;.&amp;quot; or &amp;quot;&amp;quot;&lt;br /&gt;
	)&lt;br /&gt;
	if #lemma_data.categories == 0 then&lt;br /&gt;
		return text&lt;br /&gt;
	end&lt;br /&gt;
	return text .. require(&amp;quot;Module:utilities&amp;quot;).format_categories(lemma_data.categories, lemma_data.lang, args[&amp;quot;sort&amp;quot;],&lt;br /&gt;
		nil, m_form_of.force_cat)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Function that implements {{form of}} and the various more specific form-of&lt;br /&gt;
templates (but not {{inflection of}} or templates that take tagged inflection&lt;br /&gt;
parameters).&lt;br /&gt;
&lt;br /&gt;
Invocation params:&lt;br /&gt;
&lt;br /&gt;
1= (required):&lt;br /&gt;
	Text to display before the link.&lt;br /&gt;
term_param=:&lt;br /&gt;
	Numbered param holding the term linked to. Other numbered params come after.&lt;br /&gt;
	Defaults to 1 if invocation or template param lang= is present, otherwise 2.&lt;br /&gt;
lang=:&lt;br /&gt;
	Default language code for language-specific templates. If specified, no&lt;br /&gt;
	language code needs to be specified, and if specified it needs to be set&lt;br /&gt;
	using lang=, not 1=.&lt;br /&gt;
sc=:&lt;br /&gt;
	Default script code for language-specific templates. The script code can&lt;br /&gt;
	still be overridden using template param sc=.&lt;br /&gt;
cat=, cat2=, ...:&lt;br /&gt;
	Categories to place the page into. The language name will automatically be&lt;br /&gt;
	prepended. Note that there is also a template param cat= to specify&lt;br /&gt;
	categories at the template level. Use of nocat= disables categorization of&lt;br /&gt;
	categories specified using invocation param cat=, but not using template&lt;br /&gt;
	param cat=.&lt;br /&gt;
ignore=, ignore2=, ...:&lt;br /&gt;
	One or more template params to silently accept and ignore. Useful e.g. when&lt;br /&gt;
	the template takes additional parameters such as from= or POS=. Each value&lt;br /&gt;
	is a comma-separated list of either bare parameter names or specifications&lt;br /&gt;
	of the form &amp;quot;PARAM:list&amp;quot; to specify that the parameter is a list parameter.&lt;br /&gt;
def=, def2=, ...:&lt;br /&gt;
	One or more default values to supply for template args. For example,&lt;br /&gt;
	specifying &amp;#039;|def=tr=-&amp;#039; causes the default for template param &amp;#039;|tr=&amp;#039; to be&lt;br /&gt;
	&amp;#039;-&amp;#039;. Actual template params override these defaults.&lt;br /&gt;
withcap=:&lt;br /&gt;
	Capitalize the first character of the text preceding the link, unless&lt;br /&gt;
	template param nocap= is given.&lt;br /&gt;
withdot=:&lt;br /&gt;
	Add a final period after the link, unless template param nodot= is given&lt;br /&gt;
	to suppress the period, or dot= is given to specify an alternative&lt;br /&gt;
	punctuation character.&lt;br /&gt;
nolink=:&lt;br /&gt;
	Suppress the display of the link. If specified, none of the template&lt;br /&gt;
	params that control the link (TERM_PARAM, TERM_PARAM + 1, TERM_PARAM + 2,&lt;br /&gt;
	t=, gloss=, sc=, tr=, ts=, pos=, g=, id=, lit=) will be available.&lt;br /&gt;
	If the calling template uses any of these parameters, they must be&lt;br /&gt;
	ignored using ignore=.&lt;br /&gt;
linktext=:&lt;br /&gt;
	Override the display of the link with the specified text. This is useful&lt;br /&gt;
	if a custom template is available to format the link (e.g. in Hebrew,&lt;br /&gt;
	Chinese and Japanese). If specified, none of the template params that&lt;br /&gt;
	control the link (TERM_PARAM, TERM_PARAM + 1, TERM_PARAM + 2, t=, gloss=,&lt;br /&gt;
	sc=, tr=, ts=, pos=, g=, id=, lit=) will be available. If the calling&lt;br /&gt;
	template uses any of these parameters, they must be ignored using ignore=.&lt;br /&gt;
posttext=:&lt;br /&gt;
	Additional text to display directly after the formatted link, before any&lt;br /&gt;
	terminating period/dot and inside of &amp;quot;&amp;lt;span class=&amp;#039;use-with-mention&amp;#039;&amp;gt;&amp;quot;.&lt;br /&gt;
noprimaryentrycat=:&lt;br /&gt;
	Category to add the page to if the primary entry linked to doesn&amp;#039;t exist.&lt;br /&gt;
	The language name will automatically be prepended.&lt;br /&gt;
]=]--&lt;br /&gt;
function export.form_of_t(frame)&lt;br /&gt;
	local iparams = {&lt;br /&gt;
		[1] = {required = true},&lt;br /&gt;
		[&amp;quot;term_param&amp;quot;] = {type = &amp;quot;number&amp;quot;},&lt;br /&gt;
		[&amp;quot;lang&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;sc&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;ignore&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;def&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;withcap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;withdot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;nolink&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;linktext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;posttext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;noprimaryentrycat&amp;quot;] = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local iargs = m_params.process(frame.args, iparams, nil, &amp;quot;form of/templates&amp;quot;, &amp;quot;form_of_t&amp;quot;)&lt;br /&gt;
	local parent_args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
	local term_param = iargs[&amp;quot;term_param&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
	local compat = iargs[&amp;quot;lang&amp;quot;] or parent_args[&amp;quot;lang&amp;quot;]&lt;br /&gt;
	term_param = term_param or compat and 1 or 2&lt;br /&gt;
&lt;br /&gt;
	local params = {&lt;br /&gt;
		-- Numbered params&lt;br /&gt;
		[compat and &amp;quot;lang&amp;quot; or 1] = {required = not iargs[&amp;quot;lang&amp;quot;]},&lt;br /&gt;
&lt;br /&gt;
		-- Named params not controlling link display&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;notext&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;sort&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;enclitic&amp;quot;] = {},&lt;br /&gt;
		-- FIXME! The following should only be available when withcap=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nocap= in other circumstances.&lt;br /&gt;
		[&amp;quot;nocap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		-- FIXME! The following should only be available when withdot=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nodot= in other circumstances.&lt;br /&gt;
		[&amp;quot;nodot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;pagename&amp;quot;] = {}, -- for testing, etc.&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local base_lemma_params&lt;br /&gt;
	if not iargs[&amp;quot;nolink&amp;quot;] and not iargs[&amp;quot;linktext&amp;quot;] then&lt;br /&gt;
		add_link_params(parent_args, params, term_param)&lt;br /&gt;
		base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if next(iargs[&amp;quot;cat&amp;quot;]) then&lt;br /&gt;
		params[&amp;quot;nocat&amp;quot;] = {type = &amp;quot;boolean&amp;quot;}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ignored_params = {}&lt;br /&gt;
&lt;br /&gt;
	if iargs[&amp;quot;withdot&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;dot&amp;quot;] = {}&lt;br /&gt;
	else&lt;br /&gt;
		ignored_params[&amp;quot;nodot&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not iargs[&amp;quot;withcap&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;cap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;}&lt;br /&gt;
		ignored_params[&amp;quot;nocap&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local args = process_parent_args(&amp;quot;form-of-t&amp;quot;, parent_args, params, iargs[&amp;quot;def&amp;quot;],&lt;br /&gt;
		iargs[&amp;quot;ignore&amp;quot;], ignored_params, &amp;quot;form_of_t&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local text = args[&amp;quot;notext&amp;quot;] and &amp;quot;&amp;quot; or iargs[1]&lt;br /&gt;
	if args[&amp;quot;cap&amp;quot;] or iargs[&amp;quot;withcap&amp;quot;] and not args[&amp;quot;nocap&amp;quot;] then&lt;br /&gt;
		text = require(&amp;quot;Module:string utilities&amp;quot;).ucfirst(text)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return construct_form_of_text(iargs, args, term_param, compat, base_lemma_params,&lt;br /&gt;
		function(lemma_data)&lt;br /&gt;
			return m_form_of.format_form_of {text = text, lemmas = lemma_data.lemmas, enclitics = lemma_data.enclitics,&lt;br /&gt;
				base_lemmas = lemma_data.base_lemmas, lemma_face = &amp;quot;term&amp;quot;, posttext = iargs[&amp;quot;posttext&amp;quot;]}, {}&lt;br /&gt;
		end&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Construct and return the full definition line for a form-of-type template invocation that is based on inflection tags.&lt;br /&gt;
This is a wrapper around construct_form_of_text() and takes the following arguments: processed invocation arguments&lt;br /&gt;
IARGS, processed parent arguments ARGS, TERM_PARAM (the parent argument specifying the main entry), COMPAT (true if the&lt;br /&gt;
language code is found in args[&amp;quot;lang&amp;quot;] instead of args[1]), and TAGS, the list of (non-canonicalized) inflection tags.&lt;br /&gt;
It returns that actual definition-line text including terminating period/full-stop, formatted categories, etc. and&lt;br /&gt;
should be directly returned as the template function&amp;#039;s return value. JOINER is the optional strategy to join multipart&lt;br /&gt;
tags for display; currently accepted values are &amp;quot;and&amp;quot;, &amp;quot;slash&amp;quot;, &amp;quot;en-dash&amp;quot;; defaults to &amp;quot;slash&amp;quot;.&lt;br /&gt;
]=]&lt;br /&gt;
local function construct_tagged_form_of_text(iargs, args, term_param, compat, base_lemma_params, tags, joiner)&lt;br /&gt;
	return construct_form_of_text(iargs, args, term_param, compat, base_lemma_params,&lt;br /&gt;
		function(lemma_data)&lt;br /&gt;
			-- NOTE: tagged_inflections returns two values, so we do too.&lt;br /&gt;
			return m_form_of.tagged_inflections {&lt;br /&gt;
				lang = lemma_data.lang,&lt;br /&gt;
				tags = tags,&lt;br /&gt;
				lemmas = lemma_data.lemmas,&lt;br /&gt;
				enclitics = lemma_data.enclitics,&lt;br /&gt;
				base_lemmas = lemma_data.base_lemmas,&lt;br /&gt;
				lemma_face = &amp;quot;term&amp;quot;,&lt;br /&gt;
				POS = args[&amp;quot;p&amp;quot;],&lt;br /&gt;
				pagename = args[&amp;quot;pagename&amp;quot;],&lt;br /&gt;
				-- Set no_format_categories because we do it ourselves in construct_form_of_text().&lt;br /&gt;
				no_format_categories = true,&lt;br /&gt;
				nocat = args[&amp;quot;nocat&amp;quot;],&lt;br /&gt;
				notext = args[&amp;quot;notext&amp;quot;],&lt;br /&gt;
				capfirst = args[&amp;quot;cap&amp;quot;] or iargs[&amp;quot;withcap&amp;quot;] and not args[&amp;quot;nocap&amp;quot;],&lt;br /&gt;
				posttext = iargs[&amp;quot;posttext&amp;quot;],&lt;br /&gt;
				joiner = joiner,&lt;br /&gt;
			}&lt;br /&gt;
		end&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Function that implements form-of templates that are defined by specific tagged inflections (typically a template&lt;br /&gt;
referring to a non-lemma inflection, such as {{plural of}}). This works exactly like form_of_t() except that the&lt;br /&gt;
&amp;quot;form of&amp;quot; text displayed before the link is based off of a pre-specified set of inflection tags (which will be&lt;br /&gt;
appropriately linked to the glossary) instead of arbitrary text. From the user&amp;#039;s perspective, there is no difference&lt;br /&gt;
between templates implemented using form_of_t() and tagged_form_of_t(); they accept exactly the same parameters and&lt;br /&gt;
work the same. See also inflection_of_t() below, which is intended for templates with user-specified inflection tags.&lt;br /&gt;
&lt;br /&gt;
Invocation params:&lt;br /&gt;
&lt;br /&gt;
1=, 2=, ... (required):&lt;br /&gt;
	One or more inflection tags describing the inflection in question.&lt;br /&gt;
split_tags=:&lt;br /&gt;
	If specified, character to split specified inflection tags on. This allows&lt;br /&gt;
	multiple tags to be included in a single argument, simplifying template&lt;br /&gt;
	code.&lt;br /&gt;
term_param=:&lt;br /&gt;
lang=:&lt;br /&gt;
sc=:&lt;br /&gt;
cat=, cat2=, ...:&lt;br /&gt;
ignore=, ignore2=, ...:&lt;br /&gt;
def=, def2=, ...:&lt;br /&gt;
withcap=:&lt;br /&gt;
withdot=:&lt;br /&gt;
nolink=:&lt;br /&gt;
linktext=:&lt;br /&gt;
posttext=:&lt;br /&gt;
noprimaryentrycat=:&lt;br /&gt;
	All of these are the same as in form_of_t().&lt;br /&gt;
]=]--&lt;br /&gt;
function export.tagged_form_of_t(frame)&lt;br /&gt;
	local iparams = {&lt;br /&gt;
		[1] = {list = true, required = true},&lt;br /&gt;
		[&amp;quot;split_tags&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;term_param&amp;quot;] = {type = &amp;quot;number&amp;quot;},&lt;br /&gt;
		[&amp;quot;lang&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;sc&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;ignore&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;def&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;withcap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;withdot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;nolink&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;linktext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;posttext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;noprimaryentrycat&amp;quot;] = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local iargs = m_params.process(frame.args, iparams, nil, &amp;quot;form of/templates&amp;quot;, &amp;quot;tagged_form_of_t&amp;quot;)&lt;br /&gt;
	local parent_args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
	local term_param = iargs[&amp;quot;term_param&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
	local compat = iargs[&amp;quot;lang&amp;quot;] or parent_args[&amp;quot;lang&amp;quot;]&lt;br /&gt;
	term_param = term_param or compat and 1 or 2&lt;br /&gt;
&lt;br /&gt;
	local params = {&lt;br /&gt;
		-- Numbered params&lt;br /&gt;
		[compat and &amp;quot;lang&amp;quot; or 1] = {required = not iargs[&amp;quot;lang&amp;quot;]},&lt;br /&gt;
&lt;br /&gt;
		-- Named params not controlling link display&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		-- Always included because lang-specific categories may be added&lt;br /&gt;
		[&amp;quot;nocat&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;p&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;POS&amp;quot;] = {alias_of = &amp;quot;p&amp;quot;},&lt;br /&gt;
		[&amp;quot;notext&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;sort&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;enclitic&amp;quot;] = {},&lt;br /&gt;
		-- FIXME! The following should only be available when withcap=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nocap= in other circumstances.&lt;br /&gt;
		[&amp;quot;nocap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		-- FIXME! The following should only be available when withdot=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nodot= in other circumstances.&lt;br /&gt;
		[&amp;quot;nodot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;pagename&amp;quot;] = {}, -- for testing, etc.&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local base_lemma_params&lt;br /&gt;
	if not iargs[&amp;quot;nolink&amp;quot;] and not iargs[&amp;quot;linktext&amp;quot;] then&lt;br /&gt;
		add_link_params(parent_args, params, term_param)&lt;br /&gt;
		base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ignored_params = {}&lt;br /&gt;
&lt;br /&gt;
	if iargs[&amp;quot;withdot&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;dot&amp;quot;] = {}&lt;br /&gt;
	else&lt;br /&gt;
		ignored_params[&amp;quot;nodot&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not iargs[&amp;quot;withcap&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;cap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;}&lt;br /&gt;
		ignored_params[&amp;quot;nocap&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local args = process_parent_args(&amp;quot;tagged-form-of-t&amp;quot;, parent_args,&lt;br /&gt;
		params, iargs[&amp;quot;def&amp;quot;], iargs[&amp;quot;ignore&amp;quot;], ignored_params, &amp;quot;tagged_form_of_t&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	return construct_tagged_form_of_text(iargs, args, term_param, compat, base_lemma_params,&lt;br /&gt;
		split_inflection_tags(iargs[1], iargs[&amp;quot;split_tags&amp;quot;]))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Function that implements {{inflection of}} and certain semi-specific variants,&lt;br /&gt;
such as {{participle of}} and {{past participle form of}}. This function is&lt;br /&gt;
intended for templates that allow the user to specify a set of inflection tags.&lt;br /&gt;
It works similarly to form_of_t() and tagged_form_of_t() except that the&lt;br /&gt;
calling convention for the calling template is&lt;br /&gt;
	{{TEMPLATE|LANG|MAIN_ENTRY_LINK|MAIN_ENTRY_DISPLAY_TEXT|TAG|TAG|...}}&lt;br /&gt;
instead of &lt;br /&gt;
	{{TEMPLATE|LANG|MAIN_ENTRY_LINK|MAIN_ENTRY_DISPLAY_TEXT|GLOSS}}&lt;br /&gt;
Note that there isn&amp;#039;t a numbered parameter for the gloss, but it can still&lt;br /&gt;
be specified using t= or gloss=.&lt;br /&gt;
&lt;br /&gt;
Invocation params:&lt;br /&gt;
&lt;br /&gt;
preinfl=, preinfl2=, ...:&lt;br /&gt;
	Extra inflection tags to automatically prepend to the tags specified by&lt;br /&gt;
	the template.&lt;br /&gt;
postinfl=, postinfl2=, ...:&lt;br /&gt;
	Extra inflection tags to automatically append to the tags specified by the&lt;br /&gt;
	template. Used for example by {{past participle form of}} to add the tags&lt;br /&gt;
	&amp;#039;of the|past|p&amp;#039; onto the user-specified tags, which indicate which past&lt;br /&gt;
	participle form the page refers to.&lt;br /&gt;
split_tags=:&lt;br /&gt;
	If specified, character to split specified inflection tags on. This allows&lt;br /&gt;
	multiple tags to be included in a single argument, simplifying template&lt;br /&gt;
	code. Note that this applies *ONLY* to inflection tags specified in the&lt;br /&gt;
	invocation arguments using preinfl= or postinfl=, not to user-specified&lt;br /&gt;
	inflection tags.&lt;br /&gt;
term_param=:&lt;br /&gt;
lang=:&lt;br /&gt;
sc=:&lt;br /&gt;
cat=, cat2=, ...:&lt;br /&gt;
ignore=, ignore2=, ...:&lt;br /&gt;
def=, def2=, ...:&lt;br /&gt;
withcap=:&lt;br /&gt;
withdot=:&lt;br /&gt;
nolink=:&lt;br /&gt;
linktext=:&lt;br /&gt;
posttext=:&lt;br /&gt;
noprimaryentrycat=:&lt;br /&gt;
	All of these are the same as in form_of_t().&lt;br /&gt;
]=]--&lt;br /&gt;
function export.inflection_of_t(frame)&lt;br /&gt;
	local iparams = {&lt;br /&gt;
		[&amp;quot;preinfl&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;postinfl&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;split_tags&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;term_param&amp;quot;] = {type = &amp;quot;number&amp;quot;},&lt;br /&gt;
		[&amp;quot;lang&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;sc&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;ignore&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;def&amp;quot;] = {list = true},&lt;br /&gt;
		[&amp;quot;withcap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;withdot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;nolink&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;linktext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;posttext&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;noprimaryentrycat&amp;quot;] = {},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local iargs = m_params.process(frame.args, iparams, nil, &amp;quot;form of/templates&amp;quot;, &amp;quot;inflection_of_t&amp;quot;)&lt;br /&gt;
	local parent_args = frame:getParent().args&lt;br /&gt;
&lt;br /&gt;
	local term_param = iargs[&amp;quot;term_param&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
	local compat = iargs[&amp;quot;lang&amp;quot;] or parent_args[&amp;quot;lang&amp;quot;]&lt;br /&gt;
	term_param = term_param or compat and 1 or 2&lt;br /&gt;
	local tagsind = term_param + 2&lt;br /&gt;
&lt;br /&gt;
	local params = {&lt;br /&gt;
		-- Numbered params&lt;br /&gt;
		[compat and &amp;quot;lang&amp;quot; or 1] = {required = not iargs[&amp;quot;lang&amp;quot;]},&lt;br /&gt;
		[tagsind] = {list = true,&lt;br /&gt;
			-- at least one inflection tag is required unless preinfl or&lt;br /&gt;
			-- postinfl tags are given&lt;br /&gt;
			required = #iargs[&amp;quot;preinfl&amp;quot;] == 0 and #iargs[&amp;quot;postinfl&amp;quot;] == 0},&lt;br /&gt;
&lt;br /&gt;
		-- Named params not controlling link display&lt;br /&gt;
		[&amp;quot;cat&amp;quot;] = {list = true},&lt;br /&gt;
		-- Always included because lang-specific categories may be added&lt;br /&gt;
		[&amp;quot;nocat&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;p&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;POS&amp;quot;] = {alias_of = &amp;quot;p&amp;quot;},&lt;br /&gt;
		[&amp;quot;notext&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		[&amp;quot;enclitic&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;sort&amp;quot;] = {},&lt;br /&gt;
		-- FIXME! The following should only be available when withcap=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nocap= in other circumstances.&lt;br /&gt;
		[&amp;quot;nocap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		-- FIXME! The following should only be available when withdot=1 in&lt;br /&gt;
		-- invocation args. Before doing that, need to remove all uses of&lt;br /&gt;
		-- nodot= in other circumstances.&lt;br /&gt;
		[&amp;quot;nodot&amp;quot;] = {type = &amp;quot;boolean&amp;quot;},&lt;br /&gt;
		-- Temporary, allows multipart joiner to be controlled on a template-by-template&lt;br /&gt;
		-- basis&lt;br /&gt;
		[&amp;quot;joiner&amp;quot;] = {},&lt;br /&gt;
		[&amp;quot;pagename&amp;quot;] = {}, -- for testing, etc.&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local base_lemma_params&lt;br /&gt;
	if not iargs[&amp;quot;nolink&amp;quot;] and not iargs[&amp;quot;linktext&amp;quot;] then&lt;br /&gt;
		add_link_params(parent_args, params, term_param, &amp;quot;no-numbered-gloss&amp;quot;)&lt;br /&gt;
		base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ignored_params = {}&lt;br /&gt;
&lt;br /&gt;
	if iargs[&amp;quot;withdot&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;dot&amp;quot;] = {}&lt;br /&gt;
	else&lt;br /&gt;
		ignored_params[&amp;quot;nodot&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not iargs[&amp;quot;withcap&amp;quot;] then&lt;br /&gt;
		params[&amp;quot;cap&amp;quot;] = {type = &amp;quot;boolean&amp;quot;}&lt;br /&gt;
		ignored_params[&amp;quot;nocap&amp;quot;] = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local args = process_parent_args(&amp;quot;inflection-of-t&amp;quot;, parent_args,&lt;br /&gt;
		params, iargs[&amp;quot;def&amp;quot;], iargs[&amp;quot;ignore&amp;quot;], ignored_params, &amp;quot;inflection_of_t&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	local infls&lt;br /&gt;
	if not next(iargs[&amp;quot;preinfl&amp;quot;]) and not next(iargs[&amp;quot;postinfl&amp;quot;]) then&lt;br /&gt;
		-- If no preinfl or postinfl tags, just use the user-specified tags directly.&lt;br /&gt;
		infls = args[tagsind]&lt;br /&gt;
	else&lt;br /&gt;
		-- Otherwise, we need to prepend the preinfl tags and postpend the postinfl tags. If there&amp;#039;s only one tag set&lt;br /&gt;
		-- (no semicolon), it&amp;#039;s easier. Since this is common, we optimize for it.&lt;br /&gt;
		infls = {}&lt;br /&gt;
		local saw_semicolon = false&lt;br /&gt;
		for _, infl in ipairs(args[tagsind]) do&lt;br /&gt;
			if infl == &amp;quot;;&amp;quot; then&lt;br /&gt;
				saw_semicolon = true&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local split_preinfl = split_inflection_tags(iargs[&amp;quot;preinfl&amp;quot;], iargs[&amp;quot;split_tags&amp;quot;])&lt;br /&gt;
		local split_postinfl = split_inflection_tags(iargs[&amp;quot;postinfl&amp;quot;], iargs[&amp;quot;split_tags&amp;quot;])&lt;br /&gt;
		if not saw_semicolon then&lt;br /&gt;
			extend_list(infls, split_preinfl)&lt;br /&gt;
			extend_list(infls, args[tagsind])&lt;br /&gt;
			extend_list(infls, split_postinfl)&lt;br /&gt;
		else&lt;br /&gt;
			local groups = m_form_of.split_tags_into_tag_sets(args[tagsind])&lt;br /&gt;
			for _, group in ipairs(groups) do&lt;br /&gt;
				if #infls &amp;gt; 0 then&lt;br /&gt;
					table.insert(infls, &amp;quot;;&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
				extend_list(infls, split_preinfl)&lt;br /&gt;
				extend_list(infls, group)&lt;br /&gt;
				extend_list(infls, split_postinfl)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return construct_tagged_form_of_text(iargs, args, term_param, compat, base_lemma_params, infls,&lt;br /&gt;
		parent_args[&amp;quot;joiner&amp;quot;])&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Normalize a part-of-speech tag given a possible abbreviation&lt;br /&gt;
(passed in as 1= of the invocation args). If the abbreviation&lt;br /&gt;
isn&amp;#039;t recognized, the original POS tag is returned. If no POS&lt;br /&gt;
tag is passed in, return the value of invocation arg default=.&lt;br /&gt;
]=]--&lt;br /&gt;
function export.normalize_pos(frame)&lt;br /&gt;
	local iparams = {&lt;br /&gt;
		[1] = {},&lt;br /&gt;
		[&amp;quot;default&amp;quot;] = {},&lt;br /&gt;
	}&lt;br /&gt;
	local iargs = m_params.process(frame.args, iparams, nil, &amp;quot;form of/templates&amp;quot;, &amp;quot;normalize_pos&amp;quot;)&lt;br /&gt;
	if not iargs[1] and not iargs[&amp;quot;default&amp;quot;] then&lt;br /&gt;
		error(&amp;quot;Either 1= or default= must be given in the invocation args&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if not iargs[1] then&lt;br /&gt;
		return iargs[&amp;quot;default&amp;quot;]&lt;br /&gt;
	end&lt;br /&gt;
	return mw.loadData(m_form_of.form_of_pos_module)[iargs[1]] or iargs[1]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>bob&gt;Juelos</name></author>
	</entry>
</feed>