Warning.png

Поддержка Wiki прекращена, она доступна в режиме архива. Информация в ней устарела и может быть неактуальной.

Модуль:Инвентарный слот — различия между версиями

Материал из Hilarious Wiki
Перейти к: навигация, поиск
м
 
(не показано 276 промежуточных версий 2 участников)
Строка 1: Строка 1:
 
-------------------------------------------------------------------
 
-------------------------------------------------------------------
--- Модуль для отображения инвентарных слотов в Hilarious Wiki.
+
--- Модуль для отображения инвентарных слотов в Minecraft Wiki.
 
-------------------------------------------------------------------
 
-------------------------------------------------------------------
  
 
local p = {}
 
local p = {}
 
 
-- Список приставок к названиям, обрабатываемых другими модулями.
 
-- Список приставок к названиям, обрабатываемых другими модулями.
 
-- Так будет легче, например, убирать их из целей ссылок.
 
-- Так будет легче, например, убирать их из целей ссылок.
Строка 12: Строка 11:
 
'Повреждённый', 'Повреждённая', 'Повреждённое', 'Повреждённые' -- использование Ё обязательно
 
'Повреждённый', 'Повреждённая', 'Повреждённое', 'Повреждённые' -- использование Ё обязательно
 
}
 
}
 +
 +
p.modAliases = mw.loadData("Модуль:Модификации")
  
 
--- Создание слота
 
--- Создание слота
Строка 23: Строка 24:
 
-- Первый аргумент
 
-- Первый аргумент
 
args[1] = mw.text.trim(args[1] or '')
 
args[1] = mw.text.trim(args[1] or '')
+
 
--- Псевдонимы
+
--- Псевдонимы оригинальной игры
-- Вы можете закомментировать следующую строку, если не используете псевдонимы
 
 
local aliases = mw.loadData('Модуль:Инвентарный слот/Псевдонимы')
 
local aliases = mw.loadData('Модуль:Инвентарный слот/Псевдонимы')
 
 
local modAliases = args["модпсевдонимы"] or ''
+
    local frames = {}
if modAliases ~= '' then
+
for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do
modAliases = mw.loadData('Модуль:' .. modAliases)
+
 
else
+
local frameParts = p.getParts( frame, args["мод"] )
modAliases = nil
+
local id = frameParts.name
end
+
        -- if frameParts.mod then
+
-- id = frameParts.mod .. ':' .. id
if aliases or modAliases then
+
-- end
local frames = {}
+
 
for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do
+
        --- Загрузка списка псевдонимов к модам
local frameParts = p.getParts( frame, args["мод"] )
+
        local modAliases
+
        if frameParts.mod then
local id = frameParts.name
+
            if mw.title.new('Модуль:ИнвСпрайт/' .. frameParts.mod).exists then
if frameParts.mod then
+
                modAliases = mw.loadData('Модуль:ИнвСпрайт/' .. frameParts.mod)["модпсевдонимы"]
id = frameParts.mod .. ':' .. id
+
                if modAliases and mw.title.new('Модуль:' .. modAliases).exists then
end
+
                    modAliases = mw.loadData('Модуль:' .. modAliases)
+
                end
local alias
+
            end
if modAliases and modAliases[id] then
+
        end
alias = modAliases[id]
+
 
elseif aliases and aliases[id] then
+
        local alias = nil
alias = aliases[id]
+
if frameParts.mod then
end
+
            if modAliases and modAliases[id] then
+
 
if alias then
+
            --- ['имя'] = '[титл]:имя[доп. текст]'
table.insert( frames, p.expandAlias( frameParts, alias ) )
+
 
else
+
                local title = mw.ustring.match ( modAliases[id], '^%[([^%]]+)%]' )
table.insert( frames, frame )
+
                if title then
end
+
                    local aaa = mw.ustring.match ( modAliases[id], '^%[[^%]]+%](.+)$' )
 +
                    if aaa then
 +
                        alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. aaa
 +
                    else
 +
                        alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. frameParts.name
 +
                    end
 +
                else
 +
                    alias = frameParts.mod .. ':' .. modAliases[id]
 +
                end
 +
            end
 +
