Jump to content

Module:Vi-pron

Frae Wikipedia, the free beuk o knawledge
local export = {}
local gsub = mw.ustring.gsub
local sub = mw.ustring.sub
local match = mw.ustring.match
--àằầèềìòồờùừỳ áắấéếíóốớúứý ảẳẩẻểỉỏổởủửỷ ãẵẫẽễĩõỗỡũữỹ ạặậẹệịọộợụựỵ
local tone_diacritics = { ["̀"] = 2, ["́"] = 3, ["̉"] = 4, ["̃"] = 5, ["̣"] = 6 }

local tone_contour = {
	["hn"] = { [1] = "˧˧", [2] = "˨˩", ["3a"] = "˧˦", [3] = "˧˦", [4] = "˧˩", [5] = "˦ˀ˥", [6] = "˧˨ʔ" },
	["hue"] = { [1] = "˧˧", [2] = "˦˩", ["3a"] = "˦˧˥", [3] = "˨˩˦", [4] = "˧˨", [5] = "˧˨", [6] = "˨˩ʔ" },
	["hcmc"] = { [1] = "˧˧", [2] = "˨˩", ["3a"] = "˦˥", [3] = "˦˥", [4] = "˨˩˦", [5] = "˨˩˦", [6] = "˨˩˨" },
}

local initial_ipa = {
	["b"] = { "ʔɓ", "ʔɓ", "ʔɓ" },
	["c"] = { "k", "k", "k" },
	["ch"] = { "t͡ɕ", "t͡ɕ", "c" },
	["d"] = { "z", "j", "j" },
	["đ"] = { "ʔɗ", "ʔɗ", "ʔɗ" },
	["g"] = { "ɣ", "ɣ", "ɣ" },
	["gh"] = { "ɣ", "ɣ", "ɣ" },
	["gi"] = { "z", "j", "j" },
	["gy"] = { "z", "j", "j" },
	["h"] = { "h", "h", "h" },
	["k"] = { "k", "k", "k" },
	["kh"] = { "x", "kʰ", "kʰ" },
	["l"] = { "l", "l", "l" },
	["m"] = { "m", "m", "m" },
	["n"] = { "n", "n", "n" },
	["ng"] = { "ŋ", "ŋ", "ŋ" },
	["ngh"] = { "ŋ", "ŋ", "ŋ" },
	["nh"] = { "ɲ", "ɲ", "ɲ" },
	["p"] = { "p", "p", "p" }, -- foreign
	["ph"] = { "f", "f", "f" },
	["q"] = { "k", "k", "k" },
	["qu"] = { "kw", "kw", "w" },
	["r"] = { "z", "ʐ", "ɹ" },
	["ŕ"] = { "ɹ", "ɹ", "ɹ" },
	["s"] = { "s", "ʂ", "ʂ" },
	["t"] = { "t", "t", "t" },
	["th"] = { "tʰ", "tʰ", "tʰ" },
	["tr"] = { "t͡ɕ", "ʈ", "ʈ" },
	["v"] = { "v", "v", "v" },
	["x"] = { "s", "s", "s" },
	["z"] = { "z", "z", "z" },
	[""] = { "ʔ", "ʔ", "ʔ" },
	["-"] = { "", "", "" },
}

local mvi_initial_ipa = {
	["ꞗ"] = "β", ["Ꞗ"] = "β",
	["b"] = "ɓ",
	["c"] = "k", ["ch"] = "c",
	["d"] = "ð", ["đ"] = "ɗ",
	["g"] = "ɣ", ["gh"] = "ɣ", ["gi"] = "ʝ",
	["h"] = "h",
	["k"] = "k", ["kh"] = "kʰ",
	["l"] = "l",
	["m"] = "m",
	["n"] = "n", ["ng"] = "ŋ", ["ngh"] = "ŋ", ["nh"] = "ɲ",
	["p"] = "p", ["ph"] = "pʰ",
	["r"] = "ɹ",
	["s"] = "ʂ",
	["t"] = "t", ["th"] = "tʰ", ["tr"] = "ʈ",
	["v"] = "w",
	["x"] = "ɕ",
}

