(Revert) |
Siiftun1857(留言 | 贡献) 无编辑摘要 |
||
(未显示6个用户的69个中间版本) | |||
第1行: | 第1行: | ||
local p = {} |
local p = {} |
||
+ | local Autolink = require( [[Module:Autolink]] ) |
||
− | p.value = function( f ) |
||
+ | |||
− | local args = f |
||
+ | --为维护分类提供名称。 |
||
− | if f == mw.getCurrentFrame() then |
||
+ | local categoryMapping = { |
||
− | args = require( 'Module:ProcessArgs' ).merge( true ) |
||
+ | -- 方块数据 |
||
+ | ['breaking tool'] = '合适挖掘工具', |
||
+ | ['blast resistance'] = '爆炸抗性', |
||
+ | ['hardness'] = '硬度', |
||
+ | ['material'] = '材料', -- JE |
||
+ | ['material BE'] = '基岩版材料', -- BE |
||
+ | ['suffocating'] = '窒息生物', |
||
+ | ['redstone conductor'] = '红石导体', |
||
+ | ['flame odds'] = '引燃几率', |
||
+ | ['burn odds'] = '烧毁几率', |
||
+ | ['lava flammable'] = '熔岩可燃性', |
||
+ | ['push reaction'] = '活塞推动行为', |
||
+ | -- 物品数据 |
||
+ | ['maxstack'] = '最大堆叠', |
||
+ | ['rarity'] = '稀有度', |
||
+ | ['creative tab'] = '创造标签页', -- JE |
||
+ | ['creative category'] = '创造分类', -- BE |
||
+ | } |
||
+ | |||
+ | -- 是否有对应的values BE数据表。 |
||
+ | local hasBeData = { |
||
+ | ['breaking tool'] = true, |
||
+ | ['blast resistance'] = true, |
||
+ | ['hardness'] = true, |
||
+ | ['maxstack'] = true, |
||
+ | ['rarity'] = true, |
||
+ | ['suffocating'] = true, |
||
+ | ['redstone conductor'] = true, |
||
+ | ['flame odds'] = true, |
||
+ | ['burn odds'] = true, |
||
+ | ['lava flammable'] = true, |
||
+ | ['push reaction'] = true, |
||
+ | } |
||
+ | |||
+ | local function ValueTypeExist(valueType) |
||
+ | return not not categoryMapping[valueType] |
||
+ | end |
||
+ | |||
+ | -- 从值列表按照键值获得值,找不到则返回键值。 |
||
+ | local function MappingValue(mappingName, value) |
||
+ | local mapping = mw.loadData('Module:Autovalue/' .. mappingName .. ' mapping') |
||
+ | if mapping[value] then |
||
+ | return mapping[value] |
||
+ | else |
||
+ | return value |
||
end |
end |
||
+ | end |
||
− | local block = mw.text.trim( args[1] or ''):lower() |
||
− | local type = args.type |
||
+ | -- 从值列表按照键值获得值,有去除末尾s,有__fallback,找不到则返回nil。 |
||
− | -- Most of these transforms are unnecessary, but are kept for compatibility with original template |
||
+ | local function ValueFromValuesByKey(values, key) |
||
− | |||
+ | local value = values[key] |
||
− | -- Strip trailing "s" on everything but these |
||
− | + | if value == nil then |
|
+ | value = values[key:gsub('s$', '')] |
||
− | glass = true, |
||
− | steps = true, stairs = true, |
||
− | bars = true, |
||
− | cactus = true, |
||
− | leaves = true, |
||
− | grass = true, |
||
− | potatoes = true |
||
− | } |
||
− | if not keepS[block:match( '%w+$' )] then |
||
− | block = block:gsub( 's$', '' ) |
||
end |
end |
||
+ | if value == nil then |
||
− | |||
+ | value = values['__fallback'] |
||
− | -- Other transforms |
||
+ | end |
||
− | block = block |
||
+ | return value |
||
− | :gsub( 'wooden', 'wood' ) |
||
+ | end |
||
− | :gsub( 'mossy', 'moss' ) |
||
+ | |||
− | :gsub( 'steps', 'stairs' ) |
||
+ | -- 值获取方法,不设置则直接使用ValueFromValuesByKey。 |
||
− | :gsub( "['%(%)%-%s]+", '' ) |
||
+ | local valueGettingMethod = { |
||
− | |||
+ | ['breaking tool'] = (function (values, key, onlyBE) |
||
− | local value = mw.loadData( 'Module:' .. type .. ' values' )[block] |
||
+ | local value = ValueFromValuesByKey(values, key) |
||
+ | if type(value) ~= 'table' then |
||
+ | return value |
||
+ | end |
||
+ | local hardnessValues |
||
+ | if onlyBE then |
||
+ | hardnessValues = mw.loadData('Module:hardness values BE') |
||
+ | else |
||
+ | hardnessValues = mw.loadData('Module:hardness values') |
||
+ | end |
||
+ | if ValueFromValuesByKey(hardnessValues, key) == 0 then |
||
+ | local result = {} |
||
+ | for i,breakingTool in ipairs(value) do |
||
+ | if breakingTool == 'pickaxe' |
||
+ | or breakingTool == 'shovel' |
||
+ | or breakingTool == 'axe' |
||
+ | or breakingTool == 'hoe' |
||
+ | or breakingTool == 'sword' |
||
+ | or breakingTool == 'shears' |
||
+ | then |
||
+ | -- Skip. |
||
+ | else |
||
+ | table.insert(result, breakingTool) |
||
+ | end |
||
+ | end |
||
+ | return result; |
||
+ | else |
||
+ | return value |
||
+ | end |
||
+ | end), |
||
+ | } |
||
+ | |||
+ | -- 将true和false分别转换为'是'和'否'。 |
||
+ | local function TrueFalueMapping (value) |
||
+ | if value == true then |
||
+ | return '是' |
||
+ | elseif value == false then |
||
+ | return '否' |
||
+ | else |
||
+ | return value |
||
+ | end |
||
+ | end |
||
+ | |||
+ | -- 为数字添加逗号分隔符。 |
||
+ | local function FormatNumber (value) |
||
+ | if type(value) == 'number' then |
||
+ | local i, j, minus, int, fraction = tostring(value):find('([-]?)(%d+)([.]?%d*)') |
||
+ | int = int:reverse():gsub("(%d%d%d)", "%1,") |
||
+ | return minus .. int:reverse():gsub("^,", "") .. fraction |
||
+ | else |
||
+ | return value |
||
+ | end |
||
+ | end |
||
+ | |||
+ | -- 值映射方法,不设置则输出原值。 |
||
+ | local valueMappingMethod = { |
||
+ | ['blast resistance'] = FormatNumber, |
||
+ | ['hardness'] = FormatNumber, |
||
+ | ['maxstack'] = FormatNumber, |
||
+ | ['flame odds'] = FormatNumber, |
||
+ | ['burn odds'] = FormatNumber, |
||
+ | ['suffocating'] = TrueFalueMapping, |
||
+ | ['redstone conductor'] = TrueFalueMapping, |
||
+ | ['lava flammable'] = TrueFalueMapping, |
||
+ | ['breaking tool'] = (function (value) |
||
+ | if type(value) == 'table' then |
||
+ | local valueTable = {} |
||
+ | local frame = mw.getCurrentFrame() |
||
+ | for k, v in pairs( value ) do |
||
+ | table.insert(valueTable, frame:expandTemplate { title = 'BreakingToolTooltip', args = { v } }) |
||
+ | end |
||
+ | if #valueTable <= 0 then |
||
+ | return frame:expandTemplate { title = 'BreakingToolTooltip', args = { 'none' } } |
||
+ | end |
||
+ | return table.concat(valueTable) |
||
+ | end |
||
+ | return value |
||
+ | end), |
||
+ | ['creative tab'] = (function (value) |
||
+ | if type(value) == 'table' then |
||
+ | local valueTable = {} |
||
+ | for k, v in pairs( value ) do |
||
+ | table.insert(valueTable, MappingValue('creative tab', v)) |
||
+ | end |
||
+ | if #valueTable <= 0 then |
||
+ | return "''无''" |
||
+ | end |
||
+ | return table.concat(valueTable, ",") |
||
+ | end |
||
+ | return value |
||
+ | end), |
||
+ | ['creative category'] = (function (value) |
||
+ | return MappingValue('creative category', value) |
||
+ | end), |
||
+ | ['material'] = (function (value) |
||
+ | return MappingValue('material', value) |
||
+ | end), |
||
+ | ['material BE'] = (function (value) |
||
+ | return MappingValue('material BE', value) |
||
+ | end), |
||
+ | ['push reaction'] = (function (value) |
||
+ | return MappingValue('push reaction', value) |
||
+ | end), |
||
+ | } |
||
+ | |||
+ | -- 提供值列表、类型名称、键值名称来获取值。返回原始数据类型。 |
||
+ | local function tryGetRawValue(values, valueType, targetName, onlyBE) |
||
+ | local value |
||
+ | if type(valueGettingMethod[valueType]) == 'function' then |
||
+ | value = valueGettingMethod[valueType](values, targetName, onlyBE) |
||
+ | else |
||
+ | value = ValueFromValuesByKey(values, targetName) |
||
+ | end |
||
+ | return value |
||
+ | end |
||
+ | |||
+ | -- 提供值列表、类型名称、键值名称来获取值。返回值应当是字符串。 |
||
+ | local function tryGetValue(values, valueType, targetName, onlyBE) |
||
+ | local value = tryGetRawValue(values, valueType, targetName, onlyBE) |
||
+ | if type(valueMappingMethod[valueType]) == 'function' then |
||
+ | return valueMappingMethod[valueType](value) |
||
+ | else |
||
+ | return value |
||
+ | end |
||
+ | end |
||
+ | |||
+ | -- 获取值。 |
||
+ | local function GetValue(targetName, argType, argMode, nocat) |
||
+ | if not ValueTypeExist(argType) then |
||
+ | return '?[[Category:未知自动值类型]]' |
||
+ | end |
||
+ | |||
+ | local frame = mw.getCurrentFrame() |
||
+ | local values |
||
+ | local valuesBE |
||
+ | local onlyBE = false |
||
+ | if hasBeData[argType] then |
||
+ | if argMode == 'infobox' |
||
+ | or argMode == 'content' then |
||
+ | values = mw.loadData('Module:' .. argType .. ' values') |
||
+ | valuesBE = mw.loadData('Module:' .. argType .. ' values BE') |
||
+ | elseif argMode == 'onlyBE' then |
||
+ | values = mw.loadData('Module:' .. argType .. ' values BE') |
||
+ | onlyBE = true |
||
+ | else |
||
+ | values = mw.loadData('Module:' .. argType .. ' values') |
||
+ | end |
||
+ | else |
||
+ | values = mw.loadData('Module:' .. argType .. ' values') |
||
+ | end |
||
+ | local value |
||
+ | local valueBE |
||
local category = '' |
local category = '' |
||
+ | local result |
||
− | if not value then |
||
+ | if values then |
||
− | value = '[[Template:' .. type .. ' values#缺失的值|?]]' |
||
+ | value = tryGetValue(values, argType, targetName, onlyBE) |
||
− | local title = mw.title.getCurrentTitle() |
||
− | if |
+ | if value == nil and argMode == 'onlyBE' then |
− | + | values = mw.loadData('Module:' .. argType .. ' values') |
|
+ | value = tryGetValue(values, argType, targetName, false) |
||
+ | end |
||
+ | if value == nil then |
||
+ | value = '[[Template:' .. argType .. ' values#缺失值|?]]' |
||
+ | local title = mw.title.getCurrentTitle() |
||
+ | if not nocat and title.namespace == 0 and not title.isSubpage then |
||
+ | category = '[[Category:缺失' .. (categoryMapping[argType:lower()] or argType:lower()) .. ']]' |
||
+ | end |
||
end |
end |
||
end |
end |
||
+ | if valuesBE then |
||
− | return value .. category |
||
+ | valueBE = tryGetValue(valuesBE, argType, targetName, true) or value |
||
+ | end |
||
+ | if valueBE then |
||
+ | if argMode == 'infobox' then |
||
+ | result = "'''" .. frame:expandTemplate { title = 'el', args = { 'je' } } .. ":'''" .. value .. "<br>'''" .. frame:expandTemplate { title = 'el', args = { 'be' } } .. ":'''" .. valueBE |
||
+ | else |
||
+ | result = value .. frame:expandTemplate { title = 'only', args = { 'je' } } .. "或" .. valueBE .. frame:expandTemplate { title = 'only', args = { 'be' } } |
||
+ | end |
||
+ | else |
||
+ | result = value |
||
+ | end |
||
+ | result = result .. category |
||
+ | return result |
||
end |
end |
||
+ | |||
+ | -- 去除参数字符串头尾的空格和换行符。 |
||
+ | local function StripSpaceAndLineAtBothEnds(str) |
||
+ | return string.gsub(str, '^[%s\n]*(.-)[%s\n]*$', '%1') |
||
+ | end |
||
+ | |||
+ | -- 将字符串转换为键值对表。 |
||
+ | local function LoadKeyValuePairsFromString(str) |
||
+ | local strTable = {} |
||
+ | local resultTable = {} |
||
+ | local lastPoint = 0 |
||
+ | while true do |
||
+ | local point1,point2 = string.find(str, "[^;]+", lastPoint + 1) |
||
+ | if point1 == nil then |
||
+ | break |
||
+ | end |
||
+ | lastPoint = point2 |
||
+ | table.insert(strTable, string.sub(str, point1, point2)) |
||
+ | end |
||
+ | for i,strInTable in ipairs(strTable) do |
||
+ | local key, value |
||
+ | local point = string.find(strInTable, ":", 1) |
||
+ | if point ~= nil then |
||
+ | key = StripSpaceAndLineAtBothEnds(string.sub(strInTable, 1, point - 1)) |
||
+ | value = StripSpaceAndLineAtBothEnds(string.sub(strInTable, point + 1, string.len(strInTable))) |
||
+ | else |
||
+ | key = StripSpaceAndLineAtBothEnds(strInTable) |
||
+ | end |
||
+ | table.insert(resultTable, {key = key, value = value}) |
||
+ | end |
||
+ | return resultTable |
||
+ | end |
||
+ | |||
+ | -- 外部模块调用此函数。 |
||
+ | function p.getRawValue(targetName, valueType, onlyBE) |
||
+ | local values |
||
+ | if hasBeData[valueType] and onlyBE then |
||
+ | values = mw.loadData('Module:' .. valueType .. ' values BE') |
||
+ | else |
||
+ | values = mw.loadData('Module:' .. valueType .. ' values') |
||
+ | onlyBE = false |
||
+ | end |
||
+ | local value = tryGetRawValue(values, valueType, targetName, onlyBE) |
||
+ | if value == nil and onlyBE then |
||
+ | return p.getValue(targetName, valueType, false) |
||
+ | end |
||
+ | return value |
||
+ | end |
||
+ | |||
+ | -- 外部模块调用此函数。 |
||
+ | function p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge) |
||
+ | local targetNames = LoadKeyValuePairsFromString(mw.text.trim(argTargetNames or ''):lower()) |
||
+ | local argOriginalMode = argMode |
||
+ | |||
+ | if #targetNames < 1 then |
||
+ | return GetValue('', argType, argMode, argNocat) |
||
+ | end |
||
+ | if #targetNames == 1 and targetNames.value == nil then |
||
+ | return GetValue(targetNames[1].key, argType, argMode, argNocat) |
||
+ | end |
||
+ | |||
+ | if argMode == 'infobox' then |
||
+ | argMode = 'content' |
||
+ | end |
||
+ | |||
+ | local resultEntries = {} |
||
+ | |||
+ | for i,keyValuePair in ipairs(targetNames) do |
||
+ | local entryName = keyValuePair.value or Autolink.invlink( keyValuePair.key, 'nolink' ) |
||
+ | local entryValue = GetValue(keyValuePair.key, argType, argMode, argNocat) |
||
+ | |||
+ | local targetResultEntryFound = false |
||
+ | if doNotMerge and doNotMerge ~= true then |
||
+ | for i,resultEntry in ipairs(resultEntries) do |
||
+ | if resultEntry.value == entryValue then |
||
+ | targetResultEntryFound = true |
||
+ | table.insert(resultEntry.names, entryName) |
||
+ | break |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | if not targetResultEntryFound then |
||
+ | table.insert(resultEntries, { |
||
+ | names = { entryName }, |
||
+ | value = entryValue |
||
+ | }) |
||
+ | end |
||
+ | end |
||
+ | |||
+ | local resultStringTable = {} |
||
+ | for i,targetResultEntry in ipairs(resultEntries) do |
||
+ | local rowNames = {} |
||
+ | for i,entryName in ipairs(targetResultEntry.names) do |
||
+ | table.insert(rowNames, "'''"..entryName.."'''") |
||
+ | end |
||
+ | local rowName = table.concat(rowNames, '、') |
||
+ | local rowValue = targetResultEntry.value |
||
+ | table.insert(resultStringTable, rowName..":"..rowValue) |
||
+ | end |
||
+ | |||
+ | if #resultStringTable == 1 then |
||
+ | if argOriginalMode == 'infobox' and hasBeData[argType] then |
||
+ | return GetValue(targetNames[1].key, argType, 'infobox', argNocat) |
||
+ | else |
||
+ | return resultEntries[1].value |
||
+ | end |
||
+ | else |
||
+ | return table.concat(resultStringTable, "<br>") |
||
+ | end |
||
+ | end |
||
+ | |||
+ | -- 模板调用此函数。 |
||
+ | function p.value(f) |
||
+ | local args = f |
||
+ | local frame = mw.getCurrentFrame() |
||
+ | if f == frame then |
||
+ | args = require('Module:ProcessArgs').merge(true) |
||
+ | end |
||
+ | local argTargetNames = mw.text.trim(args[1] or ''):lower() |
||
+ | local argType = args.type |
||
+ | local argMode = args.mode or 'onlyJE' |
||
+ | local argNocat = args.nocat |
||
+ | local argNoMergeSameValues = args['autovalue-do-not-merge-rows'] |
||
+ | local doNotMerge = type(argNoMergeSameValues) == 'string' and #argNoMergeSameValues > 0 |
||
+ | |||
+ | return p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge ) |
||
+ | end |
||
+ | |||
return p |
return p |
2023年11月10日 (五) 13:55的最新版本
本模块用于实现值提供器模板。
用法
此模块对外公开了以下方法:
p.value(f)
:模板使用的方法,会解析模板被传入的参数。p.getValue(argTargetNames, argType, argMode, argNocat)
:其他模块可以使用的易于调用的方法。p.getRawValue(targetName, valueType, onlyBE)
:直接返回原始数据类型、不进行转换为字符串的方法。每次调用只能处理单个目标名称。
名称 | p.value | p.getValue |
---|---|---|
目标名称 | 1 | argTargetNames |
目标类型 | type | argType |
数据模式 | mode | argMode |
停用分类 | nocat | argNocat |
目标名称
需要解析的一系列目标名称。
每一个目标名称应当是一个Reverselink的英文名称,之间使用;
作为分割,分隔符之间可以插入空格、制表符和换行符。模块会自动从Module:Autolink获取名称,但可以通过目标名称:可读名称
来覆盖。
{{Hardness values| Structure Void; Crafting Table; Beehive; Bee nest; Chest:大箱子; }}
结构空位:0
工作台:2.5
蜂箱:0.6
蜂巢:0.3
大箱子:2.5
目标类型
目标值的类型。
* 合适挖掘工具:{{#invoke: Autovalue | value | Crafting Table | type = breaking tool }} * 硬度:{{#invoke: Autovalue | value | Crafting Table | type = hardness }} * 爆炸抗性:{{#invoke: Autovalue | value | Crafting Table | type = blast resistance }}
数据模式
影响模块在数据于JE和BE有不同值时的输出方式。若没有JE和BE使用不同值的情况,模式对输出没有影响。
模式 | 输出 | 说明 |
---|---|---|
onlyJE | 0 | 只输出JE值。 |
content | 0 |
适用于文内插入的使用{{only}} 的叙述。
|
infobox | Java版:0 基岩版:-1 |
适用于插入信息框的纵列叙述。 |
onlyBE | -1 | 只输出BE值。 |
停用分类
指定后不再添加缺失值的维护分类。
依赖项
另见
- 实现
- Module:Autovalue
- Module:Autovalue/types
{{Autovalue}}
- 主要用途
- 分类
- 数据
local p = {}
local Autolink = require( [[Module:Autolink]] )
--为维护分类提供名称。
local categoryMapping = {
-- 方块数据
['breaking tool'] = '合适挖掘工具',
['blast resistance'] = '爆炸抗性',
['hardness'] = '硬度',
['material'] = '材料', -- JE
['material BE'] = '基岩版材料', -- BE
['suffocating'] = '窒息生物',
['redstone conductor'] = '红石导体',
['flame odds'] = '引燃几率',
['burn odds'] = '烧毁几率',
['lava flammable'] = '熔岩可燃性',
['push reaction'] = '活塞推动行为',
-- 物品数据
['maxstack'] = '最大堆叠',
['rarity'] = '稀有度',
['creative tab'] = '创造标签页', -- JE
['creative category'] = '创造分类', -- BE
}
-- 是否有对应的values BE数据表。
local hasBeData = {
['breaking tool'] = true,
['blast resistance'] = true,
['hardness'] = true,
['maxstack'] = true,
['rarity'] = true,
['suffocating'] = true,
['redstone conductor'] = true,
['flame odds'] = true,
['burn odds'] = true,
['lava flammable'] = true,
['push reaction'] = true,
}
local function ValueTypeExist(valueType)
return not not categoryMapping[valueType]
end
-- 从值列表按照键值获得值,找不到则返回键值。
local function MappingValue(mappingName, value)
local mapping = mw.loadData('Module:Autovalue/' .. mappingName .. ' mapping')
if mapping[value] then
return mapping[value]
else
return value
end
end
-- 从值列表按照键值获得值,有去除末尾s,有__fallback,找不到则返回nil。
local function ValueFromValuesByKey(values, key)
local value = values[key]
if value == nil then
value = values[key:gsub('s$', '')]
end
if value == nil then
value = values['__fallback']
end
return value
end
-- 值获取方法,不设置则直接使用ValueFromValuesByKey。
local valueGettingMethod = {
['breaking tool'] = (function (values, key, onlyBE)
local value = ValueFromValuesByKey(values, key)
if type(value) ~= 'table' then
return value
end
local hardnessValues
if onlyBE then
hardnessValues = mw.loadData('Module:hardness values BE')
else
hardnessValues = mw.loadData('Module:hardness values')
end
if ValueFromValuesByKey(hardnessValues, key) == 0 then
local result = {}
for i,breakingTool in ipairs(value) do
if breakingTool == 'pickaxe'
or breakingTool == 'shovel'
or breakingTool == 'axe'
or breakingTool == 'hoe'
or breakingTool == 'sword'
or breakingTool == 'shears'
then
-- Skip.
else
table.insert(result, breakingTool)
end
end
return result;
else
return value
end
end),
}
-- 将true和false分别转换为'是'和'否'。
local function TrueFalueMapping (value)
if value == true then
return '是'
elseif value == false then
return '否'
else
return value
end
end
-- 为数字添加逗号分隔符。
local function FormatNumber (value)
if type(value) == 'number' then
local i, j, minus, int, fraction = tostring(value):find('([-]?)(%d+)([.]?%d*)')
int = int:reverse():gsub("(%d%d%d)", "%1,")
return minus .. int:reverse():gsub("^,", "") .. fraction
else
return value
end
end
-- 值映射方法,不设置则输出原值。
local valueMappingMethod = {
['blast resistance'] = FormatNumber,
['hardness'] = FormatNumber,
['maxstack'] = FormatNumber,
['flame odds'] = FormatNumber,
['burn odds'] = FormatNumber,
['suffocating'] = TrueFalueMapping,
['redstone conductor'] = TrueFalueMapping,
['lava flammable'] = TrueFalueMapping,
['breaking tool'] = (function (value)
if type(value) == 'table' then
local valueTable = {}
local frame = mw.getCurrentFrame()
for k, v in pairs( value ) do
table.insert(valueTable, frame:expandTemplate { title = 'BreakingToolTooltip', args = { v } })
end
if #valueTable <= 0 then
return frame:expandTemplate { title = 'BreakingToolTooltip', args = { 'none' } }
end
return table.concat(valueTable)
end
return value
end),
['creative tab'] = (function (value)
if type(value) == 'table' then
local valueTable = {}
for k, v in pairs( value ) do
table.insert(valueTable, MappingValue('creative tab', v))
end
if #valueTable <= 0 then
return "''无''"
end
return table.concat(valueTable, ",")
end
return value
end),
['creative category'] = (function (value)
return MappingValue('creative category', value)
end),
['material'] = (function (value)
return MappingValue('material', value)
end),
['material BE'] = (function (value)
return MappingValue('material BE', value)
end),
['push reaction'] = (function (value)
return MappingValue('push reaction', value)
end),
}
-- 提供值列表、类型名称、键值名称来获取值。返回原始数据类型。
local function tryGetRawValue(values, valueType, targetName, onlyBE)
local value
if type(valueGettingMethod[valueType]) == 'function' then
value = valueGettingMethod[valueType](values, targetName, onlyBE)
else
value = ValueFromValuesByKey(values, targetName)
end
return value
end
-- 提供值列表、类型名称、键值名称来获取值。返回值应当是字符串。
local function tryGetValue(values, valueType, targetName, onlyBE)
local value = tryGetRawValue(values, valueType, targetName, onlyBE)
if type(valueMappingMethod[valueType]) == 'function' then
return valueMappingMethod[valueType](value)
else
return value
end
end
-- 获取值。
local function GetValue(targetName, argType, argMode, nocat)
if not ValueTypeExist(argType) then
return '?[[Category:未知自动值类型]]'
end
local frame = mw.getCurrentFrame()
local values
local valuesBE
local onlyBE = false
if hasBeData[argType] then
if argMode == 'infobox'
or argMode == 'content' then
values = mw.loadData('Module:' .. argType .. ' values')
valuesBE = mw.loadData('Module:' .. argType .. ' values BE')
elseif argMode == 'onlyBE' then
values = mw.loadData('Module:' .. argType .. ' values BE')
onlyBE = true
else
values = mw.loadData('Module:' .. argType .. ' values')
end
else
values = mw.loadData('Module:' .. argType .. ' values')
end
local value
local valueBE
local category = ''
local result
if values then
value = tryGetValue(values, argType, targetName, onlyBE)
if value == nil and argMode == 'onlyBE' then
values = mw.loadData('Module:' .. argType .. ' values')
value = tryGetValue(values, argType, targetName, false)
end
if value == nil then
value = '[[Template:' .. argType .. ' values#缺失值|?]]'
local title = mw.title.getCurrentTitle()
if not nocat and title.namespace == 0 and not title.isSubpage then
category = '[[Category:缺失' .. (categoryMapping[argType:lower()] or argType:lower()) .. ']]'
end
end
end
if valuesBE then
valueBE = tryGetValue(valuesBE, argType, targetName, true) or value
end
if valueBE then
if argMode == 'infobox' then
result = "'''" .. frame:expandTemplate { title = 'el', args = { 'je' } } .. ":'''" .. value .. "<br>'''" .. frame:expandTemplate { title = 'el', args = { 'be' } } .. ":'''" .. valueBE
else
result = value .. frame:expandTemplate { title = 'only', args = { 'je' } } .. "或" .. valueBE .. frame:expandTemplate { title = 'only', args = { 'be' } }
end
else
result = value
end
result = result .. category
return result
end
-- 去除参数字符串头尾的空格和换行符。
local function StripSpaceAndLineAtBothEnds(str)
return string.gsub(str, '^[%s\n]*(.-)[%s\n]*$', '%1')
end
-- 将字符串转换为键值对表。
local function LoadKeyValuePairsFromString(str)
local strTable = {}
local resultTable = {}
local lastPoint = 0
while true do
local point1,point2 = string.find(str, "[^;]+", lastPoint + 1)
if point1 == nil then
break
end
lastPoint = point2
table.insert(strTable, string.sub(str, point1, point2))
end
for i,strInTable in ipairs(strTable) do
local key, value
local point = string.find(strInTable, ":", 1)
if point ~= nil then
key = StripSpaceAndLineAtBothEnds(string.sub(strInTable, 1, point - 1))
value = StripSpaceAndLineAtBothEnds(string.sub(strInTable, point + 1, string.len(strInTable)))
else
key = StripSpaceAndLineAtBothEnds(strInTable)
end
table.insert(resultTable, {key = key, value = value})
end
return resultTable
end
-- 外部模块调用此函数。
function p.getRawValue(targetName, valueType, onlyBE)
local values
if hasBeData[valueType] and onlyBE then
values = mw.loadData('Module:' .. valueType .. ' values BE')
else
values = mw.loadData('Module:' .. valueType .. ' values')
onlyBE = false
end
local value = tryGetRawValue(values, valueType, targetName, onlyBE)
if value == nil and onlyBE then
return p.getValue(targetName, valueType, false)
end
return value
end
-- 外部模块调用此函数。
function p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge)
local targetNames = LoadKeyValuePairsFromString(mw.text.trim(argTargetNames or ''):lower())
local argOriginalMode = argMode
if #targetNames < 1 then
return GetValue('', argType, argMode, argNocat)
end
if #targetNames == 1 and targetNames.value == nil then
return GetValue(targetNames[1].key, argType, argMode, argNocat)
end
if argMode == 'infobox' then
argMode = 'content'
end
local resultEntries = {}
for i,keyValuePair in ipairs(targetNames) do
local entryName = keyValuePair.value or Autolink.invlink( keyValuePair.key, 'nolink' )
local entryValue = GetValue(keyValuePair.key, argType, argMode, argNocat)
local targetResultEntryFound = false
if doNotMerge and doNotMerge ~= true then
for i,resultEntry in ipairs(resultEntries) do
if resultEntry.value == entryValue then
targetResultEntryFound = true
table.insert(resultEntry.names, entryName)
break
end
end
end
if not targetResultEntryFound then
table.insert(resultEntries, {
names = { entryName },
value = entryValue
})
end
end
local resultStringTable = {}
for i,targetResultEntry in ipairs(resultEntries) do
local rowNames = {}
for i,entryName in ipairs(targetResultEntry.names) do
table.insert(rowNames, "'''"..entryName.."'''")
end
local rowName = table.concat(rowNames, '、')
local rowValue = targetResultEntry.value
table.insert(resultStringTable, rowName..":"..rowValue)
end
if #resultStringTable == 1 then
if argOriginalMode == 'infobox' and hasBeData[argType] then
return GetValue(targetNames[1].key, argType, 'infobox', argNocat)
else
return resultEntries[1].value
end
else
return table.concat(resultStringTable, "<br>")
end
end
-- 模板调用此函数。
function p.value(f)
local args = f
local frame = mw.getCurrentFrame()
if f == frame then
args = require('Module:ProcessArgs').merge(true)
end
local argTargetNames = mw.text.trim(args[1] or ''):lower()
local argType = args.type
local argMode = args.mode or 'onlyJE'
local argNocat = args.nocat
local argNoMergeSameValues = args['autovalue-do-not-merge-rows']
local doNotMerge = type(argNoMergeSameValues) == 'string' and #argNoMergeSameValues > 0
return p.getValue(argTargetNames, argType, argMode, argNocat, doNotMerge )
end
return p