Module:zm-pron: Difference between revisions

From Linguifex
Jump to navigation Jump to search
No edit summary
No edit summary
 
(99 intermediate revisions by 2 users not shown)
Line 1: Line 1:
local export = {}
local categoryKeywords = {
common = "Utility",
utilities = "Utility",
headword = "Headword-line",
translit = "Transliteration",
decl = "Inflection",
conj = "Inflection",
pronun = "Pronunciation",
pronunc = "Pronunciation",
pronunciation = "Pronunciation",
IPA = "Pronunciation",
sortkey = "Sortkey-generating",
}
-- returnTable set to true makes function return table of categories with
-- "[[Category:" and "]]" stripped away. It is used by [[Module:documentation]].
function export.categorize(frame, returnTable)
local title = mw.title.getCurrentTitle()
local subpage = title.subpageText
-- To ensure no categories are added on documentation pages.
if subpage == "documentation" then
return ""
end
local output, categories = {}, {}
local namespace = title.nsText
local pagename, mode
if frame.args[1] then
pagename = frame.args[1]
pagename = pagename:gsub("^Module:", "")
mode = "testing"
mw.log("arg", pagename)
else
if namespace ~= "Module" then
error("This template should only be used in the Module namespace.")
end
pagename = title.text
if subpage ~= pagename then
pagename = title.rootText
end
end
--[[
If this is a transliteration module, parameter 1 is used as the code,
rather than the code in the page title.
]]
local code, categoryKeyword = pagename:match("([-%a]+)[- ]([^/]+)$")
if not code then
error("Category name was not recognized.")
end
local lang, sc
if subpage == "sandbox" then
table.insert(categories, "Sandbox modules")
else
local category = categoryKeywords[categoryKeyword]
if category == "Transliteration" then
code = frame:getParent().args[1] or code
end
if code then
if category then
local getByCode = require("Module:languages").getByCode
lang = getByCode(code) or getByCode(code .. "-pro")
if category == "Transliteration" then
if not lang then
sc = require("Module:scripts").getByCode(code)
if sc then
table.insert(categories, "Transliteration modules by script|" .. sc:getCanonicalName())
else
error('The language or script code "' .. code .. '" in the page title is not recognized by [[Module:languages]] or [[Module:scripts]].')
end
end
end
if not ( sc or lang ) then
error('The language code "' .. code .. '" in the page title is not recognized by Module:languages.')
end
local function languageCategory(lang, sortkey)
return lang:getCanonicalName() .. " modules|" .. sortkey
end
local function generalCategory(category, sortkey)
return category .. " modules|" .. sortkey
end
if category == "Transliteration" then
local langs = require("Module:languages/byTranslitModule")(pagename)
local sortkey = category
if sc then
sortkey = sortkey .. ", " .. sc:getCanonicalName()
end
if langs[1] then
for i, lang in ipairs(langs) do
table.insert(categories, languageCategory(lang, sortkey))
end
elseif lang then
table.insert(categories, languageCategory(lang, sortkey))
end
if sc then
table.insert(categories, generalCategory(category, sc:getCanonicalName()))
else
table.insert(categories, generalCategory(category, lang:getCanonicalName()))
end
else
table.insert(categories, languageCategory(lang, category))
table.insert(categories, generalCategory(category, lang:getCanonicalName()))
end
else
error('The category keyword "' .. categoryKeyword .. '" was not recognized.')
end
end
end
if returnTable then
return categories
else
categories = table.concat(
require "Module:fun".map(
function (category)
return "[[Category:" .. category .. "]]"
end,
categories))
end
if testing then
table.insert(output, pagename)
if categories == "" then
categories = '<span class="error">failed to generate categories for ' .. pagename .. '</span>'
else
categories = mw.ustring.gsub(categories, "%]%]%[%[", "]]\n[[")
categories = frame:extensionTag{ name = "syntaxhighlight", content = categories }
end
end
return table.concat(output) .. categories
end
local export = {}
local m_params = require("Module:parameters")
local m_IPA = require("Module:IPA")
local m_template_link = require("Module:zm-pron")
local lang = require("Module:languages").getByCode("zm")
local sc = require("Module:scripts").getByCode("Latn")
function export.tag_text(text, face)
return require("Module:script utilities").tag_text(text, lang, sc, face)
end
function export.link(term, face)
return require("Module:links").full_link(
{ term = term, lang = lang, sc = sc }, face
)
end
local U = mw.ustring.char
local sub = mw.ustring.sub
local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local find = mw.ustring.find
local match = mw.ustring.match
local match = mw.ustring.match
local gmatch = mw.ustring.gmatch
local gmatch = mw.ustring.gmatch
local find = mw.ustring.find
local gsub = mw.ustring.gsub
local u = mw.ustring.char
local split = mw.text.split
local gsplit = mw.text.gsplit


