মডিউল:Artwork/core

উইকিসংকলন থেকে

এই মডিউলের জন্য মডিউল:Artwork/core/নথি-এ নথিপত্র তৈরি করা হয়ে থাকতে পারে

local getLabel = require("Module:Wikidata label")._getLabel            -- used for creation of name based on Wikidata
local core     = require("Module:Core")
local TagQS            = require('Module:TagQS')
local City     = require("Module:City")                                -- used to add Wikidata based links to names of places
local ISOdate  = require('Module:ISOdate')                             -- used for simple date formating
local bit32    = require("bit32")
local labels   = {
	object_type = {
		ar = "نوع العمل",
		["be-tarask"] = "Тып аб’екту",
		bn = "বস্তুর ধরন",
		br = "Seurt traezenn",
		de = "Objektart",
		el = "Είδος αντικειμένου",
		en = "Object type",
		et = "Objekti tüüp",
		fa = "نوع شیء",
		fi = "Kohteen tyyppi",
		fr = "Type d'objet",
		he = "סוג אובייקט",
		hr = "Vrsta",
		it = "Tipo di oggetto",
		ja = "分野",
		mk = "Вид предмет",
		ml = "വസ്തുവിന്റെ തരം",
		nb = "Objekttype",
		nl = "Soort object",
		nn = "Objekttype",
		pl = "Typ obiektu",
		pt = "Tipo de objecto",
		ru = "Тип",
		sk = "Druh objektu",
		sl = "Vrsta objekta",
		sv = "Objekttyp",
		["zh-hans"] = "物体类型",
		["zh-hant"] = "物體類型"
	},
	exhibition_history = {
		ar = "تاريخ العرض",
		["be-tarask"] = "Гісторыя выставак",
		bn = "প্রদর্শনী ইতিহাস",
		br = "Diskouezadegoù",
		de = "Ausstellungsgeschichte",
		el = "Εκθέσεις",
		en = "Exhibition history",
		et = "Näituste ajalugu",
		fa = "تاریخ نمایش",
		fi = "Näyttelyhistoria",
		fr = "Expositions",
		hr = "Povijest izlaganja",
		hu = "Kiállítástörténet",
		it = "Esposizioni",
		ja = "展示履歴",
		mk = "Изложбено минато",
		ml = "പ്രദർശന ചരിത്രം",
		nb = "Utstillingshistorikk",
		nn = "Utstillingshistorikk",
		pl = "Historia wystaw",
		pt = "Exposições",
		sk = "História vystavenia",
		sl = "Razstavna zgodovina",
		sv = "Utställningshistorik",
		["zh-hans"] = "展览史",
		["zh-hant"] = "展覽史"
	},
	place_of_creation = {
		ar = 'مكان الصنع',
		bn = 'জায়গা তৈরি',
		ca = 'Lloc de creació',
		de = 'Herstellungsort',
		el = 'Τόπος δημιουργίας',
		en = 'Place of creation',
		eo = 'Loko de kreado',
		es = 'Lugar de creación',
		et = 'Loomise koht',
		fa = ' محل ساخت',
		fr = 'Lieu de fabrication',
		hr = "Mjesto nastanka",
		hu = 'Készítés helye',
		it = 'Luogo di creazione',
		ja = '製作された場所',
		mk = 'Место на изработка',
		nb = "Opphavssted",
		nn = "Opphavsstad",
		pl = 'Miejsce stworzenia',
		pt = 'Lugar de criação',
		ro = 'Loc de fabricare',
		sl = 'Kraj ustvaritve',
		["zh-hans"] = "创作地点",
		["zh-hant"] = "創作地點"
	},
	place_of_discovery = {
		ar = "مكان الاكتشاف",
		["be-tarask"] = "Месца выяўленьня",
		bn = "আবিষ্কারের স্থান",
		ca = "Lloc del descobriment",
		de = "Fundort",
		el = "Τόπος ανακάλυψης",
		en = "Place of discovery",
		eo = "Loko de malkovro",
		es = "Lugar del hallazgo",
		et = "Leiukoht",
		fa = "محل کشف",
		fi = "Löytöpaikka",
		fr = "Lieu de découverte",
		gl = "Lugar de descubrimento",
		he = "מקום הגילוי",
		hr = "Mjesto pronalaska",
		hsb = "Namakanišćo",
		hu = "Lelőhely",
		it = "Luogo della scoperta",
		ja = "発見地点",
		ko = "발견 장소",
		mk = "Место на пронаоѓање",
		ml = "കണ്ടെത്തിയ സ്ഥലം",
		nb = "Funnsted",
		nl = "Vindplaats",
		nn = "Funnstad",
		pl = "Miejsce odkrycia",
		pt = "Local da descoberta",
		ro = "Loc de descoperire",
		ru = "Место обнаружения",
		sl = "Kraj odkritja",
		sv = "Fyndplats",
		uk = "місце відкриття",
		["zh-hans"] = "发现地点",
		["zh-hant"] = "發現地點"
	},
	depicted_person = {
		ar = "الشخصية المُصوَّرة",
		ca = "Persona retratada",
		de = "Abgebildete Person",
		el = "Εικονιζόμενο πρόσωπο",
		en = "Depicted person",
		es = "Persona retratada",
		et = "Kujutatud isik",
		fi = "Kuvan esittämä henkilö",
		fr = "Personne représentée",
		he = "האדם המוצג",
		hu = "Ábrázolt személy",
		it = "Persona ritratta",
		ja = "描画された人物",
		ko = "묘사된 인물",
		mk = "Прикажана личност",
		ml = "ചിത്രീകരിച്ചിരിക്കുന്ന വ്യക്തി",
		nb = "Avbildet person",
		nl = "Afgebeelde persoon",
		nn = "Avbilda person",
		pl = "Przedstawiona osoba",
		pt = "Pessoa retratada",
		ru = "Изображённая персона",
		sl = "Upodobljena oseba",
		sv = "Avbildad person",
		uk = "Зображена особа",
		["zh-hans"] = "描绘人物",
		["zh-hant"] = "描繪人物"
	},
	depicted_people = {
		ar = "أشخاص مُصوَّرون",
		["be-tarask"] = "Асобы на выяве",
		ca = "Persones retratades",
		de = "Abgebildete Personen",
		el = "Εικονιζόμενα πρόσωπα",
		en = "Depicted people",
		es = "Personas retratadas",
		et = "Kujutatud isikud",
		fi = "Kuvan esittämät henkilöt",
		fr = "Personnes représentées",
		he = "האנשים המוצגים",
		hr = "Prikazane osobe",
		hu = "Ábrázolt személyek",
		it = "Persone ritratte",
		ja = "描画された人物",
		ko = "묘사된 인물",
		mk = "Прикажани личности",
		ml = "ചിത്രീകരിച്ചിരിക്കുന്ന വ്യക്തികൾ",
		nb = "Avbildede personer",
		nds = "Afbillt Lüüd",
		nl = "Afgebeelde personen",
		nn = "Avbilda personar",
		pl = "Przedstawione osoby",
		pt = "Pessoas retratadas",
		ro = "Persoane reprezentate",
		ru = "Изображённые персоны",
		sl = "Upodobljeni ljudje",
		sv = "Avbildade personer",
		uk = "Зображені особи",
		["zh-hans"] = "描绘人物",
		["zh-hant"] = "描繪人物"
	},
	depicted_place = {
		ar = 'المكان المُصوَّر',
		["be-tarask"] = 'Адлюстраванае месца',
		bn = 'দেখানো জায়গা',
		ca = 'Lloc representat',
		de = 'Abgebildeter Ort',
		el = 'Εικονιζόμενος τόπος',
		en = 'Depicted place',
		eo = 'Prezentita loko',
		es = 'Lugar representado',
		et = 'Kujutatud koht',
		fa = 'محل کشیده‌شده',
		fi = 'Kuvan esittämä paikka',
		fr = 'Lieu représenté',
		gl = 'Lugar representado',
		he = 'המקום המוצג',
		hr = 'Prikazano mjesto',
		hsb = 'Zwobraznjene městno',
		hu = 'Ábrázolt hely',
		it = 'Luogo rappresentato',
		ja = "描画された場所",
		ko = '묘사된 장소',
		mk = 'Прикажано место',
		ml = 'ചിത്രീകരിച്ച സ്ഥലം',
		nb = 'Avbildet sted',
		nl = 'Afgebeelde plaats',
		nn = "Avbilda stad",
		pl = 'Przedstawione miejsce',
		pt = 'Lugar retratado',
		ro = 'Loc reprezentat',
		ru = 'Изображённое место',
		sl = 'Upodobljeni kraj',
		sv = 'Avbildad plats',
		uk = 'Зображене місце',
		["zh-hans"] = "描绘地点",
		["zh-hant"] = "描繪地點"
	},
	original_description = {
		ar = "الوصف الأصلي",
		bar = "Originoibschreiwung",
		bn = "মূল বিবরণ",
		ca = "Descripció original",
		cs = "Původní popisek",
		de = "Original-Bildunterschrift",
		el = "Αυθεντική περιγραφή",
		en = "Original caption",
		eo = "Originala priskribo",
		es = "Descripción original",
		et = "Originaalkirjeldus",
		fa = "عنوان اصلی",
		fi = "Alkuperäinen kuvateksti",
		fr = "Description d’origine ",
		gl = "Descrición orixinal",
		he = "כיתוב מקורי",
		hr = "Izvorni naslov",
		hu = "Eredeti felirat",
		it = "Descrizione originale",
		ja = "元の説明",
		ko = "원본설명",
		mk = "Изворен опис",
		ml = "യഥാർത്ഥ തലക്കെട്ട്",
		nb = "Originaltittel",
		nds = "Original-Bildünnerschrift",
		nl = "Oorspronkelijk onderschrift",
		nn = "Originaltittel",
		pl = "Oryginalny opis",
		pt = "Título original",
		ro = "Descrierea originală",
		ru = "Оригинальный заголовок",
		sl = "Izvorni napis",
		sv = "Originalbeskrivning",
		vec = "Descrission original",
		["zh-hans"] = "原始说明文字",
		["zh-hant"] = "原始說明文字"
	},
	inaccurate_description = {
		ar = "وصف غير دقيق",
		bn = "এই বিবরণটি পক্ষপাতদুষ্ট বা ভুল হিসাবে চিহ্নিত করা হয়েছে",
		da = "Beskrivelsen er tendentiøs eller forkert",
		de = "Diese Beschreibung ist tendenziös oder falsch",
		el = "Αυτή η περιγραφή αναγνωρίστηκε ως μεροληπτική ή ανακριβής",
		en = "This description has been identified as biased or incorrect",
		et = "Selle kirjelduse kohta on leitud, et see on erapoolik või ekslik",
		fa = "این توضیحات به‌عنوان دارای پیش‌داوری یا نادرست تشخیص داده‌شده‌است",
		fr = "Cette description a été identifiée comme biaisiée ou incorrecte",
		gsw = "Die bildbeschriibig isch tendenziös oder falsch",
		he = "התיאור הזה זוהה כמוטה או שגוי",
		hu = "Ez a leírás elfogult vagy hibás",
		it = "Questa descrizione è stata rilevata come tendenziosa o non corretta",
		ja = "この説明は偏向している又は誤っていると判断されました。",
		mk = "Овој опис е пристрасен или неточен",
		ml = "ഈ വിവരണം പക്ഷപാതപരമാണെന്ന് അല്ലെങ്കിൽ തെറ്റാണെന്ന് തിരിച്ചറിഞ്ഞിട്ടുള്ളതാണ്",
		nb = "Beskrivelsen er tendensiøs eller feil",
		nl = "Deze beschrijving is vooringenomen of niet correct",
		nn = "Skildringa er tendensiøs eller feil",
		pl = "Ten opis został zidentyfikowany jako tendencyjny lub nieprawdziwy",
		pt = "Esta descrição foi identificada como tendenciosa ou incorrecta",
		ru = "Это описание тенденциозно или неверно",
		sl = "Ta opis je pristranski ali napačen",
		["zh-hans"] = "此描述已认定为有偏见或不正确",
		["zh-hant"] = "該描述已界定為有異見或不正確"
	},
	initial_pages = {
		ar = 'صفحات ابتدائية',
		en = 'Initial pages',
		mk = 'Почетни страници',
		pl = 'Strony początkowe',
		pt = 'Páginas iniciais',
		sl = 'Začetne strani',
		["zh-hans"] = "初始页面",
		["zh-hant"] = "初始頁面"
	}
}                        -- internationalization of labels

