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

local core     = require("Module:Core")
local artcore          = require("Module:Artwork/core")
local getDate          = require("Module:Wikidata date")._date                 -- used for processing of date properties
local getLabel         = require("Module:Wikidata label")._getLabel            -- used for creation of name based on Wikidata
local getSitelinks     = require("Module:Wikidata label")._sitelinks           -- 
local Art              = require('Module:Wikidata art')                        --
local authorityControl = require("Module:কর্তৃপক্ষ নিয়ন্ত্রণ (নতুন)")._authorityControl -- used for formatting of Authority control row
local alterName        = require("Module:Name")._name
local TitleFromWD      = require('Module:Title').wikidata_title                -- Lua code behind {{Title}} template
local Size             = require('Module:Size')._size                          -- Lua code behind {{Size}} template
local TagQS            = require('Module:TagQS')
local converter = require('মডিউল:ConvertDigit')
local work_forms = require('মডিউল:Work/form')
local work_genres = require('মডিউল:Work/genre')
local work_awards = require('মডিউল:Work/award')

local p = {}

local function getProperty(entity, prop)
	return (core.parseStatements(entity:getBestStatements( prop ), nil) or {nil})[1]
end

local function getBestProperties(entity, prop)
	return core.parseStatements(entity:getBestStatements( prop ), nil)
end

local function periodSpan(id, lang)
	local PeriodSpan = require('Module:Period')._periodSpan
	return PeriodSpan(id, lang)
end

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

local function nowiki(str) -- remove all the links
	if not str then
		return str
	end
	str = TagQS.removeTag(str, nil)
	str = mw.ustring.gsub(str, '%<abbr %</abbr%>', '')
	str = mw.ustring.gsub(str, "<[^>]*>", "")    -- remove all html tags from str
	str = mw.ustring.gsub(str, "'''", "")        -- remove bold 
	str = mw.ustring.gsub(str, "''", "")         -- remove italics
	str = mw.ustring.gsub(str, "%[%[[Ff]ile:[^%]]+%]%]", "") -- remove file icons
	str = mw.ustring.gsub(str, "%[%[[^|]*|", "") -- remove piped links, like "[[:en:test|"
	str = mw.ustring.gsub(str, "%[[hH][tT][tT][pP][sS]?://[^ ]+ ([^%]]*)%]", "%1")   -- remove URL links, like "[https://www.wikidata.org/wiki/Q2706250 xxxx] -> xxxx"
	str = mw.ustring.gsub(str, "%[%[", "" )      -- remove piped links, like "[["
	str = mw.ustring.gsub(str, "%]%]", "" )      -- remove piped links, like "]]"
	return str
end

