Module:Artwork/core

--[[   __  __           _       _           _         _                      _        __                  |  \/  | ___   __| |_   _| | ___ _   / \   _ __| |___      _____  _ __| | __   / /__ ___  _ __ ___  | |\/| |/ _ \ / _` | | | | |/ _ (_) / _ \ | '__| __\ \ /\ / / _ \| '__| |/ /  / / __/ _ \| '__/ _ \ | |  | | (_) | (_| | |_| | |  __/_ / ___ \| |  | |_ \ 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: ]] 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 = {}
 * User:Jarekt - original version

-- 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 cell. if IDs of 2 fields are the same than we ignore the second one --   - wrapper  - some fields need a 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('%s \n', param.id, args.lang, tag) local cell2 = string.format(' \n'.. param.wrapper ..' ', field or '') return string.format(' \n%s%s\n \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(' %s ', dir, args.original_description_info) end if args.biased then tag2 = core.langSwitch(labels.inaccurate_description, args.lang) tag2 = string.format(' %s: %s ', 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(' %s\n ', args.name ) ) end if args.linkback then -- Wikidata Link table.insert(top, string.format('', args.linkback, args.linkback) ) end if args.wikidata then -- Wikidata Link table.insert(top, string.format('', args.wikidata, args.wikidata) ) table.insert(top, string.format('', args.wikidata, args.wikidata) ) end if args.wikisource then --Wikisource link table.insert(top, string.format('', args.wikisource, args.wikisource) ) end if args.wikiquote then --Wikiquote link table.insert(top, string.format('', 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('%s ', nCol, table.concat(top, ' ')) table.insert(results, string.format(' \n%s\n \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 (%s) ", tag1, tag2, tag3) -- define constants for readability -- demo=art+photo+book will show that row in demo mode in {{artwork}, and  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=' \n%s '}, {field='author'             , id='fileinfotpl_aut'                       , tag='wm-license-information-author',         demo=          book, wrapper=' \n%s '}, {field='editor'             , id='fileinfotpl_book_editor'               , tag='wm-license-book-editor',                demo=          book, wrapper=' \n%s '}, {field='translator'         , id='fileinfotpl_book_translator'           , tag='wm-license-book-translator',            demo=          book, wrapper=' \n%s '}, {field='illustrator'        , id='fileinfotpl_book_illustrator'          , tag='wm-license-book-illustrator',           demo=          book, wrapper=' \n%s '}, {field='author_of_foreword' , id='fileinfotpl_aut'                       , tag='P2679',                                 demo=          book, wrapper=' \n%s '}, {field='author_of_afterword', id='fileinfotpl_aut'                       , tag='P2680',                                 demo=          book, wrapper=' \n%s '}, {field='architect'          , id='fileinfotpl_aut'                       , tag='Q42973',                                demo=none,           wrapper=' \n%s '}, {field='designer'           , id='fileinfotpl_aut'                       , tag='Q5322166',                              demo=none,           wrapper=' \n%s '}, {field='photographer'       , id='fileinfotpl_aut'                       , tag='Q33231',                                demo=    photo,      wrapper=' \n%s '}, {field='other_fields_1'}, -- title & desctiption block {field='title'              , id='fileinfotpl_art_title'                 , tag='wm-license-artwork-title',              demo=art+photo+book, wrapper=' \n%s '}, {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=' \n%s '}, {field='printer'            , id='fileinfotpl_book_printer'              , tag='wm-license-book-printer',               demo=          book, wrapper=' \n%s '}, {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=' \n%s '}, {field='description'        , id='fileinfotpl_desc'                      , tag='wm-license-information-description',    demo=art+photo+book, wrapper=' \n%s '}, {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=' \n%s '}, {field='id'                 , id='fileinfotpl_art_id'                    , tag='wm-license-artwork-id',                 demo=art+photo,      wrapper=' \n%s '}, {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|%s', args.image, tag1) else tag2 = '' end local field = string.format(, args.image, args.name or , tag2) local nRow = #results -- number of rows below local line = string.format(' %s  \n\n', nRow, field) results[2] = mw.ustring.gsub(results[2], " %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(' \n', style, table.concat(results)) -- combine "results", an array of strings into a single string results = string.format(' \n%s\n%s\n ', 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, 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 .. ''			cats = cats .. string.format('\n; Error in template: unknown parameter "%s". ', 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 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 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 and  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 and  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