local p = {}

-- ====================================================================
-- This function is responsible for producing HTML of a single row of the template
-- At this stage all the fields are already filed. There is either one or two fields
-- INPUTS:
-- * param1 and param2 - structures for 2 fields containing fields:
--    - tag      - I18n tag used for localization of the field name. Usually name of page in MediaWiki 
--                 namespace which was imported from translatewiki.org. 
--                 Alternative is to pass already translated field name.
--    - field    - field content
--    - id       - ID tag added to HTML's <td> cell. if IDs of 2 fields are the same than we ignore the second one
--    - wrapper  - some fields need a <span class=...> wrapper around the field content 
-- ====================================================================
local function Build_html_row(param, args)
	local LUT = {artwork=0, photograph=1, book=2}
    local demo = args.demo and bit32.extract( param.demo or 0, LUT[args.infobox])==1
	local field = args[param.field]
	if field=='' then field=nil; end
	if not (field or demo) then 
		return nil
	end
	if not param.id then -- "other fields" parameter
		return field
	end
	local tag = param.tag or 'bad'
	if string.sub(tag,1,10) == 'wm-license' then
		tag = mw.message.new( tag ):inLanguage(args.lang):plain() -- label message in args.lang language
	elseif string.match(tag, "^[QP]%d+$") then
		tag = getLabel(tag, args.lang, "-", "ucfirst")
	elseif labels[tag] then
		tag = core.langSwitch(labels[tag], args.lang)
	end
	local cell1 = string.format('<td id="%s" class="fileinfo-paramfield" lang="%s">%s</td>\n', param.id, args.lang, tag)
	local cell2 = string.format('<td>\n'.. param.wrapper ..'</td>', field or '')
	return string.format('<tr>\n%s%s\n</tr>\n\n', cell1, cell2)