-- ===========================================================================
-- === Adjust parameters related to books   ===
-- === and resolve potential aliases                                       ===
-- === INPUTS:                                                             ===
-- ===  * frame - contains imput parameters passed from the template       ===
-- === OUTPUTS:                                                            ===
-- ===  * args - cleaned up inputs                                         ===
-- ===========================================================================
local function header_customization(args0, data, args1)

	-- get author Wikidata ID based on Wikidata
	local creator_label, creator_id, creator_str, title_label, creator_tag
	if args0.wikidata then
		creator_id  = data.creator_id or data.author_id or data.architect_id or data.designer_id or data.editor_id or data.translator_id or data.illustrator_id  
		if creator_id then
			creator_label = getLabel(creator_id, args0.lang)
		end
		title_label = data.label -- create name based on Wikidata label
	end

	-- get author Wikidata ID based on commons
	if not creator_label then
		if args0.infobox=='artwork' then
			creator_id  = args0.artist_id or args0.author_id 
			creator_str = args0.artist or args0.author
		elseif args0.infobox=='photograph' then
			creator_id  = args0.photographer_id or args0.author_id 
			creator_str = args0.photographer or args0.author
		elseif args0.infobox=='book' then
			creator_id  = args0.author_id 
			creator_str = args0.author 
		end
		creator_tag = TagQS.readTag(creator_str or '', 'creator')
		if creator_tag then
			-- if author was "{{Creator:Meister Theoderich von Prag|circle of}}" than creator_id will be "P170|Q4233718|P1776|Q446631 "
			local res = {creator_tag:match("^P170%|Q4233718%|(P%d+)%|(Q%d+)$")}
			if res and res[1] and res[2]then 
				creator_label = getLabel(res[2], args0.lang)
				local LUT = {P1773='attributed to', P1774='workshop of', P1775='follower of', P1776='circle of', 
					P1777='manner of', P1779='possibly', P1780='school of', P1877='after'}			
				creator_label = alterName(LUT[res[1]], creator_label, args0.lang) -- call [[module:Name]] with the task
				if creator_label  == "name not supported" then 
					creator_label = nil
				end		
			end	
		elseif creator_id and creator_id:match("^Q%d+$") then
			creator_label = getLabel(creator_id, args0.lang)
		end
	end
	
	-- scrape labels from {{title}} template
	if not title_label and args0.title then
		local labels = {}
		for _, title in ipairs(TagQS.readTags(args0.title, 'label')) do
			local lang, label = mw.ustring.match(title, 'L(%w+)%|"([^"]+)"') 
			if lang and label then
				labels[lang]=label
			end
		end
		title_label = core.langSwitch(labels,args0.lang)
	end
	
	-- get title based on commons
	if not title_label and args0.title then
		title_label = nowiki(args0.title) 
	end
	
	-- if title too long than truncate it
	if title_label and #title_label>250 then 
		title_label = nil
	end
	if creator_label and #creator_label>150 then 
		creator_label = nil
	end
	
	-- combing author and title labels
	if creator_label and title_label then 
		local colon = mw.message.new( "Colon-separator" ):inLanguage(args0.lang):plain()
		args1.name = creator_label .. colon .. title_label
	else
		args1.name = title_label
	end 

	-- if we have a {{book}} template in file namespace and file of in PDF or DjVu than use it as image
	if args0.infobox=='book' and  args0.namespace==6 and args1.image==nil 
		and (args0.noimage==false or args1.image_page)
		and (args0.mimeType=='application/pdf' or args0.mimeType=='image/vnd.djvu')  then
		args1.image = args0.pagename
	end

	return args1
end

