Module:Subject index
From Calima Saga Wiki
More actions
Documentation for this module may be created at Module:Subject index/doc
-- Module:Subject index
-- Every subject of one kind (from the Cargo table Subjects, filled by
-- {{Appears in}}), as a dictionary grouped under the initial letter of its
-- name in the page's language. A leading article is ignored for sorting and
-- grouping, so "The Old Warrior" files under O and "La Cábala" under C.
--
-- {{#invoke:Subject index|main|kind=faction|lang=es}}
-- kind: character, faction, place, belief or force
-- lang: es or ca for a translation; empty for English
-- work: optional, only subjects appearing in that work
local p = {}
local ARTICLES = {
en = { 'The ' },
es = { 'El ', 'La ', 'Los ', 'Las ' },
ca = { 'El ', 'La ', 'Els ', 'Les ', "L'", 'En ', 'Na ' },
}
local PLAIN = {
['Á'] = 'A', ['À'] = 'A', ['É'] = 'E', ['È'] = 'E', ['Í'] = 'I', ['Ï'] = 'I',
['Ó'] = 'O', ['Ò'] = 'O', ['Ú'] = 'U', ['Ü'] = 'U', ['Ç'] = 'C', ['Ñ'] = 'N',
['á'] = 'a', ['à'] = 'a', ['é'] = 'e', ['è'] = 'e', ['í'] = 'i', ['ï'] = 'i',
['ó'] = 'o', ['ò'] = 'o', ['ú'] = 'u', ['ü'] = 'u', ['ç'] = 'c', ['ñ'] = 'n',
}
local NONE = { en = "''None yet.''", es = "''Ninguno todavía.''", ca = "''Encara cap.''" }
local function plain(s)
return (mw.ustring.gsub(s, '.', PLAIN))
end
-- The name without its leading article: what the dictionary sorts on.
local function sortName(name, lang)
for _, article in ipairs(ARTICLES[lang] or ARTICLES.en) do
local n = mw.ustring.len(article)
if mw.ustring.sub(name, 1, n) == article and mw.ustring.len(name) > n then
return mw.ustring.sub(name, n + 1)
end
end
return name
end
function p.main(frame)
local args = frame.args
local kind = mw.text.trim(args.kind or '')
local lang = mw.text.trim(args.lang or '')
if lang == '' then
lang = 'en'
end
local where = "kind='" .. kind:gsub("'", '') .. "'"
local work = mw.text.trim(args.work or '')
if work ~= '' then
where = where .. " AND works HOLDS '" .. work:gsub("'", '') .. "'"
end
local rows = mw.ext.cargo.query('Subjects', '_pageName=page,name_es=name_es,name_ca=name_ca',
{ where = where, limit = 5000 })
local items = {}
for _, row in ipairs(rows) do
local name = row.page
local target = row.page
if lang ~= 'en' then
local translated = row['name_' .. lang]
if translated and translated ~= '' then
name = translated
end
local t = mw.title.new(row.page .. '/' .. lang)
if t and t.exists then
target = row.page .. '/' .. lang
end
end
local key = plain(sortName(name, lang))
local letter = mw.ustring.upper(mw.ustring.sub(key, 1, 1))
if not letter:match('^%u$') then
letter = '#'
end
table.insert(items, { name = name, target = target, key = mw.ustring.lower(key), letter = letter })
end
if #items == 0 then
return NONE[lang] or NONE.en
end
table.sort(items, function(a, b)
return a.key < b.key
end)
local groups, letters = {}, {}
for _, item in ipairs(items) do
if not groups[item.letter] then
groups[item.letter] = {}
table.insert(letters, item.letter)
end
table.insert(groups[item.letter], item)
end
local anchor = function(letter)
return 'letter-' .. (letter == '#' and 'other' or letter)
end
local out, bar = {}, {}
for _, letter in ipairs(letters) do
table.insert(bar, '[[#' .. anchor(letter) .. '|' .. letter .. ']]')
end
table.insert(out, '<div class="calima-letters">' .. table.concat(bar, ' ') .. '</div>')
table.insert(out, '<div class="calima-dict">')
for _, letter in ipairs(letters) do
table.insert(out, '<div class="calima-dict__group">')
table.insert(out, '<div class="calima-dict__letter" id="' .. anchor(letter) .. '">' .. letter .. '</div>')
for _, item in ipairs(groups[letter]) do
table.insert(out, '<div class="calima-dict__item">[[' .. item.target .. '|' .. item.name .. ']]</div>')
end
table.insert(out, '</div>')
end
table.insert(out, '</div>')
return table.concat(out, '\n')
end
return p