elseif aliases and aliases[id] then
 +
alias = aliases[id]
 +
end
 +
 
 +
if alias then
 +
table.insert( frames, p.expandAlias( frameParts, alias ) )
 +
else
 +
table.insert( frames, frame )
 
end
 
end
 
args[1] = table.concat( frames, ';' )
 
 
end
 
end
 +
    args[1] = table.concat( frames, ';' )
 
 
 
--- Построение спрайта
 
--- Построение спрайта
Строка 111: Строка 127:
 
local description = parts.text
 
local description = parts.text
 
 
local img, idData
+
local img, idData, en_name
 
if mod then
 
if mod then
 
local modData = modIds[mod]
 
local modData = modIds[mod]
Строка 120: Строка 136:
 
if modData and modData[name] then
 
if modData and modData[name] then
 
idData = modData[name]
 
idData = modData[name]
 +
en_name = idData["en"]
 
else
 
else
 
img = name .. ' (' .. mod .. ')'
 
img = name .. ' (' .. mod .. ')'
Строка 128: Строка 145:
 
img = name
 
img = name
 
end
 
end
+
 
 +
local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1}
 
local link = args["ссылка"] or ''
 
local link = args["ссылка"] or ''
 
if link == '' then
 
if link == '' then
Строка 134: Строка 152:
 
link = mod .. '/' .. name
 
link = mod .. '/' .. name
 
else
 
else
link = mw.ustring.gsub(name, '^Повреждённ[ыао][йяе] ', '')
+
link = nil
 
end
 
end
 
elseif mw.ustring.lower(link) == 'нет' then
 
elseif mw.ustring.lower(link) == 'нет' then
Строка 148: Строка 166:
 
plainTitle = name
 
plainTitle = name
 
elseif mw.ustring.lower(title) ~= 'нет' then
 
