Moduuli:Translitteroija/kaannin
Moduulin Translitteroija/kaannin 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. |
Muuttaa muunnossäännöt muuntimen ymmärtämään muotoon.
Muunnostaulukko ja tyhjä taulukko annetaan parametrina populate_conversion_table -funktiolle:
local conversions = {}
compiler.populate_conversion_table(conversions, muunnokset)
return conversions
Muunnossääntötaulukko koostuu riveistä, jotka kertovat mikä merkkijono ja missä ympäristössä munnetaan miksikin.
Jokainen muunnostaulukon rivi on itsessään taulukko, jossa on 4, 2 tai 1 alkio.
Kun merkki tai merkkijono jätetään ennalleen käytetään 1 alkion muotoa:
{merkkijono}
Esim.
{"-"}
Kun merkki muutetaan konteksista riippumatta, käytetään kahden alkion muotoa.
{lähdemerkkjono, kohdemerkkijono}
Esim.
{"Б", "B"}
Muuten käytetään 4 alkion muotoa. Neljän alkion muodossa 1. alkio on edeltävä merkkijono, 2. on muutettava merkkijono, 3. seuraava merkkijon ja 4. kohdemerkkijono.
{edeltävä, lähde, seuraava, kohde}
Esim. ё muunnetaan o:ksi vain jos se sitä edeltää Ж:
{'Ж', "ё", '', "o"},
(Tässä kontekstimerkkijonot ja muunnokseen osallistuvat merkkijonot on tyylitelty erilaisilla lainausmerkeillä, mutta niillä ei ole merkitystä säännönkannalta.)
Huom. Jos kaksi sääntöä on ristiriidassa siten, että toisen edeltävä merkkijono sisältyy toisen muunnettavan merkkijonoon, käytetään sitä, jossa kaikki teksti on muunnettavassa merkkijonossa.
Kun sääntötaulukkoon ei tarvitse enää tehdä muutoksia, voi sen hakea funktiolla ??? ja siirtää muunnostaulukon paikalle, jotta sääntötaulukkoa ei tarvitse muuttaa muunnostaulukoksi joka kerta.
--- Muuttaa säännöt taulukoksi ja hakemistoiksi.
local common = require("Moduuli:Translitteroija/yhteinen")
local export = {}
local log = false
local tostring = common.tostring
local get_index_key = common.get_index_key
local function values(str)
return { string.byte(str, 1, string.len(str)) }
end
local function compare_rows(a, b)
-- Verrattava kokonaan (input .. suffiksi)
if a[5] < b[5] then
return true
elseif a[5] > b[5] then
return false
end
-- Prefiksi
if a[2] < b[2] then
return true
elseif a[2] > b[2] then
return false
end
return false
end
--- Tekee taulukon, joka on muuten kuin varsinainen muunnostaulukko, mutta tekstit on
-- tekstinä, ei numeroina. Järjestää taulukon haulle sopivaksi.
local function create_intermediate_table(conversions_in)
local tmp = {}
local input_prefix, input_replaced, input_suffix, output_replacing
local input_prefix_len, input_replaced_len, input_suffix_len, output_replacing_len
for i, row in ipairs(conversions_in) do
if #row == 1 then
input_prefix = ""
input_replaced = row[1]
input_suffix = ""
output_replacing = row[1]
elseif #row == 2 then
input_prefix = ""
input_replaced = row[1]
input_suffix = ""
output_replacing = row[2]
elseif #row == 4 then
input_prefix = row[1]
input_replaced = row[2]
input_suffix = row[3]
output_replacing = row[4]
else
error("Virheellinen syöte: " .. tostring(row))
end
input_prefix_len = string.len(input_prefix)
input_replaced_len = string.len(input_replaced)
input_suffix_len = string.len(input_suffix)
output_replacing_len = string.len(output_replacing)
tmp[i] = {
input_prefix_len, -- 1
input_prefix, -- 2
input_replaced_len + input_suffix_len, -- 3
input_replaced_len, -- 4
input_replaced .. input_suffix, -- 5
output_replacing_len, -- 6
output_replacing -- 7
}
end
table.sort(tmp, compare_rows)
return tmp
end
local function create_index(output_table, size_offset, start_offset)
local index_first = {}
local index_last = {}
local offset
local size
local current
for row_num = 1, output_table.pseudo_length do
offset = (row_num - 1) * output_table.pseudo_row_length + 1
size = output_table[offset + size_offset - 1]
current = get_index_key(output_table, offset, start_offset, size)
if not index_first[current] then
index_first[current] = row_num
end
index_last[current] = row_num
end
return index_first, index_last
end
local function get_max_values(intermediate_table)
local in_max = 0
local prefix_max = 0
local suffix_max = 0
local out_max = 0
for i, row in ipairs(intermediate_table) do
prefix_max = math.max(prefix_max, row[1])
in_max = math.max(in_max, row[3])
out_max = math.max(out_max, row[6])
end
return in_max, prefix_max, out_max
end
function export.populate_conversion_table(output_table, conversions_in)
local tmp = create_intermediate_table(conversions_in)
local in_max, prefix_max, out_max = get_max_values(tmp)
-- Koska taulukko on oikeasti yksiulotteinen, jaetaan se tasapituisiin 'virtuaalisiin' riveihin.
-- Kuinka monta solua yhdellä rivillä on.
local pseudo_row_len = 1 + prefix_max + 2 + in_max + 1 + out_max
-- Kuinka monta `pseudo_row_len` pituista riviä taulukossa on.
local pseudo_rows = #tmp
local row
local ptr = 1
local j = 0
for i, row in ipairs(tmp) do
output_table[ptr] = row[1]
local prefix_bytes = values(row[2])
for j = 1, prefix_max do
output_table[ptr + 1 + j - 1] = prefix_bytes[j] or 0 -- täytetään tyhjät 0:illa
end
output_table[ptr + 1 + prefix_max] = row[3]
output_table[ptr + 1 + prefix_max + 1] = row[4]
local in_bytes = values(row[5])
for j = 1, in_max do
output_table[ptr + 1 + prefix_max + 2 + j - 1] = in_bytes[j] or 0 -- täytetään tyhjät 0:illa
end
output_table[ptr + 1 + prefix_max + 2 + in_max] = row[6]
local out_bytes = values(row[7])
for j = 1, out_max do
output_table[ptr + 1 + prefix_max + 2 + in_max + 1 + j - 1] = out_bytes[j] or 0
end
ptr = ptr + 1 + prefix_max + 2 + in_max + 1 + out_max
end
assert ( #output_table / pseudo_row_len == pseudo_rows, "Virheellinen määrä soluja" )
output_table.pseudo_length = pseudo_rows
output_table.pseudo_row_length = pseudo_row_len
output_table.in_max = in_max
output_table.prefix_max = prefix_max
output_table.out_max = out_max
output_table.index_first_for_input, output_table.index_last_for_input
= create_index(output_table, 1 + prefix_max + 1, 1 + prefix_max + 3)
output_table.index_first_for_prefix, output_table.index_last_for_prefix
= create_index(output_table, 1, 2)
end
return export