FANDOM


--
-- Модуль для реалізації шаблону {{Картка}}
--
 
local p = {}
 
local HtmlBuilder2 = require('Module:HtmlBuilder2')
 
local args = {}
local origArgs
local argsAliases = {}
local root
 
local function union(t1, t2)
    -- Повертає об'єднання значень двох таблиць у вигляді послідовності.
    local vals = {}
    for k, v in pairs(t1) do
        vals[v] = true
    end
    for k, v in pairs(t2) do
        vals[v] = true
    end
    local ret = {}
    for k, v in pairs(vals) do
        table.insert(ret, k)
    end
    return ret
end
 
local function getArgNums(prefix)
    -- Повертає таблицю індексів існуючих полів із заданим префіксом,
    -- наприклад, для префікса 'текст' і встановлених 'текст1', 'текст2' і
    -- 'текст5' повертає {1, 2, 5}.
    local nums = {}
    for k, v in pairs(args) do
        local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
        if num then table.insert(nums, tonumber(num)) end
    end
    table.sort(nums)
    return nums
end
 
local function addRow(rowArgs)
    -- Додає рядок у картку (заголовок або мітку/текст).
    if rowArgs.header then
        root
            .tag('tr')
                .addClass(rowArgs.rowclass)
                .attr('id', rowArgs.rowid)
                .tag('th')
                    .attr('colspan', 2)
                    .attr('id', rowArgs.headerid)
                    .addClass(rowArgs.class)
                    .addClass(args['клас_заголовків'])
                    .css('text-align', 'center')
                    .cssText(args['стиль_заголовків'])
                    .wikitext(rowArgs.header)
    elseif rowArgs.data then
        local row = root.tag('tr')
        row.addClass(rowArgs.rowclass)
        row.attr('id', rowArgs.rowid)
        if rowArgs.label then
            row
                .tag('th')
                    .attr('scope', 'row')
                    .attr('id', rowArgs.labelid)
                    .css('text-align', 'left')
                    .cssText(args['стиль_міток'])
                    .wikitext(rowArgs.label)
                    .done()
        end
 
        local dataCell = row.tag('td')
        if not rowArgs.label then 
            dataCell
                .attr('colspan', 2)
                .css('text-align', 'center') 
        end
        dataCell
            .attr('id', rowArgs.dataid)
            .addClass(rowArgs.class)
            .cssText(rowArgs.datastyle)
            .newline()
            .wikitext(rowArgs.data)
    end
end
 
local function renderTitle()
    if not args['назва'] then return end
 
    root
        .tag('caption')
            .addClass(args['клас_назви'])
            .cssText(args['стиль_назви'])
            .wikitext(args['назва'])
end
 
local function renderAboveRow()
    if not args['угорі'] then return end
 
    root
        .tag('tr')
            .tag('th')
                .attr('colspan', 2)
                .addClass(args['клас_угорі'])
                .css('text-align', 'center')
                .css('font-size', '125%')
                .css('font-weight', 'bold')
                .cssText(args['стиль_угорі'])
                .wikitext(args['угорі'])
end
 
local function renderAbove2Row()
    if not args['угорі2'] then return end
 
    root
        .tag('tr')
            .tag('th')
                .attr('colspan', 2)
                .addClass(args['клас_угорі2'])
                .css('text-align', 'center')
                .css('font-style', 'oblique')
                .cssText(args['стиль_угорі2'])
                .wikitext(args['угорі2'])
end
 
local function renderBelowRow()
    if not args['внизу'] then return end
 
    root
        .tag('tr')
            .tag('td')
                .attr('colspan', '2')
                .addClass(args['клас_внизу'])
                .css('text-align', 'center')
                .cssText(args['стиль_внизу'])
                .newline()
                .wikitext(args['внизу'])
end
 
local function renderSubheaders()
    if args['підзаголовок'] then
        args['підзаголовок1'] = args['підзаголовок']
    end
    if args['клас_рядка_підзаголовка'] then
        args['клас_рядка_підзаголовка1'] = args['клас_рядка_підзаголовка']
    end
    local subheadernums = getArgNums('підзаголовок')
    for k, num in ipairs(subheadernums) do
        addRow({
            data = args['підзаголовок' .. tostring(num)],
            datastyle = args['стиль_підзаголовків'] or args['стиль_підзаголовка' .. tostring(num)],
            class = args['клас_підзаголовків'],
            rowclass = args['клас_рядка_підзаголовка' .. tostring(num)]
        })
    end
