-- settings, may differ from project to project -- taken and adapted from ruwiki local fileDefaultSize = '267x400px'; local outputReferences = true; local moduleSources = require( 'Module:Sources' ) local WDS = require( 'Module:WikidataSelectors' ); local contentLanguageCode = mw.getContentLanguage():getCode(); local p = {}; local config = nil; local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, formatProperty, getSourcingCircumstances, getPropertyDatatype, getPropertyParams, throwError, toBoolean; local function copyTo( obj, target, skipEmpty ) for k, v in pairs( obj ) do if skipEmpty ~= true or ( v ~= nil and v ~= '' ) then target[k] = v; end end return target; end local function min( prev, next ) if ( prev == nil ) then return next; elseif ( prev > next ) then return next; else return prev; end end local function max( prev, next ) if ( prev == nil ) then return next; elseif ( prev < next ) then return next; else return prev; end end local function getConfig( section, code ) if config == nil then config = require( 'Module:Wikidata/config' ); end; if not config then config = {}; end if not section then return config; end if not code then return config[ section ] or {}; end if not config[ section ] then return nil; end return config[ section ][ code ]; end local function getCategoryByCode( code, sortkey ) local value = getConfig( 'categories', code ); if not value or value == '' then return ''; end if sortkey ~= nil then return '[[Category:' .. value .. '|' .. sortkey .. ']]'; else return '[[Category:' .. value .. ']]'; end end local function splitISO8601(str) if 'table' == type(str) then if str.args and str.args[1] then str = '' .. str.args[1] else return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) end end local Y, M, D = (function(str) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local Y, M, D = mw.ustring.match( str, pattern ) return tonumber(Y), tonumber(M), tonumber(D) end) (str); local h, m, s = (function(str) local pattern = "T(%d+):(%d+):(%d+)%Z"; local H, M, S = mw.ustring.match( str, pattern); return tonumber(H), tonumber(M), tonumber(S); end) (str); local oh,om = ( function(str) if str:sub(-1)=="Z" then return 0,0 end; -- ends with Z, Zulu time -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$"; local sign, oh, om = mw.ustring.match( str, pattern); sign, oh, om = sign or "+", oh or "00", om or "00"; return tonumber(sign .. oh), tonumber(sign .. om); end )(str) return {year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}; end local function parseTimeBoundaries( time, precision ) local s = splitISO8601( time ); if (not s) then return nil; end if ( precision >= 0 and precision <= 8 ) then local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 } local power = powers[ precision + 1 ]; local left = s.year - ( s.year % power ); return { tonumber(os.time( {year=left, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber(os.time( {year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58} )) * 1000 + 1999 }; end if ( precision == 9 ) then return { tonumber(os.time( {year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber(os.time( {year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 }; end if ( precision == 10 ) then local lastDays = {31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; local lastDay = lastDays[s.month]; return { tonumber(os.time( {year=s.year, month=s.month, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber(os.time( {year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58} )) * 1000 + 1999 }; end if ( precision == 11 ) then return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0} )) * 1000, tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58} )) * 1000 + 1999 }; end if ( precision == 12 ) then return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0} )) * 1000, tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58} )) * 1000 + 1999 }; end if ( precision == 13 ) then return { tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0} )) * 1000, tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58} )) * 1000 + 1999 }; end if ( precision == 14 ) then local t = tonumber(os.time( {year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0} ) ); return { t * 1000, t * 1000 + 999 }; end error('Unsupported precision: ' .. precision ); end local function extractCategory( options, value ) if ( not options.category or options.nocat ) then return ''; end local propertyId = string.gsub( options.category, '([^Pp0-9].*)$', ''); local wbStatus, claims = pcall( mw.wikibase.getAllStatements, value.id, propertyId ); if ( wbStatus ~= true or not claims ) then return ''; end allClaims = {} allClaims[ propertyId ] = claims claims = WDS.filter( allClaims, options.category ) if not claims then return ''; end for _, claim in pairs( claims ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' ) then local catEntityId = claim.mainsnak.datavalue.value.id; local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId ); if ( wbStatus == true and catSiteLink ) then return '[[' .. catSiteLink .. ']]'; end end end return ''; end local function toBoolean( valueToParse, defaultValue ) if ( valueToParse ~= nil ) then if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then return false end return true end return defaultValue; end -- @param value String value -- @param attributes Table of attributes -- @return string HTML tag with value local function wrapValue( value, attributes ) local tagName = 'span'; local spacer = ''; if ( string.match( value, '\n' ) or string.match( value, '<t[dhr][ >]' ) or string.match( value, '<div[ >]' ) or string.find( value, 'UNIQ%-%-imagemap' ) ) then tagName = 'div'; spacer = '\n' end local attrString = '' for key, value in pairs( attributes or {} ) do local _key = mw.text.trim( key ) local _value = mw.text.encode( mw.text.trim( value ) ) attrString = attrString .. _key .. '="' .. _value .. '" ' end return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>'; end -- Wraps formatted snak value into HTML tag with attributes. -- @param value String value of snak -- @param hash Snak hash -- @param attributes Table of extra attributes -- @return string HTML tag with value local function wrapSnak( value, hash, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes['class'] = ( newAttributes['class'] or '' ) .. ' wikidata-snak' if hash then newAttributes['data-wikidata-hash'] = hash else newAttributes['class'] = newAttributes['class'] .. ' wikidata-main-snak' end return wrapValue( value, newAttributes ) end -- Wraps formatted statement value into HTML tag with attributes. -- @param value String value of statement -- @param propertyId String PID of property -- @param claimId String ID of claim or nil for local value -- @param attributes Table of extra attributes -- @return string HTML tag with value local function wrapStatement( value, propertyId, claimId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes['class'] = newAttributes['class'] or '' newAttributes['data-wikidata-property-id'] = string.upper( propertyId ) if claimId then newAttributes['class'] = newAttributes['class'] .. ' wikidata-claim' newAttributes['data-wikidata-claim-id'] = claimId else newAttributes['class'] = newAttributes['class'] .. ' no-wikidata' end return wrapValue( value, newAttributes ) end -- Wraps formatted qualifier's statement value into HTML tag with attributes. -- @param value String value of qualifier's statement -- @param propertyId String PID of qualifier -- @param attributes Table of extra attributes -- @return string HTML tag with value local function wrapQualifier( value, qualifierId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes['data-wikidata-qualifier-id'] = string.upper( qualifierId ) return wrapValue( value, newAttributes ) end local function getEntityFromId( id ) local entity; local wbStatus; if id then wbStatus, entity = pcall( mw.wikibase.getEntityObject, id ) else wbStatus, entity = pcall( mw.wikibase.getEntityObject ); end return entity; end local function throwError( key ) error( getConfig( 'errors', key ) ); end local function getEntityIdFromValue( value ) local prefix = '' if value['entity-type'] == 'item' then prefix = 'Q' elseif value['entity-type'] == 'property' then prefix = 'P' else throwError( 'unknown-entity-type' ) end return prefix .. value['numeric-id'] end local function getUserFunction( options, prefix, defaultFunction ) if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then throwError( 'unknown-' .. prefix .. '-module' ); end local formatter = require( 'Module:' .. options[ prefix .. '-module' ] ); if formatter == nil then throwError( prefix .. '-module-not-found' ) end local fun = formatter[ options[ prefix .. '-function' ] ] if fun == nil then throwError( prefix .. '-function-not-found' ) end return fun; end return defaultFunction; end local function selectClaims( context, options, propertySelector ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity is missing' ); end; if ( not propertySelector ) then error( 'propertySelector not specified' ); end; result = WDS.filter( options.entity.claims, propertySelector ); if ( not result or #result == 0 ) then return nil; end if options.limit and options.limit ~= '' and options.limit ~= '-' then local limit = tonumber( options.limit, 10 ); while #result > limit do table.remove( result ); end end return result; end local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) if (type(entityId) ~= 'string') then error('type of entityId argument expected string, but was ' .. type(entityId)); end local results = {}; if not propertyIds or #propertyIds == 0 then return results; end for _, propertyId in ipairs( propertyIds ) do local selector = selectors[_]; local propertyClaims = mw.wikibase.getAllStatements( entityId, propertyId ); local fakeAllClaims = {}; fakeAllClaims[propertyId] = propertyClaims; local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' ); if filteredClaims then for _, claim in pairs( filteredClaims ) do if not boundaries then table.insert( results, claim.mainsnak ); else local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' ); local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' ); if ( (startBoundaries == nil or ( startBoundaries[2] <= boundaries[1])) and (endBoundaries == nil or ( endBoundaries[1] >= boundaries[2]))) then table.insert( results, claim.mainsnak ); end end end end if #results > 0 then break; end end return results; end function p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId ) -- only support exact date so far, but need improvement local left = nil; local right = nil; if ( statement.qualifiers and statement.qualifiers[qualifierId] ) then for _, qualifier in pairs( statement.qualifiers[qualifierId] ) do local boundaries = context.parseTimeBoundariesFromSnak( qualifier ); if ( not boundaries ) then return nil; end left = min( left, boundaries[1] ); right = max( right, boundaries[2] ); end end if ( not left or not right ) then return nil; end return { left, right }; end function p.getTimeBoundariesFromQualifiers( frame, context, statement, qualifierIds ) if not qualifierIds then qualifierIds = { 'P582', 'P580', 'P585' }; end for _, qualifierId in ipairs( qualifierIds ) do local result = p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId ); if result then return result; end end return nil; end local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode(); local getLabelWithLang_DEFAULT_PROPERTIES = {--[["P1813", "P1705",--]] "P1448"}; local getLabelWithLang_DEFAULT_SELECTORS = { --'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P3831,P3831:Q105690470]', --'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P3831,P3831:Q105690470]', 'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P3831,P3831:Q105690470]' }; local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors ) if (type(entityId) ~= 'string') then error('type of entityId argument expected string, but was ' .. type(entityId)); end if not entityId then return nil; end local langCode = CONTENT_LANGUAGE_CODE; -- name from label local label = nil; if ( options.text and options.text ~= '' ) then label = options.text; else if not propertyIds then propertyIds = getLabelWithLang_DEFAULT_PROPERTIES; selectors = getLabelWithLang_DEFAULT_SELECTORS; end -- name from properties local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ); for _, result in pairs( results ) do if result.datavalue and result.datavalue.value then if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then label = result.datavalue.value.text; langCode = result.datavalue.value.language; break; elseif result.datavalue.type == 'string' then label = result.datavalue.value; break; end end end if (not label) then label, langCode = mw.wikibase.getLabelWithLang( entityId); if not langCode then return nil; end end end return label, langCode; end local function formatPropertyDefault( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then if options.rank then claims = context.selectClaims( options, options.property .. options.rank ); else claims = context.selectClaims( options, options.property ); end end if claims == nil then return '' end local formattedClaims = {} for i, claim in ipairs(claims) do local formattedStatement = context.formatStatement( options, claim ) if ( formattedStatement and formattedStatement ~= '' ) then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) table.insert( formattedClaims, formattedStatement ) end end local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end -- create context local function initContext( options ) local context = { entity = options.entity, extractCategory = extractCategory, formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault, wrapSnak = wrapSnak, wrapStatement = wrapStatement, wrapQualifier = wrapQualifier, } context.cloneOptions = function( options ) local entity = options.entity; options.entity = nil; newOptions = mw.clone( options ); options.entity = entity; newOptions.entity = entity; newOptions.frame = options.frame; return newOptions; end; context.formatProperty = function( options ) local func = getUserFunction( options, 'property', context.formatPropertyDefault ); return func( context, options ) end; context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end; context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end; context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end; context.parseTimeFromSnak = function( snak ) if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time ) then return tonumber(os.time( splitISO8601( tostring( snak.datavalue.value.time ) ) ) ) * 1000; end return nil; end context.parseTimeBoundariesFromSnak = function( snak ) if ( snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision ) then return parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision ); end return nil; end context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end; context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end; return context end local function formatProperty( options ) local entity = getEntityFromId( options.entityId ) if not entity then return -- throwError( 'entity-not-found' ) end if (entity.claims == nil) then return '' --TODO error? end -- improve options options.frame = g_frame; options.entity = entity; options.extends = function( self, newOptions ) return copyTo( newOptions, copyTo( self, {} ) ) end if ( options.i18n ) then options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) ); else options.i18n = getConfig( 'i18n' ); end local context = initContext( options ); return context.formatProperty( options ); end function formatStatement( context, options, statement ) if ( not statement ) then error( 'statement is not specified or nil' ); end if not statement.type or statement.type ~= 'statement' then throwError( 'unknown-claim-type' ) end local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ); return functionToCall( context, options, statement ); end function getSourcingCircumstances( statement ) if (not statement) then error('statement is not specified') end; local circumstances = {}; if ( statement.qualifiers and statement.qualifiers.P1480 ) then for i, qualifier in pairs( statement.qualifiers.P1480 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' and qualifier.datavalue.value and qualifier.datavalue.value['entity-type'] == 'item' ) then table.insert(circumstances, qualifier.datavalue.value.id) end end end return circumstances; end function formatStatementDefault( context, options, statement ) if (not context) then error('context is not specified') end; if (not options) then error('options is not specified') end; if (not statement) then error('statement is not specified') end; local circumstances = context.getSourcingCircumstances( statement ); options.qualifiers = statement.qualifiers; local result = context.formatSnak( options, statement.mainsnak, circumstances ); local qualifierValues = {}; if ( options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ]) then qualConfig = getPropertyParams( options.qualifier, nil, {}) if options.i18n then qualConfig.i18n = options.i18n end for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do local snakValue = context.formatSnak( qualConfig, qualifierSnak ); if snakValue and snakValue ~= '' then table.insert( qualifierValues, snakValue ); end end if ( result and result ~= '' and #qualifierValues ) then if qualConfig.invisible then result = result .. table.concat( qualifierValues, ', ' ); else if not statement.qualifiers[ options.secondqualifier ] then result = result .. ' <span style="font-size:95\%">(' .. options.frame:expandTemplate{ title = 'bağlantıyı kes', args = {table.concat( qualifierValues, ', ' )}} .. options.qualifierseparator .. ')</span>'; else result = result .. ' <span style="font-size:95\%">(' .. options.frame:expandTemplate{ title = 'bağlantıyı kes', args = {table.concat( qualifierValues, ', ' )}}; end end end end if ( options.secondqualifier and statement.qualifiers and statement.qualifiers[ options.secondqualifier ]) then qualConfig = getPropertyParams( options.secondqualifier, nil, {}) if options.i18n then qualConfig.i18n = options.i18n end local secondqualifier = {}; for _, qualifierSnak in pairs( statement.qualifiers[ options.secondqualifier ] ) do local snakValue = context.formatSnak( qualConfig, qualifierSnak ); if snakValue and snakValue ~= '' then table.insert( secondqualifier, snakValue ); end end if ( result and result ~= '' and #secondqualifier ) then if qualConfig.invisible then result = result .. table.concat( secondqualifier, ', ' ); else if not statement.qualifiers[ options.qualifier ] then result = result .. ' <span style="font-size:95\%">(' .. options.qualifierseparator .. options.frame:expandTemplate{ title = 'bağlantıyı kes', args = {table.concat( secondqualifier, ', ' )}} .. ')</span>'; else result = result .. options.qualifierseparator .. options.frame:expandTemplate{ title = 'bağlantıyı kes', args = {table.concat( secondqualifier, ', ' )}} .. ')</span>'; end end end end if ( result and result ~= '' and options.references ) then result = result .. context.formatRefs( options, statement ); end return result; end function formatSnak( context, options, snak, circumstances ) circumstances = circumstances or {}; if snak.snaktype == 'somevalue' then if ( options['somevalue'] and options['somevalue'] ~= '' ) then result = options['somevalue']; else result = options.i18n['somevalue']; end elseif snak.snaktype == 'novalue' then if ( options['novalue'] and options['novalue'] ~= '' ) then result = options['novalue']; else result = options.i18n['novalue']; end elseif snak.snaktype == 'value' then result = formatDatavalue( context, options, snak.datavalue, snak.datatype ); for _, item in pairs(circumstances) do if options.i18n[item] then if result then result = options.i18n[item] .. result; end end end else throwError( 'unknown-snak-type' ); end if ( not result or result == '' ) then return nil; end return context.wrapSnak( result, snak.hash ) end local function formatGlobeCoordinate( value, options ) if options['subvalue'] == 'latitude' then -- широты return value['latitude'] elseif options['subvalue'] == 'longitude' then -- долготы return value['longitude'] elseif options['nocoord'] and options['nocoord'] ~= '' then return '' else coord_mod = require( "Module:Coordinates" ); local globe = options.globe or '' if globe == '' and value['globe'] then globes = require( 'Module:Wikidata/Globes' ) globe = globes[value['globe']] or '' end local display = 'inline' if options.display and options.display ~= '' then display = options.display elseif ( options.property:upper() == 'P625' ) then display = 'title' end local format = options.format or '' if format == '' then format = 'dms' if value['precision'] then local precision = value['precision'] * 60 if precision >= 60 then format = 'd' elseif precision >= 1 then format = 'dm' end end end g_frame.args = { tostring(value['latitude']), tostring(value['longitude']), globe = globe, type = options.type and options.type or '', scale = options.scale and options.scale or '', display = display, format = format, } return coord_mod.coord(g_frame) end end local function formatCommonsMedia( value, options ) local image = value; local caption = ''; if options[ 'caption' ] and options[ 'caption' ] ~= '' then caption = options[ 'caption' ]; end if caption ~= '' then caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ); end if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then image = '[[File:' .. value .. '|frameless'; if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border'; end local size = options[ 'size' ]; if size and size ~= '' then if not string.match( size, 'px$' ) then size = size .. 'px' end else size = fileDefaultSize; end image = image .. '|' .. size; if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ]; end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]'; if caption ~= '' then image = image .. '<br>' .. caption; end else image = image .. caption .. getCategoryByCode( 'media-contains-markup' ); end return image end local function formatMath( value, options ) return options.frame:extensionTag{ name = 'math', content = value }; end local function formatExternalId( value, options ) local formatter = options.formatter; if not formatter or formatter == '' then local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, options.property:upper() ) if wbStatus == true and propertyEntity then local isGoodFormat = false; local statements = propertyEntity:getBestStatements( 'P1793' ); for _, statement in pairs( statements ) do if statement.mainsnak.snaktype == 'value' then local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' ); pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' ); if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' ) or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then isGoodFormat = true; break; end end end if ( isGoodFormat == true ) then statements = propertyEntity:getBestStatements( 'P1630' ); for _, statement in pairs( statements ) do if statement.mainsnak.snaktype == 'value' then formatter = statement.mainsnak.datavalue.value; break end end end end end if formatter and formatter ~= '' then local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) local link = mw.ustring.gsub( mw.ustring.gsub( formatter, '$1', encodedValue ), '.', { [' '] = '%20', ['+'] = '%2b', ['['] = '%5B', [']'] = '%5D' } ) local title = options.title if not title or title == '' then title = '$1' end title = mw.ustring.gsub( mw.ustring.gsub( title, '$1', encodedValue ), '.', { ['['] = '(', [']'] = ')' } ) return '[' .. link .. ' ' .. title .. ']' end return value end local function formatQuantity( value, options ) local amount = string.gsub( value['amount'], '^%+', '' ); local lang = mw.language.getContentLanguage(); local langCode = lang:getCode(); local function formatNum( number, sigfig ) local multiplier = '' if options.countByThousands then local powers = options.i18n['thousandPowers'] local pos = 1 while math.abs(number) >= 1000 and pos < #powers do number = number / 1000 pos = pos + 1 end multiplier = powers[pos] if math.abs(number) >= 100 then sigfig = sigfig or 0 elseif math.abs(number) >= 10 then sigfig = sigfig or 1 else sigfig = sigfig or 2 end else sigfig = sigfig or 12 end local mult = 10^sigfig; number = math.floor( number * mult + 0.5 ) / mult; return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier; end local out = formatNum( tonumber( amount ) ); if value.upperBound then local diff = tonumber( value.upperBound ) - tonumber( amount ) if diff > 0 then local integer, dot, decimals, expstr = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' ) local prec if dot == '' then prec = -integer:match('0*$'):len() else prec = #decimals end bound = formatNum( diff, prec ) if string.match( bound, 'E%-(%d+)' ) then digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2 bound = formatNum( diff * 10 ^ digits, prec ) bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 ) end out = out .. ' ± ' .. bound end end if options.unit and options.unit ~= '' then if options.unit ~= '-' then out = out .. ' ' .. options.unit end elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' ); if unitEntityId ~= 'undefined' then local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ); if wbStatus == true and unitEntity then if unitEntity.claims.P2370 and unitEntity.claims.P2370[1].mainsnak.snaktype == 'value' and not value.upperBound and options.siConversion == true then conversionToSIunit = string.gsub( unitEntity.claims.P2370[1].mainsnak.datavalue.value.amount, '^%+', '' ); if math.floor( math.log10( conversionToSIunit )) ~= math.log10( conversionToSIunit ) then outValue = tonumber( amount ) * conversionToSIunit if ( outValue > 0 ) then local integer, dot, decimals, expstr = amount:match( '^(%d*)(%.?)(%d*)(.*)' ) local prec if dot == '' then prec = -integer:match('0*$'):len() else prec = #decimals end local adjust = math.log10( math.abs( conversionToSIunit )) + math.log10( 2 ) local minprec = 1 - math.floor( math.log10( outValue ) + 2e-14 ); out = formatNum( outValue, math.max( math.floor( prec + adjust ), minprec )); else out = formatNum( outValue, 0 ) end unitEntityId = string.gsub( unitEntity.claims.P2370[1].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' ); wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ); end end local writingSystemElementId = 'Q8209'; local langElementId = 'Q7737'; local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, { 'P5061[language:' .. langCode .. ']', 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']', 'P558[!P282][!P407]' } ); out = out .. ' ' .. label; end end end return out; end local function formatUrlValue( context, options, value ) if not options.length or options.length == '' then options.length = 25 end local moduleUrl = require( 'Module:URL/wikidata' ) return moduleUrl.formatUrlSingle( context, options, value ) end local DATATYPE_CACHE = {} --[[ Get property datatype by ID. @param string Property ID, e.g. 'P123'. @return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'. ]] local function getPropertyDatatype( propertyId ) if not propertyId or not string.match( propertyId, '^P%d+$' ) then return nil; end local cached = DATATYPE_CACHE[propertyId]; if (cached ~= nil) then return cached; end local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId ); if wbStatus ~= true or not propertyEntity then return nil; end mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' ) DATATYPE_CACHE[propertyId] = propertyEntity.datatype; return propertyEntity.datatype; end local function getDefaultValueFunction( datavalue, datatype ) if datavalue.type == 'wikibase-entityid' then -- Entity ID return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ) ) end; elseif datavalue.type == 'string' then -- String if datatype and datatype == 'commonsMedia' then -- Media return function( context, options, value ) return formatCommonsMedia( value, options ) end; elseif datatype and datatype == 'external-id' then -- External ID return function( context, options, value ) return formatExternalId( value, options ) end elseif datatype and datatype == 'math' then -- Math formula return function( context, options, value ) return formatMath( value, options ) end elseif datatype and datatype == 'url' then -- URL return formatUrlValue end return function( context, options, value ) return value end; elseif datavalue.type == 'monolingualtext' then return function( context, options, value ) if ( options.monolingualLangTemplate == 'lang' ) then if ( value.language == contentLanguageCode ) then return value.text; end return options.frame:expandTemplate{ title = 'dil', args = { value.language, value.text } }; elseif ( options.monolingualLangTemplate == 'ref' ) then return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language }; else return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>'; end end; elseif datavalue.type == 'globecoordinate' then return function( context, options, value ) return formatGlobeCoordinate( value, options ) end; elseif datavalue.type == 'quantity' then return function( context, options, value ) return formatQuantity( value, options ) end; elseif datavalue.type == 'time' then return function( context, options, value ) local moduleDate = require( 'Module:Wikidata/date' ) return moduleDate.formatDate( context, options, value ); end; else throwError( 'unknown-datavalue-type' ) end end function formatDatavalue( context, options, datavalue, datatype ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not datavalue ) then error( 'datavalue not specified' ); end; if ( not datavalue.value ) then error( 'datavalue.value is missng' ); end; context.formatValueDefault = getDefaultValueFunction( datavalue, datatype ); local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ); return functionToCall( context, options, datavalue.value ); end local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000}; function formatEntityId( context, options, entityId ) local boundaries = nil if options.qualifiers then boundaries = p.getTimeBoundariesFromQualifiers( frame, context, { qualifiers = options.qualifiers } ) end if not boundaries then boundaries = DEFAULT_BOUNDARIES; end local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries ) local category = context.extractCategory( options, { id = entityId } ) local link = mw.wikibase.sitelink( entityId ) if link then if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then link = ':' .. link end if label and not options.rawArticle then local a = link == label and ('[[' .. link .. ']]') or '[[' .. link .. '|' .. label .. ']]'; if ( contentLanguageCode ~= labelLanguageCode and 'mul' ~= labelLanguageCode ) then a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ); end return a .. category; else return '[[' .. link .. ']]' .. category; end end local link = mw.wikibase.sitelink( entityId ) if link then if label and labelLanguageCode == 'tr' then -- Tr article and Tr label return '[[' .. link .. '|' .. label .. ']]' .. cat else -- Tr article but no Tr label return '[[' .. link .. ']]' .. cat end end if label and labelLanguageCode == 'tr' then -- No Tr article but Tr label return '<span class="plainlinks">' .. label .. '</span><sup>[[:d:' .. entityId .. '|[d]]]</sup>' .. category; else -- No Tr article and no Tr label return '' end return nil end function p.formatStatements( frame ) return p.formatProperty( frame ); end function getPropertyParams( propertyId, datatype, params ) local config = getConfig(); local propertyParams = {}; if params then for key, value in pairs( params ) do if value ~= '' then propertyParams[ key ] = value; end end end if config[ 'properties' ] and config[ 'properties' ][ propertyId ] then for key, value in pairs( config[ 'properties' ][ propertyId ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value; end end end if propertyParams[ 'preset' ] and config[ 'presets' ] and config[ 'presets' ][ propertyParams[ 'preset' ] ] then for key, value in pairs( config[ 'presets' ][ propertyParams[ 'preset' ] ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value; end end end local datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId ); if propertyParams.datatype == nil then propertyParams.datatype = datatype; end if datatype and config[ 'datatypes' ] and config[ 'datatypes' ][ datatype ] then for key, value in pairs( config[ 'datatypes' ][ datatype ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value; end end end if config[ 'global' ] then for key, value in pairs( config[ 'global' ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value; end end end return propertyParams; end function p.formatProperty( frame ) local args = frame.args if not args.property then throwError( 'property-param-not-provided' ) end local override; local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w) if string.sub( w, 1, 1 ) == '~' then override = w; end return ''; end ) ) args = getPropertyParams( propertyId, nil, args ); if (override) then args[override:match('[,~]([^=]*)=')] = override:match('=(.*)') args['property'] = propertyId end local datatype = args.datatype; p_frame = frame while p_frame do if p_frame:getTitle() == mw.site.namespaces[10].name .. ':Wikidata' then copyTo( p_frame.args, args, true ); end if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then args.entityId = p_frame.args.from; end p_frame = p_frame:getParent(); end args.plain = toBoolean( args.plain, false ); args.nocat = toBoolean( args.nocat, false ); args.references = toBoolean( args.references, true ); if args.value and args.value ~= '' then if args.value == '-' then return '' end local value = args.value if args.plain then return value end local context = initContext( args ); local wrapperExtraArgs = {} if args['value-module'] and args['value-function'] and not string.find( value, '[%[%]%{%}]' ) then local func = getUserFunction( args, 'value' ); value = func( context, args, value ); elseif datatype == 'commonsMedia' then value = formatCommonsMedia( value, args ); elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then wrapperExtraArgs['data-wikidata-external-id'] = mw.text.killMarkers( value ); value = formatExternalId( value, args ); elseif datatype == 'url' then value = formatUrlValue( context, args, value ); end if string.match( propertyId, '^P%d+$' ) then value = mw.text.trim( value ) local allowTables = getPropertyParams(propertyId, nil, {})['allowTables'] if ( not allowTables and string.match( value, '<t[dhr][ >]' ) -- and not string.match( value, '<table[ >]' ) -- and not string.match( value, '^%{%|' ) ) then value = value .. getCategoryByCode( 'value-contains-table', propertyId ) else value = wrapStatement( value, propertyId, nil, wrapperExtraArgs ); end end return value end if ( args.plain ) then local callArgs = { propertyId }; if args.entityId then callArgs.from = args.entityId; end return frame:callParserFunction( '#property', callArgs ); end g_frame = frame return formatProperty( args ) end function isReferenceDeprecated( snaks ) if not snaks then return false end if snaks.P248 and snaks.P248[1] and snaks.P248[1].datavalue and snaks.P248[1].datavalue.value.id then local entityId = snaks.P248[1].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end elseif snaks.P1433 and snaks.P1433[1] and snaks.P1433[1].datavalue and snaks.P1433[1].datavalue.value.id then local entityId = snaks.P1433[1].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end end return false end function formatRefs( context, options, statement ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; if ( not statement ) then error( 'statement not specified' ); end; if ( not outputReferences ) then return ''; end local references = {}; if ( statement.references ) then local allReferences = statement.references; local hasNotDeprecated = false; local displayCount = 0; for _, reference in pairs( statement.references ) do local entityId = nil; if not isReferenceDeprecated( reference.snaks ) then hasNotDeprecated = true; end end for _, reference in pairs( statement.references ) do local display = true; if ( hasNotDeprecated ) then if isReferenceDeprecated( reference.snaks ) then display = false; end end if ( displayCount >= 2 ) then if ( options.entity and options.property ) then local propertyID = mw.ustring.match( options.property, '^[Pp][0-9]+' ) local moreReferences = '<sup>[[d:' .. options.entity.id .. '#' .. string.upper( propertyID ) .. '|[…]]]</sup>'; table.insert( references, moreReferences ); end break; end if ( display == true ) then local refText = moduleSources.renderReference( g_frame, options.entity, reference ); if ( refText ~= '' ) then table.insert( references, refText ); displayCount = displayCount + 1; end end end end return table.concat( references ); end return p
wikipedia, wiki, viki, vikipedia, oku, kitap, kütüphane, kütübhane, ara, ara bul, bul, herşey, ne arasanız burada,hikayeler, makale, kitaplar, öğren, wiki, bilgi, tarih, yukle, izle, telefon için, turk, türk, türkçe, turkce, nasıl yapılır, ne demek, nasıl, yapmak, yapılır, indir, ücretsiz, ücretsiz indir, bedava, bedava indir, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, resim, müzik, şarkı, film, film, oyun, oyunlar, mobil, cep telefonu, telefon, android, ios, apple, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, pc, web, computer, bilgisayar
Modul belgelemesi olustur Bu Scribunto modulu icin bir belgeleme sayfasi olusturmak isteyebilirsiniz Kullanicilar denemelerini bu sablonun deneme tahtasi olustur yansitma ve test senaryosu olustur sayfalarinda yapabilirler Lutfen kategorileri alt sayfasina ekleyin Bu modul ile ilgili alt sayfalar icin buraya tiklayiniz settings may differ from project to project taken and adapted from ruwiki local fileDefaultSize 267x400px local outputReferences true local moduleSources require Module Sources local WDS require Module WikidataSelectors local contentLanguageCode mw getContentLanguage getCode local p local config nil local formatDatavalue formatEntityId formatRefs formatSnak formatStatement formatStatementDefault formatProperty getSourcingCircumstances getPropertyDatatype getPropertyParams throwError toBoolean local function copyTo obj target skipEmpty for k v in pairs obj do if skipEmpty true or v nil and v then target k v end end return target end local function min prev next if prev nil then return next elseif prev gt next then return next else return prev end end local function max prev next if prev nil then return next elseif prev lt next then return next else return prev end end local function getConfig section code if config nil then config require Module Wikidata config end if not config then config end if not section then return config end if not code then return config section or end if not config section then return nil end return config section code end local function getCategoryByCode code sortkey local value getConfig categories code if not value or value then return end if sortkey nil then return Category value sortkey else return Category value end end local function splitISO8601 str if table type str then if str args and str args 1 then str str args 1 else return unknown argument type type str table tostring str end end local Y M D function str local pattern d d d T local Y M D mw ustring match str pattern return tonumber Y tonumber M tonumber D end str local h m s function str local pattern T d d d Z local H M S mw ustring match str pattern return tonumber H tonumber M tonumber S end str local oh om function str if str sub 1 Z then return 0 0 end ends with Z Zulu time matches hh mm hhmm or hh else returns nils local pattern d d d d local sign oh om mw ustring match str pattern sign oh om sign or oh or 00 om or 00 return tonumber sign oh tonumber sign om end str return year Y month M day D hour h oh min m om sec s end local function parseTimeBoundaries time precision local s splitISO8601 time if not s then return nil end if precision gt 0 and precision lt 8 then local powers 1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 local power powers precision 1 local left s year s year power return tonumber os time year left month 1 day 1 hour 0 min 0 sec 0 1000 tonumber os time year left power 1 month 12 day 31 hour 29 min 59 sec 58 1000 1999 end if precision 9 then return tonumber os time year s year month 1 day 1 hour 0 min 0 sec 0 1000 tonumber os time year s year month 12 day 31 hour 23 min 59 sec 58 1000 1999 end if precision 10 then local lastDays 31 28 25 31 30 31 30 31 31 30 31 30 31 local lastDay lastDays s month return tonumber os time year s year month s month day 1 hour 0 min 0 sec 0 1000 tonumber os time year s year month s month day lastDay hour 23 min 59 sec 58 1000 1999 end if precision 11 then return tonumber os time year s year month s month day s day hour 0 min 0 sec 0 1000 tonumber os time year s year month s month day s day hour 23 min 59 sec 58 1000 1999 end if precision 12 then return tonumber os time year s year month s month day s day hour s hour min 0 sec 0 1000 tonumber os time year s year month s month day s day hour s hour min 59 sec 58 1000 1999 end if precision 13 then return tonumber os time year s year month s month day s day hour s hour min s min sec 0 1000 tonumber os time year s year month s month day s day hour s hour min s min sec 58 1000 1999 end if precision 14 then local t tonumber os time year s year month s month day s day hour s hour min s min sec 0 return t 1000 t 1000 999 end error Unsupported precision precision end local function extractCategory options value if not options category or options nocat then return end local propertyId string gsub options category Pp0 9 local wbStatus claims pcall mw wikibase getAllStatements value id propertyId if wbStatus true or not claims then return end allClaims allClaims propertyId claims claims WDS filter allClaims options category if not claims then return end for claim in pairs claims do if claim and claim mainsnak and claim mainsnak datavalue and claim mainsnak datavalue type wikibase entityid then local catEntityId claim mainsnak datavalue value id local wbStatus catSiteLink pcall mw wikibase getSitelink catEntityId if wbStatus true and catSiteLink then return catSiteLink end end end return end local function toBoolean valueToParse defaultValue if valueToParse nil then if valueToParse false or valueToParse or valueToParse false or valueToParse 0 then return false end return true end return defaultValue end param value String value param attributes Table of attributes return string HTML tag with value local function wrapValue value attributes local tagName span local spacer if string match value n or string match value lt t dhr gt or string match value lt div gt or string find value UNIQ imagemap then tagName div spacer n end local attrString for key value in pairs attributes or do local key mw text trim key local value mw text encode mw text trim value attrString attrString key value end return lt tagName attrString gt spacer value lt tagName gt end Wraps formatted snak value into HTML tag with attributes param value String value of snak param hash Snak hash param attributes Table of extra attributes return string HTML tag with value local function wrapSnak value hash attributes local newAttributes mw clone attributes or newAttributes class newAttributes class or wikidata snak if hash then newAttributes data wikidata hash hash else newAttributes class newAttributes class wikidata main snak end return wrapValue value newAttributes end Wraps formatted statement value into HTML tag with attributes param value String value of statement param propertyId String PID of property param claimId String ID of claim or nil for local value param attributes Table of extra attributes return string HTML tag with value local function wrapStatement value propertyId claimId attributes local newAttributes mw clone attributes or newAttributes class newAttributes class or newAttributes data wikidata property id string upper propertyId if claimId then newAttributes class newAttributes class wikidata claim newAttributes data wikidata claim id claimId else newAttributes class newAttributes class no wikidata end return wrapValue value newAttributes end Wraps formatted qualifier s statement value into HTML tag with attributes param value String value of qualifier s statement param propertyId String PID of qualifier param attributes Table of extra attributes return string HTML tag with value local function wrapQualifier value qualifierId attributes local newAttributes mw clone attributes or newAttributes data wikidata qualifier id string upper qualifierId return wrapValue value newAttributes end local function getEntityFromId id local entity local wbStatus if id then wbStatus entity pcall mw wikibase getEntityObject id else wbStatus entity pcall mw wikibase getEntityObject end return entity end local function throwError key error getConfig errors key end local function getEntityIdFromValue value local prefix if value entity type item then prefix Q elseif value entity type property then prefix P else throwError unknown entity type end return prefix value numeric id end local function getUserFunction options prefix defaultFunction if options prefix module or options prefix function then if not options prefix module or not options prefix function then throwError unknown prefix module end local formatter require Module options prefix module if formatter nil then throwError prefix module not found end local fun formatter options prefix function if fun nil then throwError prefix function not found end return fun end return defaultFunction end local function selectClaims context options propertySelector if not context then error context not specified end if not options then error options not specified end if not options entity then error options entity is missing end if not propertySelector then error propertySelector not specified end result WDS filter options entity claims propertySelector if not result or result 0 then return nil end if options limit and options limit and options limit then local limit tonumber options limit 10 while result gt limit do table remove result end end return result end local function getPropertyInBoundaries context entityId boundaries propertyIds selectors if type entityId string then error type of entityId argument expected string but was type entityId end local results if not propertyIds or propertyIds 0 then return results end for propertyId in ipairs propertyIds do local selector selectors local propertyClaims mw wikibase getAllStatements entityId propertyId local fakeAllClaims fakeAllClaims propertyId propertyClaims local filteredClaims WDS filter fakeAllClaims selector rank preferred rank normal if filteredClaims then for claim in pairs filteredClaims do if not boundaries then table insert results claim mainsnak else local startBoundaries p getTimeBoundariesFromQualifier context frame context claim P580 local endBoundaries p getTimeBoundariesFromQualifier context frame context claim P582 if startBoundaries nil or startBoundaries 2 lt boundaries 1 and endBoundaries nil or endBoundaries 1 gt boundaries 2 then table insert results claim mainsnak end end end end if results gt 0 then break end end return results end function p getTimeBoundariesFromQualifier frame context statement qualifierId only support exact date so far but need improvement local left nil local right nil if statement qualifiers and statement qualifiers qualifierId then for qualifier in pairs statement qualifiers qualifierId do local boundaries context parseTimeBoundariesFromSnak qualifier if not boundaries then return nil end left min left boundaries 1 right max right boundaries 2 end end if not left or not right then return nil end return left right end function p getTimeBoundariesFromQualifiers frame context statement qualifierIds if not qualifierIds then qualifierIds P582 P580 P585 end for qualifierId in ipairs qualifierIds do local result p getTimeBoundariesFromQualifier frame context statement qualifierId if result then return result end end return nil end local CONTENT LANGUAGE CODE mw language getContentLanguage getCode local getLabelWithLang DEFAULT PROPERTIES P1813 P1705 P1448 local getLabelWithLang DEFAULT SELECTORS P1813 language CONTENT LANGUAGE CODE P3831 P3831 Q105690470 P1705 language CONTENT LANGUAGE CODE P3831 P3831 Q105690470 P1448 language CONTENT LANGUAGE CODE P3831 P3831 Q105690470 local function getLabelWithLang context options entityId boundaries propertyIds selectors if type entityId string then error type of entityId argument expected string but was type entityId end if not entityId then return nil end local langCode CONTENT LANGUAGE CODE name from label local label nil if options text and options text then label options text else if not propertyIds then propertyIds getLabelWithLang DEFAULT PROPERTIES selectors getLabelWithLang DEFAULT SELECTORS end name from properties local results getPropertyInBoundaries context entityId boundaries propertyIds selectors for result in pairs results do if result datavalue and result datavalue value then if result datavalue type monolingualtext and result datavalue value text then label result datavalue value text langCode result datavalue value language break elseif result datavalue type string then label result datavalue value break end end end if not label then label langCode mw wikibase getLabelWithLang entityId if not langCode then return nil end end end return label langCode end local function formatPropertyDefault context options if not context then error context not specified end if not options then error options not specified end if not options entity then error options entity missing end local claims if options property then if options rank then claims context selectClaims options options property options rank else claims context selectClaims options options property end end if claims nil then return end local formattedClaims for i claim in ipairs claims do local formattedStatement context formatStatement options claim if formattedStatement and formattedStatement then formattedStatement context wrapStatement formattedStatement options property claim id table insert formattedClaims formattedStatement end end local out mw text listToText formattedClaims options separator options conjunction if out then if options before then out options before out end if options after then out out options after end end return out end create context local function initContext options local context entity options entity extractCategory extractCategory formatSnak formatSnak formatPropertyDefault formatPropertyDefault formatStatementDefault formatStatementDefault wrapSnak wrapSnak wrapStatement wrapStatement wrapQualifier wrapQualifier context cloneOptions function options local entity options entity options entity nil newOptions mw clone options options entity entity newOptions entity entity newOptions frame options frame return newOptions end context formatProperty function options local func getUserFunction options property context formatPropertyDefault return func context options end context formatStatement function options statement return formatStatement context options statement end context formatSnak function options snak circumstances return formatSnak context options snak circumstances end context formatRefs function options statement return formatRefs context options statement end context parseTimeFromSnak function snak if snak and snak datavalue and snak datavalue value and snak datavalue value time then return tonumber os time splitISO8601 tostring snak datavalue value time 1000 end return nil end context parseTimeBoundariesFromSnak function snak if snak and snak datavalue and snak datavalue value and snak datavalue value time and snak datavalue value precision then return parseTimeBoundaries snak datavalue value time snak datavalue value precision end return nil end context getSourcingCircumstances function statement return getSourcingCircumstances statement end context selectClaims function options propertyId return selectClaims context options propertyId end return context end local function formatProperty options local entity getEntityFromId options entityId if not entity then return throwError entity not found end if entity claims nil then return TODO error end improve options options frame g frame options entity entity options extends function self newOptions return copyTo newOptions copyTo self end if options i18n then options i18n copyTo options i18n copyTo getConfig i18n else options i18n getConfig i18n end local context initContext options return context formatProperty options end function formatStatement context options statement if not statement then error statement is not specified or nil end if not statement type or statement type statement then throwError unknown claim type end local functionToCall getUserFunction options claim context formatStatementDefault return functionToCall context options statement end function getSourcingCircumstances statement if not statement then error statement is not specified end local circumstances if statement qualifiers and statement qualifiers P1480 then for i qualifier in pairs statement qualifiers P1480 do if qualifier and qualifier datavalue and qualifier datavalue type wikibase entityid and qualifier datavalue value and qualifier datavalue value entity type item then table insert circumstances qualifier datavalue value id end end end return circumstances end function formatStatementDefault context options statement if not context then error context is not specified end if not options then error options is not specified end if not statement then error statement is not specified end local circumstances context getSourcingCircumstances statement options qualifiers statement qualifiers local result context formatSnak options statement mainsnak circumstances local qualifierValues if options qualifier and statement qualifiers and statement qualifiers options qualifier then qualConfig getPropertyParams options qualifier nil if options i18n then qualConfig i18n options i18n end for qualifierSnak in pairs statement qualifiers options qualifier do local snakValue context formatSnak qualConfig qualifierSnak if snakValue and snakValue then table insert qualifierValues snakValue end end if result and result and qualifierValues then if qualConfig invisible then result result table concat qualifierValues else if not statement qualifiers options secondqualifier then result result lt span style font size 95 gt options frame expandTemplate title baglantiyi kes args table concat qualifierValues options qualifierseparator lt span gt else result result lt span style font size 95 gt options frame expandTemplate title baglantiyi kes args table concat qualifierValues end end end end if options secondqualifier and statement qualifiers and statement qualifiers options secondqualifier then qualConfig getPropertyParams options secondqualifier nil if options i18n then qualConfig i18n options i18n end local secondqualifier for qualifierSnak in pairs statement qualifiers options secondqualifier do local snakValue context formatSnak qualConfig qualifierSnak if snakValue and snakValue then table insert secondqualifier snakValue end end if result and result and secondqualifier then if qualConfig invisible then result result table concat secondqualifier else if not statement qualifiers options qualifier then result result lt span style font size 95 gt options qualifierseparator options frame expandTemplate title baglantiyi kes args table concat secondqualifier lt span gt else result result options qualifierseparator options frame expandTemplate title baglantiyi kes args table concat secondqualifier lt span gt end end end end if result and result and options references then result result context formatRefs options statement end return result end function formatSnak context options snak circumstances circumstances circumstances or if snak snaktype somevalue then if options somevalue and options somevalue then result options somevalue else result options i18n somevalue end elseif snak snaktype novalue then if options novalue and options novalue then result options novalue else result options i18n novalue end elseif snak snaktype value then result formatDatavalue context options snak datavalue snak datatype for item in pairs circumstances do if options i18n item then if result then result options i18n item result end end end else throwError unknown snak type end if not result or result then return nil end return context wrapSnak result snak hash end local function formatGlobeCoordinate value options if options subvalue latitude then shiroty return value latitude elseif options subvalue longitude then dolgoty return value longitude elseif options nocoord and options nocoord then return else coord mod require Module Coordinates local globe options globe or if globe and value globe then globes require Module Wikidata Globes globe globes value globe or end local display inline if options display and options display then display options display elseif options property upper P625 then display title end local format options format or if format then format dms if value precision then local precision value precision 60 if precision gt 60 then format d elseif precision gt 1 then format dm end end end g frame args tostring value latitude tostring value longitude globe globe type options type and options type or scale options scale and options scale or display display format format return coord mod coord g frame end end local function formatCommonsMedia value options local image value local caption if options caption and options caption then caption options caption end if caption then caption wrapQualifier caption P2096 class media caption style display block end if not string find value and not string find value UNIQ imagemap then image File value frameless if options border and options border then image image border end local size options size if size and size then if not string match size px then size size px end else size fileDefaultSize end image image size if options alt and options alt then image image alt options alt end if caption then image image caption end image image if caption then image image lt br gt caption end else image image caption getCategoryByCode media contains markup end return image end local function formatMath value options return options frame extensionTag name math content value end local function formatExternalId value options local formatter options formatter if not formatter or formatter then local wbStatus propertyEntity pcall mw wikibase getEntity options property upper if wbStatus true and propertyEntity then local isGoodFormat false local statements propertyEntity getBestStatements P1793 for statement in pairs statements do if statement mainsnak snaktype value then local pattern mw ustring gsub statement mainsnak datavalue value pattern mw ustring gsub pattern d d if string find pattern or string find pattern or mw ustring match value pattern nil then isGoodFormat true break end end end if isGoodFormat true then statements propertyEntity getBestStatements P1630 for statement in pairs statements do if statement mainsnak snaktype value then formatter statement mainsnak datavalue value break end end end end end if formatter and formatter then local encodedValue mw ustring gsub value local link mw ustring gsub mw ustring gsub formatter 1 encodedValue 20 2b 5B 5D local title options title if not title or title then title 1 end title mw ustring gsub mw ustring gsub title 1 encodedValue return link title end return value end local function formatQuantity value options local amount string gsub value amount local lang mw language getContentLanguage local langCode lang getCode local function formatNum number sigfig local multiplier if options countByThousands then local powers options i18n thousandPowers local pos 1 while math abs number gt 1000 and pos lt powers do number number 1000 pos pos 1 end multiplier powers pos if math abs number gt 100 then sigfig sigfig or 0 elseif math abs number gt 10 then sigfig sigfig or 1 else sigfig sigfig or 2 end else sigfig sigfig or 12 end local mult 10 sigfig number math floor number mult 0 5 mult return string gsub lang formatNum number multiplier end local out formatNum tonumber amount if value upperBound then local diff tonumber value upperBound tonumber amount if diff gt 0 then local integer dot decimals expstr value upperBound match d d local prec if dot then prec integer match 0 len else prec decimals end bound formatNum diff prec if string match bound E d then digits tonumber string match bound E d 2 bound formatNum diff 10 digits prec bound string sub bound 0 2 string rep 0 digits string sub bound string len bound 2 end out out bound end end if options unit and options unit then if options unit then out out options unit end elseif value unit and string match value unit http www wikidata org entity then local unitEntityId string gsub value unit http www wikidata org entity if unitEntityId undefined then local wbStatus unitEntity pcall mw wikibase getEntity unitEntityId if wbStatus true and unitEntity then if unitEntity claims P2370 and unitEntity claims P2370 1 mainsnak snaktype value and not value upperBound and options siConversion true then conversionToSIunit string gsub unitEntity claims P2370 1 mainsnak datavalue value amount if math floor math log10 conversionToSIunit math log10 conversionToSIunit then outValue tonumber amount conversionToSIunit if outValue gt 0 then local integer dot decimals expstr amount match d d local prec if dot then prec integer match 0 len else prec decimals end local adjust math log10 math abs conversionToSIunit math log10 2 local minprec 1 math floor math log10 outValue 2e 14 out formatNum outValue math max math floor prec adjust minprec else out formatNum outValue 0 end unitEntityId string gsub unitEntity claims P2370 1 mainsnak datavalue value unit http www wikidata org entity wbStatus unitEntity pcall mw wikibase getEntity unitEntityId end end local writingSystemElementId Q8209 local langElementId Q7737 local label getLabelWithLang context options unitEntity id nil P5061 P558 P558 P5061 language langCode P558 P282 writingSystemElementId P407 langElementId P558 P282 P407 out out label end end end return out end local function formatUrlValue context options value if not options length or options length then options length 25 end local moduleUrl require Module URL wikidata return moduleUrl formatUrlSingle context options value end local DATATYPE CACHE Get property datatype by ID param string Property ID e g P123 return string Property datatype e g commonsMedia time or url local function getPropertyDatatype propertyId if not propertyId or not string match propertyId P d then return nil end local cached DATATYPE CACHE propertyId if cached nil then return cached end local wbStatus propertyEntity pcall mw wikibase getEntity propertyId if wbStatus true or not propertyEntity then return nil end mw log Loaded datatype propertyEntity datatype of propertyId from wikidata consider passing datatype argument to formatProperty call or to Wikidata config DATATYPE CACHE propertyId propertyEntity datatype return propertyEntity datatype end local function getDefaultValueFunction datavalue datatype if datavalue type wikibase entityid then Entity ID return function context options value return formatEntityId context options getEntityIdFromValue value end elseif datavalue type string then String if datatype and datatype commonsMedia then Media return function context options value return formatCommonsMedia value options end elseif datatype and datatype external id then External ID return function context options value return formatExternalId value options end elseif datatype and datatype math then Math formula return function context options value return formatMath value options end elseif datatype and datatype url then URL return formatUrlValue end return function context options value return value end elseif datavalue type monolingualtext then return function context options value if options monolingualLangTemplate lang then if value language contentLanguageCode then return value text end return options frame expandTemplate title dil args value language value text elseif options monolingualLangTemplate ref then return lt span class lang lang value language gt value text lt span gt options frame expandTemplate title ref value language else return lt span class lang lang value language gt value text lt span gt end end elseif datavalue type globecoordinate then return function context options value return formatGlobeCoordinate value options end elseif datavalue type quantity then return function context options value return formatQuantity value options end elseif datavalue type time then return function context options value local moduleDate require Module Wikidata date return moduleDate formatDate context options value end else throwError unknown datavalue type end end function formatDatavalue context options datavalue datatype if not context then error context not specified end if not options then error options not specified end if not datavalue then error datavalue not specified end if not datavalue value then error datavalue value is missng end context formatValueDefault getDefaultValueFunction datavalue datatype local functionToCall getUserFunction options value context formatValueDefault return functionToCall context options datavalue value end local DEFAULT BOUNDARIES os time 1000 os time 1000 function formatEntityId context options entityId local boundaries nil if options qualifiers then boundaries p getTimeBoundariesFromQualifiers frame context qualifiers options qualifiers end if not boundaries then boundaries DEFAULT BOUNDARIES end local label labelLanguageCode getLabelWithLang context options entityId boundaries local category context extractCategory options id entityId local link mw wikibase sitelink entityId if link then if mw ustring match link mw site namespaces 14 name then link link end if label and not options rawArticle then local a link label and link or link label if contentLanguageCode labelLanguageCode and mul labelLanguageCode then a a getCategoryByCode links to entities with missing local language label end return a category else return link category end end local link mw wikibase sitelink entityId if link then if label and labelLanguageCode tr then Tr article and Tr label return link label cat else Tr article but no Tr label return link cat end end if label and labelLanguageCode tr then No Tr article but Tr label return lt span class plainlinks gt label lt span gt lt sup gt d entityId d lt sup gt category else No Tr article and no Tr label return end return nil end function p formatStatements frame return p formatProperty frame end function getPropertyParams propertyId datatype params local config getConfig local propertyParams if params then for key value in pairs params do if value then propertyParams key value end end end if config properties and config properties propertyId then for key value in pairs config properties propertyId do if propertyParams key nil then propertyParams key value end end end if propertyParams preset and config presets and config presets propertyParams preset then for key value in pairs config presets propertyParams preset do if propertyParams key nil then propertyParams key value end end end local datatype datatype or params datatype or propertyParams datatype or getPropertyDatatype propertyId if propertyParams datatype nil then propertyParams datatype datatype end if datatype and config datatypes and config datatypes datatype then for key value in pairs config datatypes datatype do if propertyParams key nil then propertyParams key value end end end if config global then for key value in pairs config global do if propertyParams key nil then propertyParams key value end end end return propertyParams end function p formatProperty frame local args frame args if not args property then throwError property param not provided end local override local propertyId mw language getContentLanguage ucfirst string gsub args property Pp0 9 function w if string sub w 1 1 then override w end return end args getPropertyParams propertyId nil args if override then args override match override match args property propertyId end local datatype args datatype p frame frame while p frame do if p frame getTitle mw site namespaces 10 name Wikidata then copyTo p frame args args true end if p frame args and p frame args from and p frame args from then args entityId p frame args from end p frame p frame getParent end args plain toBoolean args plain false args nocat toBoolean args nocat false args references toBoolean args references true if args value and args value then if args value then return end local value args value if args plain then return value end local context initContext args local wrapperExtraArgs if args value module and args value function and not string find value then local func getUserFunction args value value func context args value elseif datatype commonsMedia then value formatCommonsMedia value args elseif datatype external id and not string find value then wrapperExtraArgs data wikidata external id mw text killMarkers value value formatExternalId value args elseif datatype url then value formatUrlValue context args value end if string match propertyId P d then value mw text trim value local allowTables getPropertyParams propertyId nil allowTables if not allowTables and string match value lt t dhr gt and not string match value lt table gt and not string match value then value value getCategoryByCode value contains table propertyId else value wrapStatement value propertyId nil wrapperExtraArgs end end return value end if args plain then local callArgs propertyId if args entityId then callArgs from args entityId end return frame callParserFunction property callArgs end g frame frame return formatProperty args end function isReferenceDeprecated snaks if not snaks then return false end if snaks P248 and snaks P248 1 and snaks P248 1 datavalue and snaks P248 1 datavalue value id then local entityId snaks P248 1 datavalue value id if getConfig deprecatedSources entityId then return true end elseif snaks P1433 and snaks P1433 1 and snaks P1433 1 datavalue and snaks P1433 1 datavalue value id then local entityId snaks P1433 1 datavalue value id if getConfig deprecatedSources entityId then return true end end return false end function formatRefs context options statement if not context then error context not specified end if not options then error options not specified end if not options entity then error options entity missing end if not statement then error statement not specified end if not outputReferences then return end local references if statement references then local allReferences statement references local hasNotDeprecated false local displayCount 0 for reference in pairs statement references do local entityId nil if not isReferenceDeprecated reference snaks then hasNotDeprecated true end end for reference in pairs statement references do local display true if hasNotDeprecated then if isReferenceDeprecated reference snaks then display false end end if displayCount gt 2 then if options entity and options property then local propertyID mw ustring match options property Pp 0 9 local moreReferences lt sup gt d options entity id string upper propertyID lt sup gt table insert references moreReferences end break end if display true then local refText moduleSources renderReference g frame options entity reference if refText then table insert references refText displayCount displayCount 1 end end end end return table concat references end return p