Module:snon-mut: Difference between revisions
Created page with "local m_links = require("Module:links") local lang = require("Module:languages").getByCode("snon") local export = {} local function repl(forms, param) if param ~= "normal" and forms[param] == forms["normal"] then return "''not applicable''" end local ret = m_links.full_link({lang = lang, term = forms[param]}) return ret end local table_cons = [=[ ! radical ! lenition ! nasal ! voiced |- | {{{normal}}} | {{{len}}} | {{{nas}}} | {{{voi}}} ]=] function expo..." |
No edit summary |
||
| Line 1: | Line 1: | ||
local | local export = {} | ||
local yesno = require("Module:yesno") | |||
local toNFC = mw.ustring.toNFC | |||
local toNFD = mw.ustring.toNFD | |||
local ulower = mw.ustring.lower | |||
local umatch = mw.ustring.match | |||
local usub = mw.ustring.sub | |||
local | local GRAVE = "\204\128" | ||
local ACUTE = "\204\129" | |||
local CIRC = "\204\130" | |||
local DIAER = "\204\136" | |||
local | local lang = require("Module:languages").getByCode("cy") | ||
local PAGENAME = mw.loadData("Module:headword/data").pagename | |||
local MARKER = "<sup>△</sup>" | |||
local mutation_rules = { | |||
["b"] = {"f", "m"}, | |||
["c"] = {"g", "ngh", "ch"}, | |||
["ch"] = true, | |||
["d"] = {"dd", "n"}, | |||
["dd"] = true, | |||
["f"] = true, | |||
["g"] = {"", "ng"}, | |||
["h"] = true, | |||
["j"] = true, | |||
["k"] = true, | |||
["l"] = true, | |||
["ll"] = {"l"}, | |||
["m"] = {"f"}, | |||
["mh"] = true, | |||
["n"] = true, | |||
["p"] = {"b", "mh", "ph"}, | |||
["ph"] = true, | |||
["q"] = true, | |||
["r"] = true, | |||
["rh"] = {"r"}, | |||
["s"] = true, | |||
["t"] = {"d", "nh", "th"}, | |||
["th"] = true, | |||
["ts"] = true, | |||
["tsi"] = {"j", colloquial = true}, -- TODO: add colloquial marker. | |||
["v"] = true, | |||
["x"] = true, | |||
["z"] = true | |||
} | |||
local | function export.get_mutation_data(term) | ||
local data = {radical = term} | |||
local term_lower = term:gsub("^.[\128-\191]*", ulower) -- term with lowercase initial | |||
data.is_uppercase = term_lower ~= term | |||
local normalized = toNFD(term_lower) | |||
data.vowel = normalized:match("^[aeiouwy]") and true or false | |||
if data.vowel then | |||
data.final = term_lower | |||
-- H-prothesis, unless initial "w" is a semivowel (followed by a vowel other than "y", or "y" with a diacritic). | |||
if not (normalized:match("^w[aeiouw]") or umatch(normalized, "^wy[" .. GRAVE .. ACUTE .. CIRC .. DIAER .. "]")) then | |||
data.mut3 = "h" | |||
end | |||
return data | |||
end | |||
local initial, final, mut | |||
for i = 3, 1, -1 do | |||
initial = usub(normalized, 1, i) | |||
mut = mutation_rules[initial] | |||
if mut then | |||
final = usub(normalized, i + 1) | |||
break | |||
elseif i == 1 then | |||
error(("no mutation rule found for %s"):format(term)) | |||
end | |||
end | |||
if type(mut) == "table" then | |||
for k, v in pairs(mut) do | |||
if tonumber(k) then | |||
data["mut" .. k] = v | |||
end | |||
end | |||
data.colloquial = mut.colloquial | |||
end | end | ||
if initial == "tsi" then | |||
-- "i" in "tsi" is retained if: | |||
-- followed by a consonant (e.g. "tsips" → "jips") | |||
-- followed by a semivowel (e.g. "tsiwawa" → "jiwawa", but "*tsiŵawa" → "*jŵawa"); "i" and "w" are semivowels if followed by any vowel, due to the preceding "i". | |||
-- it has a diacritic (e.g. "tsïars" → "jïars") | |||
if not (final:match("^[aeiouwy]") and not final:match("^[iw][aeiouwy]")) then | |||
final = "i" .. final | |||
-- If "i" in "tsi" is not retained, the following vowel cannot have a diaeresis unless it's followed by a vowel. | |||
elseif not umatch(final, "^[aeiouwy]" .. DIAER .. "[" .. GRAVE .. ACUTE .. CIRC .. "]?[aeiouwy]") then | |||
final = final:gsub("^([aeiouwy])" .. DIAER, "%1") -- If there's no diaeresis, this does nothing. | |||
end | |||
end | |||
return | data.final = toNFC(final) | ||
return data | |||
end | end | ||
local function construct_mutation(data, accel_form, initial, override) | |||
local normal_mutation | |||
if not initial then | |||
normal_mutation = nil | |||
else | |||
normal_mutation = initial .. data.final | |||
if data.is_uppercase then | |||
normal_mutation = require("Module:string utilities").ucfirst(normal_mutation) | |||
end | |||
end | |||
local has_override = override | |||
if not yesno(override, true) or override == "-" then -- TODO: yesno to be removed. | |||
override = nil | |||
end | |||
local has_irreg_mutation = has_override and override ~= normal_mutation | |||
local mutation | |||
-- don't combine the following into A and B or C because `override` may be nil | |||
if has_override then | |||
mutation = override | |||
else | |||
mutation = normal_mutation | |||
end | |||
local marker = has_irreg_mutation and MARKER or "" | |||
if mutation then | |||
return require("Module:links").full_link({lang = lang, accel = {form = accel_form, lemma = data.radical}, term = mutation}) .. marker, true, has_irreg_mutation | |||
else | |||
return "''unchanged''" .. marker, false, has_irreg_mutation | |||
end | |||
end | |||
function export.show(frame) | |||
function export. | |||
local params = { | local params = { | ||
[1] = {}, | [1] = {}, | ||
["soft"] = {}, | |||
["nasal"] = {}, | |||
["aspirate"] = {}, | |||
["nocat"] = {type = "boolean"}, | |||
} | } | ||
local parargs = frame:getParent().args | |||
local args = require("Module:parameters").process(parargs, params) | |||
local title = args[1] or PAGENAME | |||
local data = export.get_mutation_data(title) | |||
local soft, has_soft, has_irreg_soft = construct_mutation(data, "soft", data.mut1, args.soft) | |||
local nasal, has_nasal, has_irreg_nasal = construct_mutation(data, "nasal", data.mut2, args.nasal) | |||
local aspirate, has_aspirate, has_irreg_aspirate = construct_mutation(data, data.vowel and "h-prothesis" or "aspirate", data.mut3, args.aspirate) | |||
local result = frame:expandTemplate{ title = 'inflection-table-top', | |||
args = { title = '[[Appendix:Welsh mutations|Mutated forms]] of ' .. require("Module:links").full_link({lang = lang, alt = title}, 'term'), palette = 'green' } } | |||
result = result .. '\n! [[radical]]' | |||
result = result .. '\n! [[soft mutation|soft]]' | |||
result = result .. '\n! [[nasal mutation|nasal]]' | |||
result = result .. '\n! ' .. (data.vowel and '[[h-prothesis]]' or '[[aspirate mutation|aspirate]]') | |||
result = result .. '\n|-' | |||
result = result .. '\n| ' .. require("Module:links").full_link({lang = lang, term = data.radical}) | |||
result = result .. '\n| ' .. soft | |||
result = result .. '\n| ' .. nasal | |||
result = result .. '\n| ' .. aspirate | |||
notes = '' | |||
if has_irreg_soft or has_irreg_nasal or has_irreg_aspirate then | |||
notes = notes .. '<p style="font-size:85%;">' .. MARKER .. 'Irregular.</p>' | |||
end | |||
if has_soft or has_nasal or has_aspirate then | |||
notes = notes .. '<p style="font-size:85%;"><i>Note:</i> Certain mutated forms of some words can never occur in standard Welsh.<br>All possible mutated forms are displayed for convenience.</p>' | |||
end | |||
result = result .. '\n' .. frame:expandTemplate{ title = 'inflection-table-bottom', args = { notes = notes } } | |||
if not args.nocat and (has_irreg_soft or has_irreg_nasal or has_irreg_aspirate) then | |||
result = result .. require("Module:utilities").format_categories("Welsh terms with irregular mutation", lang) | |||
end | |||
return result | return result | ||
end | end | ||
return export | return export | ||