მოდული:ინფოდაფა

მასალა ვიკიპედიიდან — თავისუფალი ენციკლოპედია
Jump to navigation Jump to search

შეგიძლიათ შექმნათ დოკუმენტაცია ამ მოდულისათვის: მოდული:ინფოდაფა/ინფო

--
-- ამ მოდულს იყენებს {{ინფოდაფა}}
--
 
local p = {}

local navbar = require('Module:Navbar')._navbar

local args = {}
local origArgs
local root

local function notempty( s ) return s and s:match( '%S' ) end

local function fixChildBoxes(sval, tt)
	if notempty(sval) then
		local marker = '<span class=special_infobox_marker>'
		local s = sval
		s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
		s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
		if s:match(marker) then
			s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
			s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
			s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
			s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
			s = mw.ustring.gsub(s,  marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
			s = mw.ustring.gsub(s,  marker .. '(%s*\n|%})', '%1')
		end
		if s:match(marker) then
			local subcells = mw.text.split(s, marker)
			s = ''
			for k = 1, #subcells do
				if k == 1 then
					s = s .. subcells[k] .. '</' .. tt .. '></tr>'
				elseif k == #subcells then
					local rowstyle = ' style="display:none"'
					if notempty(subcells[k]) then rowstyle = ''	end
					s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k]
				elseif notempty(subcells[k]) then
					if (k % 2) == 0 then
						s = s .. subcells[k]
					else
						s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>'
					end
				end
			end
		end
		return s
	else
		return sval
	end
end