local long = "ː"
local nonsyllabic = U(0x32F) -- inverted breve below
local syllabic = U(0x0329)
local syllabic_below = U(0x030D)
local raised = U(0x31D) -- uptack below
local voiceless = U(0x30A) -- ring above
local caron = U(0x30C) -- combining caron
local tie = U(0x361) -- combining double inverted breve
local primary_stress = "ˈ"
local secondary_stress = "ˌ"


local data = {
-- To avoid weird annoying cursor behavior
["c"] = "t" .. tie .. "s",
local GRAVE = u(0x0300) -- COMBINING GRAVE ACCENT ̀◌
["č"] = "t" .. tie .. "ʃ",
local ACUTE = u(0x0301) -- COMBINING ACUTE ACCENT
["dź"] = "d" .. tie .. "ʑ",
local SYLL = u(0x0329) -- COMBINING VERTICAL LINE BELOW ̩◌
["e"] = "e",
local VL = u(0x0325) -- COMBINING RING BELOW ̥◌
["è"] = "ɛ",
local AFFR = u(0x0361) -- COMBINING DOUBLE INVERTED BREVE ͡
["g"] = "ɡ",
["h"] = "x",
["i"] = "i",
["nj"] = "ɲ",
["q"] = "k",
["š"] = "ʃ",
["t"] = "t",
["ć"] = "t" .. tie .. "ɕ",
["x"] = "ks",
["y"] = "ɪ",
["ž"] = "ʒ",
["ai"] = "ɛ" .. long,
["au"] = "ɔ" .. long,
["\""] = primary_stress,
["%"] = secondary_stress,
["?"] = "ʔ",
}


-- Add data["a"] = "a", data["b"] = "b", etc.
local back_vowel = "aouɔǫō"
for character in gmatch("abdfjklmnoprstuvz ", ".") do
local front_vowel = "ieɛɪ"
data[character] = character
local vowels = "[" .. back_vowel .. front_vowel .. "]"
end
local acuted = "[áéíóúýÉÓ]"
local oral = "áéíóúýÉÓaouɔieɛ"
local palatal = "[ʨjʎʃʒʥʤʧʦʣɕʑ]"
local sonorant = "[rl]"
local plosives = "[ptkbdg]"
local velar = "[ɡkx]"
local consonants = "[mnptkbdɡfvszxrljɲŋʋʎʨjʎʃʒʥʤʧʤʣʦɕʑ]"


--[[ This allows multiple-character sounds to be replaced
local export = {}
with single characters to make them easier to process. ]]


