Mô đun:Thống kê Wiktionary/A

---Các hàm có liên quan đến thống kê của dự án Wiktionary tiếng Việt.
local p = {}
local viet = require "Module:Quốc ngữ"
local stats = mw.site.stats
local lang = mw.getContentLanguage()

local categoryPrefix = "Mục từ "

---Dữ liệu các thể loại ngôn ngữ.
p.categoriesByCode = {
	["alu"] = {name = "tiếng 'Are'are", templates = 2},
	["ara"] = {short = "ar", name = "tiếng Ả Rập", templates = 2},
    ["arz"] = {name = "tiếng Ả Rập Ai Cập", templates = 2},
    ["acw"] = {name = "tiếng Ả Rập Hijazi", templates = 2},
    ["pga"] = {name = "tiếng Ả Rập Juba", templates = 2},
    ["shu"] = {name = "tiếng Ả Rập Tchad", templates = 2},
    ["aiw"] = {name = "tiếng Aari", templates = 2},
    ["aas"] = {name = "tiếng Aasax", templates = 2},
    ["aau"] = {name = "tiếng Abau", templates = 2},
    ["abq"] = {name = "tiếng Abaza", templates = 2},
    ["abk"] = {name = "tiếng Abkhaz", templates = 2},
    ["ace"] = {name = "tiếng Aceh", templates = 2},
	["ady"] = {name = "tiếng Adygea", templates = 2},
	["aar"] = {short = "aa", name = "tiếng Afar", templates = 2},
    ["afr"] = {short = "af", name = "tiếng Afrikaans", templates = 2},
    ["agx"] = {name = "tiếng Aghul", templates = 2},
    ["xag"] = {name = "tiếng Aghwan", templates = 2},
    ["aho"] = {name = "tiếng Ahom", templates = 2},
    ["egy"] = {name = "tiếng Ai Cập", templates = 2},
    ["ain"] = {name = "tiếng Ainu", templates = 2},
    ["ain-sak"] = {name = "tiếng Ainu Sakhalin", templates = 2},
    ["aio"] = {name = "tiếng Aiton", templates = 2},
    ["ahk"] = {name = "tiếng Akha", templates = 2},
    ["akk"] = {name = "tiếng Akkad", templates = 2},
    ["wbj"] = {name = "tiếng Alagwa", templates = 2},
    ["sqi"] = {short = "sq", name = "tiếng Albani", templates = 2},
    ["tuw-alc"] = {name = "tiếng Alchuka", templates = 2},
    ["alr"] = {name = "tiếng Alutor", templates = 2},
    ["amh"] = {short = "am", name = "tiếng Amhara", templates = 2},
    ["amu"] = {name = "tiếng Amuzgo", templates = 2},
    ["eng"] = {short = "en", name = "tiếng Anh", templates = 2},
    ["ang"] = {name = "tiếng Anh cổ", templates = 2},
    ["crp-sol"] = {name = "tiếng Anh Solombala", templates = 2},
    ["enm"] = {name = "tiếng Anh trung đại", templates = 2},
    ["apw"] = {name = "tiếng Apache Tây", templates = 2},
    ["apn"] = {name = "tiếng Apinayé", templates = 2},
    ["arg"] = {short = "an", name = "tiếng Aragon", templates = 2},
    ["aqc"] = {name = "tiếng Archi", templates = 2},
    ["aem"] = {name = "tiếng Arem", templates = 2},
    ["agj"] = {name = "tiếng Argobba", templates = 2},
    ["xrn"] = {name = "tiếng Arin", templates = 2},
    ["hye"] = {short = "hy", name = "tiếng Armenia", templates = 2},
    ["cus-ash"] = {name = "tiếng Ashraaf", templates = 2},
    ["asm"] = {short = "as", name = "tiếng Assam", templates = 2},
    ["xss"] = {name = "tiếng Assan", templates = 2},
    ["ast"] = {name = "tiếng Asturias", templates = 2},
    ["ava"] = {short = "av", name = "tiếng Avar", templates = 2},
    ["ave"] = {name = "tiếng Avesta", templates = 2},
    ["azo"] = {name = "tiếng Awing", templates = 2},
	["awn"] = {name = "tiếng Awngi", templates = 2},
    ["aib"] = {name = "tiếng Äynu", templates = 2},
    ["aze"] = {short = "az", name = "tiếng Azerbaijan", templates = 2},
}

p["số ngôn ngữ"] = function (frame)
    if p.numberOfLanguages then return p.numberOfLanguages end
    local count = 0
    for i, entry in pairs(p.categoriesByCode) do count = count + 1 end
    p.numberOfLanguages = count
    return p.numberOfLanguages
end

