Editing
Module:Sources-utils
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {}; local i18nDefaultLanguage = 'en'; p.i18nDefaultLanguage = i18nDefaultLanguage; local monthg = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'}; local options_commas_nolinks = { separator = ', ', conjunction = ', ', format = function( src ) return src end, nolinks = true, preferids = false }; -- utility functions function appendSnaks( allSnaks, snakPropertyId, result, property, options ) -- do not populate twice if ( result[property] ) then return result end; if ( not allSnaks ) then return result; end; local selectedSnakes = allSnaks[ snakPropertyId ]; if ( not selectedSnakes ) then return result; end; local hasPreferred = false; for k, snak in pairs( selectedSnakes ) do if ( snak and snak.mainsnak and snak.mainsnak.datavalue and snak.rank == 'preferred' ) then --it's a preferred claim appendImpl( snak.mainsnak.datavalue, snak.qualifiers, result, property, options ); hasPreferred = true; end end if ( hasPreferred ) then return result; end; if ( snakPropertyId == 'P316' ) then -- if there is a english for k, snak in pairs( selectedSnakes ) do if ( snak and snak.mainsnak and snak.mainsnak.datavalue and snak.mainsnak.datavalue.value and snak.rank ~= 'deprecated' and snak.mainsnak.datavalue.value.language == i18nDefaultLanguage ) then --found russian string appendImpl( snak.mainsnak.datavalue, snak.qualifiers, result, property, options ); return result; end end end; for k, snak in pairs( selectedSnakes ) do if ( snak and snak.mainsnak and snak.mainsnak.datavalue and snak.rank ~= 'deprecated' ) then --it's a claim appendImpl( snak.mainsnak.datavalue, snak.qualifiers, result, property, options ); elseif ( snak and snak.datavalue ) then -- it's a snak appendImpl( snak.datavalue, nil, result, property, options ); end end end function appendImpl( datavalue, qualifiers, result, property, options ) if ( datavalue.type == 'string' ) then local statedAs = getSingleStringQualifierValue(qualifiers, 'P318'); local value; if ( statedAs ) then value = statedAs; else value = datavalue.value; if ( options.format ) then value = options.format( value ); end end appendImpl_toTable( result, property ); table.insert( result[property], value); elseif ( datavalue.type == 'url' ) then local statedAs = getSingleStringQualifierValue(qualifiers, 'P318'); local value = datavalue.value; if ( options.format ) then value = options.format( value ); end appendImpl_toTable( result, property ); table.insert( result[property], value); elseif ( datavalue.type == 'monolingualtext' ) then local value = datavalue.value.text; if ( options.format ) then value = options.format( value ); end appendImpl_toTable( result, property ); table.insert( result[property], value); elseif ( datavalue.type == 'quantity' ) then local value = datavalue.value.amount; if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then value = mw.ustring.sub( value , 2 ); end if ( options.format ) then value = options.format( value ); end appendImpl_toTable( result, property ); table.insert( result[property], value); elseif ( datavalue.type == 'wikibase-entityid' ) then local value = datavalue.value; appendImpl_toTable( result, property ); local toInsert = { id = value.id, label = getSingleStringQualifierValue(qualifiers, 'P318') -- stated as }; table.insert( result[property], toInsert ); elseif datavalue.type == 'time' then local value = datavalue.value; if ( options.format ) then value = options.format( value ); end appendImpl_toTable( result, property ); table.insert( result[property], tostring( value.time )); end end function appendImpl_toTable(result, resultProperty) if ( not result[resultProperty] ) then result[resultProperty] = {}; elseif ( type( result[resultProperty] ) == 'string' or ( type( result[resultProperty] ) == 'table' and type( result[resultProperty].id ) == 'string' ) ) then result[resultProperty] = { result[resultProperty] }; end end function appendQualifiers( claims, qualifierPropertyId, result, resultProperty, options ) -- do not populate twice if ( not claims ) then return result end; if ( result[resultProperty] ) then return result end; for i, claim in pairs( claims ) do if ( claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] ) then for k, qualifier in pairs( claim.qualifiers[ qualifierPropertyId ] ) do if ( qualifier and qualifier.datavalue ) then appendImpl( qualifier.datavalue, nil, result, resultProperty, options ); end end end end end function assertNotNull( argName, arg ) if ( (not arg) or (arg == nil) ) then error( argName .. ' is not specified' ) end end function coalesce( arg1, arg2, arg3, arg4 ) if ( not isEmpty( arg1 ) ) then return arg1 end if ( not isEmpty( arg2 ) ) then return arg2 end if ( not isEmpty( arg3 ) ) then return arg3 end if ( not isEmpty( arg4 ) ) then return arg4 end return nil; end function copyArgsToSnaks( args, snaks ) if ( not isEmpty( args.part ) ) then snaks.P223 = { toStringSnak( 'P223', tostring( args.part ) ) } end if ( not isEmpty( args.pages ) ) then snaks.P219 = { toStringSnak( 'P219', tostring( args.pages ) ) } end if ( not isEmpty( args.issue ) ) then snaks.P320 = { toStringSnak( 'P320', tostring( args.issue ) ) } end if ( not isEmpty( args.volume ) ) then snaks.P322 = { toStringSnak( 'P322', tostring( args.volume ) ) } end if ( not isEmpty( args.url ) ) then snaks.P324 = { toUrlSnak( 'P324', tostring( args.url ) ) } end if ( not isEmpty( args.parturl ) ) then snaks.P324 = { toUrlSnak( 'P324', tostring( args.parturl ) ) } end end local LANG_CACHE = { Q269 = 'fr', Q270 = 'de', Q271 = 'es', Q96 = 'en', Q273 = 'it', Q97 = 'ru', } function getLangCode( langEntityId ) if ( not langEntityId ) then return; end -- small optimization local cached = LANG_CACHE[ langEntityId ]; if ( cached ) then return cached; end local claims = mw.wikibase.getBestStatements( langEntityId, 'P329' ); if ( claims ) then for _, claim in pairs( claims ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value ) then return '' .. claim.mainsnak.datavalue.value; end end end return; end function findClaimsByValue( entity, propertyId, value ) local result = {}; if ( entity and entity.claims and entity.claims[propertyId] ) then for i, claim in pairs( entity.claims[propertyId] ) do if ( claim.mainsnak and claim.mainsnak.datavalue ) then local datavalue = claim.mainsnak.datavalue; if ( datavalue.type == "string" and datavalue.value == value or datavalue.type == "wikibase-entityid" and datavalue.value["entity-type"] == "item" and tostring( datavalue.value.id ) == value ) then table.insert( result, claim ); end end end end return result; end function getBestStatements( entity, propertyId ) local resultClaims = {}; if ( entity and entity.claims and entity.claims[ propertyId ] ) then local rank = 'normal'; for i, statement in pairs( entity.claims[ propertyId ] ) do if ( statement.rank == 'preferred' ) then rank = 'preferred'; break; end end for i, statement in pairs( entity.claims[ propertyId ] ) do if ( statement.rank == rank ) then table.insert( resultClaims, statement ); end end end return resultClaims; end function expandBookSeries( context, data ) local bookSeries = data.bookSeries; if ( not bookSeries ) then return end; -- use only first one if ( type( bookSeries ) == 'table' and bookSeries[1] and bookSeries[1].id ) then data.bookSeries = bookSeries[1]; bookSeries = data.bookSeries; end if ( not bookSeries ) then return end; if ( not bookSeries.id ) then return end; local bookSeriesEntity = getEntity( context, bookSeries.id ); appendSnaks( bookSeriesEntity.claims, 'P218', data, 'publisher', {} ); appendSnaks( bookSeriesEntity.claims, 'P330', data, 'place', {} ); appendSnaks( bookSeriesEntity.claims, 'P331', data, 'issn', {} ); end function expandPublication( context, sourceEntity, data ) local publication = data.publication; -- use only first one if ( type( publication ) == 'table' and publication[1] and publication[1].id ) then data.publication = publication[1]; publication = data.publication; end if ( not publication ) then return end; if ( not publication.id ) then return end; if ( sourceEntity ) then -- do we have appropriate record in P333 ? local claims = findClaimsByValue( sourceEntity, 'P333', publication.id ); if ( claims and #claims ~= 0 ) then for _, claim in pairs( claims ) do populateDataFromClaims( context, sourceEntity, claim.qualifiers, data ); break; end end end local titleWerePresent = not (not data.title); local pubEntity = getEntity( context, publication.id ); populateSourceDataImpl( context, pubEntity, data ); if ( titleWerePresent and isEmpty( data.publication.label ) ) then appendSnaks( pubEntity.claims, 'P334', data, 'publication-title', {} ); -- obsolete data.publication.label = getSingle( data['publication-title'] ); end if ( titleWerePresent and isEmpty( data.publication.label ) ) then appendSnaks( pubEntity.claims, 'P225', data, 'publication-title', {} ); appendSnaks( pubEntity.claims, 'P316', data, 'publication-subtitle', {} ); data.publication.label = getSingle( data['publication-title'] ); data.publication.subtitle = getSingle( data['publication-subtitle'] ); end end -- Expand special types of references when additional data could be found in OTHER entity properties function expandSpecials( context, currentEntity, reference, data ) local sourceId; if ( reference.snaks.P250 and reference.snaks.P250[1] and reference.snaks.P250[1].datavalue and reference.snaks.P250[1].datavalue.value.id ) then sourceId = reference.snaks.P250[1].datavalue.value.id; elseif ( reference.snaks.P15 and reference.snaks.P15[1] and reference.snaks.P15[1].datavalue and reference.snaks.P15[1].datavalue.value.id ) then sourceId = reference.snaks.P15[1].datavalue.value.id; end if sourceId then data.sourceId = sourceId; -- Gemeinsame Normdatei -- specified by P227 if ( sourceId == 'Q36578' ) then appendSnaks( currentEntity.claims, 'P227', data, 'part', { format = function( gnd ) return 'Record #' .. gnd; end } ); appendSnaks( currentEntity.claims, 'P227', data, 'url', { format = function( gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } ); data.year = '2012—2016' expandSpecialsQualifiers( context, currentEntity, 'P227', data ); -- BNF -- specified by P268 elseif ( sourceId == 'Q15222191' ) then appendSnaks( currentEntity.claims, 'P268', data, 'part', { format = function( id ) return 'Record #' .. id; end } ); appendSnaks( currentEntity.claims, 'P268', data, 'url', { format = function( id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } ); expandSpecialsQualifiers( context, currentEntity, 'P268', data ); -- VIAF -- specified by P214 elseif ( sourceId == 'Q54919' ) then appendSnaks( currentEntity.claims, 'P214', data, 'part', { format = function( id ) return 'Record #' .. id; end } ); appendSnaks( currentEntity.claims, 'P214', data, 'url', { format = function( id ) return 'https://viaf.org/viaf/' .. id; end } ); expandSpecialsQualifiers( context, currentEntity, 'P214', data ); -- generic property search else local sourceEntity = getEntity( context, sourceId ); if ( sourceEntity ) then for _, sourceClaim in ipairs( getBestStatements( sourceEntity, 'P1687' ) ) do if ( sourceClaim.mainsnak.snaktype == 'value' ) then local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id; local sourcePropertyEntity = getEntity( context, sourcePropertyId ); if ( sourcePropertyEntity ) then for _, sourcePropertyClaim in ipairs( getBestStatements( sourcePropertyEntity, 'P1630' ) ) do if ( sourcePropertyClaim.mainsnak.snaktype == 'value' ) then appendSnaks( currentEntity.claims, sourcePropertyId, data, 'url', { format = function( id ) return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' ) end; } ); expandSpecialsQualifiers( context, currentEntity, sourcePropertyId, data ); break; end end end end end end end -- do we have appropriate record in P1433 ? local claims = findClaimsByValue( currentEntity, 'P1343', sourceId ); if ( claims and #claims ~= 0 ) then for _, claim in pairs( claims ) do populateDataFromClaims( context, sourceId, claim.qualifiers, data ); end end end end function expandSpecialsQualifiers( context, entity, propertyId, data ) if ( entity and entity.claims and entity.claims[propertyId] ) then for _, claim in pairs( entity.claims[propertyId] ) do populateDataFromClaims( context, nil, claim.qualifiers, data ); end end end function isEmpty( str ) return ( not str ) or ( str == nil ) or ( #str == 0 ); end function isInstanceOf( entity, typeEntityId ) if ( not entity or not entity.claims or not entity.claims.P1 ) then return false; end for _, claim in pairs( entity.claims.P1 ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.id ) then local actualTypeId = claim.mainsnak.datavalue.value.id; if ( actualTypeId == typeEntityId ) then return true; end end end return false; end function getElementLink( context, entityId, entity ) -- fast sitelink lookup, not an expensive operation local link = mw.wikibase.sitelink( entityId ) if ( link ) then return ':' .. link end if ( not entity and entityId ) then entity = getEntity( context, entityId ) end if ( entity ) then -- link to entity in source context language local projectToCheck = context.lang .. 'wiki'; if ( entity.sitelinks and entity.sitelinks[ projectToCheck ] ) then return ':' .. context.lang .. ':' .. entity.sitelinks[ projectToCheck ].title; end end if ( entityId ) then return ':d:' .. entityId end; -- if ( entityId ) then return 'https://tools.wmflabs.org/reasonator/?q=' .. entityId .. '&lang=ru' end; return nil; end function getEntity( context, entityId ) assertNotNull( 'context', context ); assertNotNull( 'entityId', entityId ); local cached = context.cache[ entityId ]; if ( cached ) then return cached; end; local wbStatus, result = pcall( mw.wikibase.getEntity, entityId ); if ( wbStatus ~= true ) then return nil; end if ( result ) then context.cache[ entityId ] = result; end return result; end function getNormativeTitle( entity ) if ( not entity or not entity.claims or not entity.claims.P1 ) then return; end for _, claim in pairs( entity.claims.P1 ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.id ) then local classId = claim.mainsnak.datavalue.value.id; local title = NORMATIVE_DOCUMENTS[ classId ]; if ( title ) then return title; end end end return; end function getPlaceName( lang, placeId ) -- ГОСТ Р 7.0.12—2011 if ( lang == 'ru' ) then if ( placeId == 'Q236' ) then return toTextWithTip('М.', 'Москва'); end if ( placeId == 'Q57' ) then return toTextWithTip('СПб.', 'Санкт-Петербург'); end if ( placeId == 'Q891' ) then return toTextWithTip('Н. Новгород', 'Нижний Новгород'); end if ( placeId == 'Q908' ) then return toTextWithTip('Ростов н/Д.', 'Ростов-на-Дону'); end end return nil; end function getSingle( value ) if ( not value ) then return; end if ( type( value ) == 'string' ) then return value; elseif ( type( value ) == 'table' ) then if ( value.id ) then return value.id; end for i, tableValue in pairs( value ) do return getSingle( tableValue ); end end return '(unknown)'; end function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId ) if ( not allQualifiers ) then return end if ( not allQualifiers[qualifierPropertyId] ) then return end for k, qualifier in pairs( allQualifiers[qualifierPropertyId] ) do if ( qualifier and qualifier.datatype == 'string' and qualifier.datavalue and qualifier.datavalue.type == 'string' and not isEmpty( qualifier.datavalue.value ) ) then return qualifier.datavalue.value; end end return; end function populateDataFromClaims( context, entityId, claims, data ) appendSnaks( claims, 'P215', data, 'author', {} ); appendSnaks( claims, 'P216', data, 'author', {} ); appendSnaks( claims, 'P44', data, 'lang', {} ); appendSnaks( claims, 'P335', data, 'lang', {} ); appendSnaks( claims, 'P223', data, 'part', {} ); if ( not data.title ) then if ( not isEmpty( entityId ) ) then local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end }; appendSnaks( claims, 'P225', data, 'title', optionsAsLinks ); else appendSnaks( claims, 'P225', data, 'title', {} ); end appendSnaks( claims, 'P316', data, 'subtitle', {} ); end appendSnaks( claims, 'P324', data, 'url', {} ); appendSnaks( claims, 'P208', data, 'url', {} ); appendSnaks( claims, 'P35', data, 'url', {} ); -- temp disable, use only for current entity, see Q22338048 for example of incorrect work -- appendSnaks( claims, 'P856', data, 'url', {} ); appendSnaks( claims, 'P338', data, 'editor', {} ); appendSnaks( claims, 'P339', data, 'translator', {} ); appendSnaks( claims, 'P333', data, 'publication', {} ); appendSnaks( claims, 'P340', data, 'edition', {} ); appendSnaks( claims, 'P218', data, 'publisher', {} ); appendSnaks( claims, 'P330', data, 'place', {} ); if ( claims and claims.P170 ) then for c, claim in pairs( claims.P170 ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.id ) then local possibleBookSeriesEntityId = claim.mainsnak.datavalue.value.id; local possibleBookSeriesEntity = getEntity( context, possibleBookSeriesEntityId ); if ( isInstanceOf( possibleBookSeriesEntity, 'Q276' ) ) then appendImpl_toTable( data, 'bookSeries' ); table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } ); appendQualifiers( { claim }, 'P322', data, 'bookSeriesVolume', {} ); appendQualifiers( { claim }, 'P320', data, 'bookSeriesIssue', {} ); end end end end appendSnaks( claims, 'P322', data, 'volume', {} ); appendSnaks( claims, 'P320', data, 'issue', {} ); appendSnaks( claims, 'P85', data, 'dateOfCreation', {} ); appendSnaks( claims, 'P19', data, 'dateOfPublication', {} ); appendSnaks( claims, 'P219', data, 'pages', {} ); appendSnaks( claims, 'P342', data, 'numberOfPages', {} ); appendSnaks( claims, 'P204', data, 'tirage', {} ); appendSnaks( claims, 'P99999', data, 'isbn', {} ); -- ISBN-13 appendSnaks( claims, 'P99989', data, 'isbn', {} ); -- ISBN-10 appendSnaks( claims, 'P99979', data, 'issn', {} ); -- web -- appendSnaks( claims, 'P813', data, 'accessdate', {} ); -- docs appendSnaks( claims, 'P344', data, 'docNumber', {} ); -- other appendSnaks( claims, 'P1', data, 'type', {} ); appendSnaks( claims, 'P346', data, 'arxiv', {} ); return src; end function populateSourceDataImpl( context, entity, plainData ) local wsLink = mw.wikibase.getSitelink( entity.id, 'ruwikisource' ); if ( wsLink ) then plainData.url = ":ru:s:" .. wsLink; end populateDataFromClaims( context, entity.id, entity.claims, plainData ); local normativeTitle = getNormativeTitle( entity ) if ( normativeTitle ) then local y, m, d = mw.ustring.match( getSingle( plainData.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" ); y,m,d = tonumber(y),tonumber(m),tonumber(d); local title = toString( { lang='ru' }, plainData.title, options_commas_nolinks ); plainData.title = { normativeTitle .. " от " .. tostring(d) .. " " .. monthg[m] .. " " .. tostring(y) .. " г. № " .. getSingle( plainData.docNumber ) .. ' «' .. title.. '»' } end if ( not plainData.title ) then if ( entity and entity.labels and entity.labels.ru and entity.labels.ru.value ) then plainData.title = { entity.labels.ru.value }; end end return plainData; end function preprocessPlaces( data, lang ) if ( not data.place ) then return; end; local newPlaces = {}; for index, place in pairs( data.place ) do if ( place.id ) then local newPlaceStr = getPlaceName(lang, place.id) if ( newPlaceStr ) then newPlaces[index] = newPlaceStr; else newPlaces[index] = place; end else newPlaces[index] = place; end end data.place = newPlaces; end function renderLink( context, entityId, customTitle, options ) if ( not entityId ) then error("entityId is not specified") end if ( type( entityId ) ~= 'string' ) then error('entityId is not string, but ' .. type( entityId ) ) end if ( type( customTitle or '' ) ~= 'string' ) then error('customTitle is not string, but ' .. type( customTitle ) ) end local title = customTitle; if ( isEmpty( title ) ) then local entity = getEntity( context, entityId ); -- ISO 4 if ( isEmpty( title ) ) then if ( entity and entity.claims and entity.claims.P334 ) then for _, claim in pairs( entity.claims.P334 ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == context.lang ) then title = claim.mainsnak.datavalue.value.text; mw.log('Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' ) break; end end end end -- official name P1448 -- short name P1813 if ( isEmpty( title ) and options.short ) then if ( entity and entity.claims and entity.claims.P203 ) then for _, claim in pairs( entity.claims.P203 ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == context.lang ) then title = claim.mainsnak.datavalue.value.text; mw.log('Got title of ' .. entityId .. ' from short name claim: «' .. title .. '»' ) break; end end end end -- person name P1559 -- labels if ( isEmpty( title ) and entity.labels[ context.lang ] ) then title = entity.labels[ context.lang ].value; mw.log('Got title of ' .. entityId .. ' from label: «' .. title .. '»' ) end end local actualText = title or '\'\'(untranslated)\'\''; local link = getElementLink( context, entityId, entity); return wrapInUrl( link, actualText ); end function toTextWithTip( text, tip ) return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>'; end function toString( context, value, options ) if ( type( value ) == 'string' ) then return options.format( value ); elseif ( type( value ) == 'table' ) then if ( value.id ) then -- this is link if ( type( value.label or '' ) ~= 'string' ) then mw.logObject( value ); error('label of table value is not string but ' .. type( value.label ) ) end if ( options.preferids ) then return options.format( value.id ); else if ( options.nolinks ) then return options.format( value.label or mw.wikibase.label( value.id ) or '\'\'(untranslated title)\'\'' ); else return options.format( renderLink( context, value.id, value.label, options ) ); end end end local resultList = {}; for i, tableValue in pairs( value ) do table.insert( resultList, toString( context, tableValue, options ) ); end return mw.text.listToText( resultList, options.separator, options.conjunction); else return options.format( '(unknown type)' ); end return ''; end function toStringSnak( propertyId, strValue ) assertNotNull('propertyId', strValue) assertNotNull('strValue', strValue) local snak = { snaktype = "value", property = propertyId, datatype = 'string'}; snak["datavalue"] = { value = strValue, type = 'string' }; return snak; end function toUrlSnak( propertyId, strValue ) assertNotNull('propertyId', strValue) assertNotNull('strValue', strValue) local snak = { snaktype = "value", property = propertyId, datatype = 'string'}; snak["datavalue"] = { value = strValue, type = 'url' }; return snak; end function toWikibaseEntityIdSnak( propertyId, entityId ) assertNotNull('propertyId', entityId) assertNotNull('entityId', entityId) if ( mw.ustring.sub( entityId, 1, 1 ) ~= 'Q' ) then error( 'Incorrect entity ID: «' .. entityId .. '»' ); end; local value = { ["entity-type"] = 'item', ["id"] = entityId, }; local snak = { snaktype = "value", property = propertyId, datatype = 'wikibase-item'}; snak["datavalue"] = { value = value, type = 'wikibase-entityid' }; return snak; end function wrapInUrl( urls, text ) local url = getSingle( urls ); if ( string.sub( url, 1, 1 ) == ':' ) then return '[[' .. url .. '|' .. text .. ']]'; else return '[' .. url .. ' ' .. text .. ']'; end end return p;
Summary:
Please note that all contributions to Porn Base Central may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Porn Base Central:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Preview page with this template
Template used on this page:
Module:Sources-utils/doc
(
view source
)
Navigation menu
Personal tools
English
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
Module
Discussion
English
Views
Read
Edit source
View history
More
Search
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Tools
What links here
Related changes
Upload file
Special pages
Page information