模組:沙盒/Yoyolin0409/Autolink
外观
local p = {}
local commonPrefix = 'Module:Autolink/'
local commonFallback = 'Other'
local globalDataSources = {}
local function getDataSource( src )
if src == nil or src == '' then
return nil
end
if string.find(src, '#') then
local splits = mw.text.split(src, '#')
if not globalDataSources[splits[1]] then
globalDataSources[splits[1]] = mw.loadData(commonPrefix .. splits[1])
end
return globalDataSources[splits[1]][splits[2]]
else
if not globalDataSources[src] then
globalDataSources[src] = mw.loadData(commonPrefix .. src)
end
return globalDataSources[src]
end
end
local function grabName( tbl, key )
if tbl[key] == nil then
return nil
end
if type(tbl[key]) == 'string' then
return tbl[key]
elseif type(tbl[key]) == 'table' then
return tbl[key][1]
else
return nil
end
end
local function grabNameTwice( tbl, key )
local result = grabName( tbl, key )
if result == nil and key:sub(-1) == 's' then
result = grabName( tbl, key:sub(0, -2) )
end
return result
end
local function grabFlags( tbl, key )
local entry = tbl[key]
if entry == nil then
return nil
end
local result = {
hideinlist = false,
groups = 'main',
}
if type(entry) == 'table' then
result.hideinlist = tbl[key][2]
result.groups = tbl[key][3]
end
return result
end
local function resolveGroups( src )
local result = {}
if string.find(src, ',') then
for v in mw.text.gsplit(src, ',') do
local keyname = mw.text.trim(v)
result[keyname] = 1
end
else
result[src] = 1
end
return result
end
-- used by templates, called via #invoke
function p.link( f )
local args = f
if f == mw.getCurrentFrame() then
args = require( 'Module:ProcessArgs' ).merge( true )
end
return p.invlink( args[1] , args[2] , args[3] )
end
function p.invlink( str, mode, spritetype )
local arg = str:gsub('-', ' '):lower()
local be
local lce
-- check for version suffix
if arg:find(' pe$') or arg:find(' be$') then
be = 1
arg = arg:sub(0, -4)
end
if arg:find(' lce$') then
lce = 1
arg = arg:sub(0, -5)
end
-- registry
local dataSources = {
BlockSprite = { 'Block', 'Exclusive#BlockSprite', 'Earth#BlockSprite' },
ItemSprite = { 'Item', 'Exclusive#ItemSprite' , 'Earth#ItemSprite' },
EntitySprite = { 'Entity', 'Exclusive#EntitySprite' },
BiomeSprite = { 'Biome' },
EffectSprite = { 'Effect' },
-- ?Sprite = { 'Enchantment' },
EnvSprite = { 'Environment' },
DungeonsItemSprite = { 'Dungeons#DungeonsItemSprite' },
DungeonsEntitySprite = { 'Dungeons#DungeonsEntitySprite' },
DungeonsEnchantmentSprite = { 'Dungeons#DungeonsEnchantmentSprite' },
DungeonsLevelSprite = { 'Dungeons#DungeonsLevelSprite' },
DungeonsEmoteSprite = { 'Dungeons#DungeonsEmoteSprite' },
DungeonsFlairSprite = { 'Dungeons#DungeonsFlairSprite' },
DungeonsMiscellaneousSprite = { 'Dungeons#DungeonsMiscellaneousSprite' },
LegendsEntitySprite = { 'Legends#LegendsEntitySprite' },
LegendsStructureSprite = { 'Legends#LegendsStructureSprite' },
EarthEntitySprite = { 'Earth#EarthEntitySprite' },
InvSprite = { 'Earth#InvSprite' },
}
local dataSourcesList = {
'BlockSprite',
'ItemSprite',
'EntitySprite',
'BiomeSprite',
'EffectSprite',
-- '?Sprite',
'EnvSprite',
'DungeonsItemSprite',
'DungeonsEntitySprite',
'DungeonsEnchantmentSprite',
'DungeonsLevelSprite',
'DungeonsEmoteSprite',
'DungeonsFlairSprite',
'DungeonsMiscellaneousSprite',
'LegendsEntitySprite',
'LegendsStructureSprite',
'EarthEntitySprite',
'InvSprite',
}
local dataSources_BE = {
BlockSprite = { 'Exclusive#BlockSprite', 'Block', 'Earth#BlockSprite' },
ItemSprite = { 'Exclusive#ItemSprite', 'Item', 'Earth#ItemSprite' },
EntitySprite = { 'Exclusive#EntitySprite', 'Entity' },
}
local dataSourcesList_BE = {
'BlockSprite',
'ItemSprite',
'EntitySprite',
}
local result = nil
-- get priored data source, then get name from it
if spritetype then
local dataSource_first = nil
if be then
dataSource_first = dataSources_BE[spritetype]
if dataSource_first == nil then
dataSource_first = dataSources[spritetype]
if dataSource_first then
dataSources[spritetype] = nil
end
else
dataSources[spritetype] = nil
dataSources_BE[spritetype] = nil
end
else
dataSource_first = dataSources[spritetype]
if dataSource_first and dataSources_BE[spritetype] then
dataSources_BE[spritetype] = nil
end
end
if dataSource_first then
for i=1, #dataSource_first do
result = grabNameTwice(getDataSource(dataSource_first[i]), arg)
if result then
break
end
end
end
end
-- get name when sprite type is not set, or failed to find in the priored data source, traverse in order
if result == nil then
if be then
for _, current_key in pairs(dataSourcesList_BE) do
if dataSources_BE[current_key] then
dataSources[current_key] = nil
for _, current_value in pairs(dataSources_BE[current_key]) do
result = grabNameTwice(getDataSource(current_value), arg)
if result then
break
end
end
if result then
break
end
end
end
end
if result == nil then
for _, current_key in pairs(dataSourcesList) do
if dataSources[current_key] then
for _, current_value in pairs(dataSources[current_key]) do
result = grabNameTwice(getDataSource(current_value), arg)
if result then
break
end
end
if result then
break
end
end
end
end
end
-- fallback to Module:Autolink/Other or even the string itself
if result == nil then
result = grabNameTwice(getDataSource(commonFallback), arg) or str
end
-- formatting
if be then
return p.mode(result, mode, '(基岩版)')
end
if lce then
return p.mode(result, mode, '(原主机版)')
end
return p.mode(result, mode)
end
function p.mode( str, mode, suffix )
if suffix then
if str:find('|') then
str = str .. suffix
else
str = str .. '|' .. str .. suffix
end
end
local index = str:find('|')
-- return the translated part
if index then
if mode == 'nolink' then
return str:sub(index + 1)
end
-- return the page link part
if mode == 'linkonly' then
return str:sub(1, index - 1)
end
end
return str
end
-- list out all entries with the type
function p.list( f )
local args = f
if f == mw.getCurrentFrame() then
args = require( 'Module:ProcessArgs' ).merge( true )
end
local type = args[1]
type = type:lower()
local groups = args.groups or 'main'
groups = groups:lower()
groups = mw.text.trim(groups)
local sprite = nil
local list = nil
local dataRegistry = {
block = { 'Block', 'BlockSprite' },
item = { 'Item', 'ItemSprite' },
entity = { 'Entity', 'EntitySprite' },
biome = { 'Biome', 'BiomeSprite' },
effect = { 'Effect', 'EffectSprite' },
enchantment = { 'Enchantment', '' },
environment = { 'Environment', 'EnvSprite' },
dungeonsitem = { 'Dungeons#DungeonsItemSprite', 'DungeonsItemSprite' },
dungeonsentity = { 'Dungeons#DungeonsEntitySprite', 'DungeonsEntitySprite' },
dungeonsenchantment = { 'Dungeons#DungeonsEnchantmentSprite', 'DungeonsEnchantmentSprite' },
dungeonslevel = { 'Dungeons#DungeonsLevelSprite', 'DungeonsLevelSprite' },
dungeonsemote = { 'Dungeons#DungeonsEmoteSprite', 'DungeonsEmoteSprite' },
dungeonsflair = { 'Dungeons#DungeonsFlairSprite', 'DungeonsFlairSprite' },
dungeonsmiscellaneous = { 'Dungeons#DungeonsMiscellaneousSprite', 'DungeonsMiscellaneousSprite' },
legendsentity = { 'Legends#LegendsEntitySprite', 'LegendsEntitySprite' },
legendsstructure = { 'Legends#LegendsStructureSprite', 'LegendsStructureSprite' },
earthentity = { 'Earth#EarthEntitySprite', 'EarthEntitySprite' },
}
if dataRegistry[type] == nil then
return ''
end
list = getDataSource(dataRegistry[type][1])
sprite = dataRegistry[type][2]
if list == nil or sprite == nil then
return ''
end
local result = ''
local t = {}
for k, _ in pairs(list) do
local flags = grabFlags(list, k)
if flags.hideinlist == false then
local query_groups = resolveGroups(groups)
local store_groups = resolveGroups(flags.groups)
for current_query, _ in pairs(query_groups) do
if store_groups[current_query] then
table.insert(t, k)
end
end
end
end
table.sort(t)
local limit = 50
local count = 0
local frame = mw.getCurrentFrame()
local itemlist = nil
local header = mw.html.create('tr')
local spriteids = nil
if sprite ~= '' then
spriteids = mw.loadData( 'Module:' .. sprite ).ids
header:tag('th'):wikitext('图标')
end
header:tag('th'):wikitext('英文名称')
header:tag('th'):wikitext('中文名称')
for _, v in ipairs(t) do
if count == 0 then
if itemlist ~= nil then
result = result .. tostring(itemlist)
end
itemlist = mw.html.create('table')
:addClass('data-table')
:node(header)
end
local row = mw.html.create('tr')
if sprite ~= '' then
if spriteids[v] or spriteids[mw.ustring.lower( v ):gsub( '[%s%+]', '-' )] then
row:tag('td'):wikitext(frame:expandTemplate{ title = sprite, args = { v } })
else
row:tag('td')
end
end
local words = {}
v:gsub('[^%s]+', function(w) table.insert(words, w) end)
for k, w in ipairs(words) do
if w ~= 'of' and w ~= 'or' and w ~= 'o\'' then
words[k] = w:gsub('(%l)(.+)', function(a, b) return a:upper() .. b end)
end
end
row:tag('td'):wikitext(tostring(table.concat(words, ' ')))
row:tag('td'):wikitext(p.mode(grabName(list, v), 'nolink'))
itemlist:node(row)
count = count + 1
if count == limit then
count = 0
end
end
result = result .. tostring(itemlist)
return result
end
return p