local final_ipa = {
	["a"] = { "aː", "aː", "aː" },
	["ac"] = { "aːk̚", "aːk̚", "aːk̚" },
	["ach"] = { "ajk̟̚", "at̚", "at̚" },
	["ai"] = { "aːj", "aːj", "aːj" },
	["am"] = { "aːm", "aːm", "aːm" },
	["an"] = { "aːn", "aːŋ", "aːŋ" },
	["ań"] = { "aːn", "aːn", "aːn" },
	["ang"] = { "aːŋ", "aːŋ", "aːŋ" },
	["anh"] = { "ajŋ̟", "ɛɲ", "an" },
	["ao"] = { "aːw", "aːw", "aːw" },
	["ao᷄"] = { "awŋ͡m", "", "" },
	["ap"] = { "aːp̚", "aːp̚", "aːp̚" },
	["at"] = { "aːt̚", "aːk̚", "aːk̚" },
	["au"] = { "aw", "aw", "aw" },
	["ay"] = { "aj", "aj", "aj" },
	["ăc"] = { "ak̚", "ak̚", "ak̚" },
	["ăm"] = { "am", "am", "am" },
	["ăn"] = { "an", "aŋ", "aŋ" },
	["ăng"] = { "aŋ", "aŋ", "aŋ" },
	["ăp"] = { "ap̚", "ap̚", "ap̚" },
	["ăt"] = { "at̚", "ak̚", "ak̚" },
	["â"] = { "ə", "ə", "ə" },
	["âc"] = { "ək̚", "ək̚", "ək̚" },
	["âm"] = { "əm", "əm", "əm" },
	["ân"] = { "ən", "əŋ", "əŋ" },
	["âng"] = { "əŋ", "əŋ", "əŋ" },
	["âp"] = { "əp̚", "əp̚", "əp̚" },
	["ât"] = { "ət̚", "ək̚", "ək̚" },
	["âu"] = { "əw", "əw", "əw" },
	["ây"] = { "əj", "əj", "əj" },
	["e"] = { "ɛ", "ɛ", "ɛ" },
	["ec"] = { "ɛk̚", "ɛk̚", "ɛk̚" },
	["em"] = { "ɛm", "ɛm", "ɛm" },
	["en"] = { "ɛn", "ɛŋ", "ɛŋ" },
	["eń"] = { "ɛn", "ɛn", "ɛn" },
	["eng"] = { "ɛŋ", "ɛŋ", "ɛŋ" },
	["eo"] = { "ɛw", "ɛw", "ɛw" },
	["ep"] = { "ɛp̚", "ɛp̚", "ɛp̚" },
	["et"] = { "ɛt̚", "ɛt̚", "ɛk̚" },
	["ê"] = { "e", "ej", "ej" },
	["êc"] = { "ek̚", "ek̚", "ek̚" },
	["êch"] = { "əjk̟̚", "et̚", "əːt̚" },
	["êm"] = { "em", "em", "em" },
	["ên"] = { "en", "en", "əːn" },
	["êng"] = { "eŋ", "eŋ", "eŋ" },
	["ênh"] = { "əjŋ̟", "en", "əːn" },
	["êp"] = { "ep̚", "ep̚", "ep̚" },
	["êt"] = { "et̚", "et̚", "əːt̚" },
	["êu"] = { "ew", "ew", "ew" },
	["i"] = { "i", "ɪj", "ɪj" },
	["ia"] = { "iə", "iə", "iə" },
	["ic"] = { "ïk̟̚", "ïk̟̚", "ïk̟̚" },
	["ich"] = { "ïk̟̚", "ɨt̚", "ɨt̚" },
	["iêc"] = { "iək̚", "iək̚", "iək̚" },
	["iêm"] = { "iəm", "iəm", "im" },
	["iên"] = { "iən", "iəŋ", "iəŋ" },
	["iêng"] = { "iəŋ", "iəŋ", "iəŋ" },
	["iêp"] = { "iəp̚", "iəp̚", "ip̚" },
	["iêt"] = { "iət̚", "iək̚", "iək̚" },
	["iêu"] = { "iəw", "iw", "iw" },
	["im"] = { "im", "im", "im" },
	["in"] = { "in", "in", "ɨn" },
	["inh"] = { "ïŋ", "ɨn", "ɨn" },
	["ip"] = { "ip̚", "ip̚", "ip̚" },
	["it"] = { "it̚", "it̚", "ɨt̚" },
	["iu"] = { "iw", "iw", "iw" },
	["o"] = { "ɔ", "ɔ", "ɔ" },
	["oa"] = { "waː", "waː", "waː" },
	["oac"] = { "waːk̚", "waːk̚", "waːk̚" },
	["oach"] = { "wajk̟̚", "wat̚", "wat̚" },
	["oai"] = { "waːj", "waːj", "waːj" },
	["oam"] = { "waːm", "waːm", "waːm" },
	["oan"] = { "waːn", "waːŋ", "waːŋ" },
	["oang"] = { "waːŋ", "waːŋ", "waːŋ" },
	["oanh"] = { "wajŋ̟", "wɛɲ", "wan" },
	["oao"] = { "waːw", "waːw", "waːw" },
	["oap"] = { "waːp̚", "waːp̚", "waːp̚" },
	["oat"] = { "waːt̚", "waːk̚", "waːk̚" },
	["oay"] = { "waj", "waj", "waj" },
	["oă"] = { "wa", "wa", "wa" },
	["oăc"] = { "wak̚", "wak̚", "wak̚" },
	["oăm"] = { "wam", "wam", "wam" },
	["oăn"] = { "wan", "waŋ", "waŋ" },
	["oăng"] = { "waŋ", "waŋ", "waŋ" },
	["oăt"] = { "wat̚", "wak̚", "wak̚" },
	["oc"] = { "awk͡p̚", "awk͡p̚", "awk͡p̚" },
	["oe"] = { "wɛ", "wɛ", "wɛ" },
	["oem"] = { "wɛm", "wɛm", "wɛm" },
	["oen"] = { "wɛn", "wɛŋ", "wɛŋ" },
	["oeo"] = { "wɛw", "wɛw", "wɛw" },
	["oet"] = { "wɛt̚", "wɛk̚", "wɛk̚" },
	["oi"] = { "ɔj", "ɔj", "ɔj" },
	["om"] = { "ɔm", "ɔm", "ɔm" },
	["on"] = { "ɔn", "ɔŋ", "ɔŋ" },
	["ong"] = { "awŋ͡m", "awŋ͡m", "awŋ͡m" },
	["ooc"] = { "ɔk̚", "ɔk̚", "ɔk̚" },
	["oong"] = { "ɔŋ", "ɔŋ͡m", "ɔŋ" },
	["op"] = { "ɔp̚", "ɔp̚", "ɔp̚" },
	["ot"] = { "ɔt̚", "ɔk̚", "ɔk̚" },
	["ô"] = { "o", "ow", "ow" },
	["ôc"] = { "əwk͡p̚", "əwk͡p̚", "əwk͡p̚" },
	["ôi"] = { "oj", "oj", "oj" },
	["ôm"] = { "om", "om", "om" },
	["ôn"] = { "on", "oŋ", "oŋ" },
	["ôń"] = { "on", "on", "on" },
	["ông"] = { "əwŋ͡m", "əwŋ͡m", "əwŋ͡m" },
	["ôôc"] = { "ok̚", "ok̚", "ok̚" },
	["ôông"] = { "oŋ", "oŋ", "oŋ" },
	["ôp"] = { "op̚", "op̚", "op̚" },
	["ôt"] = { "ot̚", "ok̚", "ok̚" },
	["ơ"] = { "əː", "əː", "əː" },
	["ơi"] = { "əːj", "əːj", "əːj" },
	["ơm"] = { "əːm", "əːm", "əːm" },
	["ơn"] = { "əːn", "əːŋ", "əːŋ" },
	["ơng"] = { "əːŋ", "əːŋ", "əːŋ" },
	["ơp"] = { "əːp̚", "əːp̚", "əːp̚" },
	["ơt"] = { "əːt̚", "əːk̚", "əːk̚" },
	["u"] = { "u", "ʊw", "ʊw" },
	["ua"] = { "uə", "uə", "uə" },
	["uac"] = { "waːk̚", "waːk̚", "waːk̚" },
	["uach"] = { "wajk̟̚", "wat̚", "wat̚" },
	["uai"] = { "waːj", "waːj", "waːj" },
	["uan"] = { "waːn", "waːŋ", "waːŋ" },
	["uang"] = { "waːŋ", "waːŋ", "waːŋ" },
	["uanh"] = { "wajŋ̟", "wɛɲ", "wan" },
	["uao"] = { "waːw", "waːw", "waːw" },
	["uat"] = { "waːt̚", "waːk̚", "waːk̚" },
	["uau"] = { "waw", "waw", "wa(ː)w" },
	["uay"] = { "waj", "waj", "waj" },
	["uă"] = { "wa", "wa", "wa" },
	["uăc"] = { "wak̚", "wak̚", "wak̚" },
	["uăm"] = { "wam", "wam", "wam" },
	["uăn"] = { "wan", "waŋ", "waŋ" },
	["uăng"] = { "waŋ", "waŋ", "waŋ" },
	["uăp"] = { "wap̚", "wap̚", "wap̚" },
	["uăt"] = { "wat̚", "wak̚", "wak̚" },
	["uâ"] = { "wə", "wə", "wə" },
	["uâc"] = { "wək̚", "wək̚", "wək̚" },
	["uân"] = { "wən", "wəŋ", "wəŋ" },
	["uâng"] = { "wəŋ", "wəŋ", "wəŋ" },
	["uât"] = { "wət̚", "wək̚", "wək̚" },
	["uây"] = { "wəj", "wəj", "wəj" },
	["uc"] = { "ʊwk͡p̚", "ʊwk͡p̚", "ʊwk͡p̚" },
	["ue"] = { "wɛ", "wɛ", "wɛ" },
	["uen"] = { "wɛn", "wɛŋ", "wɛŋ" },
	["ueo"] = { "wɛw", "wɛw", "wɛw" },
	["uep"] = { "wɛp̚", "wɛp̚", "wɛp̚" },
	["uet"] = { "wɛt̚", "wɛt̚", "wɛt̚" },
	["uê"] = { "we", "wej", "wej" },
	["uêch"] = { "wəjk̟̚", "wet̚", "wəːt̚" },
	["uên"] = { "wen", "wen", "wəːn" },
	["uênh"] = { "wəjŋ̟", "wen", "wəːn" },
	["uêt"] = { "wet̚", "wet̚", "wəːt̚" },
	["uêu"] = { "weu", "weu", "wew" },
	["ui"] = { "uj", "uj", "uj" },
	["uin"] = { "win", "win", "wɨn" },
	["uit"] = { "wit̚", "wit̚", "wit̚" },
	["um"] = { "um", "um", "ʊm" },
	["un"] = { "un", "un", "ʊwŋ͡m" },
	["ung"] = { "ʊwŋ͡m", "ʊwŋ͡m", "ʊwŋ͡m" },
	["unh"] = { "ujŋ̟", "un", "uwn" },
	["uô"] = { "uə", "uə", "uə" }, 
	["uôc"] = { "uək̚", "uək̚", "uək̚" },
	["uôi"] = { "uəj", "uj", "uj" },
	["uôm"] = { "uəm", "uəm", "uəm" },
	["uôn"] = { "uən", "uəŋ", "uəŋ" },
	["uông"] = { "uəŋ", "uəŋ", "uəŋ" },
	["uôt"] = { "uət̚", "uək̚", "uək̚" },
	["uơ"] = { "wəː", "wəː", "wəː" },
	["uơi"] = { "wəːj", "wəːj", "wəːj" },
	["uơn"] = { "uən", "wəŋ", "wəŋ" },
	["uơt"] = { "uət̚", "wək̚", "wək̚" },
	["up"] = { "up̚", "up̚", "ʊp̚" },
	["ut"] = { "ut̚", "ʊk̚", "ʊk͡p̚" },
	["uy"] = { "wi", "wɪj", "wɪj" },
	["uya"] = { "wiə", "wiə", "wiə" },
	["uych"] = { "wïk̟̚", "wɨk̟̚", "wɨt̚" },
	["uyn"] = { "win", "win", "wɨn" },
	["uich"] = { "wïk̟̚", "wɨk̟̚", "wɨt̚" },
	["uyê"] = { "wiə", "wiə", "wiə" },
	["uyên"] = { "wiən", "wiəŋ", "wiəŋ" },
	["uyênh"] = { "wiəŋ̟", "wiən", "wən" },
	["uyêt"] = { "wiət̚", "wiək̚", "wiək̚" },
	["uynh"] = { "wïŋ̟", "wɨn", "wɨn" },
	["uyp"] = { "wip̚", "wip̚", "wip̚" },
	["uyt"] = { "wit̚", "wɨt̚", "wɨt̚" },
	["uyu"] = { "wiw", "wiw", "wiw" },
	["ư"] = { "ɨ", "ɨ", "ɨ" },
	["ưa"] = { "ɨə", "ɨə", "ɨə" },
	["ưc"] = { "ɨk̚", "ɨk̚", "ɨk̚" },
	["ưi"] = { "ɨj", "ɨj", "ɨj" },
	["ưm"] = { "ɨm", "ɨm", "ɨm" },
	["ưn"] = { "ɨn", "ɨŋ", "ɨŋ" },
	["ưng"] = { "ɨŋ", "ɨŋ", "ɨŋ" },
	["ươc"] = { "ɨək̚", "ɨək̚", "ɨək̚" },
	["ươi"] = { "ɨəj", "ɨj", "ɨj" },
	["ươm"] = { "ɨəm", "ɨəm", "ɨəm" },
	["ươn"] = { "ɨən", "ɨəŋ", "ɨəŋ" },
	["ương"] = { "ɨəŋ", "ɨəŋ", "ɨəŋ" },
	["ươp"] = { "ɨəp̚", "ɨəp̚", "ɨəp̚" },
	["ươt"] = { "ɨət̚", "ɨək̚", "ɨək̚" },
	["ươu"] = { "iəw", "ɨəw", "ɨəw" },
	["ưt"] = { "ɨt̚", "ɨk̚", "ɨk̚" },
	["ưu"] = { "iw", "ɨw", "ɨw" },
	["y"] = { "i", "ɪj", "ɪj" },
	["yêc"] = { "iək̚", "iək̚", "iək̚" },
	["yêm"] = { "iəm", "iəm", "iəm" },
	["yên"] = { "iən", "iəŋ", "iəŋ" },
	["yêng"] = { "iəŋ", "iəŋ", "iəŋ" },
	["yêp"] = { "iəp̚", "iəp̚", "iəp̚" },
	["yêt"] = { "iət̚", "iək̚", "iək̚" },
	["yêu"] = { "iəw", "iw", "iw" },
}

