--[[
Вспомогательные функции для SummaryII
--]]
local gsub, lower = mw.ustring.gsub, mw.ustring.lower
local match, gmatch = mw.ustring.match, mw.ustring.gmatch
local pcre = rex_pcre.new
local split, gsplit = mw.text.split, mw.text.gsplit
local concat = table.concat
local set = mw.smw.set
local function unpack_args (args)
local cloned = {}
for key, value in pairs (args) do
cloned [key] = value
end
return unpack (cloned)
end
local function wrapper (func)
return function (first, ...)
if type (first) == 'table' and first.args then
return func (unpack_args (first.args))
else
return func (first, ...)
end
end
end
local p = {}
p.strip = wrapper (function (str)
-- Нельзя сразу return: mw.ustring.gsub возвращает два значения:
local ret = gsub (lower (str), '[%s%p_]', '')
return ret
end)
p.strip_number = wrapper (function (str)
-- Нельзя сразу return: mw.ustring.gsub возвращает два значения:
local ret = gsub (lower (str), '[%s%d()%p_]', '')
return ret
end)
p.parse_params = wrapper (function (str, regex)
local property = 'Параметр шаблона'
local value_regex = regex and regex ~= '' and regex or '.*'
local list = {
'{| class="wikitable"',
'! параметр !! значения !! контекст'
}
for triplet in gsplit (str, '%s*\n%s*') do
local name, value, context = unpack (split (triplet, '%s*;%s*'))
local record = name .. ';' .. (value or value_regex) .. ';' .. (context or '^.*$')
set {[property] = record}
list[#list + 1] = '|\n<code>' .. name .. '</code>\n|\n<code>'
.. (value or value_regex) .. '</code>\n|\n<code>'
.. (context or '^.*') .. '</code>'
end
return '\n' .. concat (list, '\n|-\n') .. '\n|}'
end)
local function strip_caron_dollar (regex)
return gsub (gsub (regex, '^%^', ''), '%$$', '')
end
-- @TODO: units.
-- @TODO: separators.
-- @TODO: illegal characters.
-- @TODO: [[]].
-- @TODO: type names.
-- @TODO: property values.
p.property_widget = wrapper (function (
prop_name,
prop_type,
prop_regex,
corresponds_to,
template
)
local name = p.strip (prop_name)
local decimal = ','
local value = ''
if prop_regex then
value = strip_caron_dollar (prop_regex)
elseif prop_type == 'Страница' then
value = '.*' -- @TODO: separators. @TODO: illegal chars.
elseif prop_type == 'Число' then
value = '\\d+(' .. decimal .. '\\d+)?'
elseif prop_type == 'Количество' then
value = '\\d+(' .. decimal .. '\\d+)?\\s*'
if corresponds_to then
local units = {}
for _, unit in ipairs (split (corresponds_to, ', ', plain)) do
units[#units + 1] = gsub (gsub (gsub (unit, '[%d,]', ''), '^ ', ''), 'e[+-]', '')
end
value = value .. '%s*(?<unit>' .. concat (units, '|') .. ')?'
end
else -- String.
value = '.*' -- @TODO: separators.
end
return '<<pcre/^' .. name .. '(?<no>\\d*)$/i_ = pcre/^(?<value>' .. value .. ')$/|'
.. '{{' .. template .. '|<<value>>}}|>>'
end)
local page_name = rex_pcre.new '(?<=:).+?(?=[|\\]])'
p.page_name_from_wikilink = wrapper( function (wikilink)
return page_name:match (wikilink)
end )
return p