---Xây dựng ánh xạ sắp xếp từ các mã ngôn ngữ ISO 639-2 đến các tên ngôn ngữ.
function p._buildNamedCodes()
    if p.namedCodes then return end
    
    p.namedCodes = {}
    for code, category in pairs(p.categoriesByCode) do
        local name = category.name or category.names[1]
        name = lang:ucfirst(mw.ustring.gsub(
            mw.ustring.gsub(name, "^tiếng ", "", 1), "^chữ ", "", 1))
        table.insert(p.namedCodes, {code, name})
    end
    table.sort(p.namedCodes, function (namedCode1, namedCode2)
        return viet.comp(namedCode1[2], namedCode2[2])
    end)
end

---Tính các mã ngôn ngữ ISO 639-2 của các ngôn ngữ Trung Quốc.
function p._buildChineseCodes()
    if p.chineseCodes then return end
    
    p.chineseCodes = {}
    for code, category in pairs(p.categoriesByCode) do
        if category.isChinese then
            local name = category.name or category.names[1]
            name = lang:ucfirst(mw.ustring.gsub(
                mw.ustring.gsub(name, "^tiếng ", "", 1), "^chữ ", "", 1))
            table.insert(p.chineseCodes, {code, name})
        end
    end
    table.sort(p.chineseCodes, function (namedCode1, namedCode2)
        return viet.comp(namedCode1[2], namedCode2[2])
    end)
end

function p.entriesForLanguage(code)
    local category = p.categoriesByCode[code]
    if category.name then
        local entries = stats.pagesInCategory(categoryPrefix .. category.name, "pages")
        return entries - category.templates
    end
    
    assert(category.names,
        "Mục ngôn ngữ trong bảng p.categoriesByCode không định rõ tên thể loại.")
    
    local total = 0
    for i, name in ipairs(category.names) do
        local entries = stats.pagesInCategory(categoryPrefix .. name, "pages")
        total = total + entries
    end
    return total - category.templates
end

---Tính tổng số mục từ tại wiki này.
-- Theo hàm này, một từ có trong hơn một ngôn ngữ có thể có hơn một mục từ ở
-- cùng một trang.
function p.entryCount(onlyCode)
    if onlyCode == "ZHO" then return p.numChineseEntries() end
    if onlyCode and #onlyCode > 0 then
        return p.entriesForLanguage(onlyCode)
    end
    
    local total = 0
    for code, category in pairs(p.categoriesByCode) do
        local entries = p.entriesForLanguage(code)
        total = total + entries
    end
    return total
end
p["số mục từ"] = function (frame)
    return p.entryCount(frame and frame.args[1])
end

---Tính tổng số mục từ trong các ngôn ngữ Trung Quốc.
function p.numChineseEntries()
    p._buildChineseCodes()
    local total = 0
    for i, code in ipairs(p.chineseCodes) do
        total = total + p.entriesForLanguage(code[1])
    end
    return total
end

function p.languageLinks(categoryNames)
    local sortKey
    local links = {}
    for i, categoryName in ipairs(categoryNames) do
        local languageName = lang:ucfirst(
            mw.ustring.gsub(
                mw.ustring.gsub(categoryName, "^tiếng ", "", 1),
            "^chữ ", "", 1))
        if not sortKey then sortKey = languageName end
        table.insert(links, string.format("[[:Thể loại:%s%s|%s]]",
            categoryPrefix, categoryName, languageName))
    end
    return table.concat(links, ", "), sortKey
end

p["bảng số mục từ"] = function (frame)
    local args = frame.args
    local expandChinese = args.subset == "zho"
    local subsetCodes = nil
    if expandChinese then
        p._buildChineseCodes()
        subsetCodes = p.chineseCodes
    else
        p._buildNamedCodes()
        subsetCodes = p.namedCodes
    end
    
    local rows = {}
    for i, namedCode in ipairs(subsetCodes) do
        category = p.categoriesByCode[namedCode[1]]
        if expandChinese or (namedCode[1] == "zho" or not category.isChinese) then
            local categoryLinks =
                p.languageLinks(category.names or {category.name})
            
            local entries
            if namedCode[1] == "zho" and not expandChinese then
                entries = p.numChineseEntries()
            else
                entries = p.entriesForLanguage(namedCode[1])
            end
            
            local entriesLink = args["chi tiết " .. namedCode[1]]
            if entriesLink then
                entries = string.format("[[%s|%s]]", entriesLink, entries)
            end
            table.insert(rows, string.format([=[
|-
| data-sort-value="%s" | %s || %s || style="text-align: right;" | %s
]=], namedCode[2], categoryLinks, namedCode[1], entries))
        end
    end
    
    local total
    if expandChinese then
        total = p.numChineseEntries()
    else
        total = p.entryCount()
    end
    
    return mw.ustring.format([=[
{| class="wikitable sortable"
|-
! Tên ngôn ngữ !! Mã ngôn ngữ !! data-sort-type="number" | Số mục từ
%s
|- class="sortbottom" style="font-weight: bold;"
! scope="row" colspan="2" | Tổng số
| style="text-align: right;" |
%s
|}
]=], table.concat(rows), total)
end

return p