Module:cmn-pron

Hello, you have come here looking for the meaning of the word Module:cmn-pron. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:cmn-pron, but we will also tell you about its etymology, its characteristics and you will know how to say Module:cmn-pron in singular and plural. Everything you need to know about the word Module:cmn-pron you have here. The definition of the word Module:cmn-pron will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:cmn-pron, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

This module does work for Template:cmn-pron and Template:zh-pron.

Homophone data stored at Module:zh/data/cmn-hom.

Testcases

Module:cmn-pron/testcases


local export = {}
local m_str_utils = require("Module:string utilities")
local cmn = require("Module:languages").getByCode("cmn")

local find = m_str_utils.find
local gsub = m_str_utils.gsub
local len = m_str_utils.len
local match = m_str_utils.match
local gmatch = m_str_utils.gmatch
local sub = m_str_utils.sub
local split = m_str_utils.split
local gsplit = m_str_utils.gsplit
local lower = m_str_utils.lower
local upper = m_str_utils.upper
local format = string.format
local u = m_str_utils.char
local toNFD = mw.ustring.toNFD
local toNFC = mw.ustring.toNFC
local trim = mw.text.trim

local pua = {}
for i = 1, 7 do
	pua = u(0xF000+i-1)
end

local m_data = mw.loadData("Module:cmn-pron/data")
local m_zh = require("Module:zh")
local _m_zh_data = nil
local hom_data = nil

local function track(page)
	local tracking_page = "cmn-pron/" .. page
	require("Module:debug/track")(tracking_page)
	return true
end

local function hom_data_part(pinyin)
	local x = toNFD(pinyin):sub(1,1)
	if "a" <= x and x <= "g" then
		return 1
	elseif "h" <= x and x <= "m" then
		return 2
	elseif "n" <= x and x <= "w" then
		return 3
	end
	return 4
end

local function get_hom_data(py)
	if hom_data == nil then
		hom_data = require("Module:zh/data/cmn-hom/" .. hom_data_part(py))
	end
	return hom_data
end

-- if not empty
local function ine(var)
	if var == "" then
		return nil
	else
		return var
	end
end

local breve, hacek, circumflex = u(0x306), u(0x30C), u(0x302)
local function input_error(text)
	if type(text) ~= "string" then
		return
	end
	local subs, err = { = hacek,  = "h",  = "ng",  = "Ng"}
	text = toNFD(text)
	if find(text, breve) and (find(text, "" .. circumflex) or find(text, "")) then
		err = "a breve and an uncommon shorthand"
	elseif find(text, breve) then
		err = "a breve"
	elseif find(text, "" .. circumflex) or find(text, "") then
		err = "an uncommon shorthand"
	end
	if err then error('The pinyin text "' .. text .. '" contains ' .. err .. '. Replace it with "' .. gsub(text, ".", subs) .. '".', 2) end
end

local function m_zh_data()
	if _m_zh_data == nil then _m_zh_data = require("Module:zh/data/cmn-tag") end;
	return _m_zh_data;
end

function export.py_detone(text)
	return toNFC(gsub(toNFD(text), "", ""))
end

function export.tone_determ(text)
	text = toNFD(text)
	return m_data.py_tone_mark_to_num or '5'
end

local function sup(text)
	local ret = mw.html.create("sup"):wikitext(text)
	return tostring(ret)
end

function export.py_transf(text)
	return export.py_detone(text) .. export.tone_determ(text)
end

local function decompose_tones(text)
	return (toNFD(text):gsub("\204", toNFC))
end

function export.py_transform(text, detone, not_spaced)
	if find(text, "​") then
		error("Pinyin contains the hidden character: ​ (U+200B). Please remove that character from the text.")
	elseif find(text, "%d") then
		-- e.g. ma1 instead of mā
		error("Numbered tones should be given with tone marks instead.")
	end
	
	local tones = m_data.tones
	detone = ine(detone)
	not_spaced = ine(not_spaced)
	
	text = decompose_tones(text)
	
	text = text
		:gsub("\204", { = "\1",  = "\2",  = "\3",  = "\4"})
		:gsub("\195", { = "\5",  = "\6",  = "\14",  = "\15"})
		:gsub("\228\184", { = "\7",  = "\8"})
	
	local function plaintext(text)
		return (text:gsub("\16()", "n%1g")
			:gsub("", function(m)
			return ({"\204\132", "\204\129", "\204\140", "\204\128", "ê", "ü", "一", "不",  = "Ê",  = "Ü",  = "ng",  = "gn",  = "'"})
		end))
	end
	
	if not not_spaced then
		local i = 1
		local function check_apostrophes(check_text)
			i = i + 1
			local new_text = check_text
				:gsub("(?)(%f)", "%1'%2")
				:gsub("()(%f)", "%1'%2")
				:gsub("()(%f)", "%1'%2")
				:gsub("()(%f)", "%1'%2")
				:gsub("()(%f)", "%1'%2")
				:gsub("()(%f)", "%1'%2")
			if new_text ~= check_text then
				check_apostrophes(new_text)
			elseif new_text ~= text then
				error(("Missing apostrophe before null-initial syllable - should be \"%s\" instead."):format(plaintext(new_text)), i)
			end
		end
		check_apostrophes(text)
	end
	
	local check_text = gsub(text,"()()(" .. tones .. ")", "%1%3%2")
	check_text = gsub(check_text,"()(" .. tones .. ")()", "%1%3%2")
	if text ~= check_text then
		error("Incorrect diacritic placement in Pinyin - should be \"".. check_text .. "\" instead.")
	end
	
	text = lower(text)
		:gsub(" *() *", " %1 ")
		:gsub("", { = " #",  = "5"})
		:gsub("%. +%. +%.", "...")
		:gsub("(%d)()", "%1 %2")
		:gsub("n(?)g", "\16%1")
		:gsub("%f\16%f", "ng")
		:gsub("gn%f", "\17")
		:gsub("'r", "\18r")
		:gsub("\18r()", "'r%1")
		:gsub("(??\18?r?)()", "%1 %2")
		:gsub("(?\18?r?)()", "%1 %2")
		:gsub(" r%f", "r")
		:gsub("(?) ()%f", "%1%2")
		:gsub("", " ")
	
	if detone or text:find("%d") then
		text = text
			:gsub("()(*)", function(m1, m2)
				return m2 .. m1:byte()
			end)
			:gsub("%f", "%05")
			:gsub("(\18?r)5", "%1")
	end
	
	text = plaintext(text)
	
	if not_spaced then
		text = text:gsub(" ", "")
	end
	
	return (toNFC(trim(text)):gsub(" +", " "))
end

local function iterate_words(text)
	local pos, word, non_word
	
	local function get_word()
		word, non_word, pos = text:match("(+)(*)()", pos)
		if pos then
			return word, non_word
		end
	end
	
	return get_word
end

