Module:ja-pron: difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
Kc kennylau (talk | contribs) Fix bug |
Kc kennylau (talk | contribs) fix |
||
Line 233: | Line 233: | ||
function export.accent(text, class, dev, dev2, devm) |
function export.accent(text, class, dev, dev2, devm) |
||
if(type(text)) == "table" then text, class, dev, dev2, devm = text.args[1], text.args[2], text.args["dev"], text.args["dev2"], text.args["devm"] end |
if(type(text)) == "table" then text, class, dev, dev2, devm = text.args[1], text.args[2], text.args["dev"], text.args["dev2"], text.args["devm"] end |
||
text = gsub(text, "%.", "") |
|||
local mora_pos = class |
|||
if dev == "" then dev = false end |
if dev == "" then dev = false end |
||
if dev2 == "" then dev2 = false end |
if dev2 == "" then dev2 = false end |
||
if devm == "" then devm = false end |
if devm == "" then devm = false end |
||
down_first = "<span style=\"border-top:1px solid black;position:relative;padding:1px;\">" |
local down_first = "<span style=\"border-top:1px solid black;position:relative;padding:1px;\">" |
||
down_last = "<span style=\"position:absolute;top:0;bottom:67%;right:0%;border-right:1px solid black;\">​</span></span>" |
local down_last = "<span style=\"position:absolute;top:0;bottom:67%;right:0%;border-right:1px solid black;\">​</span></span>" |
||
high_first = "<span style=\"border-top:1px solid black\">" |
local high_first = "<span style=\"border-top:1px solid black\">" |
||
start = "<span lang=\"ja\" class=\"Jpan\">" |
local start = "<span lang=\"ja\" class=\"Jpan\">" |
||
romaji_start = " <span class=\"Latn\"><tt>[" |
local romaji_start = " <span class=\"Latn\"><tt>[" |
||
romaji_last = "]</tt></span> " |
local romaji_last = "]</tt></span> " |
||
last = "</span>" |
local last = "</span>" |
||
local position_kana = {} --position of each kana (ぁ counted), text without space |
|||
⚫ | |||
local position_mora = {} --position of each mora (ぁ not counted), text without space |
|||
local position_mora_space = {} --position of each mora (ぁ not counted), text with space |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
local space_removed = mw.ustring.gsub(text," ","") |
|||
for i=1,mw.ustring.len(space_removed) do |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
acc_type, acc_number = "h", 0 |
acc_type, acc_number = "h", 0 |
||
elseif match(class, "[a1]") then |
elseif match(class, "^[a1]$") then |
||
acc_type, acc_number = "a", 1 |
acc_type, acc_number = "a", 1 |
||
elseif match(class, "o") then |
elseif match(class, "^o$") then |
||
acc_type = "o" |
acc_type = "o" |
||
end |
end |
||
⚫ | |||
local function move_over(text, class) |
|||
⚫ | |||
class = class + 1 |
|||
⚫ | |||
return class |
|||
⚫ | |||
⚫ | |||
⚫ | |||
class = gsub(class, "[on]", "") |
class = gsub(class, "[on]", "") |
||
acc_number = tonumber(class) |
|||
acc_number = class |
|||
⚫ | |||
class = class + small_count |
|||
class = move_over(text, class) |
|||
morae_count = len(gsub(text, "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]", "")) |
morae_count = len(gsub(text, "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ ]", "")) |
||
if morae_count == |
if morae_count == acc_number then |
||
acc_type = "o" |
acc_type = "o" |
||
elseif morae_count < |
elseif morae_count < acc_number then |
||
return error("Mora count is smaller than position of downstep mora.") |
return error("Mora count is smaller than position of downstep mora.") |
||
else |
else |
||
acc_type = "n" |
acc_type = "n" |
||
end |
end |
||
elseif not acc_number then |
elseif not acc_number then |
||
acc_number = class |
acc_number = class |
||
Line 296: | Line 301: | ||
local function kana_devoice(text) |
local function kana_devoice(text) |
||
return '<span style="border:1px dotted gray; border-radius:50%;">' .. text .. "</span>" |
return '<span style="border:1px dotted gray; border-radius:50%;">' .. text .. "</span>" |
||
⚫ | |||
⚫ | |||
local position_kana = {} |
|||
local position_mora = {} |
|||
local position_mora_space = {} |
|||
⚫ | |||
if sub(text,i,i) ~= ' ' then |
|||
⚫ | |||
⚫ | |||
⚫ | |||
table.insert(position_mora_space, i) |
|||
end |
|||
⚫ | |||
⚫ | |||
⚫ | |||
end |
end |
||
Line 323: | Line 312: | ||
if devm then |
if devm then |
||
for position in mw.text.gsplit(devm, ",") do |
for position in mw.text.gsplit(devm, ",") do |
||
position = |
position = position_mora[tonumber(position)] |
||
kanas[position] = kana_devoice(kanas[position]) |
kanas[position] = kana_devoice(kanas[position]) |
||
end |
end |
||
Line 353: | Line 342: | ||
if dev then |
if dev then |
||
for position in mw.text.gsplit(dev,",") do |
for position in mw.text.gsplit(dev,",") do |
||
position = |
position = tonumber(position) |
||
romajis[position] = romaji_devoice(romajis[position]) |
romajis[position] = romaji_devoice(romajis[position]) |
||
end |
end |
||
Line 360: | Line 349: | ||
if devm then |
if devm then |
||
for position in mw.text.gsplit(devm,",") do |
for position in mw.text.gsplit(devm,",") do |
||
position = |
position = position_mora_space[tonumber(position)] |
||
romajis[position] = romaji_devoice(romajis[position]) |
romajis[position] = romaji_devoice(romajis[position]) |
||
end |
end |
||
Line 367: | Line 356: | ||
if acc_type == "n" then |
if acc_type == "n" then |
||
r_start_index = start_index + count_nspaces(romaji_text, start_index) |
r_start_index = start_index + count_nspaces(romaji_text, start_index) |
||
local r_index = position_mora_space[acc_number] |
|||
r_class = move_over(text, class + count_nspaces(romaji_text, class)) |
|||
local k_index = position_mora[acc_number] |
|||
r_parts = { |
r_parts = { |
||
[1] = table.concat(romajis, "", 1, r_start_index), |
[1] = table.concat(romajis, "", 1, r_start_index), |
||
[2] = table.concat(romajis, "", r_start_index + 1, |
[2] = table.concat(romajis, "", r_start_index + 1, r_index), |
||
[3] = table.concat(romajis, "", |
[3] = table.concat(romajis, "", r_index + 1, #romajis) |
||
} |
} |
||
k_parts = { |
k_parts = { |
||
[1] = table.concat(kanas, "", 1, start_index), |
[1] = table.concat(kanas, "", 1, start_index), |
||
[2] = table.concat(kanas, "", start_index + 1, |
[2] = table.concat(kanas, "", start_index + 1, k_index), |
||
[3] = table.concat(kanas, "", |
[3] = table.concat(kanas, "", k_index + 1, #kanas) |
||
} |
} |
||
Revision as of 14:05, 5 March 2016
- The following documentation is located at Module:ja-pron/documentation. [edit] Categories were auto-generated by Module:module categorization. [edit]
- Useful links: subpage list • links • transclusions • testcases • sandbox
Japanese pronunciation template.
See Template:ja-pron for usage and examples.
local export = {}
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local sub = mw.ustring.sub
local len = mw.ustring.len
local lang = require("Module:languages").getByCode("ja")
local m_ja = require("Module:ja")
local m_accent = require("Module:a")
local m_ipa = require("Module:IPA")
PAGENAME = PAGENAME or mw.title.getCurrentTitle().text
function export.show(frame)
local params = {
[1] = {default = PAGENAME, list = true},
["y"] = {alias_of = "yomi"},
["yomi"] = {},
["acc"] = {list = true},
["acc=_loc"] = {list = true},
["acc=_ref"] = {list = true},
["acc=_note"] = {list = true},
["accent"] = {list = true},
["accent=_loc"] = {list = true},
["accent=_ref"] = {list = true},
["accent=_note"] = {list = true},
["dev"] = {},
["dev2"] = {},
["devm"] = {},
["noipa"] = {},
["a"] = {alias_of = "audio"},
["audio"] = {}
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local yomi, au = args.yomi, args.audio
local dev, dev2, devm = args.dev, args.dev2, args.devm
local maxindex = table.getn(args[1])
local result = ""
local text
-- Deals with the yomi
if yomi then
result = "* "
if yomi == "o" or yomi == "on" then
result = result .. "[[音読み#Japanese|On'yomi]]"
elseif yomi == "go" or yomi == "goon" then
result = result .. "[[音読み#Japanese|On'yomi]]: [[呉音#Japanese|Go'on]]"
elseif yomi == "ko" or yomi == "kan" or yomi == "kanon" then
result = result .. "[[音読み#Japanese|On'yomi]]: [[漢音#Japanese|Kan'on]]"
elseif yomi == "ky" or yomi == "kanyo" or yomi == "kanyoon" then
result = result .. "[[慣用読み#Japanese|Kan'yōyomi]]"
elseif yomi == "k" or yomi == "kun" then
result = result .. "[[訓読み#Japanese|Kun'yomi]]"
elseif yomi == "j" or yomi == "ju" then
result = result .. "[[重箱読み#Japanese|Jūbakoyomi]]"
elseif yomi == "y" or yomi == "yu" then
result = result .. "[[湯桶読み#Japanese|Yutōyomi]]"
elseif yomi == "i" or yomi == "irr" or yomi == "irreg" then
result = result .. '<span class="ib-brac"><span class="qualifier-brac">(</span></span>'
result = result .. '<span class="ib-content"><span class="qualifier-content">Irregular reading</span></span>'
result = result .. '<span class="ib-brac"><span class="qualifier-brac">)</span></span>'
end
end
-- Deals with the accents
local a, al, ar, an = args.acc, args.acc_loc, args.acc_ref, args.acc_note
for i,position in ipairs(a) do
text = args[1][math.min(maxindex,i)]
result = result .. "\n*"
if al[i] then
result = result .. m_accent.show({al[i]}) .. " "
else
result = result .. m_accent.show({"[[w:Tokyo dialect|Tokyo]]"}) .. " "
end
result = result .. export.accent(text, position, dev, dev2, devm)
if ar[i] then
result = result .. frame:expandTemplate{title = "ja-pron/acc-ref", args = {ar[i]}}
end
result = result .. (an[i] and (" " .. an[i]) or "")
end
-- Alternate parameter "accent"
a, al, ar, an = args.accent, args.accent_loc, args.accent_ref, args.accent_note
for i,position in ipairs(a) do
text = args[1][math.min(maxindex,i)]
result = result .. "\n*"
if al[i] then
result = result .. m_accent.show({al[i]}) .. " "
else
result = result .. m_accent.show({"[[w:Tokyo dialect|Tokyo]]"}) .. " "
end
result = result .. export.accent(text, position, dev, dev2, devm)
if ar[i] then
result = result .. frame:expandTemplate{title = "ja-pron/acc-ref", args = {ar[i]}}
end
result = result .. (an[i] and (" " .. an[i]) or "")
end
-- Deals with the IPA
if not noipa then
for i,text in ipairs(args[1]) do
result = result .. "\n* " .. m_ipa.format_IPA_full(lang, {{pron = "[" .. export.ipa(text, dev, dev2, devm) .. "]"}})
end
end
-- Deals with the audio
if au then
result = result .. "\n* " .. frame:expandTemplate{title = "audio", args = {au, "Audio", lang = "ja"}}
end
return result
end
function export.ipa(text, dev, dev2, devm)
if type(text) == "table" then text, dev, dev2, devm = text.args[1], text.args["dev"], text.args["dev2"], text:getParent().args["devm"] end
dev = dev or ""
dev2 = dev2 or ""
devm = devm or ""
if dev2 ~= "" then error('Please remove parameter dev2 and change paramter dev to \"dev=' .. dev .. ',' .. dev2 .. '"') end
local position_kana = {}
local position_mora = {}
for i=1,mw.ustring.len(text) do
if sub(text,i,i) ~= ' ' then
table.insert(position_kana, i)
if not mw.ustring.match(sub(text,i,i), "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]") then
table.insert(position_mora, i)
end
end
end
if dev ~= "" then
for position in mw.text.gsplit(dev,",") do
position = position_kana[tonumber(position)]
text = sub(text, 1, position) .. "̥" .. sub(text, position + 1, -1)
for i=position+1,table.getn(position_kana) do
position_kana[i] = position_kana[i] + 1
end
end
end
if devm ~= "" then
for position in mw.text.gsplit(devm,",") do
position = position_mora[tonumber(position)]
text = sub(text, 1, position) .. "̥" .. sub(text, position + 1, -1)
for i=position+1,table.getn(position_mora) do
position_mora[i] = position_mora[i] + 1
end
end
end
text = m_ja.kana_to_romaji(text, nil, true)
text = gsub(text, "[ptkbjgzsd][ptckbjgzsd][hs]?", {
["pp"] = "p̚p", ["tch"] = "t̚ch", ["kk"] = "k̚k", ["bb"] = "b̚b̥", ["jj"] = "t̚j",
["dd"] = "d̚d̥", ["gg"] = "g̚g̊", ["zz"] = "t̚z", ["tt"] = "t̚t", ["tts"] = "t̚ts", ["ssh"] = "ɕː" })
text = gsub(text, "ei", "ē")
text = gsub(text, "[āēīōūnfjyz]", {
["ā"] = "aː", ["ē"] = "eː", ["ī"] = "iː", ["ō"] = "oː", ["ū"] = "uː",
["n"] = "ɴ", ["f"] = "ɸ", ["j"] = "d͡ʑ", ["y"] = "j", ["z"] = "z" })
text = gsub(text, "[sct][hs]", {
["sh"] = "ɕ",
["ch"] = "t͡ɕ",
["ts"] = "t͡s",
["ss"] = "sː" })
text = gsub(gsub(text, "([^ ])g([^̊̚])", "%1g̃%2"), "([^ ^ɴ])b", "%1β")
text = gsub(gsub(text, "ɴ([aeioujw%'])", "n%1"), "([aeiou̥])ɴ", "%1̃ɴ")
text = gsub(text, "([ɕʑ])([^i^ʲ])", "%1ʲ%2")
text = gsub(gsub(gsub(text, "ɴ([ ]?)([kg])", "ŋ%1%2"), "ɴ([ ]?)([tdsnzrɕ%(])", "n%1%2"), "ɴ([ ]?)([pbm])", "m%1%2")
text = gsub(text, "h[iju]", {
["hi"] = "çi", ["hj"] = "çj",
["hu"] = "ɸu" })
text = gsub(text, "r[aeiou]", {
["ra"] = "ɾ̠a",
["ri"] = "ɾi",
["ru"] = "ɾ̠u",
["re"] = "ɺ̠e",
["ro"] = "ɺ̠o" })
text = gsub(text, "[aeouw]", {
["a"] = "a̠",
["u"] = "ɯᵝ",
["e"] = "e̞",
["o"] = "o̞",
["w"] = "ɰᵝ"})
text = gsub(text, "ᵝ([̥̃])", "%1ᵝ")
text = gsub(text, "%.", "")
text = gsub(text, "'", ".")
text = gsub(text, "g", "ɡ")
return text
end
function export.rise_and_fall(word, rftype)
word = m_ja.kana_to_romaji(word)
if rftype == "rise" then
word = gsub(word, ".", {
["a"] = "á", ["e"] = "é", ["i"] = "í", ["o"] = "ó", ["u"] = "ú",
["ā"] = "áá", ["ē"] = "éé", ["ī"] = "íí", ["ō"] = "óó", ["ū"] = "úú" })
word = gsub(gsub(word, "n([bcdfghjkmnprstvw%'z ])", "ń%1"), "n$", "ń")
elseif rftype == "fall" then
word = gsub(word, ".", {
["a"] = "à", ["e"] = "è", ["i"] = "ì", ["o"] = "ò", ["u"] = "ù",
["ā"] = "àà", ["ē"] = "èè", ["ī"] = "ìì", ["ō"] = "òò", ["ū"] = "ùù" })
word = gsub(gsub(word, "n([bcdfghjkmnprstvw%'z ])", "ǹ%1"), "n$", "ǹ")
else
return error("Type not recognised.")
end
return word
end
function export.accent(text, class, dev, dev2, devm)
if(type(text)) == "table" then text, class, dev, dev2, devm = text.args[1], text.args[2], text.args["dev"], text.args["dev2"], text.args["devm"] end
text = gsub(text, "%.", "")
if dev == "" then dev = false end
if dev2 == "" then dev2 = false end
if devm == "" then devm = false end
local down_first = "<span style=\"border-top:1px solid black;position:relative;padding:1px;\">"
local down_last = "<span style=\"position:absolute;top:0;bottom:67%;right:0%;border-right:1px solid black;\">​</span></span>"
local high_first = "<span style=\"border-top:1px solid black\">"
local start = "<span lang=\"ja\" class=\"Jpan\">"
local romaji_start = " <span class=\"Latn\"><tt>["
local romaji_last = "]</tt></span> "
local last = "</span>"
local position_kana = {} --position of each kana (ぁ counted), text without space
local position_mora = {} --position of each mora (ぁ not counted), text without space
local position_mora_space = {} --position of each mora (ぁ not counted), text with space
for i=1,mw.ustring.len(text) do
if not mw.ustring.match(sub(text,i,i), "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ ]") then
local extra = mw.ustring.len(mw.ustring.match(sub(text,i+1), "^[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]*"))
table.insert(position_mora_space, i+extra)
end
end
local space_removed = mw.ustring.gsub(text," ","")
for i=1,mw.ustring.len(space_removed) do
table.insert(position_kana, i)
if not mw.ustring.match(sub(space_removed,i,i), "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]") then
local extra = mw.ustring.len(mw.ustring.match(sub(space_removed,i+1), "^[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]*")) mw.log(sub(space_removed,i,i),extra)
table.insert(position_mora, i+extra)
end
end
if match(class, "^[h0]$") then
acc_type, acc_number = "h", 0
elseif match(class, "^[a1]$") then
acc_type, acc_number = "a", 1
elseif match(class, "^o$") then
acc_type = "o"
end
if match(class, "^[0-9]+$") and not match(class,"^[01]$") then
class = gsub(class, "[on]", "")
acc_number = tonumber(class)
morae_count = len(gsub(text, "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ ]", ""))
if morae_count == acc_number then
acc_type = "o"
elseif morae_count < acc_number then
return error("Mora count is smaller than position of downstep mora.")
else
acc_type = "n"
end
elseif not acc_number then
acc_number = class
end
local start_index = 1
while match(sub(text, start_index+1, start_index+1), "[ァィゥェォャュョヮぁぃぅぇぉゃゅょゎ]") do
start_index = start_index + 1
end
local kanas = mw.text.split(gsub(text, " ", ""), "")
local function kana_devoice(text)
return '<span style="border:1px dotted gray; border-radius:50%;">' .. text .. "</span>"
end
if dev then
for position in mw.text.gsplit(dev, ",") do
position = tonumber(position)
kanas[position] = kana_devoice(kanas[position])
end
end
if devm then
for position in mw.text.gsplit(devm, ",") do
position = position_mora[tonumber(position)]
kanas[position] = kana_devoice(kanas[position])
end
end
romaji_text = gsub(text, "([ょおこそとのほもよろごぞどぼぽオコソトノホモヨロゴゾドボポ])う", "%1お")
romaji_text = gsub(romaji_text, "([えエけケせセてテねネへヘめメれレゑヱげゲぜゼでデべベぺペ])い", "%1え")
romaji_text = gsub(romaji_text, "([オコソトノホモヨロヲゴゾドボポョォ])ー", "%1オ")
romaji_text = gsub(romaji_text, "([エケセテネヘメレヱッゲゼデベペェ])ー", "%1エ")
romaji_text = gsub(romaji_text, "([ウクスツヌフムユルグズヅブプュゥ])ー", "%1ウ")
romaji_text = gsub(romaji_text, "([イキシチニヒミリヰギジヂビピィ])ー", "%1イ")
romaji_text = gsub(romaji_text, "([アカサタナハマヤラワンガザダバパャァ])ー", "%1ア")
local romajis = mw.text.split(romaji_text, "")
local function count_nspaces(text, index)
local i, sample, nspaces = 0, "", 0
while len(sample) < index do
i = i + 1
sample, nspaces = gsub(sub(text, 1, i), " ", "")
end
return nspaces
end
local function romaji_devoice(text)
return text .. "̥"
end
if dev then
for position in mw.text.gsplit(dev,",") do
position = tonumber(position)
romajis[position] = romaji_devoice(romajis[position])
end
end
if devm then
for position in mw.text.gsplit(devm,",") do
position = position_mora_space[tonumber(position)]
romajis[position] = romaji_devoice(romajis[position])
end
end
if acc_type == "n" then
r_start_index = start_index + count_nspaces(romaji_text, start_index)
local r_index = position_mora_space[acc_number]
local k_index = position_mora[acc_number]
r_parts = {
[1] = table.concat(romajis, "", 1, r_start_index),
[2] = table.concat(romajis, "", r_start_index + 1, r_index),
[3] = table.concat(romajis, "", r_index + 1, #romajis)
}
k_parts = {
[1] = table.concat(kanas, "", 1, start_index),
[2] = table.concat(kanas, "", start_index + 1, k_index),
[3] = table.concat(kanas, "", k_index + 1, #kanas)
}
result = start ..
k_parts[1] ..
down_first ..
k_parts[2] ..
down_last ..
k_parts[3] ..
last ..
romaji_start ..
export.rise_and_fall(r_parts[1], "fall") ..
export.rise_and_fall(r_parts[2], "rise") ..
"ꜜ" ..
export.rise_and_fall(r_parts[3], "fall") ..
romaji_last ..
"([[中高型|Nakadaka]] - [" .. acc_number .. "])"
else
r_start_index = start_index + count_nspaces(romaji_text, start_index)
r_parts = {
[1] = table.concat(romajis, "", 1, r_start_index),
[2] = table.concat(romajis, "", r_start_index + 1, #romajis)
}
k_parts = {
[1] = table.concat(kanas, "", 1, start_index),
[2] = table.concat(kanas, "", start_index + 1, #kanas)
}
if acc_type == "h" then
result = start ..
k_parts[1] ..
high_first ..
k_parts[2] ..
last ..
last ..
romaji_start ..
export.rise_and_fall(r_parts[1], "fall") ..
export.rise_and_fall(r_parts[2], "rise") ..
romaji_last ..
"([[平板型|Heiban]] - [" .. acc_number .. "])"
elseif acc_type == "a" then
result = start ..
down_first ..
k_parts[1] ..
down_last ..
k_parts[2] ..
last ..
romaji_start ..
export.rise_and_fall(r_parts[1], "rise") ..
"ꜜ" ..
export.rise_and_fall(r_parts[2], "fall") ..
romaji_last ..
"([[頭高型|Atamadaka]] - [" .. acc_number .. "])"
elseif acc_type == "o" then
result = start ..
k_parts[1] ..
down_first ..
k_parts[2] ..
down_last ..
last ..
romaji_start ..
export.rise_and_fall(r_parts[1], "fall") ..
export.rise_and_fall(r_parts[2], "rise") ..
"ꜜ" ..
romaji_last ..
"([[尾高型|Odaka]] - [" .. acc_number .. "])"
else
return error("Accent type not recognised.")
end
end
result = gsub(result, "(.)̥", "<del>%1</del>") .. (dev and "[[Category:Kenny's testing category]]" or "")
return result
end
return export