local function union(t1, t2)
    -- Returns the union of the values of two tables, as a sequence.
    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)
    -- Returns a table containing the numbers of the arguments that exist
    -- for the specified prefix. For example, if the prefix was 'data', and
    -- 'data1', 'data2', and 'data5' exist, it would return {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)
    -- Adds a row to the infobox, with either a header cell
    -- or a label/data cell combination.
    if rowArgs.header then
        root
            :tag('tr')
                :addClass(rowArgs.rowclass)
                :cssText(rowArgs.rowstyle)
                :attr('id', rowArgs.rowid)
                :tag('th')
                    :attr('colspan', 2)
                    :attr('id', rowArgs.headerid)
                    :addClass(rowArgs.class)
                    :addClass(args['თავის კლასი'])
                    :css('text-align', 'center')
                    :cssText(args['თავის სტილი'])
                    :cssText(rowArgs.rowcellstyle)
                    :wikitext(fixChildBoxes(rowArgs.header, 'th'))
    elseif rowArgs.data then
        local row = root:tag('tr')
        row:addClass(rowArgs.rowclass)
        row:cssText(rowArgs.rowstyle)
        row:attr('id', rowArgs.rowid)
        if rowArgs.label then
            row
                :tag('th')
                    :attr('scope', 'row')
                    :attr('id', rowArgs.labelid)
                    :cssText(args['სახელის სტილი'])
                    :cssText(rowArgs.rowcellstyle)
                    :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)
            :cssText(rowArgs.rowcellstyle)
            :newline()
            :wikitext(fixChildBoxes(rowArgs.data, 'td'))
    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(fixChildBoxes(args.above,'th'))
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(fixChildBoxes(args['ქვევით'],'td'))
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 = mw.html.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()
    -- Gets the union of the header and data argument numbers,
    -- and renders them all in order using 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)],
            rowstyle = args['რიგის სტილი' .. tostring(num)],
            rowcellstyle = args['rowcellstyle' .. tostring(num)],
            dataid = args['dataid' .. tostring(num)],
            labelid = args['labelid' .. tostring(num)],
            headerid = args['headerid' .. tostring(num)],
            rowid = args['rowid' .. 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(navbar{
                    args['სახელწოდება'],
                    mini = 1,
                })
end

local function renderItalicTitle()
    local italicTitle = args['კურსივისახელი'] and mw.ustring.lower(args['კურსივისახელი'])
    if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
        root:wikitext(mw.getCurrentFrame():expandTemplate({title = 'კურსივისახელი'}))
    end
end

local function renderTrackingCategories()
    if args.decat ~= 'yes' then
        if #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
            root:wikitext('[[Category:Articles which use infobox templates with no data rows]]')
        end
        if args.child == 'yes' and args.title then
            root:wikitext('[[Category:Pages which use embedded infobox templates with the title parameter]]')
        end
    end
end

local function _infobox()
    -- Specify the overall layout of the infobox, with special settings
    -- if the infobox is used as a 'child' inside another infobox.
    if args.child ~= 'yes' then
        root = mw.html.create('table')
        
        root
            :addClass((args.subbox ~= 'yes') and 'infobox' or nil)
            :addClass(args['სხეულის კლასი'])
            
            if args.subbox == 'yes' 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
        root
            :cssText(args['სხეულის სტილი'])
    
        renderTitle()
        renderAboveRow()
    else
        root = mw.html.create()
        
        root
            :wikitext(args['წარწერა'])
    end

    renderSubheaders()
    renderImages() 
    renderRows() 
    renderBelowRow()  
    renderNavBar()
    renderItalicTitle()
    renderTrackingCategories()
    
    return tostring(root)
end

local function preprocessSingleArg(argName)
    -- If the argument exists and isn't blank, add it to the argument table.
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
    if origArgs[argName] and origArgs[argName] ~= '' then
        args[argName] = origArgs[argName]
    end
end

local function preprocessArgs(prefixTable, step)
    -- Assign the parameters with the given prefixes to the args table, in order, in batches
    -- of the step size specified. This is to prevent references etc. from appearing in the
    -- wrong order. The prefixTable should be an array containing tables, each of which has
    -- two possible fields, a "prefix" string and a "depend" table. The function always parses
    -- parameters containing the "prefix" string, but only parses parameters in the "depend"
    -- table if the prefix parameter is present and non-blank.
    if type(prefixTable) ~= 'table' then
        error("Non-table value detected for the prefix table", 2)
    end
    if type(step) ~= 'number' then
        error("Invalid step value detected", 2)
    end
    
    -- Get arguments without a number suffix, and check for bad input.
    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('Invalid input detected to preprocessArgs prefix table', 2)
        end
        preprocessSingleArg(v.prefix)
        -- Only parse the depend parameter if the prefix parameter is present and not blank.
        if args[v.prefix] and v.depend then
            for j, dependValue in ipairs(v.depend) do
                if type(dependValue) ~= 'string' then
                    error('Invalid "depend" parameter value detected in preprocessArgs')
                end
                preprocessSingleArg(dependValue)
            end
        end
    end

    -- Get arguments with number suffixes.
    local a = 1 -- Counter variable.
    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 -- Do another loop if any arguments are found, even blank ones.
                    preprocessSingleArg(prefixArgName)
                end
                -- Process the depend table if the prefix argument is present and not blank, or
                -- we are processing "prefix1" and "prefix" is present and not blank, and
                -- if the depend table is present.
                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)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end
    
    -- Parse the data parameters in the same order that the old {{infobox}} did, so that
    -- references etc. will display in the expected places. Parameters that depend on
    -- another parameter are only processed if that parameter is present, to avoid
    -- phantom references appearing in article reference lists.
    preprocessSingleArg('child')
    preprocessSingleArg('bodyclass', 'სხეულის კლასი')
    preprocessSingleArg('subbox')
    preprocessSingleArg('bodystyle', 'სხეულის სტილი')
    preprocessSingleArg('title', 'წარწერა')
    preprocessSingleArg('titleclass', 'წარწერის კლასი')
    preprocessSingleArg('titlestyle', 'წარწერის სტილი')
    preprocessSingleArg('above', 'ზევით')
    preprocessSingleArg('aboveclass', 'ზედა კლასი')
    preprocessSingleArg('abovestyle', 'ზედა სტილი')
    preprocessArgs({
        {prefix = 'subheader', 'ქვეთავი', depend = {'subheaderstyle', 'ქვეთავის სტილი', 'subheaderrowclass', 'ქვეთავის რიგის კლასი'}}
    }, 10)
    preprocessSingleArg('subheaderstyle', 'ქვეთავის სტილი')
    preprocessSingleArg('subheaderclass', 'ქვეთავის კლასი')
    preprocessArgs({
        {prefix = 'image', 'სურათი', depend = {'caption', 'ტიტრი', 'imagerowclass', 'სურათირიგის კლასი'}}
    }, 10)
    preprocessSingleArg('captionstyle')
    preprocessSingleArg('imagestyle', 'სურათის სტილი')
    preprocessSingleArg('imageclass', 'სურათის კლასი')
    preprocessArgs({
        {prefix = 'header', 'თავი'},
        {prefix = 'data', 'მონაცემი', depend = {'label', 'სახელი'}},
        {prefix = 'rowclass', 'რიგის კლასი'},
        {prefix = 'rowstyle', 'რიგის სტილი'},
        {prefix = 'rowcellstyle'},
        {prefix = 'class', 'კლასი'},
        {prefix = 'dataid'},
        {prefix = 'labelid'},
        {prefix = 'headerid'},
        {prefix = 'rowid'}
    }, 50)
    preprocessSingleArg('headerclass', 'თავის კლასი')
    preprocessSingleArg('headerstyle', 'თავის სტილი')
    preprocessSingleArg('labelstyle', 'სახელის სტილი')
    preprocessSingleArg('datastyle', 'მონაცემის სტილი')
    preprocessSingleArg('below', 'ქვევით')
    preprocessSingleArg('belowclass', 'ქვედა კლასი')
    preprocessSingleArg('belowstyle', 'ქვედა სტილი')
    preprocessSingleArg('name', 'სახელწოდება')
    args['italic title'] = origArgs['italic title'] -- different behaviour if blank or absent
    preprocessSingleArg('decat')
 
    return _infobox()
end
 
return p