Modul:sort

Definition från Wiktionary, den fria ordlistan.
Hoppa till: navigering, sök

Dokumentation för denna modul finns på /dok (redigera), /test


Syfte[redigera]

När sidor kategoriseras sorteras enligt standardalgoritmen för svenskspråka Wiktionary så sorteras de i en ordning som inte alltid stämmer överens med det aktuella språkets regler. Exempelvis sorteras ä och ö framför å, vilket blir fel för svenska. Olika språk har olika regler och dessa regler hämtas från Modul:lang som har dessa sorteringsregler och annan språkrelaterad information sparad i Modul:lang/data.

Användning[redigera]

local sort = require("Modul:sort")
local sort_code = sort.getSortCode("sv", "sidnamnet")
Modulen används endast av andra moduler, och inte direkt från mallkoden. Mallar bör istället använda Modul:categorize för att skapa kategorier där sorteringsnyckeln är inkluderad.

Specifikation[redigera]

Den textsträng som returnereras är sidnamnet som skickas in, efter det att särskilda operationer utförts som delvis är beroende på språk.
1= språkkod (bör anges, annars tilldelas "xx" som språkkod)
Språkkoden anges för att kunna använda sig av de speciella sorteringsregler som finns för det aktuella språket.
Om språkkoden är "xx" används inga speciella sorteringsregler.
Om språkkoden inte existerar blir resultatet samma som om språkkoden hade varit "xx".
2= sidnamnet (om utesluts eller lämnas tom, kommer textsträngen som returneras att vara tom).
1. Ett antal tecken plockas bort från textsträngen: .,&!-/:"'$()*+\;=?~% samt mellanrum. borde mellanrummet behållas?
2. Gör om hela textsträngen till gemener (vi vill att "A" ska sorteras på samma sätt som "a").
3. Ta bort alla diakriter enligt Modul:sort/data-diacritics. "å" görs om till "a", "é" görs om till "e" osv. Men hantera varje språks speciella regler. För svenska, t.ex., ska "å" inte göras om till "a" utan till "z~" (vilket betyder "sortera direkt efter "z").
4. Applicera en speciell algoritm på strängen så att inkluderade nummer sorteras i nummerordning, dvs. att 99 sorteras före 100. Detta görs genom att lägga till ett prefix framför numret med det antal ":"-tecken som är antalet siffror i talet.
5. Efter att ovanstående punkterna har gåtts igenom kan textsträngen returneras.

Tester[redigera]

All tests passed. (refresh)

Text Expected Actual
test01_basic:
Passed s.getSortKey("sv","abc") abc abc
Passed s.getSortKey("sv","a b c") abc abc
Passed s.getSortKey("fr","TV") tv tv
Text Expected Actual
test02_diacritics:
Passed s.getSortKey("sv","åra") z~ra z~ra
Passed s.getSortKey("en","åra") ara ara
Passed s.getSortKey("sv","Åre") z~re z~re
Passed s.getSortKey("fr","Åre") are are
Passed s.getSortKey("","éüåäö") euaao euaao
Passed s.getSortKey("xyz","éüåäö") euaao euaao
Text Expected Actual
test03_special_characters:
Passed s.getSortKey("de","a.,-b") ab ab
Passed s.getSortKey("","a.,-b") ab ab
Passed s.getSortKey("xx","a.,-b") ab ab
Passed s.getSortKey("xx","a&b") ab ab
Text Expected Actual
test04_missing_pagename:
Passed s.getSortKey("sv")
Passed s.getSortKey("sv","")
Text Expected Actual
test05_bad_language_code:
Passed s.getSortKey(nil,"é.,-b") eb eb
Passed s.getSortKey("","é.,-b") eb eb
Passed s.getSortKey("xx","é.,-b") eb eb
Passed s.getSortKey("xyz","é.,-b") eb eb
Text Expected Actual
test06_numbers_basic:
Passed s.getSortKey("sv","33")  ::33  ::33
Passed s.getSortKey("sv","ab33cd") ab::33cd ab::33cd
Text Expected Actual
test07_numbers_with_special_characters:
Passed s.getSortKey("sv","1,2-etandiol")  ::12etandiol  ::12etandiol
Passed s.getSortKey("sv","1,2,3-propantriol")  :::123propantriol  :::123propantriol
Text Expected Actual
test08_numbers_multiple_occurances:
Passed s.getSortKey("sv","ab33cd9988ef") ab::33cd::::9988ef ab::33cd::::9988ef
Passed s.getSortKey("sv","ab0033cd09900ef") ab::33cd::::9900ef ab::33cd::::9900ef
Text Expected Actual
test09_dont_mess_up_non_latin:
Passed s.getSortKey("zh", "中世紀") 中世紀 中世紀


local lang = require('Modul:lang')
local diacritic_objects = mw.loadData("Modul:sort/data-diacritics")

local export = {}

local function excludeSpecificCharsFromString(str)
	--settings for which characters that should always be excluded from the sort key, fetched from Wiktionary:Användare/Robotar/Tecken som exkluderas för sortering 2017-05-12
	local excluded_chars = {" ", "%.", ",", "%&", "!", "%-", "/", ":", "\"", "\'", "%$", "%(", "%)", "%*", "%+", "\\", ";", "=", "%?", "~", "%%"}

	for k,v in pairs(excluded_chars) do
		str = mw.ustring.gsub(str, v, "")
	end

	return str;
end

local function undiacritic(str, language_specific_rules)
	local diacritic_exceptions = {} --don't remove diacritics for letters put in this table
	for k,v in pairs(language_specific_rules) do
	    local replace_pair = mw.text.split(v, ">", true)
		str = mw.ustring.gsub(str, replace_pair[1], replace_pair[2])
		table.insert(diacritic_exceptions, replace_pair[2])
	end

	for k,v in pairs(diacritic_objects) do --i.e. v == {"α", {"ά", "ὰ", "ἀ", "ἅ", "ᾶ", "ἆ", "ἇ"}}
		local char_without_diacritics = v[1]
		local chars_with_diacritics = v[2]
		for k2,v2 in pairs(chars_with_diacritics) do 
			local is_diacritic_exception = false
			for k3,v3 in pairs(diacritic_exceptions) do
		        if v3 == v2 then 
		        	is_diacritic_exception = true
		        end
		    end
		    if is_diacritic_exception ~= true then
				str = mw.ustring.gsub(str, v2, char_without_diacritics)
			end
		end
	end

	return str;
end

local function applyNumberSorting(str)
	return mw.ustring.gsub(str, "0*(%d+)", function(d) return mw.ustring.rep(":", mw.ustring.len(d)) .. d end) --add a ":" for each numeral in each number in front of the number
end

local function getKey(str, language_specific_rules)
	str = excludeSpecificCharsFromString(str)
	str = mw.ustring.lower(str)
	str = undiacritic(str, language_specific_rules)
	str = applyNumberSorting(str)
	
	return str
end

function export.getSortKey(arg1, arg2)
	local lang_code, pagename

	if arg1 == mw.getCurrentFrame() then
		local frame = arg1
		lang_code = frame.args[1] or "xx"
		pagename = frame.args[2] or mw.title.getCurrentTitle().text
	else
		lang_code = arg1 or "xx"
		pagename = arg2 or ""
	end

	local language_specific_rules = lang.getSortRules(lang_code) or {}

	return getKey(pagename, language_specific_rules)
end

return export