Module:Library classification navigation
Jump to navigation
Jump to search
Lua
Documentation for this module may be created at Module:Library classification navigation/doc
Code
-- Introduction:
-- This Lua module, named Module:Library classification navigation, is designed for facilitating navigation within book classification categories on Wikimedia Commons. It includes functions to search for values in nested dictionaries, retrieve keys from tables, check if a table is an array, check if a value is in an array, and perform category and display name lookups. The main module utilizes these functions to generate a formatted category link based on a given classification structure.
-- Function to search for a value in a nested dictionary
function searchNestedDict(dictionary, searchValue, currentPath)
currentPath = currentPath or {} -- Set default value for currentPath
for key, value in pairs(dictionary) do
local path = {unpack(currentPath)} -- Create a copy of currentPath
table.insert(path, {[key] = getKeys(dictionary)}) -- Add the current key and its keys to the path
if key == searchValue then
-- Immediate child level
local childValue=getKeysOrValues(value)
if type(value) == "table" and #childValue~=0 then
table.insert(path, {[key] = childValue})
end
return path
elseif type(value) == "table" and not isArray(value) then
local result = searchNestedDict(value, searchValue, path) -- Recursive call for nested tables
if result then
return result
end
elseif isArray(value) and inArray(searchValue, value) then
table.insert(path, {[searchValue] = value}) -- Add the searchValue and its array to the path
return path
end
end
return nil -- Return nil if searchValue is not found
end
-- Function to get keys from a table
function getKeys(t)
local keySet = {}
for k, v in pairs(t) do
table.insert(keySet, k)
end
return keySet
end
function getKeysOrValues(t)
local keySet = {}
for k, v in pairs(t) do
if type(k) == "number" then
table.insert(keySet, v)
else
table.insert(keySet, k)
end
end
return keySet
end
-- Function to check if a table is an array
function isArray(t)
local i = 0
for _ in pairs(t) do
i = i + 1
if t[i] == nil then return false end
end
return true
end
-- Function to check if a value is in an array
function inArray(val, arr)
for _, v in ipairs(arr) do
if v == val then
return true
end
end
return false
end
-- Function to look up a category name in a table
function categoryNameLookup(table, targetKey)
local value = table[targetKey]
return value or targetKey
end
-- Function to look up a display name in a table based on language preference
function displayNameLookup(table, key)
local langTable = table[key] or {}
local value = langTable[myLang] or langTable["en"] or langTable["ja"] or langTable["zh"] or ""
return value
end
-- Function to generate a formatted category link
function showCatLink(sisterCat, currentCat)
local result
local displayName = displayNameLookup(DisplayNameTable, sisterCat)
-- show class number or not
if showClass == true then
classText = sisterCat .. " "
else
classText = ""
end
local showName = displayName ~= "" and classText .. displayName or sisterCat
if sisterCat == currentCat then
result = "'''[[:Category:"..classification.." " .. categoryNameLookup(CategoryNameTable, sisterCat) .. "|" .. showName .. "]]'''"
else
result = "[[:Category:"..classification.." " .. categoryNameLookup(CategoryNameTable, sisterCat) .. "|" .. showName .. "]]"
end
return result
end
-- Main module
local p = {}
function p.main(frame)
myLang = frame:preprocess('{{Int:Lang}}') -- Get language preference from the frame
myLang = string.gsub(myLang, "zh.+", "zh")
local pageTitle = mw.title.getCurrentTitle().text -- Get the current page title
local parts = {}
for part in pageTitle:gmatch("%S+") do
table.insert(parts, part) -- Split the page title into parts
end
classification = parts[1]
local class = parts[2]
-- Load required tables based on classification
StructureTable = mw.loadJsonData("Module:Library classification navigation/"..classification.."/StructureTable.json")
CategoryNameTable = mw.loadJsonData("Module:Library classification navigation/"..classification.."/CategoryTitleTable.json")
DisplayNameTable = mw.loadJsonData("Module:Library classification navigation/"..classification.."/DisplayNameTable.json")
--title bug (https://phabricator.wikimedia.org/T355763) temporary solution start: prepended "test" in keys and remove here before use.
function removeTestFromKeys(t)
local newTable = {}
for k, v in pairs(t) do
local newKey = k
if type(k) == 'string' then
newKey = k:gsub("^test", "")
end
if type(v) == 'table' then
newTable[newKey] = removeTestFromKeys(v)
else
newTable[newKey] = v
end
end
return newTable
end
if classification:sub(1, 3) == "NDC" then
StructureTable = removeTestFromKeys(StructureTable)
CategoryNameTable = removeTestFromKeys(CategoryNameTable)
DisplayNameTable = removeTestFromKeys(DisplayNameTable)
end
--title bug temporary solution end.
local result = searchNestedDict(StructureTable, class) -- Search for the class in the structure table
local hr = "<hr style='border-width: 2px; margin: 2px 0;' />"
local classificationName = displayNameLookup(DisplayNameTable, "title")
local showName = classificationName ~= "" and classificationName or classification
local output = "'''[[:Category:"..CategoryNameTable["title"].."|"..showName.."]]'''" .. hr
if DisplayNameTable["showClass"] == nil then
showClass = true
else
showClass = false
end
local resultCount = #result
for i, value in pairs(result) do
for currentCat, v in pairs(value) do
local sortedV = {}
for _, sisterCat in pairs(v) do
table.insert(sortedV, sisterCat) -- Create a sorted array of sister categories. In Lua, tables are inherently unordered collections. However, if you want to create a sorted representation of the values in a table, you can achieve this by creating a separate array and sorting it.
end
table.sort(sortedV)
for i, sisterCat in ipairs(sortedV) do
output = output .. showCatLink(sisterCat, currentCat) -- Add formatted category links to the output
if i < #sortedV then
output = output .. " · "
end
end
if i < resultCount or next(result, i) ~= nil then
output = output .. hr -- Add horizontal rule if not the last iteration
end
end
end
return output -- Return the final output
end
return p -- Return the module
--code for debug:
--classification = "SIBU"
--local class = "經部-易類"
--local result = searchNestedDict(StructureTable, class)
--print(mw.dumpObject(result ))