local function iterate_syllables(text)
	local cap = find(text, "^%u")
	text = export.py_transform(text, true)
	text = text
		:gsub("\195", { = "\1",  = "\2"})
		:gsub("h", { = "\3",  = "\4",  = "\5"})
	local raw_syllables = split(text, " ")
	
	local function plaintext(text)
		return (text and text:gsub("", function(m)
			return ({"ê", "ü", "ẑ", "ĉ", "ŝ", "ŋ", "ɲ", "ɨ"})
		end))
	end
	
	local i = 0
	local function explode_syllable()
		i = i + 1
		if raw_syllables then
			local syllable, tone, sandhi, block_sandhi = raw_syllables
			if syllable == "" then
				return explode_syllable()
			end
			syllable = syllable
				:gsub("(\228\184)('?r?)$", function(m, erhua)
					sandhi = m
					return (m:gsub(".*", { = "yi1",  = "bu4"})
						:gsub("(%a+)(%d)", "%1" .. erhua .. "%2"))
				end)
				:gsub("^#", function(m)
					block_sandhi = true
					return ""
				end)
				:gsub("%d$", function(m)
					tone = m
					return ""
				end)
				:gsub("ng", "\6")
				:gsub("gn", "\7")
				:gsub("()(o'?r?)$", "%1u%2")
				:gsub("()u", "%1\2")
				:gsub("u", { = "iou",  = "\2"})
				:gsub("i", { = "\1i",  = "u\1i"})
				:gsub("ao", "au")
				:gsub("", { = "u",  = "i"})
				:gsub("()e('?r?)$", "%1\1%2")
				:gsub("(.)o('?r?)$", "%1u%2")
				:gsub("iu", "\2")
				:gsub("^(?)('?r?)$", "%1e%2")
				:gsub("()%1", "%1")
				:gsub("()i('?r?)$", "%1\8%2")
			local initial, glide1, nucleus, glide2, nasal, erhua = syllable:match("^(?)(?)(?)(?)(?)('?r?)$")
			return (syllable:gsub("", "")), plaintext(initial), plaintext(glide1), plaintext(nucleus), glide2, plaintext(nasal), erhua, tone, sandhi, (not not block_sandhi)
		end
	end
	
	return explode_syllable
end

-- Generate a normalized pinyin version as a baseline, which everything else can work from.
local function normalize_py(text, no_words)
	local raw_words, words = split(text, " "), {}
	for i, word in ipairs(raw_words) do
		local cap = find(word, "^%u")
		word = export.py_transform(word, true)
		word = word:gsub("\195", { = "\1",  = "\2"})
		
		local raw_syllables, syllables = split(word, " "), {}
		for j, s in ipairs(raw_syllables) do
			s = s
				:gsub("h", { = "\3",  = "\4",  = "\5"})
				:gsub("ng", "\6")
				:gsub("gn", "\7")
				:gsub("()(or?%d)", "%1u%2")
				:gsub("()u", "%1\2")
				:gsub("iu", "iou")
				:gsub("yu", "\2")
				:gsub("ui", "uei")
				:gsub("ao", "au")
				:gsub("", { = "u",  = "i"})
				:gsub("()e(r?%d)", "%1\1%2")
				:gsub("ue(r?)", "u%1")
				:gsub("io(\6r?)", "\2%1")
				:gsub("()%1", "%1")
				:gsub("()i(r?%d)", "%1ɨ%2")
				:gsub("", function(m)
					return ({"ê", "ü", "ẑ", "ĉ", "ŝ", "ŋ", "ɲ"})
				end)
			table.insert(syllables, toNFC(s))
		end
		
		word = syllables
		if #word > 0 then
			word = cap and gsub(word, "^.", upper) or word
			table.insert(words, word)
		end
	end
	
	if no_words then
		local syllables = {}
		for _, word in ipairs(words) do
			for _, s in ipairs(word) do
				table.insert(syllables, s)
			end
		end
		words = syllables
	end
	
	return words
end

function export.py_ipa(text)
	local ipa_initials = m_data.py_ipa_initials
	local ipa_initials_tl = m_data.py_ipa_initials_tl
	local ipa_finals = m_data.py_ipa_finals
	local ipa_erhua = m_data.py_ipa_erhua
	local ipa_tl_ts = m_data.py_ipa_tl_ts
	local ipa_t_values = m_data.py_ipa_t_values

	local tones = {}
	local tone_cats = {}
	text = lower(text)
	
	local syllables = normalize_py(text, true)
	
	for i, s in ipairs(syllables) do
		if s:find("^+$") then
			table.remove(syllables, i)
		end
	end
	
	for i = 1, #syllables do
		syllables = syllables:gsub("%d", function(m)
			tone_cats = m
			return ""
		end)
		if syllables == "一" then
			tone_cats = syllables and (syllables:match("%d") == "4" or syllables == "ge") and "1-2" or "1-4"
			syllables = "i"
		elseif syllables == "不" then
			tone_cats = syllables and syllables:match("%d") == "4" and "4-2" or "4"
			syllables = "bu"
		end
		tone_cats = tone_cats or "5"
		syllables = syllables:gsub("#", function(m)
			tone_cats = "#" .. tone_cats
			return ""
		end)
	end
	
	for i, s in ipairs(syllables) do
		s = gsub(s, "^(?)(+)('?r?)$", function(initial, final, erhua)
			if initial == "" and find(final, "^") then
				initial = "ˀ"
			end
			final = ipa_finals or final
			if erhua == "r" then
				for i, from in ipairs(ipa_erhua) do
					final = gsub(toNFD(final), toNFD(from) .. "$", ipa_erhua)
				end
				final = toNFC(final)
			end
			if initial:find("") then
				final = final:gsub("ʐ", "z")
			elseif initial == "" then
				final = final:gsub("̯", { = "j",  = "w",  = "ɥ"})
			end
			initial = ipa_initials or initial
			if tone_cats == "5" then
				initial = initial:gsub(".*", ipa_initials_tl)
				final = final:gsub("ɤ$", "ə")
			end
			return gsub(initial .. final, "ʐʐ̩", "ʐ̩")
		end)
		
		local curr_tone_cat, prev_tone_cat, next_tone_cat = tone_cats, tone_cats, tone_cats
		
		if curr_tone_cat == "5" then
			tones = prev_tone_cat and ipa_tl_ts or ""
		else
			tones = ipa_t_values
		end
		
		if curr_tone_cat:find("3") then
			if i == #tone_cats then
				if i > 1 then
					tones = "²¹⁴⁻²¹⁽⁴⁾"
				end
			elseif next_tone_cat == "3" then
				tones = "²¹⁴⁻³⁵"
			elseif next_tone_cat ~= "5" then
				tones = "²¹⁴⁻²¹"
			end
		elseif curr_tone_cat == "4" and (next_tone_cat == "4" or next_tone_cat == "1-4") then
			tones = "⁵¹⁻⁵³"
		elseif curr_tone_cat == "1-4" and next_tone_cat == "4" then
			tones = "⁵⁵⁻⁵³"
		end
		syllables = s .. tones
		syllables = gsub(syllables, "#", "")
	end
	
	return table.concat(syllables, " ")
end

function export.py_number_to_mark(text)
	local priority = m_data.py_mark_priority
	local tones = m_data.py_tone_num_to_mark
	
	text = text:gsub("(+)()", function(syl, tone)
		for _, pattern in ipairs(priority) do
			local syl, n = gsub(syl, pattern, "%0" .. (tones or ""))
			if n > 0 then
				return syl
			end
		end
		return syl .. tone
	end)
	
	return toNFC(text)
end

