Module:Artwork/core

From WWII Archives

Documentation for this module may be created at Module:Artwork/core/doc

--[[  
  __  __           _       _           _         _                      _        __                 
 |  \/  | ___   __| |_   _| | ___ _   / \   _ __| |___      _____  _ __| | __   / /__ ___  _ __ ___ 
 | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ /  / / __/ _ \| '__/ _ \
 | |  | | (_) | (_| | |_| | |  __/_ / ___ \| |  | |_ \ V  V / (_) | |  |   <  / / (_| (_) | | |  __/
 |_|  |_|\___/ \__,_|\__,_|_|\___(_)_/   \_\_|   \__| \_/\_/ \___/|_|  |_|\_\/_/ \___\___/|_|  \___|
                                                                                                                                                                               
This submodule is intended for converting inputs into html.

Please do not modify this code without applying the changes first at 
"Module:Artwork/sandbox" and testing at "Template:
/testcases".

Authors and maintainers:
* User:Jarekt - original version 
]]
require('strict') -- used for debugging purposes as it detects cases of unintended global variables
local getLabel = require("Module:Wikidata label")._getLabel            -- used for creation of name based on Wikidata
local core     = require("Module:Core")
local labels   = require("Module:I18n/artwork")                        -- internationalization of labels
local bit32    = require("bit32")
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 p = {}

-- Lazy loading function: load them only if they are needed
local function ObjectLocation_label()
	return mw.loadData('Module:i18n/coordinates').ObjectLocation
end

local function Creator(args)
	return require("Module:Creator")._creator(args)
end

local function Institution(args)
	return require("Module:Institution")._institution(args)
end

-- ==================================================
-- === Internal functions ===========================
-- ==================================================

-------------------------------------------------------------------------------
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

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

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

-- ====================================================================
-- 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


-- ====================================================================
-- === 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='P195',                                  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

-- ===========================================================================
-- === 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

-- ===========================================================================
function p.verify_input_parameters(args)
	local cats = '' -- categories 
	
	-- add [[Category:Creator templates with unknown parameter]] category, if some parameter not on the following list is used
	local fields = { 'title', 'object_type', 'description', 'date', 'medium', 'permission', 
		'artist', 'author', 'architect', 'designer', 'illustrator', 'publisher', 'editor', 'translator', 'printer', 'photographer', 
		'dimensions',  'institution', 'department',  'references', 'object_history', 'genre',
		'exhibition_history', 'credit_line', 'other_versions', 'source', 'strict', 'inscriptions', 'notes', 'linkback', 'camera_coord',
		'other_fields', 'other_fields_1', 'other_fields_2', 'other_fields_3',  'demo', 'id', 'wikidata', 'year', 'homecat', 'authority',
		'place_of_creation', 'place_of_discovery', 'source_', 'wikidata_cat', 'namespace', 'lang', 'image', 'noimage', 
		'depicted_people', 'depicted_place', 'original_description_info', 'original_description', 'biased', 'photo_date', 'infobox',
		'place_of_publication', 'publication_date', 'language', 'subtitle', 'series_title', 'volume', 'edition', 'edition_of', 
		'pageoverview', 'wikisource', 'wikiquote', 'demo_image', 'image_page', 'depicted_part', 'mimeType', 'num_pages', 
		'author_of_foreword', 'author_of_afterword', 'infobox', 'no_qs', 'no_sdc', 'part_of'
	}
	local set = {}
	for _, field in ipairs(fields) do set[field] = true end
	for field, _ in pairs( args ) do 
		if not set[field] then
			local LUT = {artwork='Artwork', photograph='Photograph', book='Book'}
			local infobox = LUT[args.infobox]
			cats = cats .. '[[Category:Pages using ' .. infobox .. ' template with incorrect parameter]]'
			cats = cats .. string.format('\n;<span style="color:red">Error in [[Template:%s|{{%s}} template]]: unknown parameter "%s".</span>', infobox, infobox, field)
		end
	end 
	return cats
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
	if args.source and mw.ustring.find( args.source, 'www%.wga%.hu' ) then
		-- code to help copy links to www.wga.hu to Wikidata
		args.reference_wga = string.gsub(args.source, 'http://www%.wga%.hu', 'https://www.wga.hu')
	end
	return args
end

-- ===========================================================================
function p.test(frame)
	local args  = p.read_input_parameters(frame)
	args.infobox = 'artwork'
	local cats0 = p.verify_input_parameters(args)
	args  = p.clean_input_parameters(args)
	return p.build_html(args)
end

return p