-- правильно поставить пробелы в десятичном целом
function FormatDecimalInteger(digits)
return mw.getCurrentFrame():callParserFunction('formatnum', digits)
end
-- возвращает true для включений в основном пространстве
function InvokedFromArticle()
return mw.title.getCurrentTitle():inNamespace(0)
end
-- возвращает true, если статья существует
function ArticleExists(link)
return mw.title.new(link, 0).exists
end
-- отв. за форматирование последовательности в викитекст
function SequenceFormatter(formatNumberMode, itemPrefix, itemSuffix, usualSeparator, lastSeparator)
-- instance data
local formatter = {
_formatNumberMode = formatNumberMode,
_itemPrefix = itemPrefix,
_itemSuffix = itemSuffix,
_usualSeparator = usualSeparator,
_lastSeparator = lastSeparator,
_linkCount = 0,
_items = {}
}
-- вернуть внутреннюю ссылку и посчитать её
-- изменяет self._linkCount
function formatter:_WikiLink(link, text)
self._linkCount = self._linkCount + 1
return '[[' .. link .. '|' .. text .. ']]'
end
-- возвращает метод объекта formatter, форматирующий целое число
function formatter:_FormatNumberFunc()
function mode0(self, text)
return self._itemPrefix .. text .. self._itemSuffix
end
function mode1(self, text)
local link = text .. ' (число)'
return self._itemPrefix .. self:_WikiLink(link, text) .. self._itemSuffix
end
function mode2(self, text)
local link = text .. ' (число)'
if ArticleExists(link) then
return self._itemPrefix .. self:_WikiLink(link, text) .. self._itemSuffix
end
return self._itemPrefix .. text .. self._itemSuffix
end
local modes = {
['no'] = mode0,
['нет'] = mode0,
['0'] = mode0,
['yes'] = mode1,
['да'] = mode1,
['1'] = mode1,
['nrl'] = mode2,
['бкс'] = mode2,
['2'] = mode2
}
return modes[self._formatNumberMode] or mode0
end
-- форматирует целое число
formatter._FormatNumber = formatter:_FormatNumberFunc()
-- форматирует элемент последовательности
-- изменяет self._linkCount
function formatter:_FormatItem(item)
-- целое число в десятичной системе счисления?
if mw.ustring.match(item, '^[%s]*[%-]?[%s]*[%d]+[%d%s]*$') then
local digits = mw.ustring.gsub(item, '%s', '') -- без пробелов
local decimal = FormatDecimalInteger(digits) -- с пробелами
local number = self:_FormatNumber(decimal) -- с оформлением
return number
end
-- здесь могли быть другие варианты
-- ничего не совпало, выводим без изменений
mw.log(item)
return item
end
-- форматирует и запоминает элемент последовательности
-- изменяет self._linkCount, self._items
function formatter:AddItem(item)
table.insert(self._items, self:_FormatItem(item))
end
-- последовательность в викитекст для вывода
function formatter:Sequence()
local num_of_items = #self._items
if num_of_items > 2 then
return table.concat(self._items, self._usualSeparator,
1, num_of_items - 1) .. self._lastSeparator .. self._items[num_of_items]
else
return table.concat(self._items, self._lastSeparator)
end
end
-- категории в викитекст для вывода
function formatter:Categories()
local c = ''
if (self._linkCount > 0) and InvokedFromArticle() then
c = c .. '[[Категория:Википедия:Статьи со ссылками на статьи об отдельных числах]]'
end
return c
end
return formatter
end
-- возвращает первый из параметров в keys, указанных в frame, либо default
function SelectSeparator(frame, keys, default)
local before = {
['x'] = ' ',
['x!'] = '',
['xx'] = ' ',
['xx!'] = ''
}
local after = {
['x'] = ' ',
['x!'] = '',
['xx'] = ' ',
['xx!'] = ''
}
for i, key in ipairs(keys) do
local sep = frame.args[key]
if sep then
return before[key] .. sep .. after[key]
end
end
return default
end
local p = {}
-- реализация для шаблона
-- код шаблона: {{#invoke:имя_модуля|numsImpl}}
function p.numsImpl(_frame)
-- доступ к параметрам, переданным в шаблон (а не из шаблона в модуль)
local frame = _frame:getParent()
-- настройка по параметрам
local usep = SelectSeparator(frame, {'x', 'x!'}, ', ')
local lsep = SelectSeparator(frame, {'xx', 'xx!'}, usep)
local formatter = SequenceFormatter(
frame.args['link'] or 'no',
frame.args['prefix'] or '',
frame.args['suffix'] or '',
usep,
lsep)
-- получение элементов последовательности
for i, v in ipairs(frame.args) do
formatter:AddItem(v)
end
--mw.log(formatter._linkCount .. ' links / ' .. #formatter._items .. ' items')
-- форматирование, автокатегоризация, вывод
return formatter:Sequence() .. formatter:Categories()
end
return p