function export.py_zhuyin(text)
	input_error(text)
	
	local py_zhuyin_consonant = m_data.py_zhuyin_consonant
	local py_zhuyin_glide = m_data.py_zhuyin_glide
	local py_zhuyin_nucleus = m_data.py_zhuyin_nucleus
	local py_zhuyin_final = m_data.py_zhuyin_final
	local py_zhuyin_syllabic_nasal = m_data.py_zhuyin_syllabic_nasal
	local py_zhuyin_tone = m_data.py_zhuyin_tone
	
	local output = {}
	text = export.py_transform(text)
	
	for syllable, initial, glide1, nucleus, glide2, nasal, erhua, tone in iterate_syllables(text) do
		if not (initial or glide1 or nucleus or glide2 or nasal) then
			table.insert(output, syllable)
		else
			local final = (py_zhuyin_nucleus or nucleus) .. (py_zhuyin_glide or glide2)
			final = (py_zhuyin_final or final) .. (py_zhuyin_consonant or nasal)
			final = ((py_zhuyin_glide or glide1) .. (py_zhuyin_final or final))
				:gsub("(\227\132)ㄜ", "%1")
			syllable = (py_zhuyin_consonant or initial) .. final
			if initial:find("") and syllable:find("ㄨㄛ$") then
				syllable = syllable:gsub("ㄨ", "")
			end
			syllable = syllable:gsub("^\227\132$", py_zhuyin_syllabic_nasal)
				:gsub("\227\132$", "<small>%0</small>")
			if syllable == "ㄜ" and erhua == "r" then
				syllable = "ㄦ"
				erhua = ""
			elseif #erhua > 0 then
				erhua = "ㄦ"
			end
			if tone == "5" then
				syllable = py_zhuyin_tone .. syllable .. erhua
			else
				syllable = syllable .. py_zhuyin_tone .. erhua
			end
			table.insert(output, syllable)
		end
	end
	
	return table.concat(output, " ")
end

function export.zhuyin_py(text)
	local zhuyin_py_initial = m_data.zhuyin_py_initial
	local zhuyin_py_final = m_data.zhuyin_py_final
	local zhuyin_py_tone = m_data.zhuyin_py_tone
	
 	local word = split(text, " ", true)
 	
 	local function process_syllable(syllable)
 		syllable = gsub(syllable, "^()(?)$", "%1ㄧ%2")
 		return gsub(syllable, "(?)(?)(?)(ㄦ?)", function(initial, final, tone, erhua)
 			
			initial = zhuyin_py_initial
			final = zhuyin_py_final
			
			if erhua ~= "" then
				final = final .. "r"
			end
			if initial == "" then
				final = final
					:gsub("^()(n?g?)$", function(a, b) return gsub(a, "", { = "yi",  = "wu"}) .. b end)
					:gsub("^(w?u)()$", "ue%2")
					:gsub("^iu$", "iou")
					:gsub("^()", { = "y",  = "w"})
					:gsub("^ong", "weng")
					:gsub("^ü", "yu")
			end
			
			if initial:find("") then
				final = final:gsub("^ü", "u")
			end
			local tone = zhuyin_py_tone
			
			if final:find("") then
				final = final:gsub("()", "%1" .. tone)
			elseif final:find("i") then
				final = final:gsub("(i)", "%1" .. tone)
			elseif final:find("") then
				final = final:gsub("()", "%1" .. tone)
			else
				final = gsub(final, "^(?)(.)", "%1" .. "%2" .. tone)
			end
			
 			return initial .. final
 		end)
 	end
 	
 	for i, syllable in ipairs(word) do
 		word = process_syllable(syllable)
 	end
	
	return toNFC(table.concat(word, " "))
end