-- ===========================================================================
-- === Harvest Wikidata properties matching creator template fields        ===
-- === INPUTS:                                                             ===
-- ===  * itemID1 - item id or a q-code from the template                  ===
-- ===  * itemID2 - item id or a q-code from SDC                           ===
-- ===  * lang  - language id of the desired language                      ===
-- ===  * namespace - namespace number of the page calling the module      ===
-- ===========================================================================
local function harvest_wikidata(itemID1, itemID2, lang, namespace, infobox, pagename)
	local data = {} -- structure similar to "args" but filled with Wikidata data
	local cats = ''
	local frame = mw.getCurrentFrame()
	local entity = nil
	local itemID = itemID1 or itemID2
	if mw.wikibase and itemID then
		local LUT = {artwork='Artworks', photograph='Photographs', book='Books'}
		entity = mw.wikibase.getEntity(itemID)
		if not entity then
			 cats = string.format('[[Category:%s with bad Wikidata link]]', LUT[infobox])
		elseif entity.id~=itemID and itemID1 then
			 cats = string.format('[[Category:%s with redirected Wikidata link]]', LUT[infobox])
		end
	end
	if not entity then
		return data, cats
	end

	-- inception date: translated date and year number
	local d = getDate(entity, 'P571' , lang) -- inception date
	if d.str then
		data.date_, data.year = d.iso, d.year
		data.date = d.str .. core.editAtWikidata(entity.id, 'P571', lang)
	end

	-- publication date: translated date and year number
	local d = getDate(entity, 'P577' , lang) -- publication date
	if d.str then
		data.publication_date_, data.publication_year = d.iso, d.year
		data.publication_date = d.str .. core.editAtWikidata(entity.id, 'P577', lang)
        cats = cats .. '[[বিষয়শ্রেণী:' .. converter._main(tostring(data.publication_year)) .. ' খ্রিস্টাব্দে প্রকাশিত]]'
	end
	
	-- harvest string properties
	local Debug ={}
	local property = {P10='video', P18='image', P996='scan', P4896='model3D', P373='homecat', P51='audio',
		P2093='authorStr', P393='edition', P4714='image_page', P1957='wikisource_index',  P7420='framed_image',P478='volume' }
	for prop, field in pairs( property ) do
		data[field] = getProperty(entity, prop)
		data[prop]  = data[field] -- keep tract which properties were present at Wikidata
	end
	data.image = data.image or data.scan or data.video or data.model3D or data.framed_image
	data.image_page = tonumber(data.image_page)
	if data.edition then
		data.edition = data.edition .. core.editAtWikidata(entity.id, 'P393', lang)
	end
	
	-- harvest Q-code properties which are than converted from Q-number to labels (pick one)
	local property = { P189='place_of_discovery', P2079='technique',  P872='printer', 
	                   P136='genre', P921='subject', P179='series_title', P361='part_of',  
					   P629='edition_of', P1071='place_of_creation', P495='country_of_origin', P7937='form_of_creative_work', P166='award', }
	for prop, field in pairs( property ) do
		local id = getProperty(entity, prop)
		if id then 
			data[field] = getLabel(id, lang, "wikipedia") .. core.editAtWikidata(entity.id, prop, lang)
	        data[field .. '_id'] = id
		end
	end
	data.place_of_creation = data.place_of_creation or data.country_of_origin
	
	-- harvest Q-code properties which are than converted from Q-number to labels (pick all)
	local property = { P31='object_type', P407='language', P123='publisher', P291='place_of_publication'}
	for prop, field in pairs( property ) do
		local ids = getBestProperties(entity, prop)
		if ids then 
			local T = {}
			for _, id in ipairs( ids ) do
				table.insert(T, getLabel(id, lang))
			end
			data[field] = table.concat(T, " / ") .. core.editAtWikidata(entity.id, prop, lang)
			data[field ..'_id'] = ids
		end
	end

	-- get era
	data.era_id = getBestProperties(entity, 'P2348')
	if data.era_id then
		local T = {}
		for _, id in ipairs( data.era_id ) do
			local eraText  = getLabel(id, lang)
			local spanText = periodSpan(id, lang)
			if spanText then
				eraText = eraText .. ' ' .. spanText
			end
			table.insert(T, eraText)
		end
		data.era = table.concat(T, " / ") .. core.editAtWikidata(entity.id, 'P2348', lang)
	end
	if data.era and data.date then
		data.date = data.date .. "<br/>" .. data.era
	elseif data.era and not data.date then
		data.date = data.era
	end
	
	-- get author and/or author creator template
	local property = { P170='creator', P50='author', P84='architect', P287='designer', P98='editor', 
		P655='translator', P110='illustrator', P2679='author_of_foreword', P2680='author_of_afterword' }   
	for prop, field in pairs( property ) do
		local d = Art.get_creator(entity, prop, lang)
		data[field] = d.str 
		data[field.."_id"] = d.id
		data[field.."_IDs"] = d.IDs
	end
	data.author = data.author or data.authorStr      -- P2093='author name string'

	-- get title (from 3 properties and label)
	--local property = { P1476 = 'title', P1448='official_name', P1705='native_label', P1680='subtitle'}
	local property = { P1476 = 'title', P1680='subtitle'}
	for prop, field in pairs( property ) do
		local title = {}
		for _, statement in pairs( entity:getBestStatements(field)) do 
			if (statement.mainsnak.snaktype == "value") then 
				local val = statement.mainsnak.datavalue.value
				title[val.language] = val.text -- look for multiple values each with a language code
			end
		end
		if #title>0 then
			data[field] = core.langSwitch(title, lang)
		end
		if field=='title' then
			data.title_ = title
		end
	end
	--data.title = data.title or data.official_name or data.native_label
	data.title = TitleFromWD(entity, lang)
	data.label = getLabel(entity, lang)
	
	-- get labels in all the languages
	data.labels = {}
	if entity.labels then
		for lang, val in pairs(entity.labels) do -- loop over all labels
			data.labels[lang] = val.value;
			data.label = data.label or data.labels[lang] -- no label in preferred language so grab any label
		end
	end
	-- get labels in all the languages
	data.descriptions = {}
	if entity.descriptions then
		for lang, val in pairs(entity.descriptions) do -- loop over all descriptions
			data.descriptions[lang] = 1; -- just record if it is present or not
		end
	end
	
	-- get authority control (rarely used for artworks)
	local AC_cats
	data.authority, AC_cats = authorityControl(entity, {wikidata = itemID}, lang, 5) 
	local _,nIdentifiers = string.gsub(data.authority, "*", "")
	if nIdentifiers<=1 then
		data.authority, AC_cats = nil, ''
	end
	if not (namespace == 2 or namespace == 828 or math.fmod(namespace,2)==1) then
		cats = cats .. AC_cats -- lets not add authorityControl categories to user pages, modules or talk pages and concentrate on templates and categories instead
	end
	
	-- get object location
	if getProperty(entity, 'P625') or getProperty(entity, 'P9149') then
		local coorFun = require('Module:Coordinates')._LocationTemplateCore
		local coori18n = require('Module:i18n/coordinates')
		data.coordinates = coorFun({wikidata=entity, lang=lang, globe='earth', mode='object', bare=true})
	end
	
	-- prepare fallback list of languages
	local langList = mw.language.getFallbacksFor(lang)
	table.insert(langList, 1, lang)
	
	-- get wikisource or wikiquote
	local projects = {s='wikisource', q='wikiquote'}
	for code, project in pairs(projects) do
		local sitelinks = getSitelinks(entity, project)
		if sitelinks then
			local lng, _ = next(sitelinks)    -- get language of the first sitelink
			table.insert(langList, lng) -- and add it to the list	so there is at least one lang with sitelink on the list
			for _, language in ipairs(langList) do 
				local sitelink = sitelinks[language]
				if sitelink then 
					data[project] = string.format('%s:%s:%s', code, language, sitelink)
					break 
				end
			end
		end
	end
	-- if no wikisource sitelink than use P1957 'wikisource_index' property
	-- wikisource_index is in full url format (like https://es.wikisource.org/wiki/%C3%8Dndice:Sonetos_-_Leopoldo_Diaz.pdf) 
	-- instead of interlink format (like s:es:%C3%8Dndice:Sonetos_-_Leopoldo_Diaz.pdf) 
	data.wikisource = data.wikisource or data.wikisource_index 

	-- properties with functions
	data.object_history     = Art.get_object_history(entity, lang)     -- object history
	data.exhibition_history = Art.get_exhibition_history(entity, lang) -- exhibition.history
	data.inscriptions       = Art.get_inscription(entity, lang)
	data.medium             = Art.get_medium(entity, lang)
	data.medium             = empty2nil(data.medium) or data.technique; 
	data.references         = Art.get_references(entity, lang)
	data.other_versions     = Art.get_other_versions(entity, pagename)
	local X                 = Art.get_depicted(entity, lang)
	data.depicted_people    = X[1]
	data.description        = X[2] -- depicted artistic or religious themes
	X                       = Art.get_accession_number(entity, lang)
	data.id                 = X.str -- wikitext version of the accession number 
	data.id_id              = X.id  -- one of accession numbers, which will be used as a sortkey
	X                       = Art.get_institution(entity, lang)	
	data.institution        = X.institution
	data.institution_id     = X.id
	data.department         = X.location
	data.dimensions         = Size({entity=entity}, nil, nil, lang)
	data.dimensions         = empty2nil(data.dimensions); 

	return data, cats
end

-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p.create_infobox(args0)
	local lang = args0.lang  -- user's language
	local cats, cats1, cats2 = '', '', ''         -- categories 
	local str, data, sdc
	
	-- ===========================================================================
	-- === Step 1: clean up of template arguments "args0"
	-- ===========================================================================
	args0 = artcore.clean_input_parameters(args0)
	if not args0.wikidata and args0.namespace==14 then
		local entity = mw.wikibase.getEntity()
		if entity then -- category page connected to Wikidata through a sitelink
			args0.wikidata = entity.id
			cats1 = '[[Category:Artwork categories with sitelinks to Wikidata]]'
			local qid = getProperty(entity, 'P301') -- follow wikidata's item redirect-like properties
			if qid then -- item had "category's main topic (P301)" -> use it
				args0.wikidata = qid
			end
		end
	end
	
	-- ===========================================================================
	-- === Step 2: one by one merge Wikidata and creator data
	-- ===========================================================================
	local wikidata_temp = args0.wikidata -- Wikidata from template
	sdc = {}

    args0.no_sdc = 1 -- TODO: come back to this
	if not args0.no_sdc and args0.namespace==6 then -- if file namespace
		sdc, cats2 = harvest_SDC(args0, lang) -- harvest Structured Data on Commons
		if (args0.sdc_source==false) or (args0.source) then
			-- get source from SDC only if this is NOT the artwork infobox of {{Art Photo}} template
			-- also skip sdc.source if we have args0.source, otherwise we might and up with 2 source fields
			sdc.source_ = nil
			args0.sdc_source = nil -- not needed anymore
		end
		args0.source_    = args0.source_    or sdc.source_    -- if source not provided than get it from SDC
		args0.wikidata   = args0.wikidata   or sdc.wikidata   -- if Wikidata not provided than get it from P6243 ("digital representation of") 
		args0.image_page = args0.image_page or sdc.image_page -- title image page for multipage book files 
	end

	data, cats = harvest_wikidata(wikidata_temp, sdc.wikidata, lang, args0.namespace, args0.infobox, args0.pagename)
	cats = (cats or '') .. (cats1 or '') .. (cats2 or '')
    if data.author ~= nil then
        if data.author_id == 'Q4233718' then
            cats = cats .. '[[বিষয়শ্রেণী:অজ্ঞাত লেখক রচিত]]'
        elseif #data.author_IDs > 1 then
            for i, idobj in pairs(data.author_IDs) do
                cats = cats .. '[[বিষয়শ্রেণী:' .. mw.wikibase.getLabel(idobj.itemID, lang) .. ' রচিত]]'
            end
        else
            cats = cats .. '[[বিষয়শ্রেণী:' .. mw.wikibase.getLabel(data.author_id, lang) .. ' রচিত]]'
        end
    end
    if data.translator ~= nil then
        if data.translator_id == 'Q4233718' then
            cats = cats .. '[[বিষয়শ্রেণী:অজ্ঞাত লেখক অনূদিত]] [[বিষয়শ্রেণী:অনুবাদ সাহিত্য]]'
        elseif #data.translator_IDs > 1 then
            for i, idobj in pairs(data.translator_IDs) do
                cats = cats .. '[[বিষয়শ্রেণী:' .. mw.wikibase.getLabel(idobj.itemID, lang) .. ' অনূদিত]] [[বিষয়শ্রেণী:অনুবাদ সাহিত্য]]'
            end
        else
            cats = cats .. '[[বিষয়শ্রেণী:' .. mw.wikibase.getLabel(data.translator_id, lang) .. ' অনূদিত]] [[বিষয়শ্রেণী:অনুবাদ সাহিত্য]]'
        end
    end
    if data.publisher ~= nil then
        for i, publisher_id in pairs(data.publisher_id) do
            cats = cats .. '[[বিষয়শ্রেণী:' .. mw.wikibase.getLabel(publisher_id, lang) .. ' দ্বারা প্রকাশিত]]'
        end
    end
    if data.edition_of ~= nil then
        local edition_of = mw.wikibase.getEntity(data.edition_of_id)
        local edition_of_genre = edition_of:getBestStatements('P136')
        local edition_of_form = edition_of:getBestStatements('P7937')
        local edition_of_award = edition_of:getBestStatements('P166')
        if edition_of_genre[1] ~= nil and work_genres[edition_of_genre[1].mainsnak.datavalue.value.id] ~= nil then
            cats = cats .. '[[বিষয়শ্রেণী:' .. work_genres[edition_of_genre[1].mainsnak.datavalue.value.id] .. ']]'
        end
        if edition_of_form[1] ~= nil and work_forms[edition_of_form[1].mainsnak.datavalue.value.id] ~= nil then
            cats = cats .. '[[বিষয়শ্রেণী:' .. work_forms[edition_of_form[1].mainsnak.datavalue.value.id] .. ']]'
        end
        if edition_of_award[1] ~= nil and work_awards[edition_of_award[1].mainsnak.datavalue.value.id] ~= nil then
            cats = cats .. '[[বিষয়শ্রেণী:' .. work_awards[edition_of_award[1].mainsnak.datavalue.value.id] .. ']]'
        end
    end
	-- based on the template type determine the meaning of "creator" 
	if args0.infobox=='book' then
		--data.author, data.author_id = data.creator, data.creator_id
	end
	
	-- mass merge (prioritize local values)  
	local args = {}
	local fields = { 'artist', 'artist_id', 'author', 'author_id', 'architect', 'designer', 'illustrator', 
		'publisher', 'editor', 'translator', 'printer', 'photographer', 'photographer_id', 'wikisource', 'wikiquote',
		'title', 'object_type', 'authority',  'image', 'id', 'homecat', 'coordinates', 'genre', 'subject', 'image_page',
		'date', 'medium', 'name', 'depicted_people', 'depicted_place', 'place_of_creation', 'place_of_discovery', 
		'dimensions', 'institution', 'department', 'references', 'object_history', 	'exhibition_history',  'inscriptions', 	
        'place_of_publication', 'publication_date', 'language', 'subtitle', 'series_title', 'volume', 'edition', 'edition_of',
		'author_of_foreword', 'author_of_afterword','description','other_versions', 'part_of'
	}
	for _, field in ipairs( fields ) do 
		args[field] = args0[field] or data[field]
	end
	-- copy fields only defined locally
	local fields = { 'wikidata', 'original_description_info', 'original_description', 'biased', 'camera_coord', 'depicted_part',
		'source', 'source_', 'strict',  'permission', 'demo', 'lang', 'notes', 'credit_line', 'linkback', 'pageoverview', 
		'other_fields', 'other_fields_1', 'other_fields_2', 'other_fields_3', 'wikidata_cat', 'namespace', 'infobox', 'demo_image',
		'no_qs'
	}
	for _, field in ipairs( fields ) do 
		args[field] = args0[field] 
	end

	if args.artist_id and #args.artist_id>1 and args.artist_id==args.author_id and data.artist_id~=data.author_id then
		-- args.artist_id is string so #args.artist_id is string length. data.artist_id!=data.author_id is to make sure
		-- both _ids are not coming from Wikidata. Might need to also skip if args0.author has content other than creator template
		args.author, args.author_id = nil, nil; -- if artist and author are the same than drop one
		cats = cats .. '[[Category:Artworks with the same artist and author]]\n'
	end
	if args0.infobox=='artwork' and args0.photo_date and args0.photographer then
		cats = cats .. '[[Category:Artworks with photograph information]]\n' 
	end	
	if args0.infobox=='book' and args0.publication_date and data.date then
		-- some magazines have local publication date for specific issue and inception date on Wikidata for the 
		-- magazine (publication of the first issue) -> ignore the inception date
		args.date = nil 
	end
	
	-- look for cases where a field like "photographer" has a single creator template with a role
	-- "photographer" stated in front of it -> strip the role.
	local LUT = { Q483501='artist', Q482980='author', Q42973='architect', Q5322166='designer', 
		Q1607826='editor', Q333634='translator', Q644687='illustrator', Q33231='photographer' }    
	for item, field in pairs( LUT ) do
		if args[field] and args[field .. '_id'] then 
			local tag = TagQS.createTag('creator_role', nil, item)
			local start, finish = mw.ustring.find( args[field], tag, 1, true )
			if start then -- remove "<b>...</b>: " + tag
				-- split the string in 2 using the tag as a divider
				local str1 = mw.ustring.sub( args[field], 1, start-1 ) 
				local str2 = mw.ustring.sub( args[field],   finish+1 )
				-- remove bold text at the end of str1
				local str1 = mw.ustring.gsub( str1, "'''.*''': $" , '' ) 
				args[field] = str1 .. str2 -- splice 2 halfs
			end
		end
	end

	-- internationalize local object_type string
	if args0.object_type and args.object_type==args0.object_type then
		local objectType = require('Module:I18n/objects')._object
		args.object_type = objectType(args.object_type, nil, lang)
	end	

	-- convert all empty strings to nils
	for _, field in ipairs( fields ) do 
		if args[field] == '' then 
			args[field] = nil; 
		end
	end
	
	-- ===========================================================================
	-- === Step 3: create maintenance categories and render html of the table
	-- ===========================================================================
	args = header_customization(args0, data, args)

    -- TODO: come back to the next five commented lines
	-- cats = cats .. add_maintenance_categories(args0, args)
	args.QS = nil;
	-- if not args0.no_sdc then
	--	cats2, args = add_wikidata_maintenance_categories(args0, args, data)
	--	cats = cats .. cats2
	-- end
    sdc.artwork_types = {}
	if args0.wikidata and (args0.wikidata ~='CREATE') and (args.namespace==6) and not (sdc.digital_representation_of or sdc.main_subject) then
		if data.object_type_id then
			for _, typeId in ipairs( data.object_type_id ) do
				local artwork_type = sdc.artwork_types[typeId]
				if artwork_type == '2D' then
					cats = string.format('%s\n[[Category:Artworks missing digital representation of for 2D work |%s]]', cats, args0.wikidata)
				elseif artwork_type == '3D' then
					cats = string.format('%s\n[[Category:Artworks missing main subject for 3D work|%s]]', cats, args0.wikidata)
				-- Can add the other types here later
				end
			end
		end
	end

	local results = artcore.build_html(args)
	return results, cats
end	

function p.book(frame)
	local args = artcore.read_input_parameters(frame)
    args.lang = 'bn'
	args.infobox               = 'book'
	args.demo_image            = 'Placeholder book.svg'
	args.strict                = false
	args.place_of_publication  = args.place_of_publication or args.city -- book specific aliases
	args.publication_date      = args.publication_date or args.date
	args.source_               = args.source or args.source_
	if args.isbn or args.lccn or args.oclc or args.bnf then
		local auth_args = { ISBN=args.isbn, LCCN=args.lccn, OCLC=args.oclc, BNF=args.bnf, bare=1 }
		args.authority = frame:expandTemplate{ title = 'Book authority control', args=auth_args }
		args.isbn, args.lccn, args.oclc, args.bnf = nil, nil, nil, nil
	end	
	args.source, args.city, args.date  = nil, nil, nil
	local results, cats = p.create_infobox(args) -- call the inner "core" function	 
	return results .. cats
end

return p