elseif mw.ustring.lower(title) ~= 'нет' then
plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' )
+
plainTitle = mw.ustring.gsub(mw.ustring.gsub(title, '\\\\', '\'), '\\&', '&')
 
 
 
local formatPattern = '&[0-9a-fk-or]'
 
local formatPattern = '&[0-9a-fk-or]'
Строка 159: Строка 177:
 
plainTitle = name
 
plainTitle = name
 
else
 
else
plainTitle = plainTitle:gsub( '\', '\\' ):gsub( '&', '&' )
+
plainTitle = mw.ustring.gsub(mw.ustring.gsub(plainTitle, '\', '\\'), '&', '&')
 
end
 
end
 
elseif link then
 
elseif link then
Строка 171: Строка 189:
 
item:attr{
 
item:attr{
 
['data-minetip-title'] = formattedTitle,
 
['data-minetip-title'] = formattedTitle,
['data-minetip-text'] = description
+
['data-minetip-text'] = description,
 +
['data-modinfo-text'] = mod,
 +
                ['data-minetip-lowtitle'] = en_name
 
}
 
}
 
 
Строка 177: Строка 197:
 
-- & is re-escaped because mw.html treats attributes
 
-- & is re-escaped because mw.html treats attributes
 
-- as plain text, but MediaWiki doesn't
 
-- as plain text, but MediaWiki doesn't
local escapedTitle = mw.ustring.gsub((plainTitle or ''), '&', '&')
+
local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' )
 
item:addClass('invslot-item-image')
 
item:addClass('invslot-item-image')
 
:wikitext('[[Файл:Grid ', img, '.png|32x32px|link=', link or '', '|', escapedTitle, ']]')
 
:wikitext('[[Файл:Grid ', img, '.png|32x32px|link=', link or '', '|', escapedTitle, ']]')
Строка 204: Строка 224:
 
    }
 
    }
 
end
 
end
 
 
item:node(image)
 
item:node(image)
 
category = spriteCat
 
category = spriteCat
Строка 246: Строка 265:
 
function p.expandAlias( frameParts, alias )
 
function p.expandAlias( frameParts, alias )
 
-- If the frame has no parts, we can just return the alias as-is
 
-- If the frame has no parts, we can just return the alias as-is
if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then
+
--[[if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then
 
return alias
 
return alias
end
+
end--]]
 
 
 
local expandedFrames = {}
 
local expandedFrames = {}
Строка 266: Строка 285:
 
return table.concat(expandedFrames, ';')
 
return table.concat(expandedFrames, ';')
 
end
 
end
 +
  
 
function p.getParts(frame, mod)
 
function p.getParts(frame, mod)
 +
----Функция получает название предмета в формате "[титл]мод:имя[доп.текст],число"
 +
----parts.title = титл, название предмета при наведении
 +
----parts.mod = мод
 +
----parts.name = имя
 +
----parts.text = текст, дополнительный текст при наведении на предмет
 +
----parts.num = число
 +
 
local parts = {}
 
local parts = {}
 
parts.title = mw.ustring.match(frame, '^%[%s*([^%]]+)%s*%]')
 
parts.title = mw.ustring.match(frame, '^%[%s*([^%]]+)%s*%]')
 
 
parts.mod = mw.text.trim(mw.ustring.match(frame, '([^:%]]+):') or mod or '')
+
    local modPattern
+
    if mw.ustring.match(frame, '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):') then
 +
    modPattern = '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):'
 +
    else
 +
    modPattern = '^([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):'
 +
    end
 +
 
 +
parts.mod = mw.text.trim(mw.ustring.match(frame, modPattern) or mod or '') ---- Получаем название мода
 +
 
 
local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1}
 
local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1}
if parts.mod == '' or vanilla[mw.ustring.lower(parts.mod)] then
+
if parts.mod == '' or vanilla[mw.ustring.lower(parts.mod)] then  
 +
link = nil
 
parts.mod = nil
 
parts.mod = nil
 +
else
 +
    if p.modAliases[parts.mod] then
 +
    parts.mod = p.modAliases[parts.mod]
 +
        end
 +
        parts.mod = mw.ustring.gsub(parts.mod,'_',' ')
 
end
 
end
+
local _, nameStartV = mw.ustring.find( frame, '^%[[^%]]*%]' )
local nameStart = (mw.ustring.find(frame, ':') or mw.ustring.find(frame, '%]') or 0 ) + 1
+
local nameStart = ( ({mw.ustring.find( frame, modPattern )})[2] or nameStartV or 0 ) + 1
 
if nameStart - 1 == #frame then
 
if nameStart - 1 == #frame then
 
nameStart = 1
 
nameStart = 1
 
end
 
end
parts.name = mw.text.trim(mw.ustring.sub(frame, nameStart, (mw.ustring.find(frame, '[,%[]', nameStart) or 0) - 1))
+
parts.name = mw.text.trim( mw.ustring.sub( frame, nameStart, ( mw.ustring.find( frame, '[,%[]', nameStart ) or 0 ) - 1 ) )
 
 
 
parts.num = math.floor(mw.ustring.match(frame, ',%s*(%d+)') or 0)
 
parts.num = math.floor(mw.ustring.match(frame, ',%s*(%d+)') or 0)
Строка 290: Строка 330:
 
 
 
parts.text = mw.ustring.match(frame, '%[%s*([^%]]+)%s*%]$')
 
parts.text = mw.ustring.match(frame, '%[%s*([^%]]+)%s*%]$')
+
   
 
return parts
 
return parts
 
end
 
end
 
   
 
   
 
return p
 
return p

Текущая версия на 08:11, 16 октября 2018

Документация

Этот модуль используется для изображения инвентарных слотов с изображениями блоков и предметов. Эти слоты по виду подобны тем, что имеются в игре Minecraft (при стандартном пакете ресурсов). Изображение каждого предмета достаётся из таблицы спрайтов, а если оно там отсутствует — из файла с полным названием в формате Файл:Grid Название предмета [(Модификация игры, если указана)].png[1]

Модуль рекомендуется использовать в других модулях напрямую (через require("Модуль:Инвентарный слот")), а вне их — через шаблон {{Инвентарный слот}}.

Использование

Смотрите также: Справка:Модули

Внутри других модулей этот модуль включается через функцию Lua require: require("Модуль:Инвентарный слот"), которая возвращает ассоциативный массив (таблицу) с функциями и параметрами. Основной функцией является slot, именно её и следует вызывать, чтобы отобразить слот.

В других страницах модуль (а конкретно её функция slot) используется преимущественно через шаблон {{Инвентарный слот}}, который вызывает программу через конструкцию {{#invoke: Инвентарный слот|slot}} (при этом параметры шаблона передаются модулю неявно). Именно эту конструкцию необходимо использовать, если модуль нужно вызвать из обычной страницы напрямую (вот только зачем?).

Параметры

Модуль поддерживает следующие параметры:

Название Описание Значение по умолчанию
Основные параметры
1[2] Указывает название блока или предмета (или псевдоним). Можно указывать несколько предметов (до 16), отделяя их точкой с запятой. После названия через запятую можно указывать число предметов в стопке. Перед же названием можно указать в [квадратных скобках] иной всплывающий текст (по умолчанию он такой же, как и название предмета, если только не переопределён псевдонимом). Пустое (тогда слот создаётся пустым)
назв Переопределяет всплывающий текст для предметов. Следует обратить внимание, что он имеет более низкий приоритет, чем переопределение с помощью квадратных скобок, а значит, если используются оба метода сразу, отображён будет текст из скобок. Пустое (тогда всплывающие тексты остаются нетронутыми)
ссылка Определяет, на какую страницу ссылаются изображения. Пустое (тогда изображения ссылаются на одноимённые с ними страницы)

Зависимости

Примечания

  1. Курсивом выделен текст, который заменяется на соответствующее значение. В [квадратных скобках] указан фрагмент, который не всегда присутствует.
  2. Параметры с числовыми названиями являются порядковыми и обычно указываются без названия, которое тогда соответствует порядковому номеру среди таких аргументов.

Расположенная выше документация включена из Модуль:Инвентарный слот/док.

-------------------------------------------------------------------
--- Модуль для отображения инвентарных слотов в Minecraft Wiki.
-------------------------------------------------------------------

local p = {}
-- Список приставок к названиям, обрабатываемых другими модулями.
-- Так будет легче, например, убирать их из целей ссылок.
-- ВНИМАНИЕ: указывайте все варианты склонения по родам и числам.
p.prefixes = {
	'Любой', 'Любая', 'Любое', 'Любые',
	'Повреждённый', 'Повреждённая', 'Повреждённое', 'Повреждённые' -- использование Ё обязательно
}

p.modAliases = mw.loadData("Модуль:Модификации")

--- Создание слота
function p.slot(f)
	--- Получение аргументов
	local args = f.args or f
	if f == mw.getCurrentFrame() and args[1] == nil then
		args = f:getParent().args
	end
	
	-- Первый аргумент
	args[1] = mw.text.trim(args[1] or '')

	--- Псевдонимы оригинальной игры
	local aliases = mw.loadData('Модуль:Инвентарный слот/Псевдонимы')
	
    local frames = {}
	for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do

		local frameParts = p.getParts( frame, args["мод"] )
		local id = frameParts.name
        -- if frameParts.mod then
		--	id = frameParts.mod .. ':' .. id
		-- end

        --- Загрузка списка псевдонимов к модам
        local modAliases
        if frameParts.mod then
            if mw.title.new('Модуль:ИнвСпрайт/' .. frameParts.mod).exists then
                modAliases = mw.loadData('Модуль:ИнвСпрайт/' .. frameParts.mod)["модпсевдонимы"]
                if modAliases and mw.title.new('Модуль:' .. modAliases).exists then
                    modAliases = mw.loadData('Модуль:' .. modAliases)
                end
            end
        end

        local alias = nil
		if frameParts.mod then
            if modAliases and modAliases[id] then

            --- ['имя'] = '[титл]:имя[доп. текст]'

                local title = mw.ustring.match ( modAliases[id], '^%[([^%]]+)%]' )
                if title then
                    local aaa = mw.ustring.match ( modAliases[id], '^%[[^%]]+%](.+)$' )
                    if aaa then
                        alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. aaa
                    else
                        alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. frameParts.name
                    end
                else 
                    alias = frameParts.mod .. ':' .. modAliases[id]
                end
            end
		elseif aliases and aliases[id] then
			alias = aliases[id]
		end

		if alias then
			table.insert( frames, p.expandAlias( frameParts, alias ) )
		else
			table.insert( frames, frame )
		end
	end
    args[1] = table.concat( frames, ';' )
	
	--- Построение спрайта
	
	-- Параметры
	local sprite
	local ids = mw.loadData([[Модуль:ИнвСпрайт/ID]])["IDы"]
	local modIds = {}
	local animated = mw.ustring.find(args[1], ';')
	local pageName = mw.title.getCurrentTitle().text
	local imgClass = args["классизобр"]
	local numStyle = args["стильцифр"]
	
	local body = mw.html.create('span'):addClass('invslot'):css{['vertical-align'] = args["выравн"]}
	
	if animated then
		body:addClass('animated')
	end
	if args["класс"] then
		body:addClass(args["класс"])
	end
	if args["стиль"] then
		body:cssText(args["стиль"])
	end
	
	if (args["умолчание"] or '') ~= '' then
		body:css('background-image', '{{FileUrl|' .. args["умолчание"] .. '.png}}')
	end
	
	--- Обработка фреймов
	local first = true
	for frame in mw.text.gsplit(args[1], '%s*;%s*') do
		local item
		if frame ~= '' or frame == '' and animated then
			item = body:tag('span'):addClass('invslot-item')
			if imgClass then
				item:addClass(imgClass)
			end
		end
		
		if frame == '' then
			(item or body):tag('br')
		else
			local category
			local parts = p.getParts(frame, args["мод"])
			local title = parts.title or mw.text.trim(args["назв"] or '')
			local mod = parts.mod
			local name = parts.name
			local num = parts.num
			local description = parts.text
			
			local img, idData, en_name
			if mod then
				local modData = modIds[mod]
				if not modData and mw.title.new('Модуль:ИнвСпрайт/' .. mod .. '/ID').exists then
					modData = mw.loadData('Модуль:ИнвСпрайт/' .. mod .. '/ID')["IDы"]
					modIds[mod] = modData
				end
				if modData and modData[name] then
					idData = modData[name]
					en_name = idData["en"]
				else
					img = name .. ' (' .. mod .. ')'
				end
			elseif ids[name] then
				idData = ids[name]
			else
				img = name
			end

			local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1}
			local link = args["ссылка"] or ''
			if link == '' then
				if mod then
					link = mod .. '/' .. name
				else
					link = nil
				end
			elseif mw.ustring.lower(link) == 'нет' then
				link = nil
			end
			if link == pageName then
				link = nil
			end
			
			local formattedTitle
			local plainTitle
			if title == '' then
				plainTitle = name
			elseif mw.ustring.lower(title) ~= 'нет' then
				plainTitle = mw.ustring.gsub(mw.ustring.gsub(title, '\\\\', '\'), '\\&', '&')
				
				local formatPattern = '&[0-9a-fk-or]'
				if mw.ustring.match(plainTitle, formatPattern) then
					formattedTitle = title
					plainTitle = mw.ustring.gsub(plainTitle, formatPattern, '')
				end
				
				if plainTitle == '' then
					plainTitle = name
				else
					plainTitle =  mw.ustring.gsub(mw.ustring.gsub(plainTitle, '\', '\\'), '&', '&')
				end
			elseif link then
				if img then
					formattedTitle = ''
				else
					plainTitle = ''
				end
			end
			
			item:attr{
				['data-minetip-title'] = formattedTitle,
				['data-minetip-text'] = description,
				['data-modinfo-text'] = mod,
                ['data-minetip-lowtitle'] = en_name
			}
			
			if img then
				-- & is re-escaped because mw.html treats attributes
				-- as plain text, but MediaWiki doesn't
				local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' )
				item:addClass('invslot-item-image')
					:wikitext('[[Файл:Grid ', img, '.png|32x32px|link=', link or '', '|', escapedTitle, ']]')
			else
				if not sprite then
					sprite = require([[Модуль:Спрайт]]).sprite
				end
				local image
				if mod then
					image = (args["таблспрайтов"] or mod or "Inv") .. 'CSS.png'
				end
				if link then
					item:wikitext('[[', link, '|')
				end

				local image, spriteCat;
				if not mod then
				    image, spriteCat = sprite{
					    ["данныеID"] = idData, ["назв"] = plainTitle,
					    ["изобр"] = image, ["настройки"] = 'ИнвСпрайт'
					    }
				else 
				    image, spriteCat = sprite{
					    ["данныеID"] = idData, ["назв"] = plainTitle,
					    ["изобр"] = image, ["настройки"] = 'ИнвСпрайт/' .. mod
					    }
				end
				item:node(image)
				category = spriteCat
			end
			
			if num and num > 1 and num < 1000 then
				if img and link then
					item:wikitext('[[', link, '|')
				end
				local number = item
					:tag('span')
						:addClass('invslot-stacksize')
						:attr{title = plainTitle}
						:wikitext(num)
				if numStyle then
					number:cssText(numStyle)
				end
				if img and link then
					item:wikitext(']]')
				end
			end
			
			if idData and link then
				item:wikitext(']]')
			end
			
			item:wikitext(category)
		end
		
		if first then
			if animated and item then
				item:addClass('active')
			end
			first = false
		end
	end
	
	return tostring( body )
end

function p.expandAlias( frameParts, alias )
	-- If the frame has no parts, we can just return the alias as-is
	--[[if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then
		return alias
	end--]]
	
	local expandedFrames = {}
	for aliasFrame in mw.text.gsplit(alias, '%s*;%s*') do
		local aliasParts = p.getParts(aliasFrame)
		aliasParts.title = frameParts.title or aliasParts.title or ''
		aliasParts.mod = frameParts.mod or aliasParts.mod or 'Minecraft'
		aliasParts.num = frameParts.num or aliasParts.num or ''
		aliasParts.text = frameParts.text or aliasParts.text or ''
		
		table.insert(expandedFrames, mw.ustring.format(
			'[%s]%s:%s,%s[%s]',
			aliasParts.title, aliasParts.mod, aliasParts.name, aliasParts.num, aliasParts.text
		))
	end
	
	return table.concat(expandedFrames, ';')
end


function p.getParts(frame, mod)
----Функция получает название предмета в формате "[титл]мод:имя[доп.текст],число"
----parts.title = титл, название предмета при наведении
----parts.mod = мод
----parts.name = имя
----parts.text = текст, дополнительный текст при наведении на предмет
----parts.num = число

	local parts = {}
	parts.title = mw.ustring.match(frame, '^%[%s*([^%]]+)%s*%]')
	
    local modPattern
    if mw.ustring.match(frame, '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):') then
    modPattern = '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):'
    else
    modPattern = '^([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):'
    end

	parts.mod = mw.text.trim(mw.ustring.match(frame, modPattern) or mod or '') ---- Получаем название мода

	local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1}
	if parts.mod == '' or vanilla[mw.ustring.lower(parts.mod)] then 
		link = nil
		parts.mod = nil
	else
	    if p.modAliases[parts.mod] then
		    parts.mod = p.modAliases[parts.mod]
        end
        parts.mod = mw.ustring.gsub(parts.mod,'_',' ')
	end
	local _, nameStartV = mw.ustring.find( frame, '^%[[^%]]*%]' )
	local nameStart = ( ({mw.ustring.find( frame, modPattern )})[2] or nameStartV or 0 ) + 1
	if nameStart - 1 == #frame then
		nameStart = 1
	end
	parts.name = mw.text.trim( mw.ustring.sub( frame, nameStart, ( mw.ustring.find( frame, '[,%[]', nameStart ) or 0 ) - 1 ) )
	
	parts.num = math.floor(mw.ustring.match(frame, ',%s*(%d+)') or 0)
	if parts.num == 0 then
		parts.num = nil
	end
	
	parts.text = mw.ustring.match(frame, '%[%s*([^%]]+)%s*%]$')
    
	return parts
end
 
return p