local multiple_to_single = {
local rules = {
["t" .. tie .. "s" ] = "ʦ",
{"ai", "ɛ"}, {"", "É"}, {"au", "ɔ"}, {"", "Ó"}, {"è", "ɛ"}, {"ò", "ɔ"}, {"y", "ɪ"},
["t" .. tie .. "ɕ" ] = "ʨ",
{"", "ʥ"}, {"", "ʤ"}, {"c", "ʦ"}, {"ć", "ʨ"}, {"nj", "ɲ"}, {"č", "ʧ"}, {"ž", "ʒ"}, {"š", "ʃ"}, {"lj", "ʎ"},
["d" .. tie .. "ʑ" ] = "ʥ",
{"h", "x"}, {"g", "ɡ"}, {"ǫ", "o"}, {"ō", "o"}, {"", "ʃt͡ʃ"}, {"ou", "u"}, {"ś", "ɕ"}, {"ź", "ʑ"},
["t" .. tie .. "ʃ" ] = "ʧ",
["d" .. tie .. "z" ] = "ʣ",
{"(" .. vowels .. ")[lv]$", "%1ʋ"}, {"(" .. acuted .. ")[lv]$", "%1ʋ"},
["d" .. tie .. "ʒ" ] = "ʤ",
}
 
--[[ "voiceless" and "voiced" are obstruents only;
sonorants are not involved in voicing assimilation. ]]
 
-- ʦ, ʧ, "" replace t͡s, t͡ʃ, r̝̊
local voiceless = { "p", "t", "k", "f", "s", "ʃ", "x", "ʦ", "ʧ", "ʨ", "ʔ" }
-- "ʣ", ʤ, ř replace d͡z, d͡ʒ, r̝
local voiced = { "b", "d", "ʥ", "ɡ", "v", "z", "ʒ", "ʣ", "ʤ" }
local sonorants = { "m", "n", "ɲ", "r", "l", "j", }
local consonant = "[" .. table.concat(sonorants) .. "ŋ"
.. table.concat(voiceless) .. table.concat(voiced) .. "]"
assimil_consonants = {}
assimil_consonants.voiceless = voiceless
assimil_consonants.voiced = voiced
 
local features = {}
local indices = {}
for index, consonant in pairs(voiceless) do
if not features[consonant] then
features[consonant] = {}
end
features[consonant]["voicing"] = "voiceless"
indices[consonant] = index
end
 
for index, consonant in pairs (voiced) do
if not features[consonant] then
features[consonant] = {}
end
features[consonant]["voicing"] = "voiced"
indices[consonant] = index
end
local short_vowel = "[aeɛiɪou]"
{"(" .. plosives .. ")[ptkbdg]$", "[ptkbdg]"},
local long_vowel = "[ɛɔ]" .. long
local syllabic_consonant = "[mnrl]" .. syllabic
 
-- all but v and r̝
local causing_assimilation =
gsub(
"[" .. table.concat(voiceless) .. table.concat(voiced) .. "ʔ]",
"[vř]",
""
)
 
local assimilable = "[" .. table.concat(voiceless):gsub("ʔ", "") .. table.concat(voiced) .. "]"
 
local function regressively_assimilate(IPA)
IPA = gsub(
IPA,
"(" .. assimilable .. "+)(" .. causing_assimilation .. ")",
function (assimilated, assimilator)
local voicing = features[assimilator] and features[assimilator].voicing
or error('The consonant "' .. consonant
.. '" is not recognized by the function "regressively_assimilate".')
return gsub(
assimilated,
".",
function (consonant)
return assimil_consonants[voicing][indices[consonant]]
end)
.. assimilator
end)
IPA = gsub(IPA, "smus", "zmus")
{"pt" , "t"}, {"pk" , "k"}, {"tp" , "p"}, {"tk" , "k"}, {"kp" , "p"}, {"kt" , "t"},
{"bd" , "d"}, {"bg" , "g"}, {"db" , "b"}, {"dg" , "g"}, {"gb" , "b"}, {"gd" , "d"},
return IPA
{"(" .. consonants ..")([rŕ])(" .. consonants ..")", "%1ə%2" .. SYLL .. "%3"}, {"(" .. consonants ..")r$", "%1ər"},
end
{"n(" .. velar .. ")", "ŋ%1"},
 
{"p(" .. vowels .. ")", "pʰ%1"}, {"t(" .. vowels .. ")", "tʰ%1"}, {"k(" .. vowels .. ")", "kʰ%1"},
local function devoice_finally(IPA)
{"p(" .. acuted .. ")", "pʰ%1"}, {"t(" .. acuted .. ")", "tʰ%1"}, {"k(" .. acuted .. ")", "kʰ%1"},
local obstruent = "[" .. table.concat(voiced) .. table.concat(voiceless) .. "]"
IPA = gsub(
{"(" .. palatal .. ")e", "%1ɛ"}, {"(" .. palatal .. ")é", "%1É"},
IPA,
{"(" .. palatal .. ")o", "%1ɔ"}, {"(" .. palatal .. "", "%1Ó"},
"(" .. obstruent .. "+)#",
function (final_obstruents)
return gsub(
final_obstruents,
".",
function (obstruent)
return voiceless[indices[obstruent]]
end)
.. "#"
end)
return IPA
{"É", "ɛ" .. ACUTE}, {"Ó", "ɔ" .. ACUTE}, {"ý", "ɪ" .. ACUTE},
end
}
 
