Moduuli:tavutus/fi
Moduulin tavutus/fi käyttöohje [näytä tämä käyttöohje omalla sivullaan] [muokkaa tätä käyttöohjetta] [päivitä] [testit] [hiekkalaatikko]
Tässä ohjeessa kuvataan toiminnallisuutta jonka kehitys on vielä kesken. Sivu on tarkoitettu lähinnä kehityksen apuvälineeksi, ei yleiseen käyttöön. |
Funktiot
muokkaatavutettu_teksti
muokkaatavutettu_teksti(sana)
Tavuttaa sanan suomen kielen tavutussääntöjen mukaisesti.
Parametrit
muokkaasana
Tavutettava sana. Sanassa voi käyttää lisäksi seuraavia merkkejä:
- 0: Merkitsee katoa D-astevaihtelutyypin sanoissa, esimerkiksi hiki : hi0en. 0:aa ei tulosteta lopputulokseen.
- .: Tavutusvihje. Käytetään vierasperäisissä sanoissa, joilla on vaihtoehtoinen alkuperäisiin yhdysosiin perustuva tavutus. Esimerkiksi eks.pressiivinen, Man.chester.
Seuraavat eroaa muista rajamerkeistä siinä, että merkin jälkeen voivat taas esiintyä vain ensitavussa esiintyvät diftongit.
- -: Sanaan kuuluva yhdyssanojen yhdysosien erotin. Esimerkisi kuorma-auto.
- #: Ýhdyssanan pääosien erotin. Näitä on vain yksi sanassa. Vaikuttaa tavutukseen, mutta poistetaan tulostuksesta. Merkitsee sivupainon paikan yhdyssanoissa. Esim. kolmi+vaihe#kilo+watti+tunti+mittari (parempi esimerkki, tässä +-merkit turhia).
- +: Toissijainen yhdyssanojen yhdysosien erotin, joka ei kuulu sanaan. Vaikuttaa tavutukseen, mutta poistetaan tulostuksesta. Esimerkiksi erin+omainen.
Paluuarvo
muokkaaPalauttaa taulukon, jossa on alkioina vaihtoehtoisten tavutusten tavut taulukkona.
Esim.
{ {'va', 'paut', 'ta'}, {'va', 'pa', 'ut', 'ta'} }
local mallinetyokalut = require("Moduuli:Mallinetyokalut")
local luokitus = require("Moduuli:luokittelu")
local export = {}
local ALL = 99999
-- Asteriskilla merkityt ovat diftongeja kaikissa tavuissa, 1:llä merkityt vain ensimmäisessä.
local diftongit = {
['ai'] = ALL,
['au'] = ALL,
['ei'] = ALL,
['eu'] = ALL,
['ey'] = ALL,
['ie'] = 1,
['iu'] = ALL,
['iy'] = ALL,
['oi'] = ALL,
['ou'] = ALL,
['ui'] = ALL,
['uo'] = 1,
['yi'] = ALL,
['yö'] = 1,
['äi'] = ALL,
['äy'] = ALL,
['öi'] = ALL,
['öy'] = ALL,
}
local astevaihteludiftongit = {
['a0i'] = ALL, -- laki : lain
['a0u'] = ALL, -- maku : maun
['e0i'] = ALL, -- reki : reissä
['e0u'] = ALL,
['e0y'] = ALL,
['i0e'] = 1, -- ien : ikenet
['i0u'] = ALL,
['i0y'] = ALL,
['o0i'] = ALL, -- hokea : hoitte
['o0u'] = ALL, -- hoku : houn
['u0i'] = ALL, -- lukea : luitte
['u0o'] = 1, -- ruko : ruon
['y0i'] = ALL, -- rykiä : ryin
['y0ö'] = 1,
['ä0i'] = ALL, -- mäki : mäillä
['ä0y'] = ALL, -- täky : täyn
['ö0i'] = ALL,
['ö0y'] = ALL,
}
local function vokaali(env)
if not mw.ustring.match(env.input_lower, "^[aeiouyäö]", env.pos) then
return false
end
env.pos = env.pos + 1
return true
end
local function diftongi(env)
local sub = mw.ustring.sub(env.input_lower, env.pos, env.pos + 1)
local nxt = mw.ustring.sub(env.input_lower, env.pos + 1, env.pos + 2)
local scope = diftongit[sub]
if ((diftongit[sub] and scope == ALL)
or (env.first_syllable and scope == 1))
-- tarkistetaan, että kaksi seuraavaa merkkiä eivät ole kaksoisvokaali,
-- esim. "kokaiini" pitää tavuttua "ko.ka.ii.ni"
and not mw.ustring.match(nxt, "^([aeiouyäö])%1")
then
env.pos = env.pos + 2
return true
end
return false
end
--- K:n kadon aiheuttama diftongi.
-- Nämä pitää merkitä erikseen 0:lla, esim. "i0en"
local function astevaihteludiftongi(env)
local sub = mw.ustring.sub(env.input_lower, env.pos, env.pos + 2)
local nxt = mw.ustring.sub(env.input_lower, env.pos + 1, env.pos + 2)
local scope = astevaihteludiftongit[sub]
if ((astevaihteludiftongit[sub] and scope == ALL)
or (env.first_syllable and scope == 1))
and not mw.ustring.match(nxt, "^([aeiouyäö])%1")
then
env.pos = env.pos + 3
return true
end
return false
end
--- U- tai y-loppuinen diftongi muussa kuin ensitavussa.
local function agglutinointidiftongi(env)
local sub = mw.ustring.sub(env.input_lower, env.pos, env.pos + 1)
local nxt = mw.ustring.sub(env.input_lower, env.pos + 1, env.pos + 2)
if not env.first_syllable
and diftongit[sub]
and mw.ustring.match(sub, "^.[uy]")
and not mw.ustring.match(nxt, "^([aeiouyäö])%1")
then
env.pos = env.pos + 2
return true
end
return false
end
local function kaksoisvokaali(env)
if mw.ustring.match(env.input_lower, "^([aeiouyäö])%1", env.pos) then
env.pos = env.pos + 2
return true
end
return false
end
local function konsonantteja_0_n(env)
local m = mw.ustring.match(
env.input_lower,
"^[*bcdfghjklmnpqrsštvwxzž0]*",
env.pos
)
if m then
env.pos = env.pos + mw.ustring.len(m)
return true
end
return false
end
local function is_short(syllable)
if mw.ustring.match(syllable, "[aeiouyäöAEIOUYÄÖ][aeiouyäö]$") then
return false
elseif mw.ustring.match(syllable, "[aeiouyäö]$") then
return true
end
return false
end
--- Palauttaa tavun kuvauksen.
--
-- @param text: tavun sisältö
-- @param pos: tavun sijainti sanassa
-- @param first: onko sanan ensimmäinen
--
local function make_syllable_description(text, pos, first, separator)
local open_or_closed
local short_or_long
if is_short(text) then
short_or_long = "short"
else
short_or_long = "long"
end
if mw.ustring.match(text, "[aeiouyäöAEIOUYÄÖ]$") then
open_or_closed = "open"
else
open_or_closed = "closed"
end
return {
text = text,
pos = pos,
short_or_long = short_or_long,
open_or_closed = open_or_closed,
first_syllable = first,
word_separator = separator
}
end
local function insert_as_one_and_two_syllables(env, type, start, delim_pos)
end
--- Lisää `inputin` tekstin väliltä `first`–`last` (inkl.) outputtiin `output`.
local function insert_from(input, output, first, last, first_syllable, separator)
table.insert(
output,
make_syllable_description(
mw.ustring.sub(input, first, last):gsub("0", ""),
first,
first_syllable,
separator
)
)
end
--- Lukee seuraavan umpi- tai avotavun, jossa on U:hun päättyvä diftongi, esim. "kaut", jos tavu ei ole ensitavu.
-- Lisää tavun yhtenä ("kaut", "pau") ja kahtena ("ka-ut", "pa-u").
-- http://www.kielitoimistonohjepankki.fi/ohje/357
-- avotavussa yksi tavu ja umpitavussa kaksi tavua on ensisijainen per SKAM, s. 89:
-- ”(ii) Ensi tavua kauempana olevat u- ja y-loppuiset jonot ovat avotavussa diftongeja, esim. puu.rou.tu.a,
-- vär.väy.dyn. (iii) U- ja Y-loppuiset jonot ovat eritavuisia eli vokaaliyhtymiä, kun niitä seuraa jälkisegmentin
-- kanssa samassa tavussa oleva konsontantti, siis pa.la.ut.taa, tar.jo.us, töy.ke.yt.tä. Kaikkia kielentaitajia
-- koskevia ehdottomia sääntöjä nämä eivät kuitenkaan ole, vaan on idiolektikohtaisia vaihteluita.”
local function schrodingerin_tavu(env)
local start = env.pos
if konsonantteja_0_n(env)
and agglutinointidiftongi(env)
and konsonantteja_0_n(env)
then
local uy_pos = mw.ustring.find(env.input_lower, "[uy]", start)
assert(uy_pos > -1, "Ei u:ta tai y:tä")
if mw.ustring.match(env.input_lower, "^[*bcdfghjklmnpqrsštvwxzž0][aeiouyöä]", env.pos - 1) then
env.pos = env.pos - 1
end
assert(uy_pos < env.pos, "U tai y vikana: " .. mw.ustring.sub(env.input, start) )
local open_syllable = false
-- Katsotaan onko viimeinen merkki vokaali.
if mw.ustring.match(env.input_lower, "^[aeiouyöä]", env.pos - 1) then
open_syllable = true
end
-- Umpitavussa halutaan, että "ka-ut"-tavutus tulee ennen "kaut"-tavutusta.
-- Avotavussa halutaan, että "kau"-tavutus tulee ennen "ka-u"-tavutusta, joten
-- vaihdetaan outputtien paikkaa.
local output1 = env.output1
local output2 = env.output2
if open_syllable then
output1 = env.output2
output2 = env.output1
end
-- Lisätään kahtena tavuna...
insert_from(
env.input,
output1,
start,
uy_pos - 1,
env.first_syllable,
env.word_separator
)
insert_from(
env.input,
output1,
uy_pos,
env.pos - 1,
false
)
-- ... ja yhtenä tavuna.
insert_from(
env.input,
output2,
start,
env.pos - 1,
env.first_syllable,
env.word_separator
)
env.first_syllable = false
return true
end
env.pos = start
return false
end
--- Lukee seuraavan umpi- tai avotavun, jossa on kadon aiheuttama diftongi.
-- Lisää tavun kahtena ("i-en") ja yhtenä ("ien").
-- ”– – astevaihteludiftongit voivat foneettisesti toteutua joko aitoina diftongeina taikka
-- eritavuisina. Tämä on melko vapaa ja ennustamaton vaihtelu.” (SKAM, s. 89–90)
local function astevaihteludiftongitavu(env)
local start = env.pos
if konsonantteja_0_n(env)
and astevaihteludiftongi(env)
and konsonantteja_0_n(env)
then
local k0_pos = mw.ustring.find(env.input_lower, "0", start)
-- Tarkistetaan, ettei kadon jälkeen tule toista diftongia. "Ru0oissa" pitää tavuttua "ru-ois-sa".
local after = mw.ustring.sub(env.input_lower, k0_pos + 1, k0_pos + 2)
if diftongit[after] then
env.pos = start
return false
end
assert(k0_pos > -1, "Ei 0:aa")
if mw.ustring.match(env.input_lower, "^[*bcdfghjklmnpqrsštvwxzž0][aeiouyöä]", env.pos - 1) then
env.pos = env.pos - 1
end
assert(k0_pos < env.pos, "0 vikana: " .. mw.ustring.sub(env.input, start) )
-- Lisätään kahtena tavuna...
insert_from(
env.input,
env.output1,
start,
k0_pos - 1,
env.first_syllable,
env.word_separator
)
insert_from(
env.input,
env.output1,
k0_pos,
env.pos - 1,
false
)
-- ... ja yhtenä tavuna.
insert_from(
env.input,
env.output2,
start,
env.pos - 1,
env.first_syllable,
env.word_separator
)
env.first_syllable = false
return true
end
env.pos = start
return false
end
--- Lukee seuraavan umpi- tai avotavun, jossa ei ole u:hun tai y:hyn päättyvää diftongia.
local function tavu(env)
local start = env.pos
if konsonantteja_0_n(env)
and (
diftongi(env)
or kaksoisvokaali(env)
or vokaali(env)
)
and konsonantteja_0_n(env)
then
-- Jos seuraava on vokaali, peruutetaan yksi konsonantti taaksepäin.
if mw.ustring.match(env.input_lower, "^[*bcdfghjklmnpqrsštvwxzž0][aeiouyöä]", env.pos - 1) then
env.pos = env.pos - 1
end
-- Lisätään sama tavu molempaan outputtiin.
insert_from(
env.input,
env.output1,
start,
env.pos - 1,
env.first_syllable,
env.word_separator
)
insert_from(
env.input,
env.output2,
start,
env.pos - 1,
env.first_syllable,
env.word_separator
)
env.first_syllable = false
return true
end
env.pos = start
return false
end
local function sanaraja(env)
local word_sep = mw.ustring.match(env.input, "[-+# ˌ]", env.pos)
if not word_sep then
return false
end
env.first_syllable = true
env.word_separator = word_sep
env.pos = env.pos + 1
return true
end
local function tavuraja(env)
-- Huom. nollan pitää olla täälläkin, että voi antaa muitakin nollan sisältäviä tekstejä
-- (joissa nolla ei ole diftongin keskellä).
local m = mw.ustring.match(env.input, "[.’'ˌ0]", env.pos)
if not m then
return false
end
env.pos = env.pos + 1
return true
end
--- Tavuttaa syötteen sanan ja palauttaa aina taulukon, jossa on joko yksi tai kaksi tulosta.
--
local function syllabify(input)
local env = {
input = input,
input_lower = mw.ustring.lower(input),
output1 = {},
output2 = {},
alternative = nil,
pos = 1,
first_syllable = true,
word_separator = " "
}
local prev_pos = env.pos
while env.pos <= mw.ustring.len(env.input) do
if schrodingerin_tavu(env)
or astevaihteludiftongitavu(env)
or tavu(env)
or sanaraja(env)
or tavuraja(env)
then
-- OK
else
error("Odottamaton merkki kohdassa " ..env.pos .. ": " .. mw.ustring.sub(env.input, env.pos))
end
if env.pos == prev_pos then
break
end
prev_pos = env.pos
end
-- Palautetaan molemmat, jos eroavat.
for i, v in ipairs(env.output1) do
if v.text ~= env.output2[i].text then
return { env.output1, env.output2 }
end
end
return { env.output1 }
end
function export.tavuta(input)
return syllabify(input)
end
--- Palauttaa tavutuksesta pelkän tekstin.
--
-- Jos syötteellä on useita tavutuksia, palauttaa niistä vain kaksi siten, että ensimmäisessä on
-- tavallisempi tavutus ja toisessa harvinaisempi. Esim. jos syöte olisi "vapauden rakkautta ies"
-- tuotettaisiin
-- va-pau-den rak-ka-ut-ta i-es
-- va-pa-u-den rak-kaut-ta ies
-- eikä kaikkia yhdistelmiä.
--
function export.tavutettu_teksti(input)
local combinations = export.tavuta(input)
local out = {}
for k, syllableInfos in pairs(combinations) do
out[k] = mallinetyokalut.map(function (syllableInfo) return syllableInfo.text end, syllableInfos)
end
return out
end
return export