Module:translations/multi

From Wiktionary, the free dictionary
Jump to navigation Jump to search


--[=[
	This module implements the {{multitrans}} template.
	
	Original author: Benwing2, based on an idea from Rua.
	Significantly reworked by Theknightwho.
	
	The idea is to reduce the memory usage of large translation tables by
	computing the whole table at once instead of through several separate calls.
	The entire text of the translation table should be passed as follows:
	
	{{multitrans|data=
* Abkhaz: {{tt|ab|аиқәаҵәа}}
* Acehnese: {{tt|ace|itam}}
* Afrikaans: {{tt+|af|swart}}
* Albanian: {{tt+|sq|zi}}
* Amharic: {{tt|am|ጥቁር}}
* Arabic: {{tt+|ar|أَسْوَد|m}}, {{tt|ar|سَوْدَاء|f}}, {{tt|ar|سُود|p}}
*: Moroccan Arabic: {{tt|ary|كحال|tr=kḥāl}}
* Armenian: {{tt|hy|սև}}
* Aromanian: {{tt|rup|negru}}, {{tt+|rup|laiu}}
* Asháninka: {{tt|cni|cheenkari}}, {{tt|cni|kisaari}}
* Assamese: {{tt|as|ক‌’লা}}, {{tt|as|কুলা}} {{qualifier|Central}}
* Asturian: {{tt|ast|ñegru}}, {{tt|ast|negru}}, {{tt|ast|prietu}}
* Atikamekw: {{tt|atj|makatewaw}}
* Avar: {{tt|av|чӏегӏера}}
* Aymara: {{tt|ay|ch’iyara}}
* Azerbaijani: {{tt+|az|qara}}
	[etc.]
	}}
	
	That is, take the original text and add a 't' to the beginning of translation
	templates:
		{{t|...}} -> {{tt|...}}
		{{t+|...}} -> {{tt+|...}}
		{{t-check|...}} -> {{tt-check|...}}
		{{t+check|...}} -> {{tt+check|...}}
		
	The {{tt*|...}} templates are pass-throughs, so that e.g.
	{{tt|ary|كحال|tr=kḥāl}} generates the literal text "{{t|ary|كحال|tr=kḥāl}}".
	This is then parsed by the template parser to extract the arguments, which
	are then passed into the same code that underlyingly implements the regular
	translation templates. Because all of this happens inside a single module
	invocation instead of lots of separate ones, it's much faster and more
	memory-efficient.
]=]

local export = {}

local m_template_parser = require("Module:template parser")

local class_else_type = m_template_parser.class_else_type
local get_lang = require("Module:languages").getByCode
local get_script = require("Module:scripts").getByCode
local parse = m_template_parser.parse
local pcall = pcall
local show_terminfo = require("Module:translations").show_terminfo
local split = require("Module:string utilities").split

local templates = {
	["t"] = true,
	["t+"] = true,
	["t-check"] = true,
	["t+check"] = true,
}

local function process_template(node, name)
	-- The expanded templates have already culled unspecified/blank
	-- parameters and trimmed those which are present. Parameters 3+
	-- have been converted into a gap-tolerant comma-separated list
	-- at parameter 3, which matches [[Module:translations]].
	-- Parameter 1 is an exception, because [[Module:languages]]
	-- expects an empty string if it's blank.
	local args = node:get_arguments()
	local sc = args.sc
	local genders = args[3]
	return show_terminfo({
		lang = get_lang(args[1], 1, true),
		sc = sc ~= nil and get_script(sc, "sc") or nil,
		track_sc = true,
		term = args[2],
		alt = args["alt"],
		id = args["id"],
		genders = genders and split(genders, ",", true, true) or {},
		tr = args["tr"],
		ts = args["ts"],
		lit = args["lit"],
		interwiki = (name == "t+" or name == "t+check") and "tpos",
	}, name == "t-check" or name == "t+check")
end

function export.show(frame)
	local text = frame:getParent().args["data"]
	if not text then
		return ""
	end
	
	text = parse(frame:getParent().args["data"])
	for node, parent, key in text:__pairs("next_node") do
		local class = class_else_type(node)
		if class ~= "wikitext" then
			local new
			if class == "template" then
				local name = node:get_name()
				if templates[name] then
					local success, result = pcall(process_template, node, name)
					if success then
						new = result
					end
				end
			end
			if not new then
				new = node:preprocess()
			end
			if parent then
				parent[key] = new
			else
				text = new
			end
		end
	end
	return tostring(text)
end

return export