local affricates = {
{"ʥ", "d͡ʑ"}, {"ʤ", "d͡ʒ"}, {"ʦ", "t͡s"}, {"ʨ", "t͡ɕ"}, {"ʧ", "t͡ʃ"}, {"ʣ", "d͡z"},
}


local function devoice_fricative_r(IPA)
function export.crux(term, d)
-- all but r̝̊, which is added by this function
term = mw.ustring.lower(term)
local voiceless = gsub("[" .. table.concat(voiceless) .. "]", "ṙ", "")
-- ř represents r̝, "ṙ" represents r̝̊
for _, rule in ipairs(rules) do
IPA = gsub(IPA, "(" .. voiceless .. ")" .. "ř", "%1ṙ")
term = gsub(term, rule[1], rule[2])
IPA = gsub(IPA, "ř" .. "(" .. voiceless .. ")", "ṙ%1")
end
return IPA
if d == "c" then term = gsub(term, "ʨ", "ʧ"); term = gsub(term, "ʥ", "ʤ") end
end
if d == "s" then term = gsub(term, "ʨ", "ʦ"); term = gsub(term, "ʥ", "ʣ"); term = gsub(term, "ʰ", "") end
if d == "s" then term = gsub(term, "aj", "ɛː"); term =gsub(term, "ej", "ɛː") end
if d == "c" then term = gsub(term, "aj", "ɛː"); term =gsub(term, "ej", "ɛː") end
if d == "c" then term = gsub(term, "a", "ɐ"); term = gsub(term, "e", "ɪ"); term = gsub(term, "i", "ɪ"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "ʊ")  end
if d == "s" then term = gsub(term, "a", "ɐ"); term = gsub(term, "e", "ɛ"); term = gsub(term, "i", "e"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "o"); term = gsub(term, "ɪ", "i"); term = gsub(term, "ɪ́", "í"); term = gsub(term, "ų", "u")  end
if d == "n" then term = gsub(term, "a", "ə"); term = gsub(term, "e", "ə"); term = gsub(term, "i", "y"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "ʊ"); term = gsub(term, "ɪ", "ɨ"); term = gsub(term, "ɪ́", "ɨ́"); term = gsub(term, "y", "ɪ")  end


local function syllabicize_sonorants(IPA)
-- all except ɲ and j
local sonorant = gsub("[" .. table.concat(sonorants) .. "]", "[ɲj]", "")
local obstruent = "[" .. table.concat(voiced) .. table.concat(voiceless) .. "]"
-- between a consonant and an obstruent
for _, aff in ipairs(affricates) do
IPA = gsub(
term = gsub(term, aff[1], aff[2])
IPA,
end
"(" .. consonant .. "+" .. sonorant .. ")(" .. consonant .. ")",
"%1" .. syllabic .. "%2"
)
-- at the end of a word after an obstruent
return term
IPA = gsub(IPA, "(" .. obstruent .. sonorant .. ")#", "%1" .. syllabic)
return IPA
end
end


local function assimilate_nasal(IPA)
local velar = "[ɡk]"
IPA = gsub(IPA, "n(" .. velar .. ")", "ŋ%1")
return IPA
end


