Open main menu

Ideally, not to be invoked directly, but from Module:form of/templates instead. (But in practice it contains some functions meant to be invoked directly from templates. These should be moved to Module:form of/templates.)

This module is used by many templates, in particular the form-of templates.

The grammatical labels used by {{inflection of}} are found in Module:form of/data.

format_t

format_t(text, terminfo)

Innermost guts of the majority of the form-of templates. Most of the work however is done by form_of_t below. text is the text to display before the link, and terminfo is a table describing the link itself, exactly as for full_link in Module:links.

form_of_t

{{#invoke:form of|form_of_t}}

Template-callable implementation of the majority of the form-of templates. See also alt_form_of_t below. The invocation arguments are as follows:

|1= (required)
The form-of text to display before the link (e.g. alternative typography of).
|cat=, |cat2=, etc.
Categories to add the page to. Should omit the language name at the beginning, e.g. obsolete forms is a possible value, and e.g. if the language is English the page will be categorized into Category:English obsolete forms.
|lang=
If specified, this is a language-specific template for the specified language code, and the template doesn't take a language-code parameter.
|sc=
If specified, this is the script code for a language-specific template. Normally unnecessary.
|id=
If specified, this overrides the |id= template parameter. Normally unnecessary.
|ignore=, |ignore2=, etc.
Parameters to accept and silently ignore. This should be used for parameters interpreted by the template definition itself. For example, {{comparative of}} uses |ignore=POS as it uses the |POS= parameter to control categorization and doesn't want an error thrown if this parameter is specified.
|ignorelist=, |ignorelist2=, etc.
List parameters to accept and silently ignore. This should be used for parameters interpreted by the template definition itself. For example, {{alternative spelling of}} uses |ignore=from as it uses the |from=, |from2=, etc. parameters to specify region context labels, and doesn't want an error thrown if these parameters are specified.
|term_param=
Identity of first numbered param parsed by the code, containing the language code. Defaults to 1, and not clear if it's ever overridden.

alt_format_t

alt_format_t(text, terminfo)

Innermost guts of the alternative (full-sentence) form-of templates. Most of the work however is done by alt_form_of_t below. text is the text to display before the link, and terminfo is a table describing the link itself, exactly as for full_link in Module:links.

alt_form_of_t

{{#invoke:form of|alt_form_of_t}}

Template-callable implementation of the alternative (full-sentence) form-of templates. For historical reasons, there are two different types of form-of templates, those implemented by form_of_t which don't add a trailing period by default, and those implemented by form_of_t which do add a trailing period. The invocation arguments are as follows:

|text= (required)
The form-of text to display before the link (e.g. obsolete form of).
|cat=, |cat2=, etc.
Categories to add the page to. Should omit the language name at the beginning, e.g. obsolete forms is a possible value, and e.g. if the language is English the page will be categorized into Category:English obsolete forms.
|lang=
If specified, this is a language-specific template for the specified language code, and the template doesn't take a language-code parameter.
|sc=
If specified, this is the default script code for a language-specific template. Normally unnecessary.
|id=
If specified, this is the default for the |id= template parameter. Normally unnecessary.
|ignore=, |ignore2=, etc.
Parameters to accept and silently ignore. This should be used for parameters interpreted by the template definition itself.
|ignorelist=, |ignorelist2=, etc.
List parameters to accept and silently ignore. This should be used for parameters interpreted by the template definition itself.
|nodot=
If given, don't display a final period, and don't allow the |dot= or |nodot= parameters.
|nocap=
If given, don't display an initial capital letter, and don't allow the |nocap= parameter.

tagged_inflections

tagged_inflections(tags, terminfo)

Document me.

to_Wikidata_IDs

to_Wikidata_IDs(tags)

Document me.


local m_links = require("Module:links")
local m_table = require("Module:table")
local m_data = mw.loadData("Module:form of/data")

local rmatch = mw.ustring.match
local rsplit = mw.text.split

local export = {}

-- FIXME! Move to a utility module.

function export.ucfirst(text)
	local function doucfirst(text)
		-- Actual function to uppercase first letter.
		return mw.ustring.upper(mw.ustring.sub(text, 1, 1)) .. mw.ustring.sub(text, 2)
	end
	-- If there's a link at the beginning, uppercase the first letter of the
	-- link text. This pattern matches both piped and unpiped links.
	-- If the link is not piped, the second capture (linktext) will be empty.
	local link, linktext, remainder = rmatch(text, "^%[%[([^|%]]+)%|?(.-)%]%](.*)$")
	if link then
		return "[[" .. link .. "|" .. doucfirst(linktext ~= "" and linktext or link) .. "]]" .. remainder
	end
	return doucfirst(text)
end


function export.format_form_of(text, terminfo, posttext)
	local parts = {}
	table.insert(parts, "<span class='form-of-definition use-with-mention'>")
	table.insert(parts, text)
	if text ~= "" and terminfo then
		table.insert(parts, " ")
	end
	if terminfo then
		table.insert(parts, "<span class='form-of-definition-link'>")
		if type(terminfo) == "string" then
			table.insert(parts, terminfo)
		else
			table.insert(parts, m_links.full_link(terminfo, "term", false))
		end
		table.insert(parts, "</span>")
	end
	if posttext then
		table.insert(parts, posttext)
	end
	table.insert(parts, "</span>")
	return table.concat(parts)
end


local function normalize_tag(tag)
	if m_data.shortcuts[tag] then
	elseif m_data.tags[tag] then
	else
		require("Module:debug").track{
			"inflection of/unknown",
			"inflection of/unknown/" .. tag:gsub("%[", "("):gsub("%]", ")"):gsub("|", "!")
		}
	end

	tag = m_data.shortcuts[tag] or tag
	local data = m_data.tags[tag]

	-- If the tag has a special display form, use it
	if data and data.display then
		tag = data.display
	end

	-- If there is a nonempty glossary index, then show a link to it
	if data and data.glossary then
		tag = "[[Appendix:Glossary#" .. mw.uri.anchorEncode(data.glossary) .. "|" .. tag .. "]]"
	end
	return tag
end

function export.tagged_inflections(tags, terminfo, notext, capfirst, posttext)
	local cur_infl = {}
	local inflections = {}
	
	for i, tagspec in ipairs(tags) do
		if tagspec == ";" then
			if #cur_infl > 0 then
				table.insert(inflections, table.concat(cur_infl, " "))
			end
			
			cur_infl = {}
		else
			local split_tags = rsplit(tagspec, "//", true)
			if #split_tags == 1 then
				table.insert(cur_infl, normalize_tag(split_tags[1]))
			else
				local normalized_tags = {}
				for _, tag in ipairs(split_tags) do
					table.insert(normalized_tags, normalize_tag(tag))
				end
				table.insert(cur_infl, m_table.serialCommaJoin(normalized_tags))
			end
		end
	end
	
	if #cur_infl > 0 then
		table.insert(inflections, table.concat(cur_infl, " "))
	end
	
	if #inflections == 1 then
		return export.format_form_of(
			notext and "" or ((capfirst and export.ucfirst(inflections[1]) or inflections[1]) ..
				(terminfo and " of" or "")),
			terminfo, posttext
		)
	else
		local link = export.format_form_of(
			notext and "" or ((capfirst and "Inflection" or "inflection") ..
				(terminfo and " of" or "")),
			terminfo, (posttext or "") .. ":"
		)
		return link .."\n## <span class='form-of-definition use-with-mention'>" .. table.concat(inflections, "</span>\n## <span class='form-of-definition use-with-mention'>") .. "</span>"
	end
end

function export.to_Wikidata_IDs(tags)
	if type(tags) == "string" then
		tags = mw.text.split(tags, "|", true)
	end
	
	local ret = {}
	
	for i, tag in ipairs(tags) do
		if tag == ";" then
			error("Semicolon is not supported for Wikidata IDs")
		end
		
		tag = m_data.shortcuts[tag] or tag
		local data = m_data.tags[tag]
		
		if not data or not data.wikidata then
			error("The tag \"" .. tag .. "\" does not have a Wikidata ID defined in Module:form of/data")
		end
		
		table.insert(ret, data.wikidata)
	end
	
	return ret
end


return export

-- For Vim, so we get 4-space tabs
-- vim: set ts=4 sw=4 noet: