A module for collation (alphabetization) that is used by Module:columns and {{sort}}
. Contains functions to alphabetize lists of terms.
local export = {}
local compare_module = "Module:compare"
local functions_module = "Module:fun"
local memoize_module = "Module:memoize"
local string_utilities_module = "Module:string utilities"
local utilities_module = "Module:utilities"
local concat = table.concat
local find = string.find
local format = string.format
local make_sort_function -- defined below
local match = string.match
local remove = table.remove
local require = require
local sort = table.sort
local sub = string.sub
local type = type
local function get_plaintext(...)
get_plaintext = require(utilities_module).get_plaintext
return get_plaintext(...)
end
local function is_callable(...)
is_callable = require(functions_module).is_callable
return is_callable(...)
end
local function memoize(...)
memoize = require(memoize_module)
return memoize(...)
end
local function trim(...)
trim = require(string_utilities_module).trim
return trim(...)
end
-- Custom functions for generating a sortkey that will achieve the desired sort
-- order.
local custom_funcs
local function get_custom_funcs()
custom_funcs, get_custom_funcs = {
ahk = "Mymr-sortkey",
aio = "Mymr-sortkey",
blk = "Mymr-sortkey",
egy = "egy-utilities",
kac = "Mymr-sortkey",
kht = "Mymr-sortkey",
ksw = "Mymr-sortkey",
kyu = "Mymr-sortkey",
= "Mymr-sortkey",
mnw = "Mymr-sortkey",
my = "Mymr-sortkey",
phk = "Mymr-sortkey",
pwo = "Mymr-sortkey",
omx = "Mymr-sortkey",
shn = "Mymr-sortkey",
tjl = "Mymr-sortkey",
}, nil
return custom_funcs
end
local function is_lang_object(lang)
return lang and type(lang) == "table" and type(lang.getCanonicalName) == "function"
end
local function check_function(funcName, argIdx, func)
return is_callable(func) or error(format("bad argument #%d to %s: expected function or callable table; got %s", argIdx, funcName, type(func)), 2)
end
function export.make_lang_sortkey_function(lang, make_sortbase)
local makeDisplayText, makeSortKey = lang.makeDisplayText
local custom = (custom_funcs or get_custom_funcs())
if custom then
local _makeSortKey = require("Module:" .. custom).makeSortKey
function makeSortKey(_, text)
return _makeSortKey(text, lang, lang:findBestScript(text))
end
else
makeSortKey = lang.makeSortKey
end
return make_sortbase and check_function("make_sort_function", 3, make_sortbase) and function(element)
return (makeSortKey(
lang,
(makeDisplayText(
lang,
get_plaintext(make_sortbase(element))
))
))
end or function(element)
return (makeSortKey(
lang,
(makeDisplayText(
lang,
get_plaintext(element)
))
))
end
end
do
local compare
local function get_compare()
compare, get_compare = require(compare_module), nil
return compare
end
function export.make_sort_function(lang, make_sortbase)
local compare_func, make_sortkey = compare or get_compare()
if is_lang_object(lang) then
make_sortkey = memoize(export.make_lang_sortkey_function(lang, make_sortbase), true)
elseif make_sortbase and check_function("make_sort_function", 2, make_sortbase) then
make_sortkey = memoize(make_sortbase, true)
else
return compare_func
end
return function(elem1, elem2)
return compare_func(make_sortkey(elem1), make_sortkey(elem2))
end
end
make_sort_function = export.make_sort_function
end
function export.sort(elems, lang, make_sortbase)
return sort(elems, make_sort_function(lang, make_sortbase))
end
function export.sort_template(frame)
if not mw.isSubsting() then
error("This template must be substed.")
end
local args
if frame.args.parent then
args = frame:getParent().args
else
args = frame.args
end
local m_table = require("Module:table")
local elems = m_table.shallowCopy(args)
local m_languages = require("Module:languages")
local lang
if args.lang then
lang = m_languages.getByCode(args.lang) or m_languages.err(args.lang, "lang")
else
local code = remove(elems, 1)
code = code and trim(code)
lang = m_languages.getByCode(code) or m_languages.err(code, 1)
end
local i = 1
while true do
local elem = elems
while elem do
elem = trim(elem, "%s")
if elem ~= "" then
break
end
remove(elems, i)
elem = elems
end
if not elem then
break
elseif not ( -- Strip redundant wikilinks.
not match(elem, "^()%[%[") or
find(elem, "[[", 3, true) or
find(elem, "]]", 3, true) ~= #elem - 1 or
find(elem, "|", 3, true)
) then
elem = sub(elem, 3, -3)
elem = trim(elem, "%s")
end
elems = elem .. "\n"
i = i + 1
end
elems = m_table.removeDuplicates(elems)
export.sort(elems, lang)
return concat(elems, args.sep or "|")
end
return export