function export.py_wg(text)
	local py_wg_consonant = m_data.py_wg_consonant
	local py_wg_consonant_dental = m_data.py_wg_consonant_dental
	local py_wg_glide = m_data.py_wg_glide
	local py_wg_nucleus = m_data.py_wg_nucleus
	local py_wg_o = m_data.py_wg_o
	
	local output = {}
	
	for word, non_word in iterate_words(text) do
		local cap = find(word, "^%u")
		word = cap and lower(word) or word
		local syllables = {}
		for syllable, initial, glide1, nucleus, glide2, nasal, erhua, tone in iterate_syllables(word) do
			if not (initial or glide1 or nucleus or glide2 or nasal) then
				table.insert(syllables, syllable)
			else
				if glide1 == "ɨ" and  py_wg_consonant_dental then
					syllable = py_wg_consonant_dental .. "ŭ"
				else
					syllable = ((py_wg_consonant or initial) .. (py_wg_glide or glide1) .. (py_wg_nucleus or nucleus) .. glide2 .. (py_wg_consonant or nasal))
						:gsub("ehi", "ei")
						:gsub("au", "ao")
						:gsub("iou", "iu")
						:gsub("ian$", "ien")
					if py_wg_o then
						syllable = syllable:gsub("ê$", "o")
					elseif initial ~= "ŝ" then
						syllable = syllable:gsub("uo$", "o")
					end
					syllable = (#glide1 > 0 and syllable:gsub("ê(g?)", "%1") or syllable)
						:gsub("üng", "iung")
					if initial == "" then
						syllable = syllable
							:gsub("^.*", { = "y",  = "w",  = "yü"})
							:gsub("^$", { = "i",  = "wu"})
							:gsub("^()()", function(m1, m2)
								return ({ = "wê",  = "yi",  = "u"}) .. m2
							end)
					elseif glide1 == "u" and not initial:find("") then
						syllable = syllable:gsub("uei", "ui")
					end
				end
				if syllable == "o" and nucleus == "e" and erhua == "r" then
					syllable = "êrh"
					erhua = ""
				elseif #erhua > 0 then
					erhua = "-ʼrh"
				end
				table.insert(syllables, syllable .. tone:gsub("%d", sup) .. erhua)
			end
		end
		syllables = cap and gsub(syllables, "^.", upper) or syllables
		word = table.concat(syllables, "-")
			:gsub("%-()", "%1")
		table.insert(output, word .. non_word)
	end
	
	return table.concat(output)
end

local function temp_bg(text, bg)
	if bg == 'y' then
		return '<' .. text .. '>'
	end
	return text
end
	
local function make_bg(text, bg)
	if bg == 'y' then
		return '<span style="background-color:#F5DEB3">' .. text .. '</span>'
	else
		return text
	end
end

function export.py_gwoyeu(text, original_text)
	local initials = m_data.py_gwoyeu_initial
	local finals = m_data.py_gwoyeu_final
	
	if text:find('^%s') or text:find('%s$') then error('invalid spacing') end
	local words = split(text, " ")
	local count = 0
	for i, word in ipairs(words) do
		local cap = find(toNFD(word), "^%u")
		word = export.py_transform(word, true, true)
		word = gsub(word, "()", "%1 ")
		word = gsub(word, " $", "")
		word = gsub(word, '()', ' %1 ')
		word = gsub(word, ' +', ' ')
		word = gsub(word, ' $', '')
		word = gsub(word, '^ ', '')
		local syllables = split(word, " ")
		for j, syllable in ipairs(syllables) do
			count = count + 1
			if not find(syllable, '^+$') then
				local current = sub(mw.title.getCurrentTitle().text, count, count)
				if find(current, '^$') then
					local exceptions = { = 'i',  = 'chi',  = 'ba',  = 'bu'}
					syllables = exceptions
				else
					local initial, final, tone = '', '', ''
					syllable = gsub(syllable, '()u', '%1ü')
					syllable = gsub(syllable, '^(h?)i(r?)$', '%1ɨ%2')
					if find(syllable, '(?h?)(??g?r?)()') then
						syllable = gsub(syllable, '(?h?)(??g?r?)()', function(a, b, c)
							initial = initials or error('Unrecognised initial:' .. a); final = finals or error('Unrecognised final:' .. b); tone = c
							return (initial .. final .. tone) end)
					elseif not (find(mw.title.getCurrentTitle().text, "") or find(mw.title.getCurrentTitle().text, "cmn-pron/testcases", 1, true)) then
						error('Unrecognised syllable:' .. syllable)
					end
					local original = initial..final..tone
					if initial:find('^$') then
						final = initial .. final
						initial = ''
					end
					if initial .. final == "e'l" then
						final = "el"
					end
					final = gsub(final, '()%1', '%1')
					local len = len(initial) + len(final)
					local detone = initial..final
					local replace = detone
					local fullstop = false
					if tone == 5 or tone == '5' then
						fullstop = true
						if original_text then
							tone = split(export.py_transform(original_text, true), ' '):match('')
						elseif initial:find('^$') then
							tone = 2
						else tone = 1 end
						if tone == 5 or tone == '5' then
							tone = export.tone_determ(m_zh.py(current))
						end
					end
					if tone == 1 or tone == '1' then
						if initial:find('^$') then
							replace = initial .. 'h' .. sub(detone, 2, len)
						else
							replace = detone
						end
					elseif tone == 2 or tone == '2' then
						if not initial:find('^$') then
							if final:find('^') then
								replace = gsub(detone, '', { = 'y',  = 'w'}, 1)
								replace = gsub(replace, 'l?$', { = 'yi',  = 'wu',  = 'wul',})
							else
								replace = gsub(detone, '(+)', '%1r')
							end
						else
							replace = detone
						end
					elseif tone == 3 or tone == '3' then
						if final:find("^iu?e'l$") then
							detone = gsub(detone, "'", '')
						end
						detone = gsub(detone, '^', { = 'yi',  = 'wu'})
						if final:find('') and (not final:find('^') or initial..final=="ie") and (not final:find('^') or initial..final=="uo") then
							replace = gsub(detone, '', { = 'e',  = 'o'}, 1)
						elseif final:find('') then
							replace = gsub(detone, '(?)()', '%1%2%2', 1)
						else
							error('Unrecognised final:'..final)
						end
					elseif tone == 4 or tone == '4' then
						if final:find("^iu?e'l$") then
							detone = gsub(detone, "'", '')
						end
						detone = gsub(detone, '^', { = 'yi',  = 'wu'})
						if detone:find('l?$') then
							replace = gsub(detone, "l?$", { = 'y',  = 'w',  = 'wl'})
						elseif detone:find('$') then
							replace = gsub(detone, "l?$", { = 'nn',  = 'q',  = 'll',  = 'ql',  = 'hl'})
						else
							replace = detone .. 'h'
						end
						replace = gsub(replace, 'yi()', 'y%1')
						replace = gsub(replace, 'wu()', 'w%1')
					end
					if fullstop then replace = '.' .. replace end
					syllables = gsub(syllable, original, replace)
				end
			end
		end
		words = table.concat(syllables, "")
		words = cap and gsub(words, "^.", upper) or words
	end
	return table.concat(words, " ")
end

-- Converts Hanyu Pinyin into Tongyong Pinyin.
function export.py_tongyong(text)
	local ty_tone = {
		 = "",  = "\204\129",  = "\204\140",  = "\204\128",  = "\204\138"
	}
	
	local function num_to_mark(syllable, tone)
		tone = ty_tone
		if tone ~= "" then
			if find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			elseif find(syllable, "o") then
				syllable = gsub(syllable, "(o)", "%1" .. tone)
			elseif find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			elseif find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			end
		end
		return syllable
	end
	
	local words = {}
	for word in gsplit(text, " ") do
		local cap = find(toNFD(word), "^%u")
		word = export.py_transform(word, true)
		local syllables = {}
		for syllable in gsplit(word, " ") do
			syllable = toNFC(gsub(syllable, "(h?i)", "%1h"))
			syllable = gsub(syllable, "ü", "yu")
			syllable = gsub(syllable, "()u", "%1yu")
			syllable = gsub(syllable, "iu", "iou")
			syllable = gsub(syllable, "ui", "uei")
			syllable = gsub(syllable, "()eng", "%1ong")
			syllable = gsub(syllable, "wen", "wun")
			syllable = gsub(syllable, "iong", "yong")
			syllable = gsub(syllable, "^zh", "jh")
			syllable = gsub(syllable, "^q", "c")
			syllable = gsub(syllable, "^x", "s")
			syllable = #syllables ~= 0 and gsub(syllable, "^()", "-%1") or syllable
			syllable = gsub(syllable, "^(+)()$", num_to_mark)
			
			table.insert(syllables, syllable)
		end
		word = table.concat(syllables, "")
		word = cap and gsub(word, "^.", upper) or word
		table.insert(words, word)
	end
	
	return toNFC(table.concat(words, " "))
end

-- Converts Hanyu Pinyin into the Yale system.
function export.py_yale(text)
	local yale_tone = {
		 = u(0x304),  = u(0x301),  = u(0x30C),  = u(0x300),  = ""
	}
	
	local function num_to_mark(syllable, tone)
		tone = yale_tone
		if tone ~= "" then
			if find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			elseif find(syllable, "o") then
				syllable = gsub(syllable, "(o)", "%1" .. tone)
			elseif find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			elseif find(syllable, "") then
				syllable = gsub(syllable, "()", "%1" .. tone)
			end
		end
		return syllable
	end
	
	local words = {}
	for word in gsplit(text, " ") do
		local cap = find(toNFD(word), "^%u")
		word = export.py_transform(word, true)
		local syllables = {}
		for syllable in gsplit(word, " ") do
			syllable = toNFC(gsub(syllable, "^r(%d)", "er%1"))
			syllable = gsub(syllable, "^()u", "%1ü")
			syllable = gsub(syllable, "^(.h)i(%d)", "%1r%2")
			syllable = gsub(syllable, "^ri(%d)", "r%1")
			syllable = gsub(syllable, "^()i(%d)", "%1z%2")
			syllable = gsub(syllable, "^zh", "j")
			syllable = gsub(syllable, "^.", m_data.py_yale_initial)
			syllable = gsub(syllable, "^tsh", "ch")
			syllable = gsub(syllable, "i()", "y%1")
			syllable = gsub(syllable, "u()", "w%1")
			syllable = gsub(syllable, "ü()", "yw%1")
			for chars, replacement in pairs(m_data.py_yale_two_medials) do
				syllable = gsub(syllable, chars, replacement)
			end
			syllable = gsub(syllable, "ong", "ung")
			syllable = gsub(syllable, ".", m_data.py_yale_one_medial)
			syllable = gsub(syllable, "ü", "yu")
			syllable = gsub(syllable, "()o(%d)$", "%1wo%2")
			syllable = gsub(syllable, "()%1", "%1")
			syllable = gsub(syllable, "^(+)(%d)$", num_to_mark)
			
			table.insert(syllables, syllable)
		end
		word = table.concat(syllables, "-")
		
		word = cap and gsub(word, "^.", upper) or word
		table.insert(words, word)
	end
	
	return toNFC(table.concat(words, " "))
end

-- Converts Hanyu Pinyin into the Palladius system.
function export.py_palladius(text)
	local words = {}
	for word in gsplit(text, " ") do
		local cap = find(toNFD(word), "^%u")
		word = export.py_transform(word, true)
		local syllables = {}
		for syllable in gsplit(word, " ") do
			syllable = toNFC(gsub(syllable, "%d", ""))
			syllable = gsub(syllable, "^()u", "%1ü")
			syllable = gsub(syllable, "()(r?)$", function(m1, m2)
				m1 = m_data.py_palladius_final or m1
				return m1 .. (m2 == "r" and "р" or "")
			end)
			syllable = gsub(syllable, "ng", "н")
			syllable = gsub(syllable, "^..", m_data.py_palladius_two_initials)
			syllable = gsub(syllable, "^.", m_data.py_palladius_one_initial)
			for chars, replacement in pairs(m_data.py_palladius_three_medials) do
				syllable = gsub(syllable, chars, replacement)
			end
			for chars, replacement in pairs(m_data.py_palladius_two_medials) do
				syllable = gsub(syllable, chars, replacement)
			end
			syllable = gsub(syllable, ".", m_data.py_palladius_one_medial)
			for chars, replacement in pairs(m_data.py_palladius_specials) do
				syllable = gsub(syllable, chars, replacement)
			end
			syllable = gsub(syllable, "н$", "%1" .. pua)
			syllable = gsub(syllable, "$", "%1" .. pua)
			syllable = gsub(syllable, "?о$", "%1" .. pua)
			syllable = gsub(syllable, "$", "%1" .. pua)
			syllable = gsub(syllable, "ю?$", "%1" .. pua)
			syllable = gsub(syllable, "оу$", "%1" .. pua)
			if syllable == "н" or syllable == "нь" then
				syllable = syllable .. pua
			end
			table.insert(syllables, syllable)
		end
		word = table.concat(syllables, "")
		word = gsub(word, "н" .. pua .. "()", "нъ%1")
		for chars, replacement in pairs(m_data.py_palladius_disambig) do
			word = gsub(word, chars, replacement)
		end
		word = gsub(word, " .. "-" .. pua .. "]", "")
		word = cap and gsub(word, "^.", upper) or word
		table.insert(words, word)
	end
	
	return toNFC(table.concat(words, " "))
end

function export.py_format(text, cap, bg, simple)
	if cap == false then cap = nil end
	if bg == false then bg = 'n' else bg = 'y' end
	if simple == false then simple = nil end
	text = toNFD(text)
	local phon = text
	local title = mw.title.getCurrentTitle().text
	local cat = ''
	local spaced = toNFD(export.py_transform(text))
	local space_count
	spaced, space_count = spaced:gsub(' ', '@')
	local consec_third_count
	
	for _ = 1, space_count do
		spaced, consec_third_count = gsub(spaced, "(+)̌(*)@(+̌)", function(a, b, c)
			return temp_bg(a..'́'..b, bg)..'@'..c end, 1)
		if consec_third_count > 0 then
			phon = gsub(spaced, '@', '')
		end
	end
	text = gsub(text, "#", "")
	phon = gsub(phon, "#", "")
	
	if title:find('一') and not text:find('一') and not simple then
		cat = cat .. ']'
	end
	
	if text:find('') and not simple then
		text = gsub(text, '$', { = 'yī',  = 'bù'})
		phon = gsub(phon, '$', { = 'yī',  = 'bù'})
		
		if find(text, '一') then
			if find(text, '一*') then
				cat = cat .. ']'
				phon = gsub(phon, '一(*)', function(a) return temp_bg('yì', bg) .. a end)
				text = gsub(text, '一(*)', 'yī%1')
			end
			if find(text, '一*̀') or find(text, '一ge$') or find(text, '一ge') then
				cat = cat .. ']'
				phon = gsub(phon, '一(*̀)', function(a) return temp_bg('yí', bg) .. a end)
				phon = gsub(phon, '一ge', temp_bg('yí', bg) .. 'ge')
				text = gsub(text, '一(*)', 'yī%1')
			end
		end
		if find(text, '不 ???*̀') then
			cat = cat .. ']'
			phon = gsub(phon, '不( ???*̀)', function(a) return temp_bg('bú', bg) .. a end)
		end
	end
	text = gsub(text, '', { = 'yī',  = 'bù'})
	text = gsub(text, '兒', function() return make_bg('r', bg) end) -- character is deleted
	phon = gsub(phon, '', { = 'yī',  = 'bù'})
	phon = gsub(phon, '<(+)>', '<span style="background-color:#F5DEB3">%1</span>')
	
	if not simple then
		if cap then
			text = gsub(text, '^%l', upper)
			phon = gsub(phon, '^%l', upper)
		end
		local linked_text = require("Module:links").full_link{term = text, lang = cmn}
		if phon ~= text then
			text = (linked_text) .. " "
		else
			text = linked_text
		end
		if mw.title.getCurrentTitle().nsText ~= "Template" then
			text = text .. cat
		end
	end
	return toNFC(text)
end

function export.make_tl(original_text, tl_pos, bg, cap)
	if bg == false then bg = 'n' else bg = 'y' end
	local _, countoriginal = original_text:gsub(" ", " ")
	local spaced = export.py_transform(original_text)
	if sub(spaced, -1, -1) == ' ' then spaced = sub(spaced, 1, -2) end
	local _, count = spaced:gsub(" ", " ")
	local index = {}
	local start, finish
	local pos = 1
	for i = 1, count, 1 do
		if i ~= 1 then pos = (index + 1) end
		index = find(spaced, ' ', pos)
	end
	if tl_pos == 2 then
		start = index - count + countoriginal + 2
		finish = index - count + countoriginal
	elseif tl_pos == 3 then
		start = index - count + countoriginal + 3
		finish = index - count + countoriginal + 1
	else
		start = count == 0 and 1 or (index - count + countoriginal + 1)
		finish = -1
	end
	local text = (sub(original_text, 1, start-1) .. make_bg(gsub(sub(original_text, start, finish), '.', export.py_detone), bg))
	if finish ~= -1 then text = (text .. sub(original_text, finish+1, -1)) end
	if cap == true then text = gsub(text, '^%l', upper) end
	return text
end

function export.tag(first, second, third, fourth, fifth)
	local text = "(''"
	local tag = {}
	local tagg = first or "Standard Chinese"
	tag = (second ~= '') and second or "Standard Chinese"
	tag = (third ~= '') and third or nil
	tag = (fourth ~= '') and fourth or nil
	tag = (fifth ~= '') and fifth or nil
	text = text .. ((tagg == '') and table.concat(tag, ", ") or tagg) .. "'')"
	text = gsub(text, 'Standard Chinese', "]")
	text = gsub(text, 'Mainland', "]")
	text = gsub(text, 'Taiwan', "]")
	text = gsub(text, 'Beijing', "]")
	text = gsub(text, 'erhua', "]")
	text = gsub(text, 'Min Nan', "]")
	text = gsub(text, 'shangkouzi', "'']''")
	return text
end

function export.straitdiff(text, pron_ind, tag)
	local conv_text = text
	for i = 1, #text do
		if m_zh_data().MT then conv_text = 'y' end
	end
	if tag == 'tag' then
		conv_text = (conv_text == 'y') and m_zh_data().MT_tag')] or ''
	elseif pron_ind == 1 or pron_ind == 2 or pron_ind == 3 or pron_ind == 4 or pron_ind == 5 then
		local reading = {}
		for a, b in pairs(m_zh_data().MT) do
			reading = b
			if reading then reading = gsub(reading, "^()", "'%1") end
		end
		conv_text = gsub(text, '.', reading)
		text = gsub(text, "^'", "")
		text = gsub(text, " '", " ")
		if conv_text == text and tag == 'exist' then return nil end
	end
	conv_text = gsub(conv_text, "^'", "")
	return conv_text
end

function export.str_analysis(text, conv_type, other_m_vars)
	local MT = m_zh_data().MT
	
	text = gsub(text, '{default}', '')
	text = gsub(text, '=', '—')
	text = gsub(text, ',', '隔')
	text = gsub(text, '隔 ', ', ')
	if conv_type == 'head' or conv_type == 'link' then
		if find(text, '隔cap—') then
			text = gsub(text, '', { = 'Yī',  = 'Bù'})
		end
		text = gsub(text, '', { = 'yī',  = 'bù'})
	end
	local comp = split(text, '隔', true)
	local reading = {}
	local alternative_reading = {}
	local zhuyin = {}
	--[[
	-- not used
	local param = {
		'1n', '1na', '1nb', '1nc', '1nd', 'py', 'cap', 'tl', 'tl2', 'tl3', 'a', 'audio', 'er', 'ertl', 'ertl2', 'ertl3', 'era', 'eraudio',
		'2n', '2na', '2nb', '2nc', '2nd', '2py', '2cap', '2tl', '2tl2', '2tl3', '2a', '2audio', '2er', '2ertl', '2ertl2', '2ertl3', '2era', '2eraudio',
		'3n', '3na', '3nb', '3nc', '3nd', '3py', '3cap', '3tl', '3tl2', '3tl3', '3a', '3audio', '3er', '3ertl', '3ertl2', '3ertl3', '3era', '3eraudio',
		'4n', '4na', '4nb', '4nc', '4nd', '4py', '4cap', '4tl', '4tl2', '4tl3', '4a', '4audio', '4er', '4ertl', '4ertl2', '4ertl3', '4era', '4eraudio',
		'5n', '5na', '5nb', '5nc', '5nd', '5py', '5cap', '5tl', '5tl2', '5tl3', '5a', '5audio', '5er', '5ertl', '5ertl2', '5ertl3', '5era', '5eraudio'
	}
	--]]
	
	if conv_type == '' then
		return comp
	elseif conv_type == 'head' or conv_type == 'link' then
		for i, item in ipairs(comp) do
			if not find(item, '—') then
				if find(item, '') then
					local M, T, t = {}, {}, {}
					for a, b in pairs(MT) do
						M = b; T = b; t = b;
						M = gsub(M, "^()", "'%1")
						T = gsub(T, "^()", "'%1")
						if t then t = gsub(t, "^()", "'%1") end
					end
					local mandarin = gsub(item, '.', M)
					local taiwan = gsub(item, '.', T)
					mandarin = gsub(mandarin, "^'", "")
					mandarin = gsub(mandarin, " '", " ")
					if conv_type == 'link' then return mandarin end
					taiwan = gsub(taiwan, "^'", "")
					taiwan = gsub(taiwan, " '", " ")
					local tt = gsub(item, '.', t)
					if find(text, 'cap—') then
						mandarin = gsub(mandarin, '^%l', upper)
						taiwan = gsub(taiwan, '^%l', upper)
						tt = gsub(tt, '^%l', upper)
					end
					if tt == item then
						zhuyin = export.py_zhuyin(mandarin, true) .. ', ' .. export.py_zhuyin(taiwan, true)
						reading = mandarin .. ']], [[' .. taiwan
					else
						tt = gsub(tt, "^'", "")
						tt = gsub(tt, " '", " ")
						zhuyin = export.py_zhuyin(mandarin, true) .. ', ' .. export.py_zhuyin(taiwan, true) .. ', ' .. export.py_zhuyin(tt, true)
						reading = mandarin .. ']], ], [[' .. tt
					end
				else
					if conv_type == 'link' then return item end
					zhuyin = export.py_zhuyin(item, true)
					reading = item
					if len(mw.title.getCurrentTitle().text) == 1 and #split(export.py_transform(item), " ") == 1 then
						local target = export.py_transf(reading)
						alternative_reading = ")', sup) .. "]]"
						if alternative_reading:find("5") then
							alternative_reading = alternative_reading .. "<span class=\"Zsym mention\" style=\"font-size:100%;\">/</span>" .. alternative_reading:gsub("5", "0")
						end
						local title = mw.title.new(mw.ustring.lower(target)):getContent()
						if not (title and title:find("{{cmn%-pinyin}}")) then
							track("uncreated pinyin")
						end
					end
				end
				if reading ~= '' then reading = ' .. ']]' end
				reading = gsub(reading, "#", "")
			end
			comp = item
			if conv_type == 'link' then return comp end
		end
		local id = m_zh.ts_determ(mw.title.getCurrentTitle().text)
		local accel
		if id == 'trad' then
			accel = '<span class="form-of pinyin-t-form-of transliteration-' .. m_zh.ts(mw.title.getCurrentTitle().text)
		elseif id == 'simp' then
			accel = '<span class="form-of pinyin-s-form-of transliteration-' .. m_zh.st(mw.title.getCurrentTitle().text)
		elseif id == 'both' then
			accel = '<span class="form-of pinyin-ts-form-of'
		end
		accel = accel .. '" lang="cmn" style="font-family: Consolas, monospace;">'
		local result = other_m_vars and "*: <small>('']'')</small>\n*::" or "*:"
		result = result .. "<small>('']'')</small>: " .. accel .. gsub(table.concat(reading, ", "), ", ,", ",")
		if alternative_reading then
			result = result .. " (" .. table.concat(alternative_reading, ", ") .. ")"
		end
		result = result .. (other_m_vars and "</span>\n*::" or "</span>\n*:")
		result = result .. "<small>('']'')</small>: " .. '<span lang="cmn-Bopo" class="Bopo">' .. gsub(table.concat(zhuyin, ", "), ", ,", ",") .. "</span>"
		return result

	elseif conv_type == '2' or conv_type == '3' or conv_type == '4' or conv_type == '5' then
		if not find(text, '隔') or (comp and find(comp, '—')) then
			return ''
		else
			return comp
		end
	else
		for i = 1, #comp, 1 do
			local target = '^' .. conv_type .. '—'
			if find(comp, target) then
				text = gsub(comp, target, '')
				return text
			end
		end
		text = ''
	end
	return text
