Module:User:Benwing2/be-common
Jump to navigation
Jump to search
- This module sandbox lacks a documentation subpage. You may create it.
- Useful links: root page • root page’s subpages • links • transclusions • testcases • user page • user talk page • userspace
This is a private module sandbox of Benwing2, for their own experimentation. Items in this module may be added and removed at Benwing2's discretion; do not rely on this module's stability.
local export = {}
local u = mw.ustring.char
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local ulower = mw.ustring.lower
local uupper = mw.ustring.upper
local usub = mw.ustring.sub
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- apply rsub() repeatedly until no change
local function rsub_repeatedly(term, foo, bar)
while true do
local new_term = rsub(term, foo, bar)
if new_term == term then
return term
end
term = new_term
end
end
local AC = u(0x0301) -- acute = ́
local GR = u(0x0300) -- acute = ̀
local CFLEX = u(0x0302) -- circumflex = ̂
local DOTBELOW = u(0x0323) -- dot below = ̣
export.accents = AC .. CFLEX .. DOTBELOW
export.accents_c = "[" .. export.accents .. "]"
export.vowel = "аеіоуяэыёюАЕІОУЯЭЫЁЮ"
export.vowel_c = "[" .. export.vowel .. "]"
export.non_vowel_c = "[^" .. export.vowel .. "]"
export.velar = "кгґхКГҐХ"
export.velar_c = "[" .. export.velar .. "]"
export.always_hard = "ршчжРШЧЖ"
export.always_hard_c = "[" .. export.always_hard .. "]"
export.always_hard_or_ts = export.always_hard .. "цЦ"
export.always_hard_or_ts_c = "[" .. export.always_hard_or_ts .. "]"
export.cons_except_always_hard_or_ts = "бдфгґйклмнпствхзўьБДФГҐЙКЛМНПСТВХЗЎЬ'"
export.cons_except_always_hard_or_ts_c = "[" .. export.cons_except_always_hard_or_ts .. "]"
export.cons = export.always_hard .. export.cons_except_always_hard_or_ts .. "цЦ"
export.cons_c = "[" .. export.cons .. "]"
export.VAR1 = u(0xFFF0)
export.VAR2 = u(0xFFF1)
export.VAR3 = u(0xFFF2)
export.var_code_c = "[" .. export.VAR1 .. export.VAR2 .. export.VAR3 .. "]"
local grave_deaccenter = {
[GR] = "", -- grave accent
["ѐ"] = "е", -- composed Cyrillic chars w/grave accent
["Ѐ"] = "Е",
["ѝ"] = "и",
["Ѝ"] = "И",
}
local deaccenter = mw.clone(grave_deaccenter)
deaccenter[AC] = "" -- acute accent
local destresser = mw.clone(deaccenter)
destresser["ё"] = "е"
destresser["Ё"] = "Е"
destresser["о"] = "а"
destresser["О"] = "А"
destresser["э"] = "а"
destresser["Э"] = "А"
local pre_tonic_destresser = mw.clone(destresser)
pre_tonic_destresser["ё"] = "я"
pre_tonic_destresser["Ё"] = "Я"
pre_tonic_destresser["е"] = "я"
pre_tonic_destresser["Е"] = "Я"
local ae_stresser = {
["а"] = "э",
["я"] = "е",
}
local ao_stresser = {
["а"] = "о",
["я"] = "ё",
}
local first_palatalization = {
["к"] = "ч",
["г"] = "ж",
["ґ"] = "ж",
["х"] = "ш",
["ц"] = "ч",
}
local second_palatalization = {
["к"] = "ц",
["г"] = "з",
["ґ"] = "з",
["х"] = "с",
}
function export.get_variants(form)
return
form:find(export.VAR1) and "var1" or
form:find(export.VAR2) and "var2" or
form:find(export.VAR3) and "var3" or
nil
end
function export.remove_variant_codes(word)
return rsub(word, export.var_code_c, "")
end
-- Remove acute and grave accents; don't affect ёЁ.
function export.remove_accents(word)
return rsub(word, "[́̀ѐЀѝЍ]", deaccenter)
end
function export.needs_accents(text)
for _, word in ipairs(rsplit(text, "%s+")) do
-- A word needs accents if it contains no accent or ё and has more than one vowel
if not export.is_stressed(word) and not export.is_monosyllabic(word) then
return true
end
end
return false
end
function export.is_stressed(word)
return rfind(word, "[́ёЁ]")
end
-- Return whether the word has an acute accent. Use this in preference to is_stressed()
-- once mark_stressed_vowels_in_unstressed_syllables() has been called, because
-- is_accented() will correctly ignore ё/Ё in unstressed syllables (those in stressed
-- syllables are marked with an acute accent).
function export.is_accented(word)
return rfind(word, AC)
end
function export.is_initial_stressed(word)
return rfind(word, "^" .. export.non_vowel_c .. "*" .. export.vowel_c .. AC) or
not rfind(word, AC) and rfind(word, "^" .. export.non_vowel_c .. "*[ёЁ]")
end
function export.is_final_stressed(word)
return rfind(word, AC .. export.non_vowel_c .. "*$") or
not rfind(word, AC) and rfind(word, "[ёЁ]" .. export.non_vowel_c .. "*$")
end
-- Check if word ends in a vowel.
function export.ends_in_vowel(word)
return rfind(word, export.vowel_c .. export.accents_c .. "*$")
end
-- Check if word ends in a velar.
function export.ends_in_velar(word)
return rfind(word, export.velar_c .. "$")
end
-- Check if word ends in an always-hard consonant.
function export.ends_always_hard(word)
return rfind(word, export.always_hard_c .. "$")
end
-- Check if word ends in an always-hard consonant or ц.
function export.ends_always_hard_or_ts(word)
return rfind(word, export.always_hard_or_ts_c .. "$")
end
--[=[
HANDLING BELARUSIAN VOWEL ALTERNATIONS:
We proceed as follows:
1. Call mark_stressed_vowels_in_unstressed_syllables() to attach a stress mark
(acute accent) to monosyllabic vowels and to stressed ё vowels, and attach
a special signal (DOTBELOW) to vowels that are in positions they should not be
(о э ё in unstressed syllables, е directly before the stress), so that they
are never converted to their destressed equivalent.
2. Attempt to reconstruct, as much as possible, the underlying vowels of the word.
This is normally done using apply_vowel_alternation().
3. Move the stress mark elsewhere in the word (e.g. by removing the stress mark and
appending a stressed suffix).
4. Call destress_vowels_after_stress_movement() to convert the word to its final
form. This turns о э ё in unstressed syllables and е directly before the stress
into other vowels, taking care not to do this if DOTBELOW follows the vowel.
After that, it undoes the changes made in mark_stressed_vowels_in_unstressed_syllables().
]=]
-- Apply one or more vowel alternant specifications ("ao"/"ao2"/"ao3", "ae"/"ae2"/"ae3",
-- "avo"/"avo2"/"avo3", "yo"/"yo2"/"yo3", "oy" or "voa") to the given word.
function export.apply_vowel_alternation(word, vowel_alternants)
if not vowel_alternants then
return word
end
for _, valt in ipairs(vowel_alternants) do
if rfind(valt, "^av?[eo][23]?$") or rfind(valt, "^yo[23]?$") then
local re, errmsg
if rfind(valt, "[^23]$") then
re = export.non_vowel_c .. "*" .. export.vowel_c .. AC
errmsg = "directly before the stress"
elseif rfind(valt, "2$") then
re = export.non_vowel_c .. "*" .. export.vowel_c .. export.non_vowel_c .. "*" .. export.vowel_c .. AC
errmsg = "two syllables before the stress"
elseif rfind(valt, "3$") then
re = export.non_vowel_c .. "*" .. export.vowel_c .. export.non_vowel_c .. "*" .. export.vowel_c .. export.non_vowel_c .. "*" .. export.vowel_c
errmsg = "three syllables before the stress"
else
error("Unrecognized vowel alternant '" .. valt .. "'")
end
local new_word, req_vowel
if rfind(valt, "^a[eo]") then
new_word = rsub(word, "([аАяЯ])(" .. re .. ")",
function(a_vowel, rest)
local stresser = rfind(valt, "^ao") and ao_stresser or ae_stresser
return stresser[a_vowel] .. rest
end
)
req_vowel = "а or я"
elseif rfind(valt, "^avo") then
new_word = rsub(word, "([аА])(" .. re .. ")",
function(a_vowel, rest)
return (a_vowel == "а" and "в" or "В") .. CFLEX .. "о" .. rest
end
)
req_vowel = "а"
elseif rfind(valt, "^yo") then
new_word = rsub(word, "([ыЫ])(" .. re .. ")",
function(y_vowel, rest)
return (y_vowel == "ы" and "о" or "О") .. CFLEX .. rest
end
)
req_vowel = "ы"
else
error("Unrecognized vowel alternant '" .. valt .. "'")
end
if new_word == word then
error("Indicator '" .. valt .. "' can't be applied because word '" .. word .. "' doesn't have an " .. req_vowel .. " " .. errmsg)
end
word = new_word
elseif valt == "oy" then
local new_word = rsub(word, "([оО]́)", "%1" .. CFLEX)
if new_word == word then
error("Indicator 'oy' can't be applied because word '" .. word .. "' doesn't have a stressed о")
end
word = new_word
elseif valt == "voa" then
local new_word = rsub(word, "([вВ])о́", "%1" .. CFLEX .. "о́")
if new_word == word then
error("Indicator 'voa' can't be applied because word '" .. word .. "' doesn't have a stressed во")
end
word = new_word
else
error("Unrecognized vowel alternant '" .. valt .. "'")
end
end
return word
end
-- Mark vowels that should only occur in stressed syllables (э, о, ё) but
-- actually occur in unstressed syllables with a dot-below. Also mark е
-- that occurs directly before the stress in this fashion, and add an acute
-- accent to stressed ё. We determine whether an ё is stressed as follows:
-- (1) If an acute accent already occurs, an ё isn't marked with an acute
-- accent (e.g. ра́дыё).
-- (2) Otherwise, mark only the last ё with an acute, as multiple ё sounds
-- can occur (at least, in Russian this is the case, as in трёхколёсный).
function export.mark_stressed_vowels_in_unstressed_syllables(word)
if export.is_nonsyllabic(word) then
return word
end
if export.is_multi_stressed(word) then
error("Word " .. word .. " has multiple accent marks")
end
if export.has_grave_accents(word) then
error("Word " .. word .. " has grave accents")
end
word = export.add_monosyllabic_accent(word)
if not rfind(word, AC) then
if rfind(word, "[ёЁ]") then
word = rsub(word, "([ёЁ])(.-)$", "%1" .. AC .. "%2")
else
error("Multisyllabic word " .. word .. "missing an accent")
end
end
word = rsub(word, "([эоёЭОЁ])([^́])", "%1" .. DOTBELOW .. "%2")
word = rsub(word, "([эоёЭОЁ])$", "%1" .. DOTBELOW)
word = rsub(word, "([еЕ])(" .. export.non_vowel_c .. "*" .. export.vowel_c .. AC .. ")",
"%1" .. DOTBELOW .. "%2")
return word
end
-- Undo extra diacritics added by `mark_stressed_vowels_in_unstressed_syllables` or
-- otherwise (e.g. CFLEX).
function export.undo_mark_stressed_vowels_in_unstressed_syllables(word)
word = rsub(word, DOTBELOW, "")
word = rsub(word, CFLEX, "")
word = rsub(word, "([ёЁ])́", "%1")
return word
end
-- Destress vowels in unstressed syllables. Vowels followed by DOTBELOW are unchanged;
-- otherwise, о -> а; э -> а; ё -> я directly before the stress or when followed by
-- CFLEX, otherwise е; е -> я directly before the stress. After that, remove extra
-- diacritics added by mark_stressed_vowels_in_unstressed_syllables().
function export.destress_vowels_after_stress_movement(word)
-- Handle ё + CFLEX. This assumes that a stress mark comes between ё and CFLEX,
-- which will normally be the case if maybe_accent_initial_syllable() or
-- maybe_accent_final_syllable() is used to add stress. We remove the CFLEX after
-- destressing the syllable; a CFLEX after a stressed syllable will get removed by
-- undo_mark_stressed_vowels_in_unstressed_syllables().
word = rsub(word, "([ёЁ])" .. CFLEX, pre_tonic_destresser)
-- Handle о + CFLEX; same idea as above.
word = rsub(word, "([оО])" .. CFLEX, function(o_vowel) return o_vowel == "о" and "ы" or "Ы" end)
word = rsub_repeatedly(word, "([эоёЭОЁ])([^" .. AC .. DOTBELOW .. "])",
function(vowel, rest)
return destresser[vowel] .. rest
end
)
word = rsub(word, "([эоёЭОЁ])$", destresser)
word = rsub(word, "([еЕ])(" .. export.non_vowel_c .. "*" .. export.vowel_c .. AC .. ")",
function(vowel, rest)
if not rfind(rest, "^" .. DOTBELOW) then
return pre_tonic_destresser[vowel] .. rest
else
return vowel .. rest
end
end)
-- Handle в + CFLEX + non-о, which loses the в. Do this after converting unstressed о to а.
word = rsub_repeatedly(word, "([вВ])" .. CFLEX .. "([^оО])", "%2")
return export.undo_mark_stressed_vowels_in_unstressed_syllables(word)
end
-- If word is lacking an accent, add it onto the initial syllable.
-- This assumes the word has been processed by mark_stressed_vowels_in_unstressed_syllables(),
-- so that even the ё vowel gets stress.
function export.maybe_accent_initial_syllable(word)
if not rfind(word, AC) then
-- accent first syllable
word = rsub(word, "^(.-" .. export.vowel_c .. ")", "%1" .. AC)
end
return word
end
-- If word is lacking an accent, add it onto the final syllable.
-- This assumes the word has been processed by mark_stressed_vowels_in_unstressed_syllables(),
-- so that even the ё vowel gets stress.
function export.maybe_accent_final_syllable(word)
if not rfind(word, AC) then
-- accent last syllable
word = rsub(word, "(.*" .. export.vowel_c .. ")", "%1" .. AC)
end
return word
end
-- Make a word unstressed, appropriately handling akanye and yakanye on the
-- stressed syllable. PRE_TONIC indicates whether ё should be converted to я
-- (PRE_TONIC is true) or е (otherwise). This has no effect on unstressed
-- syllables, although in some cases they need to change (in particular,
-- я in the pre-tonic syllabic might need to change to underlying е, and
-- other changes might be necessary if the stress is going to be moved onto
-- a different syllable of the word).
function export.make_unstressed(word, pre_tonic)
local destresser = pre_tonic and pre_tonic_destresser or destresser
-- ё may occur in unstressed syllables, e.g. ра́дыё "radio". э may occur in
-- unstressed syllables, e.g. тэлеві́зар "television". Possibly the same
-- with о. In this case, we don't want to modify the ё/э/о. But we do want to
-- modify stressed ё́/э́/о́ appropriately.
if rfind(word, AC) then
word = rsub(word, "([ёЁэЭоО])́", function(vowel)
return destresser[vowel]
end)
return rsub(word, AC, "")
end
return rsub(word, "[̀ёЁэЭоОѐЀѝЍ]", destresser)
end
function export.is_multi_stressed(text)
for _, word in ipairs(rsplit(text, "[%s%-]+")) do
if ulen(rsub(word, "[^́]", "")) > 1 then
return true
end
end
return false
end
-- Check if word is nonsyllabic.
function export.is_nonsyllabic(word)
return not rfind(word, export.vowel_c)
end
-- Check if word is monosyllabic (also includes words without vowels).
function export.is_monosyllabic(word)
local num_syl = ulen(rsub(word, export.non_vowel_c, ""))
return num_syl <= 1
end
-- Check if word has grave accents.
function export.has_grave_accents(word)
return rfind(word, "[̀ѐЀѝЍ]")
end
-- If word is monosyllabic, add an accent mark to the vowel. Don't affect ёЁ
-- unless `even_yo` is specified.
function export.add_monosyllabic_stress(word, even_yo)
if export.is_monosyllabic(word) and not rfind(word, "^%-") and not rfind(word, "%-$") and
not (even_yo and export.is_accented(word) or export.is_stressed(word)) then
word = rsub(word, "(" .. export.vowel_c .. ")", "%1" .. AC)
end
return word
end
-- If word is monosyllabic, add an accent mark to the vowel. Unlike
-- add_monosyllabic_stress(), even add an accent to ёЁ.
function export.add_monosyllabic_accent(word)
return export.add_monosyllabic_stress(word, "even yo")
end
-- If word is monosyllabic, remove accent marks from the vowel.
function export.remove_monosyllabic_accents(word)
if export.is_monosyllabic(word) and not rfind(word, "^%-") and not rfind(word, "%-$") then
return export.remove_accents(word)
end
return word
end
function export.iotate(stem)
stem = rsub(stem, "с[ктц]$", "шч")
stem = rsub(stem, "[ктц]$", "ч")
stem = rsub(stem, "[сх]$", "ш")
stem = rsub(stem, "[гґз]$", "ж")
stem = rsub(stem, "дз?$", "дж")
stem = rsub(stem, "([бўмпф])$", "%1л")
stem = rsub(stem, "в$", "ўл")
return stem
end
function export.apply_first_palatalization(word)
return rsub(word, "^(.*)([кгґхц])$",
function(prefix, lastchar) return prefix .. first_palatalization[lastchar] end
)
end
function export.apply_second_palatalization(word)
return rsub(word, "^(.*)([кгґх])$",
function(prefix, lastchar) return prefix .. second_palatalization[lastchar] end
)
end
function export.palatalize_td(stem)
stem = rsub(stem, "т$", "ц")
stem = rsub(stem, "д$", "дз")
return stem
end
function export.combine_stem_ending(stem, ending)
if stem == "?" then
return "?"
end
if export.is_accented(ending) then
stem = export.remove_accents(stem)
end
if rfind(ending, "^[яеіёюь]") then
stem = export.palatalize_td(stem)
end
return stem .. ending
end
function export.combine_stem_ending_into_external_form(stem, ending)
return export.destress_vowels_after_stress_movement(
export.combine_stem_ending(stem, ending)
)
end
-- Remove the vowel between the last two consonants of a stem.
-- Used especially in masculine and third-declension feminine nouns to
-- generate the stem that is used before endings beginning with a vowel.
-- This is based on the corresponding function in [[Module:ru-common]],
-- adapted for Belarusian phonology and orthography.
function export.reduce(stem)
local pre, letter, post = rmatch(stem, "^(.+)([оОёЁаАэЭеЕ])́?(" .. export.cons_c .. "+)$")
if not pre then
return nil
end
if rfind(letter, "[оОаАэЭ]") then
-- FIXME, what about when the accent is on the removed letter?
if rfind(post, "^[йЙ]$") then
-- FIXME, is this correct?
return nil
end
-- аўто́рак -> аўто́рк-, вы́нятак -> вы́нятк-, ло́жак -> ло́жк-
-- алжы́рац -> алжы́рц-
-- міні́стар -> міні́стр-
letter = ""
else
local is_upper = rfind(post, "%u")
if export.ends_in_vowel(pre) then
-- аўстралі́ец -> аўстралі́йц-
-- аўстры́ец -> аўстры́йц-
-- еўрапе́ец -> еўрапе́йц
letter = is_upper and "Й" or "й"
elseif rfind(post, "[йЙ]") then
if rfind(pre, "[вВ]$") then
-- салаве́й -> салаў-
letter = ""
elseif rfind(pre, "[uбБпПфФмМ]$") then
-- верабе́й -> вераб'-
letter = "'"
elseif is_upper then
letter = usub(pre, -1)
else
-- вуле́й -> вулл-
letter = ulower(usub(pre, -1))
end
post = ""
elseif rfind(post, export.velar_c .. "$") and rfind(pre, export.cons_except_always_hard_or_ts_c .. "$") or
rfind(post, "[^йЙ" .. export.velar .. "]$") and rfind(pre, "[лЛ]$") then
-- For the first part: князёк -> князьк-
-- For the second part: алёс -> альс-, відэ́лец -> відэ́льц-
-- Both at once: матылёк -> матыльк-
letter = is_upper and "Ь" or "ь"
else
-- пёс -> пс-
-- асёл -> асл-, бу́сел -> бу́сл-
-- бабёр -> бабр-, шва́гер -> шва́гр-
-- італья́нец -> італья́нц-
letter = ""
end
-- адзёр -> адр-
-- ірла́ндзец -> ірла́ндц-
pre = rsub(pre, "([Дд])[Зз]$", "%1")
-- кацёл -> катл-, ве́цер -> ве́тр-
pre = rsub(pre, "ц$", "т")
pre = rsub(pre, "Ц$", "Т")
end
-- ало́вак -> ало́ўк-, авёс -> аўс-, чо́вен -> чо́ўн-, ядло́вец -> ядло́ўц-
-- NOTE: любо́ў -> любв- but we need to handle this elsewhere as it also applies
-- to non-reduced nouns, e.g. во́страў -> во́страв-
pre = rsub(pre, "в$", "ў")
pre = rsub(pre, "В$", "Ў")
return pre .. letter .. post
end
-- Add an epenthetic vowel between the last two consonants of the stem.
-- Used especially in feminine and neuter nouns to generate the genitive
-- plural. `epenthetic_stress` is true if the inserted vowel should bear
-- the stress according to the accent pattern of the noun. This is based
-- on the corresponding function in [[Module:ru-common]], adapted for
-- Belarusian phonology and orthography.
function export.dereduce(stem, epenthetic_stress)
if epenthetic_stress then
stem = export.remove_accents(stem)
end
-- FIXME, any cases where we have to dereduce a sequence Cдз -> CVдз?
local pre, letter, post = rmatch(stem, "^(.*)(" .. export.cons_c .. ")(" .. export.cons_c .. ")$")
if not pre then
return nil
end
local epvowel
local is_upper = rfind(post, "%u")
if post == "'" then
-- сям'я́ "family" -> сяме́й
post = "й"
epvowel = "е"
elseif rfind(letter, "[ьйЬЙ]") then
-- аўстралі́йка "Australian woman" -> аўстралі́ек
letter = ""
if rfind(post, "[цЦ]") or not epenthetic_stress then
epvowel = "е"
else
epvowel = "ё"
end
elseif rfind(letter, export.cons_except_always_hard_or_ts_c) and rfind(post, export.velar_c) or rfind(letter, export.velar_c) then
if epenthetic_stress then
epvowel = "о"
else
epvowel = "а"
end
elseif rfind(post, "[цЦ]") then
if export.ends_always_hard(letter) then
if epenthetic_stress then
-- FIXME, is this right?
epvowel = "э"
else
epvowel = "а"
end
else
epvowel = "е"
end
elseif epenthetic_stress then
if export.ends_always_hard_or_ts(letter) then
epvowel = "о"
else
epvowel = "ё"
end
elseif export.ends_always_hard_or_ts(letter) then
epvowel = "а"
else
epvowel = "е"
end
if letter == "ў" then
letter = "в"
elseif letter == "Ў" then
letter = "В"
end
if rfind(epvowel, "[её]") then
if letter == "т" then
letter = "ц"
elseif letter == "Т" then
letter = "Ц"
elseif letter == "д" then
letter = "дз"
elseif letter == "Д" then
letter = is_upper and "ДЗ" or "Дз"
end
end
if is_upper then
epvowel = upper(epvowel)
end
if epenthetic_stress then
epvowel = epvowel .. AC
end
return pre .. letter .. epvowel .. post
end
-- Handles the alternation between initial і/у and й/ў.
function export.initial_alternation(word, previous)
if type(word) == "table" then
word, previous = word.args[1], word.args[2]
end
local prev_ends_in_vowel = export.ends_in_vowel(previous)
if rfind(word, "^[іІ][лр]" .. export.cons_c) and prev_ends_in_vowel then
if rfind(word, "^І") then
return rsub(word, "^І(.)", function(letter) return uupper(letter) end)
else
return rsub(word, "^і", "")
end
elseif rfind(word, "^[ЛРлр]" .. export.cons_c) and not prev_ends_in_vowel then
if rfind(word, "^[ЛР]") then
return "І" .. rsub(word, "^(.)", function(letter) return ulower(letter) end)
else
return "і" .. word
end
elseif rfind(word, "^[іІ]") or rfind(word, "^[йЙ]" .. export.non_vowel_c) then
if prev_ends_in_vowel then
return rsub(word, "^[іІ]", {["і"] = "й", ["І"] = "Й"})
else
return rsub(word, "^[йЙ]", {["й"] = "і", ["Й"] = "І"})
end
elseif rfind(word, "^[уУ]") or rfind(word, "^[ўЎ]" .. export.non_vowel_c) then
if prev_ends_in_vowel then
return rsub(word, "^[уУ]", {["у"] = "ў", ["У"] = "Ў"})
else
return rsub(word, "^[ўЎ]", {["ў"] = "у", ["Ў"] = "У"})
end
end
return word
end
function export.u_v_alternation_msg(frame)
local m_links = require("Module:links")
local lang = require("Module:languages").getByCode("be")
local params = {
[1] = {}
}
local parargs = frame:getParent().args
local args = require("Module:parameters").process(parargs, params)
local alternant = args[1] or mw.title.getCurrentTitle().text
local ualt, valt, ufirst
if rfind(alternant, "^[ўЎ]") then
valt = alternant
ualt = rsub(export.add_monosyllabic_stress(valt), "^([ўЎ])", {["ў"] = "у", ["Ў"] = "У"})
ufirst = false
else
ualt = alternant
valt = export.remove_monosyllabic_accents(rsub(ualt, "^([уУ])", {["у"] = "ў", ["У"] = "Ў"}))
ufirst = true
end
ualt = m_links.full_link({lang = lang, term = ualt}, "term") .. " (used after consonants or at the beginning of a clause)"
valt = m_links.full_link({lang = lang, term = valt}, "term") .. " (used after vowels)"
local first, second
if ufirst then
first, second = ualt, valt
else
first, second = valt, ualt
end
return "The forms " .. first .. " and " .. second .. " differ in pronunciation but are considered variants of the same word."
end
return export