end
 
local function renderImages()
    if args['зображення'] then
        args['зображення1'] = args['зображення']
    end
    if args['підпис'] then
        args['підпис1'] = args['підпис']
    end
    local imagenums = getArgNums('зображення')
    for k, num in ipairs(imagenums) do
        local caption = args['підпис' .. tostring(num)]
        local data = HtmlBuilder2.create().wikitext(args['зображення' .. tostring(num)])
        if caption then
            data
                .tag('div')
                    .cssText(args['стиль_підпису'])
                    .wikitext(caption)
        end
        addRow({
            data = tostring(data),
            datastyle = args['стиль_зображення'],
            class = args['клас_зображення'],
            rowclass = args['клас_рядка_зображення' .. tostring(num)]
        })
    end
end
 
local function renderRows()
    -- Об'єднує індекси заголовків і текстових рядків картки,
    -- і візуалізує їх у правильному порядку через addRow.
    local rownums = union(getArgNums('заголовок'), getArgNums('текст'))
    table.sort(rownums)
    for k, num in ipairs(rownums) do
        addRow({
            header = args['заголовок' .. tostring(num)],
            label = args['мітка' .. tostring(num)],
            data = args['текст' .. tostring(num)],
            datastyle = args['стиль_тексту'],
            class = args['клас' .. tostring(num)],
            rowclass = args['клас_рядка' .. tostring(num)],
            dataid = args['id_тексту' .. tostring(num)],
            labelid = args['id_мітки' .. tostring(num)],
            headerid = args['id_заголовка' .. tostring(num)],
            rowid = args['id_рядка' .. tostring(num)]
        })
    end
end
 
local function renderNavBar()
    if not args['ім\'я'] then return end
 
    root
        .tag('tr')
            .tag('td')
                .attr('colspan', 2)
                .css('text-align', 'right')
                .wikitext(mw.getCurrentFrame():expandTemplate({ 
                    title = 'Tnavbar', 
                    args = { args['ім\'я'], mini = 1 }
                }))
end
 
local function isSet(x)
    -- Повертає істину, якщо x вказаний і не порожній
    -- Увага: відрізняється від enwiki! В enwiki перевіряється на рівеність 'yes'
    return x and x ~= ''
end
 
local function renderItalicTitle()
    -- Увага: відрізняється від enwiki! В enwiki очікується yes або force, тут працює будь-яке значення
    if isSet(args['заголовок_курсивом']) then
        root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'}))
    end
end
 
local function renderTrackingCategories()
    if not isSet(args.nocat) then
        if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
            root.wikitext('[[Категорія:Статті з карткою без заповнених даних]]')
        end
        if isSet(args['встроєння']) and args['назва'] then
            root.wikitext('[[Категорія:Статті з вбудованою карткою і параметром назви]]')
        end
    end
end
 
local function _infobox()
    -- Задання загальної структури картки з додаванням стилів
    -- для карток-нащадків.
    if not isSet(args['встроєння']) then
        root = HtmlBuilder2.create('table')
 
        root
            .addClass('infobox')
            .addClass(args['клас_тіла'])
            .attr('cellspacing', 3)
            .css('border-spacing', '3px')
 
            if isSet(args['підкартка']) then
                root
                    .css('padding', '0')
                    .css('border', 'none')
                    .css('margin', '-3px')
                    .css('width', 'auto')
                    .css('min-width', '100%')
                    .css('font-size', '100%')
                    .css('clear', 'none')
                    .css('float', 'none')
                    .css('background-color', 'transparent')
            else
                root
                    .css('width', '22em')
            end
 
        -- Мікророзмітка
        if isSet(args['мікр_тіла']) then
        	root
        	  .attr('itemscope', 'itemscope')
        	  .attr('itemtype', args['мікр_тіла'])
        end
 
        root
            .cssText(args['стиль_тіла'])
 
        renderTitle()
        renderAboveRow()
        renderAbove2Row()
    else
        root = HtmlBuilder2.create()
 
        root
            .wikitext(args['назва'])
    end
 
    renderSubheaders()
    renderImages() 
    renderRows() 
    renderBelowRow()  
    renderNavBar()
    renderItalicTitle()
    renderTrackingCategories()
 
    return tostring(root)