local varieties = { 
	["hn"] = { "Hà Nội", 1 },
	["hue"] = { "Huế", 2 },
	["hcmc"] = { "Hồ Chí Minh City", 3 },
}

local hcmc_opt_w = {
	["ch"] = true,
	["d"] = true,
	["l"] = true,
	["s"] = true,
	["t"] = true, ["th"] = true, ["tr"] = true,
	["x"] = true,
}

local variations = {
	["hn"] = { { "^ɹ", "z" }, { " ɹ", " z" } },
	["hue"] = { { "z", "j" } },
	["hcmc"] = { { "ʂ", "s" }, { "v", "j" }, { "kʰ", "x" }, { "z", "j" } },
}

function export.ipa(frame)
	local p, output = {}, { ["hn"] = {}, ["hue"] = {}, ["hcmc"] = {} }
	local output_text = {}
	local pronunciations = { ["hn"] = {}, ["hue"] = {}, ["hcmc"] = {} }
	local pagename = gsub(gsub(mw.ustring.lower(mw.title.getCurrentTitle().subpageText), "%-", " "), "%,", "")
	local args = frame:getParent().args
	local mvi = frame.args["mvi"] or nil
	if args[1] then
		for index, item in ipairs(args) do
			table.insert(p, (item ~= "") and mw.ustring.lower(gsub(gsub(item, "%-", " "), "%,", "")) or nil)
		end
	else
		table.insert(p, pagename)
	end
	for variety, _ in ipairs(varieties) do
		table.insert(pronunciations[variety], (args[variety] ~= "") and args[variety] or nil)
	end
	for i, word in ipairs(p) do
		local pronunciations = { ["hn"] = {}, ["hue"] = {}, ["hcmc"] = {} }
		for syllable in mw.text.gsplit(word, " ", true) do
			local ipa = {}
			local initial, final, tone = nil, nil, nil, nil
			tone = 1
			syllable = mw.ustring.toNFD(syllable)
			syllable = gsub(syllable, "([nr]́)", mw.ustring.toNFC)
			
			for diac_pattern, tone_num in pairs(tone_diacritics) do
				if match(syllable, diac_pattern) then
					tone = tone_num
					break
				end
			end
			syllable = mw.ustring.toNFC(gsub(syllable, "[̣̀́̉̃]", ""))
			if syllable == "gi" or syllable == "gin" then
				syllable = gsub(syllable, "gi", "gii")
			end
			initial = match(syllable, "^g[ꞗꞖbcdđgklmnpqrŕstvx]+") or match(syllable, "^(g[hiy])[^cmnpt]")
				or match(syllable, "^g") or match(syllable, "^[ꞗꞖbcdđghklmnpqrŕstvxz]+") or ""
			initial = (match(syllable, "^giê.") and syllable ~= "giên") and "d" or initial
			initial = match(syllable, "qu$") and "qu" or initial
			final = sub(syllable, mw.ustring.len(initial) + 1, -1)
			for loc, location in pairs(varieties) do
				local ipa, seq, detoned = {}, location[2], ""
				if mvi then
					if mvi_initial_ipa[initial] then
						table.insert(ipa, mvi_initial_ipa[initial])
					else
						local initial_cluster = ""
						for cc in mw.ustring.gcodepoint(initial) do
							local ch = mw.ustring.char(cc)
							initial_cluster = initial_cluster .. mvi_initial_ipa[ch]
						end
						table.insert(ipa, initial_cluster)
					end
				elseif initial_ipa[initial] then
					table.insert(ipa, initial_ipa[initial][seq])
				else
					local initial_cluster = ""
					initial = gsub(initial, "r$", "ŕ")
					for cc in mw.ustring.gcodepoint(initial) do
						local ch = mw.ustring.char(cc)
						initial_cluster = initial_cluster .. initial_ipa[ch][seq]
					end
					initial_cluster = gsub(initial_cluster, "([cgknpt]h)", function(digraph)
						return initial_ipa[digraph][seq] end)
					table.insert(ipa, initial_cluster)
				end
				if final_ipa[final] then
					detoned = gsub(final_ipa[final][seq], "^([wu].+)", function(nucleus)
						if initial .. final == "qua" then
							nucleus = final_ipa["oa"][seq]
						elseif initial .. final == "qui" then
							nucleus = final_ipa["uy"][seq]
						end
						if loc == "hcmc" then
							if initial == "-" then
								nucleus = gsub(nucleus, "^u", "w")	
							end
							if hcmc_opt_w[initial] then
								nucleus = gsub(nucleus, "^w", "⁽ʷ⁾")
							end
						end
						return nucleus end)
					table.insert(ipa, detoned)
				else
					error(("Unrecognised final: \"%s\""):format(final))
				end
				if tone == 3 and match(final, "[chmngpt]") then
					tone = "3a"
				end
				table.insert(ipa, tone_contour[loc][tone])
				table.insert(pronunciations[loc], table.concat(ipa, ""))
			end
		end
		for loc, location in pairs(varieties) do
			table.insert(output[loc], table.concat(pronunciations[loc], " "))
		end
	end
	for loc, location in pairs(varieties) do
		if mvi then
			if loc == "hn" then
				location[1] = "Đông Kinh"
			end
			args["hue"], args["hcmc"] = "-", "-"
		end
		if args[loc] ~= "-" then
			if not args[loc] then
				args[loc] = table.concat(output[loc], "], [")
				local alternative = args[loc]
				for _, variation in ipairs(variations[loc]) do
					alternative = gsub(alternative, variation[1], variation[2])
				end
				if alternative ~= args[loc] then args[loc] = args[loc] .. "] ~ [" .. alternative end
			end
			if loc == "hcmc" then args[loc] = gsub(args[loc], "[hk]w", "w") args[loc] = gsub(args[loc], "ʔw", "(ʔ)w") end
			table.insert(output_text, location[2], "* (''[[" .. location[1] .. "|" .. location[1] .. "]]'') " .. 
				"[[Wiktionary:International Phonetic Alphabet|IPA]]<sup>([[Appendix:Vietnamese pronunciation|key]])</sup>: <span class=\"IPA\">[" ..
					args[loc] .. "]</span>")
		end
	end
	if table.concat(p, "") ~= mw.ustring.lower(pagename) then
		table.insert(output_text, #output_text + 1, "* ''Phonetic'': " .. gsub(table.concat(p, ", "), "ŕ", "R"))
	end
	return table.concat(output_text, "\n")
end

return export