local export = {}
local gsub = mw.ustring.gsub
local sub = mw.ustring.sub
local match = mw.ustring.match
local initial_ipa = {
= { = "g", = "k", = "mid" },
= { = "j", = "t͡ɕ", = "mid" },
= { = "d", = "d", = "mid" },
= { = "d", = "d", = "mid" },
= { = "dt", = "t", = "mid" },
= { = "dt", = "t", = "mid" },
= { = "b", = "b", = "mid" },
= { = "bp", = "p", = "mid" },
= { = "", = "ʔ", = "mid" },
= { = "ng", = "ŋ", = "low" },
= { = "n", = "n", = "low" },
= { = "n", = "n", = "low" },
= { = "m", = "m", = "low" },
= { = "y", = "j", = "low" },
= { = "y", = "j", = "low" },
= { = "r", = "r", = "low" },
= { = "l", = "l", = "low" },
= { = "l", = "l", = "low" },
= { = "w", = "w", = "low" },
= { = "k", = "kʰ", = "low" },
= { = "k", = "kʰ", = "low" },
= { = "k", = "kʰ", = "low" },
= { = "k", = "kʰ", = "high" },
= { = "k", = "kʰ", = "high" },
= { = "ch", = "t͡ɕʰ", = "low" },
= { = "ch", = "t͡ɕʰ", = "low" },
= { = "ch", = "t͡ɕʰ", = "high" },
= { = "t", = "tʰ", = "low" },
= { = "t", = "tʰ", = "low" },
= { = "t", = "tʰ", = "low" },
= { = "t", = "tʰ", = "low" },
= { = "t", = "tʰ", = "high" },
= { = "t", = "tʰ", = "high" },
= { = "p", = "pʰ", = "low" },
= { = "p", = "pʰ", = "low" },
= { = "p", = "pʰ", = "high" },
= { = "f", = "f", = "low" },
= { = "f", = "f", = "high" },
= { = "s", = "s", = "low" },
= { = "s", = "s", = "high" },
= { = "s", = "s", = "high" },
= { = "s", = "s", = "high" },
= { = "h", = "h", = "low" },
= { = "h", = "h", = "high" },
= { = "ng", = "ŋ", = "high" },
= { = "n", = "n", = "high" },
= { = "m", = "m", = "high" },
= { = "y", = "j", = "high" },
= { = "y", = "j", = "high" },
= { = "r", = "r", = "high" },
= { = "l", = "l", = "high" },
= { = "w", = "w", = "high" },
= { = "…", = "…", = "" },
= { = "]", = "", = "" },
}
local vowel_ipa = {
= {
= {
= "a", = "a", = "i", = "ʉ", = "u", = "e", = "ɛ",
= "o", = "ɔ", = "ɔ", = "ə", = "ə",
= "aa", = "ii", = "uu", = "ʉʉ", = "ee", = "ɛɛ",
= "oo", = "ɔɔ", = "ɔɔn", = "əə",
= "ia", = "ʉa", = "ua",
= "iia", = "ʉʉa", = "uua",
= "iu", = "iiu", = "eo", = "ɛo", = "ao",
= "eeo", = "ɛɛo", = "aao", = "əəo", = "oow",
= "iao",
= "ai", = "ai", = "ai", = "ai",
= "ʉi", = "ɔi", = "əi", = "ui",
= "aai", = "ɔɔi", = "ooi", = "əəi", = "uui",
= "uai", = "ʉai",
= "am",
},
= {
= "a", = "a", = "i", = "ʉ", = "u",
= "ee", = "e", = "ɛ", = "ɛɛ",
= "o", = "ɔ", = "ə",
= "aa", = "ii", = "ʉʉ", = "uu", = "uu",
= "oo", = "ɔɔ", = "əə", = "əə",
= "iia", = "ʉʉa", = "uua",
= "ai", = "ao", = "ɔi",
}
},
= {
= {
= "a", = "a", = "i", = "ɯ", = "u", = "eʔ", = "ɛʔ",
= "oʔ", = "ɔʔ", = "ɔ", = "ɤ", = "ɤʔ",
= "aː", = "iː", = "uː", = "ɯː", = "eː", = "ɛː",
= "oː", = "ɔː", = "ɔːn", = "ɤː",
= "ia̯ʔ", = "ɯa̯ʔ", = "ua̯ʔ",
= "ia̯", = "ɯa̯", = "ua̯",
= "iw", = "iːw", = "ew", = "ɛw", = "aw",
= "eːw", = "ɛːw", = "aːw", = "ɤːw", = "oːw",
= "ia̯w",
= "aj", = "aj", = "aj", = "aj",
= "ɯj", = "ɔj", = "ɤj", = "uj",
= "aːj", = "ɔːj", = "oːj", = "ɤːj", = "uːj",
= "ua̯j", = "ɯa̯j",
= "am",
},
= {
= "a", = "a", = "i", = "ɯ", = "u",
= "eː", = "e", = "ɛ", = "ɛː",
= "o", = "ɔ", = "ɤ",
= "aː", = "iː", = "ɯː", = "uː", = "uː",
= "oː", = "ɔː", = "ɤː", = "ɤː",
= "ia̯", = "ɯa̯", = "ua̯",
= "aj", = "aw", = "ɔj",
}
}
}
local unromLong = {
= true, = true, = true, = true,
= true, = true, = true,
= true,
}
local liveExc = {
= true, = true, = true, = true,
= true, = true, = true, = true,
= true, = true, = true, = true,
= true,
}
-- ย,ว are not included.
-- ช,ซ,ส,ฟ,ล are changed for loanwords.
-- ห,อ,ฮ can never be codas.
local coda_ipa = {
= {
= "k", = "k", = "k", = "k", = "k", = "k",
= "t", = "t", = "ch", = "s", = "t",
= "t", = "t", = "t", = "t", = "t",
= "t", = "t", = "t", = "t", = "t",
= "t", = "t", = "s",
= "p", = "p", = "p", = "p", = "p", = "f", = "p",
= "ng",
= "n", = "n", = "n", = "n", = "l", = "n",
= "m",
},
= {
= "k̚", = "k̚", = "k̚", = "k̚", = "k̚", = "k̚",
= "t̚", = "t̚", = "t͡ɕʰ", = "s", = "t̚",
= "t̚", = "t̚", = "t̚", = "t̚", = "t̚",
= "t̚", = "t̚", = "t̚", = "t̚", = "t̚",
= "t̚", = "t̚", = "s",
= "p̚", = "p̚", = "p̚", = "p̚", = "p̚", = "f", = "p̚",
= "ŋ",
= "n", = "n", = "n", = "n", = "l", = "n",
= "m",
},
}
local tFromMark = {
-- common
= { = "low", = "low", = "falling" },
= { = "falling", = "falling", = "high" },
= { = "high", = "high", = "high" },
= { = "rising", = "rising", = "rising" },
-- forced mid tone
= { = "mid", = "mid", = "mid" },
}
local tNoMark = {
= { = "low", = "low", = "high" },
= { = "low", = "low", = "falling" },
= { = "rising", = "mid", = "mid" },
}
local tRomMarks = {
= "́", = "", = "̀",
= "̌", = "̂",
}
local tLevels = {
= "˦˥", = "˧", = "˨˩",
= "˩˩˦", = "˥˩",
}
local permitted_cluster = {
= 1, = 1, = 1, = 1, = 1
}
function export.translit(text, lang, sc, mode, source)
for word in mw.ustring.gmatch(text, "+") do
local orig_word, class, tMark, tone, long, coda = word, "", false, false, false, false
if match(word, ".?") then
return nil
end
local function coda_decomp(coda_char, mode, source)
local converted_coda = {}
for character in mw.text.gsplit(coda_char, "") do
table.insert(converted_coda, coda_ipa)
end
local cluster = table.concat(converted_coda)
if source == "translit-module" and not permitted_cluster then
return coda_char
else
return cluster
end
end
local function syllable(vowel1, main, glide, vowel2, coda)
tMark = match(vowel2, "")
vowel2 = gsub(vowel2, "", "")
if match(main, "^ห.$") then
local pattern = "^(?)(???ะ?)(?)$"
if match(sub(main, 2, 2) .. glide .. vowel2 .. coda, pattern) then
glide, vowel2, coda = match(sub(main, 2, 2) .. glide .. vowel2 .. coda, pattern)
main = "ห"
end
end
if glide == "ล" and vowel2 .. coda == "" then
coda = glide
glide = ""
end
openness = coda ~= "" and "closed" or "open"
if vowel_ipa then
original_vowel = vowel1 .. glide .. vowel2
vowel, glide = vowel_ipa, ""
else
original_vowel = vowel1 .. vowel2
vowel = vowel_ipa or (vowel1 .. vowel2)
glide = (initial_ipa or initial_ipa)
end
main = gsub(main, "ฺ", "")
initial, class = "", ""
if initial_ipa then
initial, class = initial_ipa, initial_ipa
else
return nil
end
length = (match(vowel, "()%1") or match(vowel, "ː") or unromLong) and "long" or "short"
life = (match(coda, "") or (match(original_vowel, "ย$") and match(vowel, "i$")) or
coda..length == "long" or liveExc) and "live" or "dead"
coda = coda_ipa or coda_decomp(coda, mode, source)
tone = tMark and tFromMark or (tNoMark or tNoMark)
if mode == "paiboon" then
vowel = gsub(vowel, "^(*)()", "%1%2" .. tRomMarks)
else
coda = coda .. tLevels
end
return initial .. glide .. vowel .. coda
end
word = gsub(word, "^(?)(ห?ฺ?)(ฺ??)(?็????ะ?)(??)$", syllable)
text = gsub(text, orig_word, word, 1)
end
local count_syl = 0
if mode == "ipa" then
text, count_syl = gsub(text, "", ".") -- space, common hyphen, en dash
if not match(text, "%.$") then
count_syl = count_syl + 1
end
text = gsub(text, "()(+)$", "%1ʔ%2") -- add ʔ if last syllable ends with
end
if match(text, "") then
if source == "translit-module" then
return nil
else
return "]"
end
else
return mw.ustring.toNFC(text) .. (count_syl > 0 and "]" or "")
end
end
function annotate(main_text, annotation)
return "<span style=\"border-bottom: 1px dotted #000; cursor:help\" " ..
"title=\"" .. annotation .. "\">" .. main_text .. "</span>"
end
-- modified ISO 11940 (so that sound values are more apparent)
local charTable = {
= "k", = "kʰ", = "x", = "g", = "ɣ", = "gʰ", = "ŋ",
= "t͡ɕ", = "t͡ɕʰ", = "d͡ʑ", = "z", = "d͡ʑʰ", = "ɲ",
= "ᶑ", = "ʈ", = "ʈʰ", = "ɖ", = "ɖʰ", = "ɳ",
= "ɗ", = "t", = "tʰ", = "d", = "dʰ", = "n",
= "ɓ", = "p", = "pʰ", = "v", = "b", = "f", = "bʰ", = "m",
= "y", = "r", = "ṛ", = "l", = "ḷ", = "w",
= "ɕ", = "ʂ", = "s", = "h", = "ɭ", = "ɒ", = "ɦ",
= "a", = "ạ", = "ā", = "å", = "i", = "ī",
= "ụ", = "ụ̄", = "u", = "ū", = "ɨ", = "̥", = "฿", -- uses spacing marks
= "Front-e</span>",
= "Front-æ</span>",
= "Front-o</span>",
= "Front-au</span>",
= "Front-ai</span>",
= "ˋ", = "ˆ", = "ˊ", = "ˇ", -- uses spacing marks
= "ǂ", = "«", = "˘", -- uses spacing marks
= annotate("ʻ","CANCEL"), = "˚", = "~", = "§", -- uses spacing marks
= "ǁ", = "»",
= "0", = "1", = "2", = "3", = "4",
= "5", = "6", = "7", = "8", = "9",
= " ", -- for visibility
= "–", -- for visibility
= "…",
}
function export.getCharSeqTbl(text)
local result = {}
for character in mw.text.gsplit(text, "") do
local charDetail = charTable or nil
if charDetail and charDetail then
table.insert(result, annotate(charDetail, charDetail))
else
table.insert(result, charDetail)
end
end
return result
end
function getCharSeq(text)
function tidyChar(text)
text = gsub(text, "%+ %+", " ")
text = gsub(text, "%+%-%+", " — ")
text = gsub(text, "Front%-", "<span style=\"border:1px dotted gray; border-radius:50%; cursor:help\" title=\"Vowel sign appearing in front of the initial consonant.\">")
return text
end
return "<br><small>" .. tidyChar(table.concat(export.getCharSeqTbl(text), " ")) .. "</small>" -- thin space
end
local nSet = {
= annotate("-ɔɔ r-", "In this word, the double consonant combinations กร, ทร, ธร, มร, and หร are pronounced 'gaaw ra', 'thaaw ra', 'maaw ra' and 'haaw ra', respectively."),
= annotate("Reduplication", "This word exhibits reduplication in pronunciation, i.e. one written consonant is used as the final consonant of a syllable as well as the initial consonant of the next syllable."),
= annotate("Short", "The vowel in this word is pronounced irregularly short."),
= annotate("Unorthographical", "This phonetic respelling violates Thai alphabet rules to indicate an irregular pronunciation."),
}
function export.show(frame)
local lang, sc = "th", "Thai"
local args = frame:getParent().args
local pagename = args.pagename or mw.title.getCurrentTitle().text
local p, note = {}, {}
if args then
for ind_note in mw.text.gsplit(args, ",") do
table.insert(note, nSet)
end
end
if args then
for index, item in ipairs(args) do
table.insert(p, (item ~= "") and item or nil)
end
else
table.insert(p, pagename)
end
if match(table.concat(p, "/"), "็*") or match(table.concat(p, "/"), "*็") or match(table.concat(p, "/"), "ิ็") then
table.insert(note, nSet)
if not match(args or "", "short") then
table.insert(note, nSet)
end
end
headFmt = '{| cellpadding=10 style="border-spacing: 2px; border: 1px solid darkgray; text-align:center"'
midFmt = '\n|-\n! bgcolor="#fafeff" style="border-bottom: 1px solid lightgray;border-right: 1px solid lightgray"|'
lastFmt = '\n|-\n!bgcolor="#fafeff" style="border-right: 1px solid lightgray"|'
normCellFmt = '\n|'
preCellFmt = '\n| style="border-right: 1px solid lightgray"|'
orthoCellFmt = '\n|colspan="' .. #p .. '" style="border-bottom: 1px solid lightgray"|'
footFmt = '\n|}'
homEdit = '<div style="float: right; clear: right; font-size:60%"><span class="plainlinks">[' ..
tostring(mw.uri.fullUrl("Modül:th-eşs/veri", { = "edit" })) ..
' edit]</span></div></sup>'
function formatThai(text, mode)
return (match(text, "-$")
and '<span style="background-color:#ffffe6"><small></small></span><br>'
or '') .. '<span lang="th" class="Thai">' .. text .. '</span>'
end
local result = { = {}, = {}, = {}, = {}, = {} }
local m_hom_data = require("Modül:th-eşs/veri")
local m_hom = require("Modül:th-eşs").makeList
local m_fileData = require("Modül:th-söyleniş/dosyalar")
for _, system in ipairs( { "charPhon", "paiboon", "ipa", "homophone", "file" } ) do
for i, spelling in ipairs(p) do
local before = {
= "<span class=\"tr\">",
= "<span class=\"IPA\">/",
= '<div class="vsSwitcher vsToggleCategory-homophones"><span class="vsToggleElement"> </span><div class="vsShow" style="display:none"></div><div class="vsHide">',
= "[[File:",
}
local after = {
= "</span>",
= "/</span>",
= "</div></div>",
}
local function fileAfter(text)
length = ((mw.ustring.len(gsub(text, "", "")) + 1) * 25 + 50)
return "|" .. (length > 200 and 200 or length) ..
"px|center]]]"
end
table.insert(result, (i < #p and preCellFmt or normCellFmt) ..
(system == "charPhon"
and formatThai(spelling, true) .. getCharSeq(spelling)
or (system ~= "homophone"
and (system ~= "file"
and before .. export.translit(spelling, lang, sc, system) .. after
or (m_fileData
and before .. m_fileData .. fileAfter(spelling)
or "" ))
or (m_hom_data and (#m_hom_data > 3
and before .. gsub(m_hom(spelling), ", ", "<br>") .. after
or gsub(m_hom(spelling), ", ", "<br>")) or "" ))))
end
end
inclHom = match(table.concat(result), "Thai") or false
inclFile = match(table.concat(result), "terms") or false
return
headFmt ..
((mw.title.getCurrentTitle().nsText ~= "" and not args.pagename)
and (midFmt .. "'']''" ..
(#note > 0 and "<br><small>{" .. table.concat(note, "; ") .. "}</small>" or ""))
or (pagename == table.concat(p)
and (midFmt .. "'']''")
or (midFmt .. "'']''" ..
orthoCellFmt .. formatThai(pagename)) .. getCharSeq(pagename) ..
midFmt .. "'']''" ..
(#note > 0 and "<br><small>{" .. table.concat(note, "; ") .. "}</small>" or ""))) ..
table.concat(result) ..
midFmt .. "'']''" ..
table.concat(result) ..
((inclHom or inclFile) and midFmt or lastFmt) .. "('']'') ]<sup>(])</sup>" ..
table.concat(result) ..
(inclHom and (inclFile and midFmt or lastFmt) .. "''Sesteşler''" .. homEdit .. table.concat(result) or "") ..
(inclFile and lastFmt .. "''Audio''" .. table.concat(result) or "") ..
footFmt ..
(match(pagename, "ทร") and match(table.concat(result), "ซ") and "]" or "")
end
return export