end

-- ===========================================================================
-- === Read input "frame", normalize input parameters (lower case, etc.)   ===
-- === and resolve potential aliases                                       ===
-- === INPUTS:                                                             ===
-- ===  * frame - contains input parameters passed from the template       ===
-- === OUTPUTS:                                                            ===
-- ===  * args - cleaned up inputs                                         ===
-- ===========================================================================
function p.read_input_parameters(frame)
	-- switch to lowercase parameters to make them case independent
	local args = core.getArgs(frame)
	
	-- resolve aliases
	args.permission        = args.permission       or args.license
	args.medium            = args.medium           or args.technique
	args.date              = args.date             or args.year
	args.department        = args.department       or args.location
	args.id                = args.accession_number or args.id
	args.object_type       = args.object_type      or args.type
	args.dimensions        = args.dimensions       or args.size
	args.object_history    = args.object_history   or args.history
	args.coordinates       = args.coordinates      or args.object_location
	args.institution       = args.institution or args.gallery or args.museum
	args.place_of_creation = args.place_of_creation or args.place_of_origin or args.country
	args.original_description = args.original_description or args.original_caption
	
	-- remove unneeded parameters
	args.technique, args.year, args.size,   args.gallery           = nil, nil, nil, nil
	args.location,  args.type, args.museum, args.accession_number  = nil, nil, nil, nil
	args.place_of_origin, args.country, args.history, args.license = nil, nil, nil, nil
	args.object_location, args.original_caption = nil, nil
	
	-- ensure the right format
	args.wikidata_cat = core.yesno(args.wikidata_cat, true)
	args.strict       = core.yesno(args.strict, true)
	args.noimage      = core.yesno(args.noimage, false)
	args.no_qs        = core.yesno(args.no_qs, false)
	args.no_sdc       = core.yesno(args.no_sdc, false)
	args.image_page   = tonumber(args.image_page)
	if args.language and #args.language==2 then 
		args.language = frame:callParserFunction( "#language", { args.language, args.lang } ) -- get  language of the written work
	end
	
	return args
