Module:Th-rm: Difference between revisions
ReisuDesign (talk | contribs) Created page with "local p = {} local U = mw.ustring local gsub = U.gsub local find = U.find local sub = U.sub local match = U.match local len = U.len local INITIAL = { ['ก'] = 'k', ['ข'] = 'kh', ['ฃ'] = 'kh', ['ค'] = 'kh', ['ฅ'] = 'kh', ['ฆ'] = 'kh', ['ง'] = 'ng', ['จ'] = 'ch', ['ฉ'] = 'ch', ['ช'] = 'ch', ['ซ'] = 's', ['ฌ'] = 'ch', ['ญ'] = 'y', ['ฎ'] = 'd', ['ฏ'] = 't', ['ฐ'] = 'th', ['ฑ'] = 'th', ['ฒ'] = 'th', ['ณ'] = 'n', ['ด'] = 'd'..." |
ReisuDesign (talk | contribs) No edit summary |
||
| Line 3: | Line 3: | ||
local U = mw.ustring | local U = mw.ustring | ||
local gsub = U.gsub | local gsub = U.gsub | ||
local | local match = U.match | ||
local sub = U.sub | local sub = U.sub | ||
local len = U.len | local len = U.len | ||
| Line 12: | Line 11: | ||
['ข'] = 'kh', ['ฃ'] = 'kh', ['ค'] = 'kh', ['ฅ'] = 'kh', ['ฆ'] = 'kh', | ['ข'] = 'kh', ['ฃ'] = 'kh', ['ค'] = 'kh', ['ฅ'] = 'kh', ['ฆ'] = 'kh', | ||
['ง'] = 'ng', | ['ง'] = 'ng', | ||
['จ'] = 'ch', ['ฉ'] = 'ch', ['ช'] = 'ch', | ['จ'] = 'ch', | ||
['ฉ'] = 'ch', ['ช'] = 'ch', | |||
['ซ'] = 's', | ['ซ'] = 's', | ||
['ฌ'] = 'ch', | ['ฌ'] = 'ch', | ||
| Line 46: | Line 46: | ||
['ข'] = 'k', ['ฃ'] = 'k', ['ค'] = 'k', ['ฅ'] = 'k', ['ฆ'] = 'k', | ['ข'] = 'k', ['ฃ'] = 'k', ['ค'] = 'k', ['ฅ'] = 'k', ['ฆ'] = 'k', | ||
['ง'] = 'ng', | ['ง'] = 'ng', | ||
['จ'] = 't', ['ฉ'] = 't', ['ช'] = 't', [' | ['จ'] = 't', | ||
[' | ['ฉ'] = 't', ['ช'] = 't', ['ซ'] = 't', | ||
['ฌ'] = '', | |||
['ญ'] = 'n', | ['ญ'] = 'n', | ||
['ฎ'] = 't', ['ฏ'] = 't', | ['ฎ'] = 't', ['ฏ'] = 't', | ||
| Line 71: | Line 72: | ||
} | } | ||
local CONSONANTS = 'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ' | |||
local | |||
local function isConsonant(c) | local function isConsonant(c) | ||
return c and | return c and match(c, '[' .. CONSONANTS .. ']') ~= nil | ||
end | end | ||
| Line 153: | Line 82: | ||
end | end | ||
local function | local function isVowelMark(c) | ||
return c and match(c, '[ | return c and match(c, '[ะาิีึืุูัำเแโใไอ]') ~= nil | ||
end | end | ||
| Line 168: | Line 93: | ||
end | end | ||
local function | local function removeMarks(str) | ||
-- Tone marks are not represented in RTGS. | |||
-- Tone marks | |||
str = gsub(str, '[่้๊๋]', '') | str = gsub(str, '[่้๊๋]', '') | ||
-- | -- Mai thanthakhat makes the marked consonant silent. | ||
str = gsub(str, ' | str = gsub(str, '([ก-ฮ])์', '') | ||
return str | return str | ||
| Line 190: | Line 104: | ||
local function getVowel(str, pos) | local function getVowel(str, pos) | ||
local | local s = sub(str, pos, -1) | ||
-- | -- Longest / most specific patterns first. | ||
local patterns = { | local patterns = { | ||
{ 'เ', 'ื', 'อ', 'ย', 'ueai' }, | { 'เ', 'ื', 'อ', 'ย', 'ueai' }, | ||
{ 'เ', 'ี', 'ย', 'ว', 'iao' }, | { 'เ', 'ี', 'ย', 'ว', 'iao' }, | ||
{ 'เ', 'ี', 'ย', 'ะ', 'ia' }, | { 'เ', 'ี', 'ย', 'ะ', 'ia' }, | ||
{ 'เ', 'ี', 'ย', '', | { 'เ', 'ี', 'ย', '', 'ia' }, | ||
{ 'เ', 'ื', 'อ', 'ะ', 'uea' }, | { 'เ', 'ื', 'อ', 'ะ', 'uea' }, | ||
{ 'เ', 'ื', 'อ', '', | { 'เ', 'ื', 'อ', '', 'uea' }, | ||
{ '', 'ั', 'ว', 'ะ', 'ua' }, | |||
{ '', 'ั', 'ว', '', 'ua' }, | |||
{ 'แ', '็', 'ว', '', 'aeo' }, | |||
{ 'แ', 'ว', '', '', 'aeo' }, | |||
{ 'เ', '็', 'ว', '', 'eo' }, | { 'เ', '็', 'ว', '', 'eo' }, | ||
{ 'เ', 'ว', '', '', 'eo' }, | { 'เ', 'ว', '', '', 'eo' }, | ||
{ ' | { '', 'ิ', 'ว', '', 'io' }, | ||
{ '', ' | { '', 'ุ', 'ย', '', 'ui' }, | ||
{ ' | { '', 'ว', 'ย', '', 'uai' }, | ||
{ '', ' | { 'เ', 'ื', 'อ', '', 'ue' }, | ||
{ '', ' | { 'เ', 'ื', '', '', 'ue' }, | ||
{ 'เ', 'า', '', '', 'ao' }, | { 'เ', 'า', '', '', 'ao' }, | ||
{ '', 'า', 'ว', '', 'ao' }, | { '', 'า', 'ว', '', 'ao' }, | ||
{ '', ' | { 'โ', 'ย', '', '', 'oi' }, | ||
{ '', ' | { '', 'อ', 'ย', '', 'oi' }, | ||
{ '', ' | |||
{ 'เ', 'ย', '', '', 'oei' }, | |||
{ 'ใ', '', '', '', 'ai' }, | { 'ใ', '', '', '', 'ai' }, | ||
{ 'ไ', '', '', '', 'ai' }, | { 'ไ', '', '', '', 'ai' }, | ||
{ '', 'ั', 'ย', '', 'ai' }, | { '', 'ั', 'ย', '', 'ai' }, | ||
{ '', 'า', 'ย', '', 'ai' }, | { '', 'า', 'ย', '', 'ai' }, | ||
{ 'เ', ' | { 'เ', 'าะ', '', '', 'o' }, | ||
{ 'โ', 'ะ', '', '', 'o' }, | { 'โ', 'ะ', '', '', 'o' }, | ||
{ ' | { 'โ', '', '', '', 'o' }, | ||
{ ' | { '', 'อ', '', '', 'o' }, | ||
{ 'เ', 'อะ', '', '', 'oe' }, | |||
{ 'เ', 'ิ', '', '', 'oe' }, | |||
{ 'เ', 'อ', '', '', 'oe' }, | { 'เ', 'อ', '', '', 'oe' }, | ||
{ 'แ', 'ะ', '', '', 'ae' }, | { 'แ', 'ะ', '', '', 'ae' }, | ||
{ 'แ', '', '', '', 'ae' }, | { 'แ', '', '', '', 'ae' }, | ||
{ 'เ', 'ะ', '', '', 'e' }, | { 'เ', 'ะ', '', '', 'e' }, | ||
{ 'เ', '็', '', '', 'e' }, | { 'เ', '็', '', '', 'e' }, | ||
{ 'เ', '', '', '', 'e' }, | { 'เ', '', '', '', 'e' }, | ||
{ '', 'ำ', '', '', 'am' }, | { '', 'ำ', '', '', 'am' }, | ||
{ '', 'ะ', '', '', 'a' }, | { '', 'ะ', '', '', 'a' }, | ||
{ '', 'ั', '', '', 'a' }, | { '', 'ั', '', '', 'a' }, | ||
{ '', 'า', '', '', 'a' }, | { '', 'า', '', '', 'a' }, | ||
{ '', 'ิ', '', '', 'i' }, | { '', 'ิ', '', '', 'i' }, | ||
{ '', 'ี', '', '', 'i' }, | { '', 'ี', '', '', 'i' }, | ||
{ '', 'ึ', '', '', 'ue' }, | { '', 'ึ', '', '', 'ue' }, | ||
{ '', 'ื', '', '', 'ue' }, | { '', 'ื', '', '', 'ue' }, | ||
{ '', 'ุ', '', '', 'u' }, | { '', 'ุ', '', '', 'u' }, | ||
{ '', 'ู', '', '', 'u | { '', 'ู', '', '', 'u' } | ||
} | } | ||
for _, v in ipairs(patterns) do | for _, v in ipairs(patterns) do | ||
local a | local a = v[1] or '' | ||
local b = v[2] or '' | |||
local c = v[3] or '' | |||
local d = v[4] or '' | |||
local roman = v[5] or '' | |||
local pattern = a .. b .. c .. d | local pattern = a .. b .. c .. d | ||
if pattern ~= '' and sub( | |||
if pattern ~= '' and sub(s, 1, len(pattern)) == pattern then | |||
return roman, len(pattern) | return roman, len(pattern) | ||
end | end | ||
| Line 269: | Line 193: | ||
end | end | ||
local function | local function romanizeSyllable(str, start) | ||
local | local pos = start | ||
local n = len(str) | |||
local initial = '' | |||
local initialRom = '' | |||
-- Preposed vowels are written before the initial consonant. | |||
local pre = sub(str, pos, pos) | |||
if pre == 'เ' or pre == 'แ' or pre == 'โ' or pre == 'ใ' or pre == 'ไ' then | |||
if | |||
pos = pos + 1 | pos = pos + 1 | ||
end | end | ||
local first = sub(str, pos, pos) | |||
local | |||
if not isConsonant( | if not isConsonant(first) then | ||
return first, 1 | |||
return | |||
end | end | ||
initial = first | |||
initialRom = INITIAL[first] or '' | |||
pos = pos + 1 | pos = pos + 1 | ||
-- ห | -- ห + sonorant consonant: ห is not romanized. | ||
local second = sub(str, pos, pos) | |||
if initial == 'ห' and second and match(second, '[งนมยรลวญณฬ]') then | |||
initial = second | |||
initialRom = INITIAL[second] | |||
pos = pos + 1 | |||
end | end | ||
-- | -- จร-, ซร-, ศร-, สร-: ร is not romanized. | ||
if (initial == 'จ' or initial == 'ซ' or initial == 'ศ' or initial == 'ส') | second = sub(str, pos, pos) | ||
if second == 'ร' | |||
and (initial == 'จ' or initial == 'ซ' or initial == 'ศ' or initial == 'ส') then | |||
pos = pos + 1 | pos = pos + 1 | ||
end | end | ||
-- | -- Read the vowel. | ||
local | local vowelPos | ||
if | if pre == 'เ' or pre == 'แ' or pre == 'โ' or pre == 'ใ' or pre == 'ไ' then | ||
vowelPos = start | |||
else | else | ||
vowelPos = pos | |||
end | end | ||
-- | local vowel, vowelLen = getVowel(str, vowelPos) | ||
-- Advance over the vowel. | |||
if vowelLen > 0 then | if vowelLen > 0 then | ||
pos = vowelPos + vowelLen | |||
end | |||
-- If there was a preposed vowel, getVowel consumed from its position, | |||
-- so the resulting position already includes it. | |||
if vowelLen == 0 and (pre == 'เ' or pre == 'แ' or pre == 'โ' or pre == 'ใ' or pre == 'ไ') then | |||
pos = start + 1 | |||
end | end | ||
-- | -- Final consonant. | ||
local final = sub(str, pos, pos) | local final = sub(str, pos, pos) | ||
local finalRom = '' | local finalRom = '' | ||
| Line 358: | Line 263: | ||
local after = sub(str, pos + 1, pos + 1) | local after = sub(str, pos + 1, pos + 1) | ||
-- | -- If another vowel begins immediately afterward, this consonant | ||
-- | -- belongs to the following syllable. | ||
if not isVowelMark(after) and not (after == 'เ' or after == 'แ' or after == 'โ' or after == 'ใ' or after == 'ไ') then | |||
finalRom = FINAL[final] or '' | finalRom = FINAL[final] or '' | ||
pos = pos + 1 | pos = pos + 1 | ||
-- -ร | -- Final -ร after another final consonant. | ||
if final == 'ร' then | if final == 'ร' then | ||
finalRom = 'n' | finalRom = 'n' | ||
| Line 382: | Line 282: | ||
end | end | ||
return initialRom .. | -- -รร- | ||
-- With a final consonant, รร = a. | |||
-- Without a final consonant, รร = an. | |||
if sub(str, vowelPos, vowelPos + 1) == 'รร' then | |||
if finalRom ~= '' then | |||
vowel = 'a' | |||
else | |||
vowel = 'an' | |||
end | |||
end | |||
return initialRom .. vowel .. finalRom, math.max(1, pos - start) | |||
end | end | ||
local function romanizeWord(word) | local function romanizeWord(word) | ||
local result = {} | |||
local | |||
local pos = 1 | local pos = 1 | ||
local n = len(word) | local n = len(word) | ||
| Line 404: | Line 305: | ||
if c == '<' then | if c == '<' then | ||
local close = find(word, '>', pos + 1, true) | local close = mw.ustring.find(word, '>', pos + 1, true) | ||
if close then | if close then | ||
local marker = sub(word, pos, close) | |||
if marker == '< >' then | |||
table.insert(result, ' ') | |||
elseif marker == '<->' then | |||
table.insert(result, '-') | |||
else | |||
table.insert(result, marker) | |||
end | |||
pos = close + 1 | pos = close + 1 | ||
else | else | ||
table.insert( | table.insert(result, c) | ||
pos = pos + 1 | pos = pos + 1 | ||
end | end | ||
elseif | elseif isThai(c) then | ||
local roman, consumed = romanizeSyllable(word, pos) | local roman, consumed = romanizeSyllable(word, pos) | ||
table.insert( | table.insert(result, roman) | ||
pos = pos + consumed | pos = pos + consumed | ||
else | |||
table.insert(result, c) | |||
pos = pos + 1 | |||
end | end | ||
end | end | ||
return table.concat( | return table.concat(result) | ||
end | end | ||
local function | local function capitalizeWords(str) | ||
local chars = mw.text.split(str, '') | local chars = mw.text.split(str, '') | ||
local | local capitalize = true | ||
for i, c in ipairs(chars) do | for i, c in ipairs(chars) do | ||
if match(c, ' | if match(c, '[A-Za-z]') then | ||
if | if capitalize then | ||
chars[i] = U.upper(c) | chars[i] = U.upper(c) | ||
capitalize = false | |||
end | end | ||
elseif c == ' ' then | elseif c == ' ' or c == '-' then | ||
if | capitalize = true | ||
end | |||
end | |||
return table.concat(chars) | |||
end | |||
local function sentenceCase(str) | |||
local chars = mw.text.split(str, '') | |||
local capitalize = true | |||
for i, c in ipairs(chars) do | |||
if match(c, '[A-Za-z]') then | |||
if capitalize then | |||
chars[i] = U.upper(c) | |||
capitalize = false | |||
end | end | ||
elseif match(c, '[ | elseif match(c, '[.!?]') then | ||
capitalize = true | |||
end | end | ||
end | end | ||
| Line 462: | Line 384: | ||
local str = clean(args[1]) | local str = clean(args[1]) | ||
-- | -- Nothing to romanize. | ||
if not match(str, '[ก-๛]') then | if not match(str, '[ก-๛]') then | ||
return '' | return '' | ||
end | end | ||
str = | str = removeMarks(str) | ||
local result = romanizeWord(str) | local result = romanizeWord(str) | ||
if args.capi then | if args.capi then | ||
result = | result = capitalizeWords(result) | ||
elseif args.sent then | elseif args.sent then | ||
result = | result = sentenceCase(result) | ||
end | end | ||