end

function export.homophones(pinyin)
	local text = ''
	if mw.title.getCurrentTitle().nsText == '' then
		local args = get_hom_data(pinyin).list
		text = '<div style="visibility:hidden; float:left"><sup><span style="color:#FFF">edit</span></sup></div>'
		for i, term in ipairs(args) do
			if i > 1 then
				text = text .. "<br>"
			end
			if mw.title.new(term).exists and term ~= mw.title.getCurrentTitle().text then
				local forms = { term }
				local content = mw.title.new(term):getContent()
				local template = match(content, "{{zh%-forms*}}")
				if template then
					local simp = match(template, "|s=()+")
					if simp then
						table.insert(forms, simp)
					end
					for tradVar in gmatch(template, "|t=()+") do
						table.insert(forms, tradVar)
					end
					for simpVar in gmatch(template, "|s=()+") do
						table.insert(forms, simpVar)
					end
					term = table.concat(forms, "/")
				end
			end
			text = text .. require("Module:links").full_link{ term = term, lang = cmn, tr = "-" }
		end
		text = text .. ']'
	end
	return text
end

local function erhua(word, erhua_pos, pagename)
	local title = split(pagename, '')
	local linked_title = ''
	local syllables = split(export.py_transform(word), ' ')
	local count = #syllables
	erhua_pos = find(erhua_pos, '') and split(erhua_pos, ';') or { count }
	for _, pos in ipairs(erhua_pos) do
		pos = tonumber(pos)
		title = title .. '兒'
		syllables = syllables .. 'r'
	end
	local title = table.concat(title)
	if mw.title.new(title).exists then
		linked_title = ' (' .. require("Module:links").full_link{ term = title, lang = cmn, tr = "-" } .. ')'
	end
	for i, syllable in pairs(syllables) do
		if i ~= 1 and toNFD(syllable):find('^') then
			syllables = "'" .. syllable
		end
	end
	word = table.concat(syllables, '')
	return (export.tag('', '', 'erhua-ed') .. linked_title), word