end

local function empty2nil(str)
	if str=='' then
		return nil
	else 
		return str
	end
end

local function if_else(Boolean, TrueStatement, FalseStatement)
	if Boolean then
		return TrueStatement
	else
		return FalseStatement
	end
end

local function ObjectLocation_label()
	return mw.loadData('Module:i18n/coordinates').ObjectLocation
end

local function isodate2timestamp(dateStr)
-- convert isodate to timestamp used by quick statements
	local tStamp = nil
	if string.match(dateStr,"^[0-1]%d%d%d$") then               -- if YYYY  format 
		tStamp = '+' .. dateStr .. '-00-00T00:00:00Z/9'
	elseif string.match(dateStr,"^[0-1]%d%d%d%-[0-1]%d$") then      -- if YYYY-MM format 
		tStamp = '+' .. dateStr .. '-00T00:00:00Z/10'
	elseif string.match(dateStr,"^[0-1]%d%d%d%-[0-1]%d%-[0-3]%d$") then  -- if YYYY-MM-DD format 
		tStamp = '+' .. dateStr .. 'T00:00:00Z/11'
	end
	return tStamp
end

-- ===========================================================================
function p.clean_input_parameters(args)
	local lang = args.lang  -- user's language
	
	-- === Step 1: clean up of template arguments "args"
	local page = mw.title.getCurrentTitle()
	args.namespace   = page.namespace   -- get page namespace
	args.url         = page:canonicalUrl()
	args.pagename    = page.text
	if args.namespace==6 then -- file namespace
		args.mimeType  = page.file.mimeType
		args.num_pages = 1
		if page.file.pages then
			args.num_pages = #page.file.pages -- in case of DjVu or PDF files count pages
		end
	end
	if args.date then 
		args.year = empty2nil(ISOdate._ISOyear(args.date)) -- get year
	end
	
	-- for places run them through {{City}} template
	local fields = { 'depicted_people', 'depicted_place', 'place_of_discovery', 'part_of'	}
	for _, field in ipairs( fields ) do 
		if args[field] and not string.find(args[field], ' ') then
			args[field] = City._city(args[field], lang) -- single word depicted_people will get a link
		end	
	end
		
	-- for dates run them through {{ISOdate}} template and add invisible QS tag if possible
	local fields = { 'date', 'publication_date'}
	for _, field in ipairs( fields ) do 
		if args[field] then 
			local val  = isodate2timestamp(args[field])        -- if date is in YYYY, YYYY-MM or YYYY-MM-DD formats than it will be saved
			args[field] = ISOdate._ISOdate(args[field], lang) -- apply ISODate to function to date string to convert date in ISO format to translated date string 
			if val then                                         -- if date is in ISO format than add an invisible tag which will be used to potentially add this date to QS used to move it to Wikidata
				args[field] = args[field] .. TagQS.createTag('date', nil, val)
			end		
		end
	end
	
	-- collapse local {{Creator}} and {{Institution}} templates and extract item ID from them 
	local fields = {author='creator', artist='creator', photographer='creator', architect='creator', printer='creator', 
		designer='creator', editor='creator', translator='creator', illustrator='creator', institution='institution'}
	for field, keyword in pairs( fields ) do 
		if args[field] then 
			if string.match(args[field], "^Q%d+$") and keyword=='creator' then -- this is wikidata item
				args[field..'_id'] = args[field]
				if keyword=='creator' then
					args[field] = Creator({wikidata=args[field], lang=lang, collapse=1})-- create creator based on item id 
				elseif keyword=='institution' then
					args[field] = Institution({wikidata=args[field], lang=lang, collapse=1})-- create institution based on item id 
				end
			else
				-- collapse local {{Creator}} and {{Institution}} templates
				args[field] = mw.ustring.gsub (args[field], 'table class="toccolours collapsible%s*"', 'table class="toccolours collapsible collapsed"')
				-- extract item ID: retrieve the tag and grab the second component
				local v = mw.text.split(  TagQS.readTag(args[field], keyword) or '', '|', true )
				if v and #v>=2 then 
					args[field..'_id'] = v[2]
				end
			end
		end
	end
	
	-- in case of invisible QS tags add correct property based on which field and infobox it come from 
	local repList = { {'author', 'book',   'creator', 'P170', 'P50' }, 
		{'artist',           'artwork',    'creator', 'P170', 'P170' },
		{'illustrator',      'book',       'creator', 'P170', 'P110'}, 
		{'editor',           'book',       'creator', 'P170', 'P98' }, 
		{'translator',       'book',       'creator', 'P170', 'P655'}, 
		{'printer',          'book',       'creator', 'P170', 'P872'}, 
		{'publication_date', 'book',       'date',     nil,   'P577'}, 
		{'date',             'photograph', 'date',     nil,   'P571'}, 
		{'date',             'artwork',    'date',     nil,   'P571'}}   
	for _, repItem in ipairs( repList ) do
		local field, infobox, tag, oldP, newP = unpack(repItem)
		if args[field] and args.infobox==infobox then 	
			args[field] = TagQS.changeProperty(args[field], tag, oldP, newP) 
			args[field] = TagQS.changeField(args[field], tag, field) 
		end
	end
	return args
