Moduuli:lajittelu

Wikisanakirjasta

Lajittele[muokkaa]

{{#invoke:lajittelu|Lajittele|teksti[|e=erotin]}}

Lajittelee tekstin erottimella erotetut osat. Käytetään abc-mallineesta käsin.

local p = {}

local kielet = require("Module:kieliaakkostus")

-- Palauttaa rivin sisennyksen (#*: -merkit alusta)
function p.sisennys(rivi, vali)
    local sis = string.match(rivi, "^[#*:]*")
    if vali and sis ~= "" then
    return sis .. " "
    end
    return sis
end


-- Palauttaa ensimmäisen epätyhjän rivin sisennyksen.
local function hae_sisennys(teksti)
    for rivi in string.gmatch(teksti, "(.-)\n") do
	    if not rivi:match("^[ \t\n]*$") then
	        return p.sisennys(rivi)
	    end
    end
end

local function __jaa(teksti, erotin, sis)
    teksti = teksti .. erotin
    local kohdat = {}
    for rivi in string.gmatch(teksti, "(.-)" .. erotin) do
	if rivi ~= "" then
	    if sis and (p.sisennys(rivi) ~= sis) then
		kohdat[#kohdat] = kohdat[#kohdat] .. "\n" .. rivi
	    else
		-- poistetaan tyhjät alusta ja lopusta
		rivi = p.sisennys(rivi, true) .. string.match(rivi, "^[*:# \n\t]*(.-)[ \n\t]*$")
		table.insert(kohdat, rivi)
	    end
	end
    end
    return kohdat
end

-- Jakaa `tekstin` `erottimen` erottamiin osiin. Palauttaa taulukon ja käytetyn erottimen.
-- Jos `erotin` on nil ja rivejä on enemmän kuin yksi (tyhjiä rivejä ei lasketa) jakaa tekstin
-- rivien mukaan siten, että kaikki ensimmäisen rivin sisennyksen kanssa samalla tasolla
-- olevat lajitellaan. Jos `erotin` on nil ja rivejä on vain yksi jaetaan teksti pilkuista.
local function _jaa(teksti, erotin)
    if erotin == nil then
	local kohdat = __jaa(teksti, "\n", hae_sisennys(teksti))
	if #kohdat >= 2 then
	    return kohdat, "\n"
	end
	return __jaa(teksti, ","), ","
    else
	return __jaa(teksti, erotin), erotin
    end
end

local cache = {}
local function vertailumuotoon(s)
    if not cache[s] then
	cache[s] = kielet.vertailumuotoon("fi", s)
    end
    return cache[s]
end

local function sorttaaja(a, b)
    return vertailumuotoon(a) < vertailumuotoon(b)
end

function p.jaa(teksti, erotin)
    local kohdat, erotin = _jaa(teksti, erotin)
    table.sort(kohdat, sorttaaja)
    -- lisätään välilyönti erottimen jälkeen, paitsi jos erotin sisältää välejä
    if not string.match(erotin, "[\n ]") then erotin = erotin .. " " end
    return table.concat(kohdat, erotin)
end

function p.Lajittele(frame)
    frame = frame:getParent()
    return p.jaa(frame.args[1], frame.args.e)
end

return p