end

export.erhua = erhua

function export.make(frame)
	local args = frame:getParent().args
	return export.make_args(args)
end

function export.make_args(args)
	local pagename = mw.title.getCurrentTitle().text
	local text = {}
	local reading = {args or '', args or '', args or '', args or '', args or ''}
	args = ine(args)
	if reading ~= '' then
		local title = export.tag((args or ''), (args or ''), (args or export.straitdiff(args, 1, 'tag')), (args or ''), (args or ''))
		local pinyin = export.straitdiff(reading, 1, '')
		table.insert(text, export.make_table(title, pinyin, (args or ''), (args or ''), (args or ''), (args or ''), (args or ''), (args or args or '')))
		
		if args and args ~= '' then
			title, pinyin = erhua(pinyin, args, pagename)
			table.insert(text, export.make_table(title, pinyin, '', (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
		end
	end
	
	if reading ~= '' or export.straitdiff(reading, 2, 'exist') then
		if args and args ~= '' then tagb = args else tagb = export.straitdiff(args, 2, 'tag') end
		title = export.tag((args or ''), (args or ''), tagb, (args or ''), (args or ''))
		pinyin = (reading ~= '') and reading or export.straitdiff(reading, 2, '')
		table.insert(text, export.make_table(title, pinyin, (args or ''), (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
		table.insert(text, ', 1, '') or args) .. ']]')
		
		if args and args ~= '' then
			title, pinyin = erhua(pinyin, args, pagename)
			table.insert(text, export.make_table(title, pinyin, '', (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
		end
		
		if reading ~= '' or export.straitdiff(reading, 3, 'exist') then
			if args and args ~= '' then tagb = args else tagb = export.straitdiff(args, 3, 'tag') end
			title = export.tag((args or ''), (args or ''), tagb, (args or ''), (args or ''))
			if reading ~= '' then pinyin = reading else pinyin = export.straitdiff(reading, 3, '') end
			table.insert(text, export.make_table(title, pinyin, (args or ''), (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
			
			if args and args ~= '' then
				title, pinyin = erhua(pinyin, args, pagename)
				table.insert(text, export.make_table(title, pinyin, '', (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
			end
			
			if reading ~= '' or export.straitdiff(reading, 4, 'exist') then
				if args and args ~= '' then tagb = args else tagb = export.straitdiff(args, 4, 'tag') end
				title = export.tag((args or ''), (args or ''), tagb, (args or ''), (args or ''))
				if reading ~= '' then pinyin = reading else pinyin = export.straitdiff(reading, 4, '') end
				table.insert(text, export.make_table(title, pinyin, (args or ''), (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
			
				if args and args ~= '' then
					title, pinyin = erhua(pinyin, args, pagename)
					table.insert(text, export.make_table(title, pinyin, '', (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
				end
				if reading ~= '' or export.straitdiff(reading, 5, 'exist') then
					if args and args ~= '' then tagb = args else tagb = export.straitdiff(args, 5, 'tag') end
					title = export.tag((args or ''), (args or ''), tagb, (args or ''), (args or ''))
					if reading ~= '' then pinyin = reading else pinyin = export.straitdiff(reading, 5, '') end
					table.insert(text, export.make_table(title, pinyin, (args or ''), (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
				
					if args and args ~= '' then
						title, pinyin = erhua(pinyin, args, pagename)
						table.insert(text, export.make_table(title, pinyin, '', (args or ''), (args or ''), (args or ''), (args or ''), (args or args or ''), true))
					end
				end
			end
		end
	end
	if (args or '') .. (args or '') .. (args or '') .. (args or '') .. (args or '') .. (args or '') ~= '' then
		table.insert(text, ', 1, '') .. ']]')
	end
	return table.concat(text)
end

local function add_audio(text, audio, pinyin)
	if audio and audio ~= "" then
		if audio == "y" then audio = format('zh-%s.ogg', pinyin) end
		table.insert(text, '\n*:: [[File:')
		table.insert(text, audio)
		table.insert(text, ']]')
		table.insert(text, ']')
	end
end

function export.make_audio(args)
	local text, reading, pinyin = {}, {}, ""
	local audio = {
		args or args or '',
		args or args or '',
		args or args or '',
		args or args or '',
		args or args or '',
	}
	for i=1, 5 do
		reading = args or ''
		if i == 1 then
			pinyin = export.straitdiff(reading, 1, '')
		else
			pinyin = (reading ~= '') and reading or export.straitdiff(reading, i, '')
		end
		pinyin = export.py_format(pinyin, false, false, true)
		add_audio(text, audio, pinyin)
	end
	return table.concat(text)
end

function export.make_table(title, pinyin, py, cap, tl, tl2, tl3, a, novariety)
	py = ine(py);cap = ine(cap);tl = ine(tl);tl2 = ine(tl2);tl3 = ine(tl3);a = ine(a);novariety = ine(novariety)
	local text = {}
	
	local pinyin_simple_fmt = export.py_format(pinyin, false, false, true)
	
	if not novariety then
		table.insert(text, '* ]')
	else
		table.insert(text, '<br>')
	end
	table.insert(text, '\n** <small>' .. title .. '</small>')
	local hom_found
	if get_hom_data(pinyin_simple_fmt).list then
		hom_found = true
	else
		hom_found = false
		table.insert(text, '<sup><small><abbr title="Add Mandarin homophones"><span class="plainlinks">="edit"})) .. ' +]</span></abbr></small></sup>')
	end
	table.insert(text, "\n*** <small>'']''</small>: ")
	local id = m_zh.ts_determ(mw.title.getCurrentTitle().text)
	if id == 'trad' then
		table.insert(text, '<span class="form-of pinyin-t-form-of transliteration-')
		table.insert(text, m_zh.ts(mw.title.getCurrentTitle().text))
	elseif id == 'simp' then
		table.insert(text, '<span class="form-of pinyin-s-form-of transliteration-')
		table.insert(text, m_zh.st(mw.title.getCurrentTitle().text))
	else -- both
		table.insert(text, '<span class="form-of pinyin-ts-form-of')
	end
	table.insert(text, '" lang="cmn" style="font-family: Consolas, monospace;">')
	if py then
		table.insert(text, py)
	else
		if cap then
			table.insert(text, export.py_format(pinyin, true, true))
		else
			table.insert(text, export.py_format(pinyin, false, true))
		end
		if tl or tl2 or tl3 then
			table.insert(text, ' → ')
			if tl then tl_pos = 1 elseif tl2 then tl_pos = 2 elseif tl3 then tl_pos = 3 end
			if cap then
				table.insert(text, export.make_tl(export.py_format(pinyin, true, false, true), tl_pos, true, true))
			else
				table.insert(text, export.make_tl(pinyin_simple_fmt, tl_pos, true))
			end
		end
		if tl then table.insert(text, ' <small>(toneless final syllable variant)</small>')
			elseif tl2 or tl3 then table.insert(text, ' <small>(toneless variant)</small>') end
	end
	table.insert(text, "</span>\n*** <small>'']''</small>: ")
	table.insert(text, '<span lang="cmn-Bopo" class="Bopo">')
	table.insert(text, export.py_zhuyin(pinyin_simple_fmt, true))
	if tl or tl2 or tl3 then
		table.insert(text, ' → ')
		table.insert(text, export.py_zhuyin(export.make_tl(pinyin_simple_fmt, tl_pos, false), true))
	end
	table.insert(text, '</span>')
	if tl then table.insert(text, ' <small>(toneless final syllable variant)</small>')
		elseif tl2 or tl3 then table.insert(text, ' <small>(toneless variant)</small>') end
	table.insert(text, "\n*** <small>'']''</small>: <span lang=\"cmn-Latn-tongyong\" style=\"font-family: Consolas, monospace;\">")
	if tl or tl2 or tl3 then
		table.insert(text, export.py_tongyong(export.make_tl(pinyin_simple_fmt, tl_pos, false), pinyin_simple_fmt))
	else
		table.insert(text, export.py_tongyong(pinyin_simple_fmt))
	end
	table.insert(text, '</span>')
	table.insert(text, "\n*** <small>'']''</small>: <span lang=\"cmn-Latn-wadegile\" style=\"font-family: Consolas, monospace;\">")
	if tl or tl2 or tl3 then
				table.insert(text, export.py_wg(export.make_tl(pinyin_simple_fmt, tl_pos, false), pinyin_simple_fmt))
	else
				table.insert(text, export.py_wg(pinyin_simple_fmt))
	end
	table.insert(text, '</span>')
	table.insert(text, "\n*** <small>'']''</small>: <span lang=\"cmn-Latn\" style=\"font-family: Consolas, monospace;\">")
	if tl or tl2 or tl3 then
				table.insert(text, export.py_yale(export.make_tl(pinyin_simple_fmt, tl_pos, false), pinyin_simple_fmt))
	else
				table.insert(text, export.py_yale(pinyin_simple_fmt))
	end
	table.insert(text, '</span>')
	table.insert(text, "\n*** <small>'']''</small>: <span lang=\"cmn-Latn\" style=\"font-family: Consolas, monospace;\">")
	if tl or tl2 or tl3 then
		table.insert(text, export.py_gwoyeu(export.make_tl(pinyin_simple_fmt, tl_pos, false), pinyin_simple_fmt))
	else
		table.insert(text, export.py_gwoyeu(pinyin_simple_fmt))
	end
	table.insert(text, '</span>')
	table.insert(text, "\n*** <small>'']''</small>: <span style=\"font-family: Consolas, monospace;\"><span lang=\"cmn-Cyrl\">")
	local palladius
	if tl or tl2 or tl3 then
				palladius = export.py_palladius(export.make_tl(pinyin_simple_fmt, tl_pos, false), pinyin_simple_fmt)
	else
				palladius = export.py_palladius(pinyin_simple_fmt)
	end
	table.insert(text, palladius)
	table.insert(text, "</span> <span lang=\"cmn-Latn\">(")
	table.insert(text, require("Module:ru-translit").tr(palladius, "cmn"))
	table.insert(text, ")</span></span>")
	table.insert(text, '\n*** <small>Sinological ] <sup>(])</sup></small>: <span class="IPA">/')
	table.insert(text, export.py_ipa(pinyin))
	if tl or tl2 or tl3 then
		table.insert(text, '/ → /')
		table.insert(text, export.py_ipa(export.make_tl(pinyin_simple_fmt, tl_pos, false)))
	end
	table.insert(text, '/</span>')
	-- if a then
	-- 	if a == 'y' then a = 'zh-' .. pinyin_simple_fmt .. '.ogg' end
	-- 	table.insert(text, '\n*** <div style="display:inline-block; position:relative; top:0.5em;">[[File:')
	-- 	table.insert(text, a)
	-- 	table.insert(text, ']]</div>]')
	-- end
	if hom_found then
		table.insert(text, "\n*** <small>Homophones</small>: " ..
			'<table class="wikitable" style="width:15em;margin:0; position:left; text-align:center">' ..
			'<tr><th class="mw-customtoggle-cmnhom" style="color:#3366bb"></th></tr>' ..
			'<tr class="mw-collapsible mw-collapsed" id="mw-customcollapsible-cmnhom">' ..
			'<td><sup><div style="float: right; clear: right;"><span class="plainlinks">[')
		table.insert(text, tostring(mw.uri.fullUrl("Module:zh/data/cmn-hom/" .. hom_data_part(pinyin_simple_fmt), {="edit"})))
		table.insert(text, ' edit]</span></div></sup>')
		table.insert(text, export.homophones(lower(pinyin_simple_fmt)))
		table.insert(text, '</td></tr></table>')
	end
	return table.concat(text)
end

function export.py_headword(frame)
	local plain_param = {}
	local params = {
		 = plain_param,
		 = plain_param,
		 = {type = "boolean"},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params, nil, "cmn-pron", "py_headword")
	
	local head = args.head or mw.title.getCurrentTitle().text
	local head_simple = require("Module:links").remove_links(head)
	
	local Latn = require("Module:scripts").getByCode("Latn")
	
	local categories = {"Hanyu Pinyin", "Mandarin non-lemma forms"}
	
	local inflections = {}
	if head:find("") then
		table.insert(categories, "Hanyu Pinyin with tone numbers")
		head = head:gsub("%d", sup)
	elseif not args.notr then
		local py_detoned = export.py_transform(head, true)
		if not py_detoned:find("%s") then
			if py_detoned:find("5") then
				py_detoned = py_detoned .. "//" .. py_detoned:gsub("5", "0")
			end
			py_detoned = py_detoned:gsub("%d", sup)
			table.insert(inflections, {py_detoned, sc = Latn})
		end
	end
	
	if not args.notr then
		local Bopo = require("Module:scripts").getByCode("Bopo")
		head_simple = export.py_number_to_mark(head_simple)
		table.insert(inflections, {
			label = "]",
			{
				term = args.zhuyin or export.py_zhuyin(head_simple),
				sc = Bopo,
				nolink = true
			}
		})
	end
	
	-- Don't pass a redundant head value, because they get categorised as redundant.
	if head == mw.title.getCurrentTitle().text then
		head = nil
	end
	
	return require("Module:headword").full_headword{lang = cmn, sc = Latn, heads = {head}, inflections = inflections, pos_category = "pinyin", categories = categories, noposcat = true}
end

return export