end

-- ====================================================================
-- === This function is just responsible for producing HTML of the  ===
-- === template. At this stage all the fields are already filled    ===
-- ====================================================================
function p.build_html(args)
	-- get text direction
	local dir = if_else(mw.language.new( args.lang ):isRTL(),'rtl','ltr')
	
	-- original_description row has a different look than other rows
	if args.original_description and (args.original_description_info or args.biased) then
		local tag1, tag2 = "", ""
		if args.original_description_info then
			tag1 = string.format('<div style="background:#dde; font-size:86%%; direction:%s;">%s</div>', dir, args.original_description_info)
		end
		if args.biased then
			tag2 = core.langSwitch(labels.inaccurate_description, args.lang)
			tag2 = string.format('<div style="padding:0.5ex; margin:0 0 0.5ex 0; border: 1px solid red;">%s: %s</div>', tag2, args.biased)
		end
		args.original_description = tag1 .. tag2 .. args.original_description
	end
	
	-- files with no source will be flagged
	if (not args.source) and (not args.source_) and (args.strict==true) and (args.namespace==6) then
		args.nosource = mw.getCurrentFrame():expandTemplate{ title = 'Source missing' }
	end
	if args.demo or args.coordinates then
		labels.ObjectLocation = ObjectLocation_label()
	end
	
	local nCol = 2
	if not args.image and args.demo then
		args.image = args.demo_image
	end
	if args.image  then
		nCol = 3
	end
	
	-- Top line 
	local top, results = {}, {}
	if args.name then
		table.insert(top, string.format('<span class="fn" id="artwork"><bdi>%s\n</bdi></span>', args.name ) )
	end
	if args.linkback then -- Wikidata Link
		table.insert(top, string.format('[[File:Blue pencil.svg|15px|%s|link=%s]]', args.linkback, args.linkback) )
	end	
	if args.wikidata then -- Wikidata Link
		table.insert(top, string.format('[[File:Wikidata-logo.svg|20px|wikidata:%s|link=wikidata:%s]]', args.wikidata, args.wikidata) )
		table.insert(top, string.format('[[File:Wikidata-Reasonator_small_logo.svg|5px|reasonator:%s|link=https://reasonator.toolforge.org/test/?q=%s]]', args.wikidata, args.wikidata) )
	end
	if args.wikisource then --Wikisource link
		table.insert(top, string.format('[[File:Wikisource-logo.svg|15px|%s|link=%s]]', args.wikisource, args.wikisource) )
	end
	if args.wikiquote then --Wikiquote link
		table.insert(top, string.format('[[File:Wikiquote-logo.svg|15px|%s|link=%s]]', args.wikiquote, args.wikiquote) )
	end
	if #top>0 and args.QS then -- quick_statement link to upload missing info to Wikidata (add if the row is not empty)
		table.insert(top, string.format('%s', args.QS) )
	end
	if #top>0 then
		local line = string.format('<th colspan="%i" style="background-color:#ccf; font-weight:bold; border:1px solid #aaa" text-align="left">%s</th>', nCol, table.concat(top, '&nbsp;')) 
		table.insert(results, string.format('<tr valign="top">\n%s\n</tr>\n', line))
	end
	
	-- Permissions tag
	local tag1 = mw.message.new( "wm-license-information-permission" ):inLanguage(args.lang):plain()
	local tag2 = mw.message.new( "wm-license-information-permission-reusing-link" ):inLanguage(args.lang):plain()
	local tag3 = mw.message.new( "wm-license-information-permission-reusing-text" ):inLanguage(args.lang):plain()
	local permission_tag = string.format("%s<br /><small>([[%s|%s]])</small>", tag1, tag2, tag3)
	
	-- define constants for readability
	-- demo=art+photo+book will show that row in demo mode in {{artwork}, {{Photograph}} and {{Book}} templates
	local none, art, photo, book  = 0, 1, 2, 4
	
	-- add other fields 'author_of_foreword', 'author_of_afterword'
	local param = {
		-- field name                   machine readable tag                         field name i18n approach                     show in demo mode?   field value wrapper
		{field='artist'               , id='fileinfotpl_aut'                       , tag='wm-license-artwork-artist',             demo=art,            wrapper='<div class="fn value">\n%s</div>'},
		{field='author'               , id='fileinfotpl_aut'                       , tag='wm-license-information-author',         demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='editor'               , id='fileinfotpl_book_editor'               , tag='wm-license-book-editor',                demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='translator'           , id='fileinfotpl_book_translator'           , tag='wm-license-book-translator',            demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='illustrator'          , id='fileinfotpl_book_illustrator'          , tag='wm-license-book-illustrator',           demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='author_of_foreword'   , id='fileinfotpl_aut'                       , tag='P2679',                                 demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='author_of_afterword'  , id='fileinfotpl_aut'                       , tag='P2680',                                 demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='architect'            , id='fileinfotpl_aut'                       , tag='Q42973',                                demo=none,           wrapper='<div class="fn value">\n%s</div>'},
		{field='designer'             , id='fileinfotpl_aut'                       , tag='Q5322166',                              demo=none,           wrapper='<div class="fn value">\n%s</div>'},
		{field='photographer'         , id='fileinfotpl_aut'                       , tag='Q33231',                                demo=    photo,      wrapper='<div class="fn value">\n%s</div>'},
		{field='other_fields_1'},
		-- title & desctiption block
		{field='title'                , id='fileinfotpl_art_title'                 , tag='wm-license-artwork-title',              demo=art+photo+book, wrapper='<div class="fn">\n%s</div>'},
		{field='subtitle'             , id='fileinfotpl_book_subtitle'             , tag='wm-license-book-subtitle',              demo=          book, wrapper='%s'},
		{field='part_of'              , id='fileinfotpl_art_part_of'               , tag='P361',                                  demo=art+photo+book, wrapper='%s'},
		{field='series_title'         , id='fileinfotpl_book_series-title'         , tag='wm-license-book-series-title',          demo=          book, wrapper='%s'},
		{field='volume'               , id='fileinfotpl_book_volume'               , tag='wm-license-book-volume',                demo=          book, wrapper='%s'},
		{field='edition'              , id='fileinfotpl_edition'                   , tag='wm-license-book-edition',               demo=          book, wrapper='%s'},
		{field='publisher'            , id='fileinfotpl_book_publisher'            , tag='wm-license-book-publisher',             demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='printer'              , id='fileinfotpl_book_printer'              , tag='wm-license-book-printer',               demo=          book, wrapper='<div class="fn value">\n%s</div>'},
		{field='object_type'          , id='fileinfotpl_art_object_type'           , tag='object_type',                           demo=art,            wrapper='%s'},
		{field='genre'                , id='fileinfotpl_art_genre'                 , tag='Q483394',                               demo=          book, wrapper='%s'},
		{field='original_description' , id='fileinfotpl_desc'                      , tag='original_description',                  demo=    photo,      wrapper='<div class="description">\n%s</div>'},
		{field='description'          , id='fileinfotpl_desc'                      , tag='wm-license-information-description',    demo=art+photo+book, wrapper='<div class="description">\n%s</div>'},
		{field='pageoverview'         , id='fileinfotpl_book-page-overview'        , tag='wm-license-book-page-overview',         demo=none,           wrapper='%s'},
		{field='depicted_people'      , id='fileinfotpl_art_depicted_people'       , tag='depicted_people',                       demo=art+photo,      wrapper='%s'},
		{field='depicted_place'       , id='fileinfotpl_art_depicted_place'        , tag='depicted_place',                        demo=art+photo,      wrapper='%s'},
		{field='depicted_part'        , id='fileinfotpl_art_depicted_part'         , tag='P5961',                                 demo=art+photo+book, wrapper='%s'},
		{field='language'             , id='fileinfotpl_book_language'             , tag='wm-license-book-language',              demo=          book, wrapper='%s'},
		{field='other_fields_2'},
		-- date, object outside description, history, etc.
		{field='date'                 , id='fileinfotpl_date'                      , tag='wm-license-information-date',           demo=art+photo,      wrapper='%s'},
		{field='publication_date'     , id='fileinfotpl_publication_date'          , tag='P577',                                  demo=          book, wrapper='%s'},
		{field='medium'               , id='fileinfotpl_art_medium'                , tag='wm-license-artwork-medium',             demo=art+photo,      wrapper='%s'},
		{field='dimensions'           , id='fileinfotpl_art_dimensions'            , tag='wm-license-artwork-dimensions',         demo=art+photo,      wrapper='%s'},
		{field='institution'          , id='fileinfotpl_art_gallery'               , tag='Q2668072',                              demo=art+photo,      wrapper='%s'},
		{field='department'           , id='fileinfotpl_art_location'              , tag='wm-license-artwork-current-location',   demo=art+photo     , wrapper='<div class="locality">\n%s</div>'},
		{field='id'                   , id='fileinfotpl_art_id'                    , tag='wm-license-artwork-id',                 demo=art+photo,      wrapper='<div class="identifier">\n%s</div>'},
		{field='coordinates'          , id='fileinfo-paramfield'                   , tag='ObjectLocation',                        demo=art+photo,      wrapper='%s'}, 
		{field='place_of_publication' , id='fileinfotpl_book_place-of-publication' , tag='wm-license-book-place-of-publication',  demo=          book, wrapper='%s'},
		{field='place_of_creation'    , id='fileinfotpl_art_creation_place'        , tag='place_of_creation',                     demo=art,            wrapper='%s'},
		{field='place_of_discovery'   , id='fileinfotpl_art_discovery_place'       , tag='place_of_discovery',                    demo=art,            wrapper='%s'},
		{field='object_history'       , id='fileinfotpl_art_object_history'        , tag='wm-license-artwork-object-history',     demo=art,            wrapper='%s'},
		{field='exhibition_history'   , id='fileinfotpl_art_exhibition_history'    , tag='exhibition_history',                    demo=art+photo,      wrapper='%s'},
		{field='credit_line'          , id='fileinfotpl_art_credit_line'           , tag='wm-license-artwork-credit-line',        demo=art,            wrapper='%s'},
		{field='inscriptions'         , id='fileinfotpl_art_inscriptions'          , tag='wm-license-artwork-inscriptions',       demo=art,            wrapper='%s'},
		{field='notes'                , id='fileinfotpl_art_notes'                 , tag='wm-license-artwork-notes',              demo=art+photo,      wrapper='%s'},
		{field='other_fields_3'},
		-- references, and sources
		{field='references'           , id='fileinfotpl_art_references'            , tag='wm-license-artwork-references',         demo=art+photo+book, wrapper='%s'},
		{field='authority'            , id='fileinfotpl_art_authority'             , tag='Q36524',                                demo=none,           wrapper='%s'},
		{field='source'               , id='fileinfotpl_src'                       , tag='wm-license-artwork-source',             demo=art,            wrapper='%s'}, -- source/photographer
		{field='source_'              , id='fileinfotpl_src'                       , tag='wm-license-information-source',         demo=    photo+book, wrapper='%s'}, -- source
		{field='nosource'             , id='fileinfotpl_nosrc'                     , tag='wm-license-information-source',         demo=none,           wrapper='%s'},
		{field='permission'           , id='fileinfotpl_perm'                      , tag=permission_tag,                          demo=art+photo+book, wrapper='%s'},
		{field='other_versions'       , id='fileinfotpl_ver'                       , tag='wm-license-information-other-versions', demo=art+photo+book, wrapper='%s'}, 
		{field='other_fields'},
		{field='camera_coord'},
	}
	for i=1,#param do
		table.insert(results, Build_html_row(param[i], args))
	end
	
	-- add material on the right: image, wikisource icon, etc.
	if args.image then 
		if args.image_page and args.image  then -- page parameter for DjVu and PDF files
			args.image = string.format('%s|page=%i', args.image, args.image_page)
		end
		if args.infobox=='book' then -- page parameter for DjVu and PDF files
			tag1 = mw.message.new( 'wm-license-book-start-this-book' ):inLanguage(args.lang):plain()
			tag2 = string.format('|thumb|[[:File:%s|%s]]', args.image, tag1)
		else
			tag2 = ''
		end
		local field = string.format('[[File:%s|250x250px|alt=image of artwork listed in title parameter on this page|class=photo%s]]', args.image, args.name or '', tag2) 
		local nRow = #results -- number of rows below 
		local line = string.format('<td rowspan="%i" style="width:200px; text-align: right;" id="fileinfotpl_creator_image"><div class="wpImageAnnotatorControl wpImageAnnotatorOff">%s</div></td></tr>\n\n', nRow, field) 
		results[2] = mw.ustring.gsub(results[2], "</tr>%s*$", line); -- attach image section to the right side of the table, by attaching to row #2
	end
	
	local templatestyles = mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:Information/styles.css' }
	}

	-- add table and outer layers
	local style = string.format('class="fileinfotpl-type-artwork vevent mw-content-%s" dir="%s"', dir, dir)
	results = string.format('<table %s>\n%s\n</table>\n', style, table.concat(results)) -- combine "results", an array of strings into a single string
	results = string.format('<div class="hproduct commons-file-information-table">\n%s\n%s\n</div>', templatestyles, results)
	return results
end


return p