end
 
local function preprocessSingleArg(argName)
    -- Додає аргумент в таблицю аргументів, якщо він визначений і не порожній.
    -- Порожні аргументи не обробляються, як і в ParserFunctions.
    if origArgs[argName] and origArgs[argName] ~= '' then
        args[argName] = origArgs[argName]
    end
end
 
local function translateArg(aliasArgName,localArgName)
	-- Функція додає підтримку аліасів параметрів (наприклад, іншою мовою)
 
	-- Додаєм аліас параметра в таблицю аліасів
	-- Для одного параметра може бути кілька аліасів
	-- Нумеровані параметри(текст1 і т.д.) заносяться без номера
	if not 	argsAliases[localArgName] then
		argsAliases[localArgName] = {}
	end
	table.insert(argsAliases[localArgName], aliasArgName)
 
	-- Пока для тестування: значення аліасів додаются в таблицю аргументів
	-- Нумеровані параметри не будуть працювати
    if origArgs[localArgName] and origArgs[localArgName] ~= '' then
    	-- параметр вже задан на локальній мові
    else
    	-- якщо аліас заданий і не пустий
	    if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then
	        origArgs[localArgName] = origArgs[aliasArgName]
	    end
    end
end
 
local function preprocessArgs(prefixTable, step)
    -- Зберігає параметри з заданими префіксами в таблицю args, послідовно обходячи 
    -- аргументи в потрібному порядку і з потрібним кроком. Завдяки цьому виноски та ін. з'являються
    -- в правильному порядку. prefixTable — масив таблиць, кожна з яких може містити
    -- два поля: a "prefix" string and a "depend" table. The function always parses
    -- Ця функція завжди обробляє параметри з префіксом, але залежні параметри
    -- обробляються, тільки якщо параметр з префіксом заданий і не порожній.
    if type(prefixTable) ~= 'table' then
        error("В якості таблиці префіксів повинна використовуватися таблиця", 2)
    end
    if type(step) ~= 'number' then
        error("Неприпустимий тип параметра кроку", 2)
    end
 
    -- Перевірка правильності даних та обробка параметрів без суфіксів.
    for i,v in ipairs(prefixTable) do
        if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
            error('Неприпустима таблиця префіксів preprocessArgs', 2)
        end
        preprocessSingleArg(v.prefix)
        -- Залежні параметри обробляються, тільки якщо параметр з префіксом заданий і не порожній.
        if args[v.prefix] and v.depend then
            for j, dependValue in ipairs(v.depend) do
                if type(dependValue) ~= 'string' then
                    error('Неприпустимий тип залежного параметра в таблиці preprocessArgs')
                end
                preprocessSingleArg(dependValue)
            end
        end
    end
 
    -- Обхід нумерованих аргументів.
    local a = 1 -- Змінна-лічильник.
    local moreArgumentsExist = true
    while moreArgumentsExist == true do
        moreArgumentsExist = false
        for i = a, a + step - 1 do
            for j,v in ipairs(prefixTable) do
                local prefixArgName = v.prefix .. tostring(i)
                if origArgs[prefixArgName] then
                    moreArgumentsExist = true -- Шукати аргументи далі, якщо був хоча б один (в т. ч. порожній)
                    preprocessSingleArg(prefixArgName)
                end
                -- Обробляємо залежні аргументи, якщо визначена таблиця залежностей,
                -- а також вказаний не порожній аргумент з префіксом, або обробляється
                -- "префікс1" і "префікс" заданий (наприклад, "зображення1" являється синонімом для "зображення").
                if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
                    for j,dependValue in ipairs(v.depend) do
                        local dependArgName = dependValue .. tostring(i)
                        preprocessSingleArg(dependArgName)
                    end
                end
            end
        end
        a = a + step
    end
end
 
