Sari la conținut

Modul:Infobox

De la Wikipedia, enciclopedia liberă

-- {{Pp|small=yes}} --
--
-- This module implements {{Infobox}}
--
 
local p = {}
local getArgs = require('Modul:Arguments').getArgs
local StringUtils = require('Modul:StringUtils')
local TableTools = require('Modul:TableTools')
local InfoboxImage = require('Modul:InfoboxImage')
local Wikidata = require('Modul:Wikidata')
local EditAtWikidata = require('Modul:EditAtWikidata')
local args = {}

-- Compute an automatic upright factor from a bare image filename.
-- The factor is width/height, clamped to [0.5, 2.0], so that landscape
-- images are displayed wider and portrait images narrower than the default.
-- Returns nil if the file metadata cannot be retrieved.
local function autoUpright(imageName)
	-- Strip known namespace prefixes (File:, Image:, Fișier:, Imagine:)
	local lower = mw.ustring.lower(imageName)
	local bare = imageName
	for _, prefix in ipairs({"fișier:", "imagine:", "image:", "file:"}) do
		if mw.ustring.sub(lower, 1, #prefix) == prefix then
			bare = mw.ustring.sub(imageName, #prefix + 1)
			break
		end
	end
	-- Trim spaces and normalise underscores→spaces
	bare = mw.ustring.gsub(bare, '^%s*(.-)%s*$', '%1')
	bare = mw.ustring.gsub(bare, '_', ' ')

	local fileTitle = mw.title.new('File:' .. bare)
	if fileTitle == nil then return nil end
	local fileObj = fileTitle.file
	if fileObj == nil then return nil end
	local w = fileObj.width
	local h = fileObj.height
	if not w or not h or h == 0 then return nil end

	-- Round to 2 decimal places and clamp
	local factor = math.floor((w / h) * 100 + 0.5) / 100
	factor = math.max(0.5, math.min(2.0, factor))
	return tostring(factor)
end

-- Build the wikitext for one image using Modul:InfoboxImage, applying any
-- infoboximage_* parameters.  Falls back to the raw image string on error.
-- `imgArgs` is a table with keys: image, size, maxsize, sizedefault, upright,
-- alt, title, link, border, center, class, suppressplaceholder, thumbtime.
local function renderWithInfoboxImage(frame, imgArgs)
	-- Resolve upright="auto"
	if imgArgs.upright == "auto" then
		local computed = autoUpright(imgArgs.image)
		if computed then
			imgArgs.upright = computed
		else
			-- Cannot determine dimensions; remove upright so InfoboxImage
			-- falls back to frameless/sizedefault normally.
			imgArgs.upright = nil
		end
	end

	-- Call InfoboxImage directly via its Lua API (i.InfoboxImage expects a
	-- frame-like object; we create a child frame so strip-markers work).
	local ok, result = pcall(function()
		local childFrame = frame:newChild{ title = 'Modul:InfoboxImage', args = imgArgs }
		return InfoboxImage.InfoboxImage(childFrame)
	end)

	if ok and result and result ~= "" then
		return result
	else
		-- Fallback: return the original image string untouched.
		return imgArgs.image
	end
end

local function containsEmbed(cellData)
	local check = { mw.ustring.find(cellData, "^%s*<%s*[Tt][Rr](%s*)([^<>]*)>%s*<%s*[Tt][DdHh](%s*)([^<>]*)>") }
	if check[1] == nil or (check[3] == "" and check[4] ~= "") or (check[5] == "" and check[6] ~= "") then return false end
	check = { mw.ustring.find(cellData, "</[Tt][DdHh]%s*>%s*</[Tt][Rr]%s*>%s*$") }
	if check[1] == nil then return false else return true end
end

-- Returns v if it is a non-empty string, otherwise nil.
-- Used to turn "" (a missing, or explicitly empty '' / "", parenthesized
-- argument) into a real nil so downstream Wikidata functions fall back to
-- their own defaults.
local function argOrNil(v)
	if v and v ~= "" then return v end
	return nil
end

-- Splits the inside of a wikidatatype<INDEX>(...) argument list on commas,
-- while treating anything wrapped in matching single or double quotes as one
-- literal token - so a quoted string argument (SEP, PICTUREPID, PICTURESIZE,
-- BRACKETTEMPLATE) may itself contain a comma (or leading/trailing spaces,
-- e.g. ', ') without being split apart or trimmed away. Bare, unquoted
-- tokens are used for LIMIT (an integer) and BEST (the literal word
-- true/false). Returns an ordered list of tokens with their surrounding
-- quotes removed; a token that ends up empty - whether left blank or
-- written as an explicit '' / "" - comes back as "" so callers can turn it
-- into nil via argOrNil.
local function splitWikidataArgs(argsStr)
	-- First, split on commas that are not inside a quoted string, without
	-- touching the raw text yet.
	local rawTokens = {}
	local start = 1
	local quoteChar = nil
	local len = mw.ustring.len(argsStr)
	local i = 1
	while i <= len do
		local c = mw.ustring.sub(argsStr, i, i)
		if quoteChar then
			if c == quoteChar then quoteChar = nil end
		elseif c == "'" or c == '"' then
			quoteChar = c
		elseif c == "," then
			table.insert(rawTokens, mw.ustring.sub(argsStr, start, i - 1))
			start = i + 1
		end
		i = i + 1
	end
	table.insert(rawTokens, mw.ustring.sub(argsStr, start, len))

	-- Trim each raw token, then strip one matching pair of surrounding
	-- quotes - but only that outer pair, so whitespace deliberately placed
	-- inside the quotes (e.g. a ', ' separator) survives untouched.
	local tokens = {}
	for idx, raw in ipairs(rawTokens) do
		local trimmed = mw.text.trim(raw)
		local firstChar = mw.ustring.sub(trimmed, 1, 1)
		local lastChar = mw.ustring.sub(trimmed, -1, -1)
		if (firstChar == "'" or firstChar == '"') and lastChar == firstChar and mw.ustring.len(trimmed) >= 2 then
			tokens[idx] = mw.ustring.sub(trimmed, 2, -2)
		else
			tokens[idx] = trimmed
		end
	end
	return tokens
end

-- Parses a wikidatatype<INDEX> spec such as:
--   "list", "list('<br/>', 5)", "unique",
--   "country('P18', '40px', 3, true, '$P580')"
-- into a bare type name plus an ordered list of its parenthesized arguments.
-- String-valued arguments (SEP, PICTUREPID, PICTURESIZE, BRACKETTEMPLATE)
-- must be wrapped in single or double quotes - this both lets them contain a
-- literal comma and lets them be left empty ('' / "") on purpose. LIMIT and
-- BEST are written bare (an integer, and the literal word true/false).
-- Returns "unique" with no arguments when spec is empty, since that is the
-- simplest, safest way to pull a single value when only wikidatap<INDEX>
-- has been supplied without an explicit wikidatatype<INDEX>.
local function parseWikidataType(spec)
	spec = spec or ""
	if mw.text.trim(spec) == "" then return "unique", {} end

	local typeName, argsStr = mw.ustring.match(spec, "^%s*([%a_]+)%s*%((.*)%)%s*$")
	if not typeName then
		-- No parentheses: treat the whole (trimmed) spec as a bare type name.
		return mw.text.trim(spec), {}
	end

	return mw.text.trim(typeName), splitWikidataArgs(argsStr)
end

-- Fetches a display-ready value from Wikidata for property `pid`, formatted
-- according to `wdtypeSpec` (see parseWikidataType above for the supported
-- syntaxes: list('SEP', LIMIT), unique, country('PICTUREPID', 'PICTURESIZE',
-- LIMIT, BEST, 'BRACKETTEMPLATE')). Returns nil (never an empty string) when
-- nothing could be found, so callers can simply check for truthiness.
local function getWikidataValue(pid, wdtypeSpec)
	if not pid or pid == "" then return nil end
	local typeName, typeArgs = parseWikidataType(wdtypeSpec)

	if typeName == "list" then
		local sep = argOrNil(typeArgs[1]) or "<br/>"
		local limit = tonumber(typeArgs[2]) or 0
		return Wikidata._getValueListWithSeparator({ sep, pid, nil, limit })

	elseif typeName == "unique" then
		return Wikidata.findOneValue(pid)

	elseif typeName == "country" then
		local picturePid  = argOrNil(typeArgs[1])
		local pictureSize = argOrNil(typeArgs[2])
		local limit = tonumber(typeArgs[3]) or -1
		local best = typeArgs[4] == "true"
		local bracketTemplate = argOrNil(typeArgs[5])
		local entityId = mw.wikibase.getEntityIdForCurrentPage()

		local rezList, rezCount = Wikidata.findValueListWithDecoratedQualifiers(entityId, pid, best, bracketTemplate, nil, picturePid, pictureSize, limit)
		if not rezList then return nil end

		-- Enforce LIMIT the same way the "list" type effectively does:
		-- show up to LIMIT values and, if there were more, append a link to
		-- the remaining ones on Wikidata (mirrors getValueListWithDecoratedQualifiers).
		if 0 < limit and rezCount and rezCount > limit + 1 and entityId then
			local hiddenVals = rezCount - limit
			local extraSpec = '[[:d:' .. entityId .. '#' .. pid .. "|...''încă " .. tostring(hiddenVals) .. "'']]"
			table.insert(rezList, extraSpec)
		end

		return #rezList > 0 and table.concat(rezList, tostring(mw.html.create('br'))) or nil
	end

	return nil
end

p._infobox = function(origArgs)

	local child = origArgs["child"] or origArgs["embed"] or "no"
	local bodyclass = origArgs["bodyclass"] or "infocaseta"
	local antet = origArgs["antet"] or "default"
	local aboveclass = origArgs["aboveclass"] or antet
	local abovestyle = origArgs["abovestyle"] or ""
	local culoare_cadru = origArgs["culoare cadru"] or "F5F5DC"
	if mw.ustring.match(culoare_cadru, '^%x%x%x$') or mw.ustring.match(culoare_cadru, '^%x%x%x%x%x%x$') then culoare_cadru = StringUtils._prependIfMissing({culoare_cadru, '#'}) end
	local culoare_text = origArgs["culoare text"] or "000000"
	if mw.ustring.match(culoare_text, '^%x%x%x$') or mw.ustring.match(culoare_text, '^%x%x%x%x%x%x$') then culoare_text = StringUtils._prependIfMissing({culoare_text, '#'}) end
	local titlestyle = origArgs["titlestyle"] or ""
	local title = origArgs["title"] or origArgs["titlu"] or ""
	title = StringUtils._capitalize({title})
	local showtitle = origArgs["showtitle"] or "yes"
	local above = origArgs["above"] or ""
	local parentColSpanArg = origArgs['parent_colspan']
	local parentColSpan
	if parentColSpanArg and mw.ustring.gsub(parentColSpanArg, '%d+', '', 1) == '' then
		parentColSpan = tonumber(parentColSpanArg)
	else
		parentColSpan = 2
	end
	
	local wikidataEnabled = origArgs["wikidata"] or ""
	local enclose = origArgs["enclose"]
	
	if type(enclose) ~= "string" then enclose = "auto" end
	
	if enclose == "begin" then enclose = { true, false }
	elseif enclose == "end" then enclose = { false, true }
	elseif enclose == "both" then enclose = { true, true }
	elseif enclose == "none" or child == "yes" then enclose = { false, false }
	else enclose = { true, true }
	end
	
	local out = ""
	
	-- open box
	if enclose[1] then
		out = out .. "<table class=\"" .. bodyclass .. "\">"
	end
	
	if child ~= "yes" then
		-- caption
		if showtitle == "yes" then
			out = out .. tostring(mw.html.create('tr')
								:tag('td')
								:attr('colspan', tostring(parentColSpan))
								:addClass('antet ' .. aboveclass)
								:css('background-color', culoare_cadru)
								:css('color', culoare_text)
								:cssText(titlestyle)
								:wikitext(title)
								:allDone())
		end
		-- header
		if above ~= "" then
			local aboveTr = mw.html.create('tr'):tag('td')
				:attr('colspan', tostring(parentColSpan))
				:addClass(aboveclass)
				:css('text-align', 'center')
				:css('font-size', '125%')
				:css('font-weight', 'bold')
				:cssText(abovestyle)
				:wikitext(above):allDone()
			out = out .. tostring(aboveTr)
		end
	else
		if showtitle == "yes" and title ~= "" then
			local newTr = mw.html.create('tr'):tag('td')
				:attr('colspan', tostring(parentColSpan))
				:css('background-color', culoare_cadru)
				:css('color', culoare_text)
				:css('font-size', '125%')
				:css('font-weight', 'bold')
				:css('margin-bottom', '2')
				:css('text-align', 'center')
				:css('line-height', '1.2em')
				:cssText(titlestyle)
				:wikitext(title):allDone()
			out = out .. tostring(newTr)
		end
	end

	-- subheaders
	local subheaders = {}
	subheaders[1] = origArgs["subheader"] or origArgs["subheader1"] or ""
	local subhIndex = 2
	while (origArgs["subheader" .. tostring(subhIndex)] or "") ~= "" do
		subheaders[subhIndex] = origArgs["subheader" .. tostring(subhIndex)] or ""
		subhIndex = subhIndex + 1
	end
	local subheaderstyle = origArgs["subheaderstyle"] or ""
	local subheaderclass = origArgs["subheaderclass"] or ""
	for subHeaderIdx = 1,#subheaders do
		if subheaders[subHeaderIdx] ~= "" then
			local subhTr = mw.html.create('tr'):tag('td'):attr('colspan', tostring(parentColSpan))
				:addClass(subheaderclass)
				:css('text-align', 'center')
				:cssText(subheaderstyle)
				:wikitext(subheaders[subHeaderIdx]):allDone()
			out = out .. tostring(subhTr)
		end
	end
	
	-- images
	local imageIndices = TableTools.affixNums(origArgs, 'image')
	local images = {}
	local captions = {}
	-- imageSlotKeys maps slot index (1-based) → the suffix used in origArgs
	-- (empty string for the bare "image"/"caption", or a number string like "2").
	local imageSlotKeys = {}
	-- 'infoboximage' is accepted as an alias for 'image' (bare slot).
	local bareImage = origArgs['image'] or origArgs['infoboximage']
	if bareImage then
		table.insert(images, bareImage)
		table.insert(captions, origArgs['caption'] or '')
		table.insert(imageSlotKeys, '')
	end
	for _,imgIndex in ipairs(imageIndices) do
		table.insert(images, origArgs['image' .. tostring(imgIndex)])
		table.insert(captions, origArgs['caption' .. tostring(imgIndex)] or '')
		table.insert(imageSlotKeys, tostring(imgIndex))
	end

	-- Global infoboximage_* parameters (apply to every image slot).
	-- Per-slot overrides use the same suffix as the image: e.g. for image2,
	-- the override is infoboximage_size2.  Empty string means "not set".
	local iiGlobal = {
		size              = origArgs["infoboximage_size"]              or "",
		maxsize           = origArgs["infoboximage_maxsize"]           or "",
		sizedefault       = origArgs["infoboximage_sizedefault"]       or "",
		upright           = origArgs["infoboximage_upright"]           or "",
		alt               = origArgs["infoboximage_alt"]               or "",
		title             = origArgs["infoboximage_title"]             or "",
		link              = origArgs["infoboximage_link"]              or "",
		border            = origArgs["infoboximage_border"]            or "",
		center            = origArgs["infoboximage_center"]            or "",
		class             = origArgs["infoboximage_class"]             or "",
		suppressplaceholder = origArgs["infoboximage_suppressplaceholder"] or "",
		thumbtime         = origArgs["infoboximage_thumbtime"]         or "",
	}

	-- Returns true when at least one infoboximage_* control parameter has been
	-- supplied (i.e. a key containing an underscore after "infoboximage").
	-- The bare "infoboximage" key is the image itself, not a control param.
	local function hasInfoboxImageParams()
		for _, v in pairs(iiGlobal) do
			if v ~= "" then return true end
		end
		-- Check for per-slot overrides like infoboximage_size2
		for k, _ in pairs(origArgs) do
			if mw.ustring.find(k, '^infoboximage_') then
				return true
			end
		end
		return false
	end

	local useInfoboxImage = hasInfoboxImageParams()

	-- Returns true when the image string is a bare filename rather than already-
	-- formatted wikitext.  Bare filenames need InfoboxImage to wrap them in [[File:…]].
	local function isBareFilename(img)
		local first2 = mw.ustring.sub(img, 1, 2)
		local first1 = mw.ustring.sub(img, 1, 1)
		return first2 ~= "[[" and first2 ~= "{{" and first1 ~= "<"
	end

	-- If the image is a [[File:Foo.jpg|...]] wikilink, extract just the filename
	-- (without namespace prefix) so it can be re-processed by InfoboxImage with
	-- our own size/upright/alt parameters.  Returns nil for non-[[ strings.
	local function extractFromWikilink(img)
		if mw.ustring.sub(img, 1, 2) ~= "[[" then return nil end
		-- Strip leading [[ and take everything before the first | or closing ]]
		local inner = mw.ustring.match(img, "^%[%[(.-)%]%]$") or mw.ustring.match(img, "^%[%[(.+)")
		if not inner then return nil end
		local imgName = mw.ustring.match(inner, "^([^|]*)") or inner
		-- Trim spaces
		imgName = mw.ustring.gsub(imgName, '^%s*(.-)%s*$', '%1')
		-- Strip namespace prefixes (File:, Image:, Fișier:, Imagine:)
		local lcImgName = mw.ustring.lower(imgName)
		for _, nsPrefix in ipairs({"fișier:", "imagine:", "image:", "file:"}) do
			if mw.ustring.sub(lcImgName, 1, #nsPrefix) == nsPrefix then
				imgName = mw.ustring.sub(imgName, #nsPrefix + 1)
				break
			end
		end
		imgName = mw.ustring.gsub(imgName, '^%s*(.-)%s*$', '%1')
		if imgName == "" then return nil end
		return imgName
	end

	local imageclass = origArgs["imageclass"]
	local imagestyle = origArgs["imagestyle"]
	local captionstyle = origArgs["captionstyle"]
	for i = 1,#images do
		if images[i] ~= "" then
			local renderedImage

			local extractedName = extractFromWikilink(images[i])
			if useInfoboxImage or isBareFilename(images[i]) or extractedName then
				-- Build per-slot arg table, starting from globals then applying
				-- per-slot overrides (suffix = imageSlotKeys[i]).
				local suffix = imageSlotKeys[i]
				local function slotArg(name)
					-- Per-slot key: e.g. "infoboximage_size2" or "infoboximage_size"
					-- (bare image has suffix "", so no extra key to look up).
					if suffix ~= "" then
						local perSlot = origArgs["infoboximage_" .. name .. suffix] or ""
						if perSlot ~= "" then return perSlot end
					end
					return iiGlobal[name] ~= "" and iiGlobal[name] or nil
				end

				-- For [[ wikilinks, pass the extracted bare filename so InfoboxImage
				-- can apply size/upright/alt instead of returning the link verbatim.
				local imgArgs = {
					image               = extractedName or images[i],
					size                = slotArg("size"),
					maxsize             = slotArg("maxsize"),
					sizedefault         = slotArg("sizedefault"),
					upright             = slotArg("upright"),
					alt                 = slotArg("alt"),
					title               = slotArg("title"),
					link                = slotArg("link"),
					border              = slotArg("border"),
					center              = slotArg("center"),
					class               = slotArg("class"),
					suppressplaceholder = slotArg("suppressplaceholder"),
					thumbtime           = slotArg("thumbtime"),
				}
				renderedImage = renderWithInfoboxImage(mw.getCurrentFrame(), imgArgs)
			else
				renderedImage = images[i]
			end

			local imageRow = mw.html.create('tr')
			local imageTd = imageRow
				:tag('td'):attr('colspan', tostring(parentColSpan))
					:addClass(imageclass)
					:css('text-align', 'center')
					:cssText(imagestyle)
					:wikitext(renderedImage)
			if captions[i] ~= "" then
				imageTd:tag('br')
				imageTd:tag('div'):cssText('margin-top: 3px')
				imageTd:tag('span'):cssText(captionstyle)
					:wikitext(captions[i])
			end
			out = out .. tostring(imageRow)
		end
	end
	
	-- rows
	local labelstyle = origArgs["labelstyle"] or ""
	local datastyle = origArgs["datastyle"] or ""
	local headerstyle = origArgs["headerstyle"] or ""
	local elementIndex = 1
	local headers = {}
	local data = {}
	local labels = {}
	local classes = {}
	local styles = {}
	local lblstyles = {}
	local rowstyles = {}
	local rowclasses = {}
	local wikidataProps = {}
	local wikidataTypes = {}
	local processingOrder = {}

	for k,v in pairs(origArgs) do
		local headerStart
		local headerEnd
		local labelStart
		local labelEnd
		local dataStart
		local dataEnd
		local styleStart
		local styleEnd
		local lblStyleStart
		local lblStyleEnd
		local rowstyleStart
		local rowstyleEnd
		local wikidatatypeStart
		local wikidatatypeEnd
		local wikidatapStart
		local wikidatapEnd
		headerStart, headerEnd = mw.ustring.find(k, "header")
		labelStart, labelEnd = mw.ustring.find(k, "label")
		dataStart, dataEnd = mw.ustring.find(k, "data")
		styleStart, styleEnd = mw.ustring.find(k, "style")
		lblStyleStart, lblStyleEnd = mw.ustring.find(k, "lblstyle")
		rowstyleStart, rowstyleEnd = mw.ustring.find(k, "rowstyle")
		-- Checked before "wikidatap" since "wikidatatypeN" would otherwise
		-- also match a naive search for the "wikidatap" prefix... (it does
		-- not, but keeping "wikidatatype" first keeps the more specific key
		-- checked first, matching the pattern used above for lblstyle/rowstyle).
		wikidatatypeStart, wikidatatypeEnd = mw.ustring.find(k, "wikidatatype")
		wikidatapStart, wikidatapEnd = mw.ustring.find(k, "wikidatap")
		
		local nr = ""
		if dataStart == 1 then
			nr = mw.ustring.sub(k, 1 + dataEnd, mw.ustring.len(k))
		elseif labelStart == 1 then
			nr = mw.ustring.sub(k, 1 + labelEnd, mw.ustring.len(k))
		elseif headerStart == 1 then
			nr = mw.ustring.sub(k, 1 + headerEnd, mw.ustring.len(k))
		elseif styleStart == 1 then
			nr = mw.ustring.sub(k, 1 + styleEnd, mw.ustring.len(k))
		elseif lblStyleStart == 1 then
			nr = mw.ustring.sub(k, 1 + lblStyleEnd, mw.ustring.len(k))
		elseif rowstyleStart == 1 then
			nr = mw.ustring.sub(k, 1 + rowstyleEnd, mw.ustring.len(k))
		elseif wikidatatypeStart == 1 then
			nr = mw.ustring.sub(k, 1 + wikidatatypeEnd, mw.ustring.len(k))
		elseif wikidatapStart == 1 then
			nr = mw.ustring.sub(k, 1 + wikidatapEnd, mw.ustring.len(k))
		end

		if nr ~= "" and processingOrder[nr] == nil and tonumber(nr) ~= nil then
			headers[elementIndex] = origArgs["header" .. nr] or ""
			labels[elementIndex] =  origArgs["label" .. nr] or ""
			data[elementIndex] = origArgs["data" .. nr] or ""
			classes[elementIndex] =  origArgs["class" .. nr] or ""
			styles[elementIndex] = origArgs["style" .. nr] or ""
			lblstyles[elementIndex] = origArgs["lblstyle" .. nr] or ""
			rowstyles[elementIndex] = origArgs["rowstyle" .. nr] or ""
			wikidataProps[elementIndex] = origArgs["wikidatap" .. nr] or ""
			wikidataTypes[elementIndex] = origArgs["wikidatatype" .. nr] or ""
			processingOrder[tonumber(nr)] = elementIndex
			elementIndex = elementIndex + 1
		end
	end

	local processingElement = 1
	while processingElement <= table.maxn(processingOrder) do
		elementIndex = processingOrder[processingElement]
		if elementIndex ~= nil then
			local crtHeader = headers[elementIndex]
			local crtData = data[elementIndex]
			local crtLabel = labels[elementIndex]
			local crtLblStyle = lblstyles[elementIndex]
			local crtClass = classes[elementIndex]
			local crtStyle = styles[elementIndex]
			local crtRowstyle = rowstyles[elementIndex]
			local crtWikidataP = wikidataProps[elementIndex]
			local crtWikidataType = wikidataTypes[elementIndex]

			-- data<NR> was left empty/missing: try to pull it from Wikidata
			-- using wikidatap<NR>/wikidatatype<NR>, and tag it with the
			-- "edit this at Wikidata" icon so readers know where it came from.
			if crtHeader == "" and crtData == "" and crtWikidataP ~= "" then
				local wdValue = getWikidataValue(crtWikidataP, crtWikidataType)
				if wdValue and wdValue ~= "" then
					crtData = wdValue .. (EditAtWikidata.displayMessage(crtWikidataP) or "")
				end
			end

			if crtHeader ~= "" then
				local headerTr = mw.html.create('tr')
					:cssText(crtRowstyle)
				local headerTh = headerTr:tag('th')
					:attr('colspan', tostring(parentColSpan))
					:css('text-align', 'center')
					:css('background-color', culoare_cadru)
					:css('color', culoare_text)
					:addClass(crtClass)
					:cssText(headerstyle)
					:wikitext(crtHeader)
				out = out .. tostring(headerTr)
			elseif crtLabel ~= "" then
				if crtData ~= "" then
					local dataAndLabelTr = mw.html.create('tr')
						:tag('th'):cssText(labelstyle):cssText(crtLblStyle)
							:wikitext(crtLabel):done()
						:tag('td')
							:attr('colspan', tostring(parentColSpan - 1))
							:addClass(crtClass)
							:cssText(datastyle):cssText(crtStyle)
							:wikitext(crtData):allDone()
					out = out .. tostring(dataAndLabelTr)
				end
			elseif crtData ~= "" then
				crtData = mw.getCurrentFrame():preprocess(crtData)
				if containsEmbed(crtData) then
					out = out .. crtData
				else
					local dataTr = mw.html.create('tr')
						:tag('td'):attr('colspan', tostring(parentColSpan))
							:addClass(crtClass)
							:css('text-align', 'center')
							:cssText(datastyle)
							:cssText(crtStyle)
							:wikitext(crtData):allDone()
					out = out .. tostring(dataTr)
				end
			end
		end
		processingElement = processingElement + 1
	end
	
	-- below
	local belowstyle = origArgs["belowstyle"] or ""
	local below = origArgs["below"] or ""
	if below ~= "" then
		out = out .. tostring(mw.html.create('tr')
								:tag('td')
									:attr('colspan', tostring(parentColSpan))
									:css('text-align', 'center')
									:cssText(belowstyle)
									:wikitext(below):allDone())
	end
	
	-- tnavbar
	local name = origArgs["name"] or ""
	local navbar = origArgs["navbar"]
	if name ~= "" and navbar ~= 'false' then
		local navBarTr = mw.html.create('tr'):tag('td')
			:css('text-align', 'right')
			:attr('colspan', tostring(parentColSpan))
			:wikitext(mw.getCurrentFrame():expandTemplate{title = "Tnavbar", args = { name }}):done()
		out = out .. tostring(navBarTr)
	end
	if child ~= "yes" then
		local doc = origArgs["doc"] or ""
		if doc ~= "" then
			local infodocTr = mw.html.create('tr'):wikitext(mw.getCurrentFrame():expandTemplate{title = "infodoc", args = {colspan = tostring(parentColSpan), culoare = culoare_cadru, link = doc, wikidata = wikidataEnabled }})
			out = out .. tostring(infodocTr)
		end
	end
	
	-- close box
	if enclose[2] then
		out = out .. "</table>" .. mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Modul:Infobox/styles.css'} } 
	end
	
	return out
end

p.infobox = function(frame)
	local origArgs = getArgs(frame)
	return p._infobox(origArgs)
end
return p