local function add_stress(IPA)
function IPA_span(items)
local syllable_count = m_syllables.getVowels(IPA, lang)
local bits = {}
for _, item in ipairs(items) do
if not ( nostress or find(IPA, ".#.") or find(IPA, primary_stress) ) then
local bit = "<span style=\"font-size:110%;font-family:'Gentium','DejaVu Sans','Segoe UI',sans-serif>" .. item.pron .. "</span>"
IPA = primary_stress .. IPA
table.insert(bits, bit)
end
end
return table.concat(bits)
return IPA
end
end


local function syllabify(IPA)
function format_IPA(items)
local syllables = {}
return "[[w:IPA chart|IPA]]<sup>([[IPA for Zemljask|key]])</sup>:&#32;" .. IPA_span(items)
local working_string = IPA
local noninitial_cluster = match(working_string, ".(" .. consonant .. consonant .. ").")
local has_cluster = noninitial_cluster and not find(noninitial_cluster, "(.)%1")
if not ( has_cluster or find(working_string, " ") ) then
while #working_string > 0 do
local syllable = match(working_string, "^" .. consonant .. "*" .. diphthong)
or match(working_string, "^" .. consonant .. "*" .. long_vowel)
or match(working_string, "^" .. consonant .. "*" .. short_vowel)
or match(working_string, "^" .. consonant .. "*" .. syllabic_consonant)
if syllable then
table.insert(syllables, syllable)
working_string = gsub(working_string, syllable, "", 1)
elseif find(working_string, "^" .. consonant .. "+$")
or find(working_string, primary_stress)
then
syllables[#syllables] = syllables[#syllables] .. working_string
working_string = ""
else
error('The function "syllabify" could not find a syllable '
.. 'in the IPA transcription "' .. working_string .. '".')
end
end
end
if #syllables > 0 then
IPA = table.concat(syllables, ".")
end
return IPA
end
end


local function apply_rules(IPA)
function line_format(pronunciation, dialect)
--[[ Adds # at word boundaries and in place of spaces, to
local full_pronunciations = {}
unify treatment of initial and final conditions.
local IPA_args = {{pron = '[' .. pronunciation .. ']'}}
# is commonly used in phonological rule notation
table.insert(full_pronunciations, format_IPA(IPA_args))
to represent word boundaries. ]]
return "(''" .. table.concat(dialect, ", ") .. "'')" .. ' ' .. table.concat(full_pronunciations, ' or ')
IPA = "#" .. IPA .. "#"
IPA = gsub(IPA, "%s+", "#")
-- Handle consonantal prepositions: v, z.
IPA = gsub(
IPA,
"(#[vz])#(.)",
function (preposition, initial_sound)
if find(initial_sound, short_vowel) then
return preposition .. "ʔ" .. initial_sound
else
return preposition .. initial_sound
end
end)
for sound, character in pairs(multiple_to_single) do
IPA = gsub(IPA, sound, character)
end
IPA = regressively_assimilate(IPA)
IPA = devoice_finally(IPA)
IPA = devoice_fricative_r(IPA)
IPA = syllabicize_sonorants(IPA)
IPA = assimilate_nasal(IPA)
IPA = add_stress(IPA, nostress)
for sound, character in pairs(multiple_to_single) do
IPA = gsub(IPA, character, sound)
end
--[[ This replaces double (geminate) with single consonants,
and changes a stop plus affricate to affricate:
for instance, [tt͡s] to [t͡s]. ]]
IPA = gsub(IPA, "(" .. consonant .. ")%1", "%1")
-- Replace # with space or remove it.
IPA = gsub(IPA, "([^" .. primary_stress .. secondary_stress .. "])#(.)", "%1 %2")
IPA = gsub(IPA, "#", "")
return IPA
end
end


function export.toIPA(term, nostress)
function separate_word(term, d)
local IPA = {}
local result = {}
local transcription = mw.ustring.lower(term)
transcription = gsub(transcription, "^%-", "")
transcription = gsub(transcription, "%-?$", "")
transcription = gsub(transcription, "nn", "n") -- similar operation is applied to IPA above
for regex, replacement in pairs(replacements) do
transcription = gsub(transcription, regex, replacement)
end
transcription = mw.ustring.toNFC(transcription) -- Recompose combining caron.
local working_string = transcription
while mw.ustring.len(working_string) > 0 do
for word in gsplit(term, " ") do
local IPA_letter
table.insert(result, export.crux(word, d))
local letter = sub(working_string, 1, 1)
local twoletters = sub(working_string, 1, 2) or ""
if data[twoletters] then
IPA_letter = data[twoletters]
working_string = sub(working_string, 3)
else
IPA_letter = data[letter]
or error('The letter "' .. tostring(letter)
.. '" is not a member of the Czech alphabet.')
working_string = sub(working_string, 2)
end
table.insert(IPA, IPA_letter)
end
end
IPA = table.concat(IPA)
return table.concat(result, " ")
IPA = apply_rules(IPA, nostress)
return IPA, transcription
end
end


function export.show(frame)
function export.show(frame)
local params = {
local params = {
[1] = {},
[1] = { default = mw.title.getCurrentTitle().nsText == 'Template' and "dźélo" or mw.title.getCurrentTitle().text },
["nostress"] = { type = "boolean" },
}
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local term = args[1]
local args = m_params.process(frame:getParent().args, params)
local ipa = "* "
local title = mw.title.getCurrentTitle()
ipa = ipa .. line_format(separate_word(term), {'Standard'})
local namespace = title.nsText
local term = args[1] or namespace == "Template" and "příklad" or title.text
local IPA = export.toIPA(term, nostress)
if export.crux(term, "c") ~= export.crux(term) then
ipa = ipa .. "\n* "
IPA = "[" .. IPA .. "]"
ipa = ipa .. line_format(separate_word(term, "n"), {'Northern'})
IPA = m_IPA.format_IPA_full(lang, { { pron = IPA } } )
end
return IPA
if export.crux(term, "s") ~= export.crux(term) then
end
ipa = ipa .. "\n* "
 
ipa = ipa .. line_format(separate_word(term, "c"), {'Central'})
function export.example(frame)
local output = {
[[
{| class="wikitable"
]]
}
local row
local namespace = mw.title.getCurrentTitle().nsText
if namespace == "Template" then
table.insert(
output,  
[[
! headword !! code !! result
]]
)
row =
[[
|-
| link || template_code || IPA
]]
else
table.insert(
output,  
[[
! headword !! result
]]
)
row =
[[
|-
| link || IPA
]]
end
end
local params = {
[1] = { required = true },
}
local args = m_params.process(frame:getParent().args, params)
local terms = mw.text.split(args[1] or "příklad", ", ")
for _, term in ipairs(terms) do
local template_parameter
local respelling_regex = "[%a\"%?%% ]+"
local respelling = match(term, "(" .. respelling_regex .. ") %(")
or match(term, respelling_regex)
local entry = match(term, "%(([%a ]+)%)") or respelling
local link = export.link(entry)
local IPA, transcribable = export.toIPA(respelling)
IPA = m_IPA.format_IPA_full(lang, { { pron = "[" .. IPA .. "]" } } )
if term ~= respelling then
template_parameter = respelling
end
if term ~= transcribable then
link = link .. " (" .. export.tag_text(transcribable) .. ")"
end
template_code = m_template_link.format_link{ "cs-IPA", template_parameter }
local content = {
if export.crux(term, "n") ~= export.crux(term) then
link = link,
ipa = ipa .. "\n* "
template_code = template_code,
ipa = ipa .. line_format(separate_word(term, "s"), {'Southern'})
IPA = IPA
}
local function add_content(name)
if content[name] then
return content[name]
else
error('No content for "' .. name .. '".')
end
end
local current_row = gsub(row, "[%a_]+", add_content)
table.insert(output, current_row)
end
end
table.insert(output, "|}")
return ipa
return table.concat(output)
end
end


return export
return export

Latest revision as of 02:48, 20 July 2022



local sub = mw.ustring.sub
local find = mw.ustring.find
local match = mw.ustring.match
local gmatch = mw.ustring.gmatch
local gsub = mw.ustring.gsub
local u = mw.ustring.char
local split = mw.text.split
local gsplit = mw.text.gsplit


-- To avoid weird annoying cursor behavior
local GRAVE = u(0x0300) -- COMBINING GRAVE ACCENT ̀◌
local ACUTE = u(0x0301) -- COMBINING ACUTE ACCENT
local SYLL = u(0x0329) -- COMBINING VERTICAL LINE BELOW ̩◌
local VL = u(0x0325) -- COMBINING RING BELOW ̥◌
local AFFR = u(0x0361) -- COMBINING DOUBLE INVERTED BREVE ͡

local back_vowel = "aouɔǫō"
local front_vowel = "ieɛɪ"
local vowels = "[" .. back_vowel .. front_vowel .. "]"
local acuted = "[áéíóúýÉÓ]"
local oral = "áéíóúýÉÓaouɔieɛ"
local palatal = "[ʨjʎʃʒʥʤʧʦʣɕʑ]"
local sonorant = "[rl]"
local plosives = "[ptkbdg]"
local velar = "[ɡkx]"
local consonants = "[mnptkbdɡfvszxrljɲŋʋʎʨjʎʃʒʥʤʧʤʣʦɕʑ]"

local export = {}

local rules = {
	{"ai", "ɛ"}, {"aí", "É"}, {"au", "ɔ"}, {"aú", "Ó"}, {"è", "ɛ"}, {"ò", "ɔ"}, {"y", "ɪ"},
	{"dź", "ʥ"}, {"dž", "ʤ"}, {"c", "ʦ"}, {"ć", "ʨ"}, {"nj", "ɲ"}, {"č", "ʧ"}, {"ž", "ʒ"},  {"š", "ʃ"},  {"lj", "ʎ"},
	{"h", "x"}, {"g", "ɡ"}, {"ǫ", "o"}, {"ō", "o"}, {"sč", "ʃt͡ʃ"}, {"ou", "u"}, {"ś", "ɕ"}, {"ź", "ʑ"},
	
	{"(" .. vowels .. ")[lv]$", "%1ʋ"}, {"(" .. acuted .. ")[lv]$", "%1ʋ"},
	
	{"(" .. plosives .. ")[ptkbdg]$", "[ptkbdg]"},
	
	{"pt" , "t"}, {"pk" , "k"}, {"tp" , "p"}, {"tk" , "k"}, {"kp" , "p"}, {"kt" , "t"},
	{"bd" , "d"}, {"bg" , "g"}, {"db" , "b"}, {"dg" , "g"}, {"gb" , "b"}, {"gd" , "d"},
	
	{"(" .. consonants ..")([rŕ])(" .. consonants ..")", "%1ə%2" .. SYLL .. "%3"}, {"(" .. consonants ..")r$", "%1ər"},
	{"n(" .. velar .. ")", "ŋ%1"},
	{"p(" .. vowels .. ")", "pʰ%1"}, {"t(" .. vowels .. ")", "tʰ%1"}, {"k(" .. vowels .. ")", "kʰ%1"},
	{"p(" .. acuted .. ")", "pʰ%1"}, {"t(" .. acuted .. ")", "tʰ%1"}, {"k(" .. acuted .. ")", "kʰ%1"},
	
	{"(" .. palatal .. ")e", "%1ɛ"}, {"(" .. palatal .. ")é", "%1É"},
	{"(" .. palatal .. ")o", "%1ɔ"}, {"(" .. palatal .. ")ó", "%1Ó"},
	
	{"É", "ɛ" .. ACUTE}, {"Ó", "ɔ" .. ACUTE}, {"ý", "ɪ" .. ACUTE},
}

local affricates = {
	{"ʥ", "d͡ʑ"}, {"ʤ", "d͡ʒ"}, {"ʦ", "t͡s"}, {"ʨ", "t͡ɕ"}, {"ʧ", "t͡ʃ"}, {"ʣ", "d͡z"},
}

function export.crux(term, d)
	term = mw.ustring.lower(term)
	
	for _, rule in ipairs(rules) do
		term = gsub(term, rule[1], rule[2])
	end
	
	if d == "c" then term = gsub(term, "ʨ", "ʧ"); term = gsub(term, "ʥ", "ʤ") end
	if d == "s" then term = gsub(term, "ʨ", "ʦ"); term = gsub(term, "ʥ", "ʣ"); term = gsub(term, "ʰ", "") end
	if d == "s" then term = gsub(term, "aj", "ɛː"); term =gsub(term, "ej", "ɛː") end
	if d == "c" then term = gsub(term, "aj", "ɛː"); term =gsub(term, "ej", "ɛː") end
	if d == "c" then term = gsub(term, "a", "ɐ"); term = gsub(term, "e", "ɪ"); term = gsub(term, "i", "ɪ"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "ʊ")  end
	if d == "s" then term = gsub(term, "a", "ɐ"); term = gsub(term, "e", "ɛ"); term = gsub(term, "i", "e"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "o"); term = gsub(term, "ɪ", "i"); term = gsub(term, "ɪ́", "í"); term = gsub(term, "ų", "u")  end
	if d == "n" then term = gsub(term, "a", "ə"); term = gsub(term, "e", "ə"); term = gsub(term, "i", "y"); term = gsub(term, "o", "ɔ"); term = gsub(term, "u", "ʊ"); term = gsub(term, "ɪ", "ɨ"); term = gsub(term, "ɪ́", "ɨ́"); term = gsub(term, "y", "ɪ")  end

	
	for _, aff in ipairs(affricates) do
		term = gsub(term, aff[1], aff[2])
	end
	
	return term
end


function IPA_span(items)
	local bits = {}
	for _, item in ipairs(items) do
		local bit = "<span style=\"font-size:110%;font-family:'Gentium','DejaVu Sans','Segoe UI',sans-serif>" .. item.pron .. "</span>"
		table.insert(bits, bit)
	end
	return table.concat(bits)
end

function format_IPA(items)
	return "[[w:IPA chart|IPA]]<sup>([[IPA for Zemljask|key]])</sup>:&#32;" .. IPA_span(items)
end

function line_format(pronunciation, dialect)
	local full_pronunciations = {}
	local IPA_args = {{pron = '[' .. pronunciation .. ']'}}
	table.insert(full_pronunciations, format_IPA(IPA_args))
	return "(''" .. table.concat(dialect, ", ") .. "'')" .. ' ' .. table.concat(full_pronunciations, ' or ')
end

function separate_word(term, d)
	local result = {}
	
	for word in gsplit(term, " ") do
		table.insert(result, export.crux(word, d))
	end
	
	return table.concat(result, " ")
end

function export.show(frame)
	local params = {
		[1] = { default = mw.title.getCurrentTitle().nsText == 'Template' and "dźélo" or mw.title.getCurrentTitle().text },	
	}
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local term = args[1]
	
	local ipa = "* "
	ipa = ipa .. line_format(separate_word(term), {'Standard'})
	
	if export.crux(term, "c") ~= export.crux(term) then
		ipa = ipa .. "\n* "
		ipa = ipa .. line_format(separate_word(term, "n"), {'Northern'})
	end
	
	if export.crux(term, "s") ~= export.crux(term) then
		ipa = ipa .. "\n* "
		ipa = ipa .. line_format(separate_word(term, "c"), {'Central'})
	end
		
	if export.crux(term, "n") ~= export.crux(term) then
		ipa = ipa .. "\n* "
		ipa = ipa .. line_format(separate_word(term, "s"), {'Southern'})
	end
	
	return ipa
end

return export