function p.infobox(frame)
    -- При запуску через #invoke аргументи передаються через стандартну систему.
    -- При тестуванні також можна передавати таблицю аргументів через frame.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end
 
    -- Підтримка параметрів з англовікі
    translateArg('child','встроєння')
    translateArg('bodyclass','клас_тіла')
    translateArg('subbox','підкартка')
    translateArg('bodystyle','стиль_тіла')
    translateArg('title','назва')
    translateArg('titleclass','клас_назви')
    translateArg('titlestyle','стиль_назви')
    translateArg('above','угорі')
    translateArg('aboveclass','клас_угорі')
    translateArg('abovestyle','стиль_угорі')
 
    translateArg('subheader','підзаголовок')
    translateArg('subheaderstyle','стиль_підзаголовка')
    translateArg('subheaderrowclass','клас_підзаголовка')
 
    translateArg('subheaderstyle','стиль_підзаголовків')
    translateArg('subheaderclass','клас_підзаголовків')
 
 
    translateArg('image','зображення')
    translateArg('caption','підпис')
    translateArg('imagerowclass','клас_рядка_зображення')
 
    translateArg('captionstyle','стиль_підпису')
    translateArg('imagestyle','стиль_зображення')
    translateArg('imageclass','клас_зображення')
 
 
    translateArg('header','заголовок')
    translateArg('data','текст')
    translateArg('label','мітка')
    translateArg('rowclass','клас_рядка')
    translateArg('class','клас')
    translateArg('dataid','id_тексту')
    translateArg('labelid','id_мітки')
    translateArg('headerid','id_заголовка')
    translateArg('rowid','id_рядка')
 
    translateArg('headerclass','клас_заголовків')
    translateArg('headerstyle','стиль_заголовків')
    translateArg('labelstyle','стиль_міток')
    translateArg('datastyle','стиль_тексту')
    translateArg('below','внизу')
    translateArg('belowclass','клас_внизу')
    translateArg('belowstyle','стиль_внизу')
    translateArg('name','ім\'я')
    --translateArg('italic title','заголовок_курсивом')
    --translateArg('','')
 
 
    -- Параметри обробляються в напрямку читання картки, щоб
    -- виноски та ін. відображалися в потрібних місцях. Параметри, що залежать 
    -- від інших параметрів, обробляються тільки за наявності інших параметрів,
    -- щоб у списку виносок не виникали небажані виноски.
    preprocessSingleArg('встроєння')
    preprocessSingleArg('клас_тіла')
    preprocessSingleArg('підкартка')
    preprocessSingleArg('стиль_тіла')
    preprocessSingleArg('назва')
    preprocessSingleArg('клас_назви')
    preprocessSingleArg('стиль_назви')
    preprocessSingleArg('угорі')
    preprocessSingleArg('клас_угорі')
    preprocessSingleArg('стиль_угорі')
    preprocessSingleArg('угорі2')
    preprocessSingleArg('клас_угорі2')
    preprocessSingleArg('стиль_угорі2')
    preprocessArgs({
        {prefix = 'підзаголовок', depend = {'стиль_підзаголовка', 'клас_підзаголовка'}}
    }, 10)
    preprocessSingleArg('стиль_підзаголовків')
    preprocessSingleArg('клас_підзаголовків')
    preprocessArgs({
        {prefix = 'зображення', depend = {'підпис', 'клас_рядка_зображення'}}
    }, 10)
    preprocessSingleArg('стиль_підпису')
    preprocessSingleArg('стиль_зображення')
    preprocessSingleArg('клас_зображення')
    preprocessArgs({
        {prefix = 'заголовок'},
        {prefix = 'текст', depend = {'мітка'}},
        {prefix = 'клас_рядка'},
        {prefix = 'клас'},
        {prefix = 'id_тексту'},
        {prefix = 'id_мітки'},
        {prefix = 'id_заголовка'},
        {prefix = 'id_рядка'}
    }, 50)
    preprocessSingleArg('клас_заголовків')
    preprocessSingleArg('стиль_заголовків')
    preprocessSingleArg('стиль_міток')
    preprocessSingleArg('стиль_тексту')
    preprocessSingleArg('внизу')
    preprocessSingleArg('клас_внизу')
    preprocessSingleArg('стиль_внизу')
    preprocessSingleArg('ім\'я')
    preprocessSingleArg('заголовок_курсивом')
    preprocessSingleArg('nocat')
 
    return _infobox()
end
 
return p

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Відвідайте інші вікіпроекти на Вікія!

Випадкова вікі