Documentation for this module may be created at ماڈیول:Cite/doc

--/-- Creates a timeline for an item based on various properties 
local Known_properties = {"P304",  "P50", "P957",  "P478", "P98", "P393", "P1476", "P357", "P123", "P577", "P433", "P275", "P698", "P356", "P958", "P1433",  "P1680", "P1683", "P387", "P1065" ,"P212","P854","P170","P248","P143"}--,"P345"
local p = {}
local wikidata = require('ماڈیول:Wikidata2').formatStatementsFromLua
local quall =  require('Module:Cite/quall')
--local wikidata2 = require('ماڈیول:Wikidata2').formatEntityId -- table

local function getentityprop(entity, p , pattern )
    -- get automatically url
	local Pattern = (pattern or 'autourl4')--autourl3
	local tot =  wikidata({ property = p , pattern = Pattern , noref = 'true', conjunction = ' & ',enlabelcate ='true', addTrackingCat= "t" , noicon = "t"   })
	local tot1 =  wikidata({entityId = entity, property = p , pattern = Pattern , noref = 'true', conjunction = ' & ',enlabelcate ='true', addTrackingCat= "t", noicon = "t" })
		if not tot or tot == '' then
			tot = tot1 
		end
--	if tot and tot ~= '' then
	--	return tot --ربط: 
	--end
	
	if tot and tot ~= '' then
		tot = 'ربط : ' .. tot
	end
	return  tot
end

--[[
   يجلب خواص معينة عند وجود مراجع محددة مسبقاً
--]]
local function getsomequall(entity, snak, property)
	if snak[property]
	and snak[property][1]
	and snak[property][1].datavalue
	and snak[property][1].datavalue.value['numeric-id']
	then 
		house = snak[property][1].datavalue.value['numeric-id'] 
		local l10n = quall[house]
		if l10n then
			local q = {}
			for _, v in pairs(l10n) do
				mw.log("finding " .. v[1] .. "house" .. house )
				b =  getentityprop (entity, v[1] , v[3])
				if b and b ~= '' 
					then table.insert( q, b ) 
				end
			end
			t =  table.concat( q )
			if t and t ~= '' then
				return t
			end
		end
	end
end

local function get_property_label( Id )
	local label = mw.wikibase.label( Id )
	return label
end

local function geturl(url,text)
	if url and url ~= '' then 
		return '[' .. url .. ' ' .. (text or url) .. ']'
	end
end

local function labeel(property,text)
		local pro = mw.wikibase.label( property ) 
			if not text or text == '' then text = pro end 
		if text then 
			return text
		end
end
local function P1629(property,text)
	--local pro = wikidata({property = 'P1629', nolink = 'true', entityId = property, enbarten = 'true', noref = 'true',enlabelcate ='true' , label = get_property_label(property) }) 
	local pro = get_property_label(property)
	if not text or text == '' then text = pro end 
	if text then 
		return text
	end
end

local function ValueFromItem(items, property,enbarten)
	local pattern = 'autourl'
	if property =='P212' or property =='P957' then pattern = nil end -- no automatic link for ISBN
	for i, item in pairs(items) do
		ednumber = wikidata({entityId = item, property = property , enbarten = enbarten, pattern =pattern
			, noref = 'true', modifytime = 'longdate',enlabelcate ='true'})
	end
	return ednumber 
end

local function ValueFromEntityId(entity, property,enbarten)
	local pattern = 'autourl'
	val = wikidata({entityId = entity, property = property, enbarten = enbarten, pattern = pattern
		, noref = 'true', modifytime = 'longdate',enlabelcate ='true'})
	if val then 
		return val 
	end
end

--local function GetValueFromEntityId(snak,entity, property, enbarten)
local function GetValueFromEntityId(snak,property, enbarten)
	--local A = wikidata({property = 'P1629', entityId = property,enlabelcate ='true' , enbarten = 'true', noref = 'true', label = get_property_label( property )}) 
	local A = get_property_label(property)
	local prop = wikidata({property = property, enbarten = enbarten, noref = 'true'
		, pattern = 'autourl', modifytime = 'longdate'}, snak)
	--if not prop then prop = ValueFromEntityId(entity, property,enbarten) end
	if prop  and prop ~= '' then
		if A  and A ~= '' then
			return A .. ': ' .. prop
		else
			return prop
		end
	end
end

local function GetValueFromItem(items, snak, property , text,enbarten)
	local pattern = 'autourl'
	if property =='P212' or property =='P957' then pattern = nil end -- no automatic link for ISBN
	local prop = wikidata({property = property
		, enbarten = enbarten
		, pattern = pattern
		, noref = 'true'
		, modifytime = 'longdate'
		,enlabelcate ='true'}, snak)
	if not prop 
		then prop = ValueFromItem(items, property,enbarten)
	end
	if prop and prop ~= '' then
		if text and text ~= '' then prop  = text ..': '.. prop end
	end
	return prop
end

local function get_number_from_item(items, property)
	for i, item in pairs(items) do
		ednumber = wikidata({entityId = item, property = property, enbarten = 'yes',enlabelcate ='true'})
		if ednumber then 
			return ednumber 
		end
	end
end
local function getnumber(items, snak, property,text)

	--local tex = wikidata({property = 'P1629', entityId = property, enbarten = 'true', noref = 'true', label = get_property_label(property ) 
		--, label = wikidata2(property, {nolink = 'true', noref = 'true',enlabelcate ='true'}).value
	--})
	local tex = get_property_label(property ) 

	local number = wikidata({property = property, enbarten = 'true',enlabelcate ='true'}, snak)
	if not number then
		number = get_number_from_item(items, property)
	end
    if not text then text = tex else end

	if number  and number ~= '' then
		 if text then
		 	return text ..': '.. number  
	 			else return number
	 		end
	end
end

local function GetItemValue(items, snak, property , text,enbarten)
	local pattern = 'autourl'
	--	if property =='P212' or property =='P957' then pattern = nil end -- no automatic link for ISBN
	local prop = wikidata({property = property, enbarten = (enbarten or ''), pattern = pattern, noref = 'true', modifytime = 'longdate'
		,separator='، ',conjunction='، '}, snak)
		if not prop then prop = ValueFromItem(items, property,(enbarten or '')) end
	
	if prop and prop ~= '' then
		if text and text ~= '' then prop  = text ..': ' .. prop end
	end
	return prop
end

local function GetNumberFromItem(items, snak, property , text,enbarten)
	local prop = wikidata({property = property, enbarten = 't'}, snak)
	for i, item in pairs(items) do
		ednumber = wikidata({entityId = item, property = property , enbarten = 'true', noref = 'true'})
	end
		if not prop then prop = ednumber  end
	if prop and prop ~= '' then
		if text and text ~= '' then prop  = text .. prop end
	end
	return prop
end

--[[
  جلب أي وصلة مرجع من الخواص مثل
     P1065,P854
--]]

local function getLink(items, snak, property,text)
	-- local tex = labeel(property,text)
	local links = wikidata({property = property, pattern = 'true', noref = 'true' , enbarten = 'true'}, snak)
	if links and links ~= '' then
		if text and text ~= '' 
			then return geturl(links,text)
			else return links
 		end
	end
end
local function getLink1(items, snak, property,text)
	local links = ValueFromItem(items, property,'true')
	local tex = labeel(property,text)
	if links and links ~= '' then
		if tex and tex ~= '' 
			then return  tex ..': '.. links
			else return links
 		end
	end
end
--[[
  جلب أي تاريخ من الخواص مثل
     P813,P577
--]]

local function getdate( snak, property,text)
	-- local tex = labeel(property,text)
	if snak[property] then
		local dat = wikidata({property = property, pattern = 'true', noref = 'true', modifytime = 'longdate'}, snak)
		if dat and dat ~= '' then
			if text and text ~= '' 
				then return text .. ': '.. dat
				else return dat
	 		end
		end
	end
end

local function getdate1(items, snak, property,text)
	for i, item in pairs(items) do
		local datetime1 = wikidata({entityId = item, property =property, noref = 'true',enlabelcate ='true', modifytime = 'longdate' })
	end
	if text then
		return text ..': '.. datetime1
			else return datetime1
	end
end

local function getedition(items, snak )
	local ordning = {'اول', 'دوم', 'سوم', 'چہارم', 'ّپنجم', 'ششم', 'ہفتم', 'ہشتم', 'نہم', 'دہم', 'گیارہ', 'بارہ'}
	local ednumber;
	if snak['P393'] then
		ednumber = wikidata({property = 'P393', enbarten = 'true',enlabelcate ='true'}, snak)
	else
		ednumber = get_number_from_item(items, "P393")
	end
	if not ednumber then 
		return nil
	end
	if not tonumber(ednumber) then
		return  ' اشاعت ' .. ednumber 
	end
	if ordning[tonumber(ednumber)] then
		return  ' اشاعت ' .. ordning[tonumber(ednumber)] 
	end
	local sist = string.sub(ednumber, string.len(ednumber))
	if sist == '1' or sist == '2' then
		return  ' : اشاعت ' .. ednumber 
	else
		return ' : اشاعت ' .. ednumber 
	end
end

local function getsubtitle(items, snak)-- needs i18n some languages do not use this format
	local s = {}
	if snak['P1680'] then
		table.insert(s, wikidata({property = 'P1680', enbarten = 'true',enlabelcate ='true'}, snak))
	else
		for i, item in pairs( items) do
			local lab = wikidata({property = 'P1680',enlabelcate ='true', entityId = item, enbarten = 'true', noref = 'true'})
			local sitelink = mw.wikibase.sitelink( item )
			if sitelink and lab then
				table.insert(s, '[[:' .. sitelink .. '|' .. lab .. ']]')
			elseif sitelink then
				table.insert(s, '[[:' .. sitelink .. ']]')
			elseif lab then
				table.insert(s, lab)
			end
		end
	end
	tot = table.concat(s, ' — ')
	if tot and tot ~= '' then
		return tot
	else
		return nil
	end
end

local function gettitle(items, snak)
	local link = getLink(items, snak, 'P854') or getLink(items, snak, 'P1065','')  -- the title will be with the link
	local title = GetItemValue(items, snak, 'P1476' ,  'عنوان ' ,' ')
	local subtitle = GetItemValue(items, snak, 'P1680' ,  'عنوان ' ,' ')
		if not title or title =='' then title = subtitle end
		if link and link ~= ''
		then
			return '' 
		else 
			return title
		end
end

local function getwhatever(snak, property)
	if snak[property] then
		--mw.log("getwhatever property " .. property)
		local a = get_property_label(property)
		--local a = wikidata({property = 'P1629', entityId = property, enbarten = 'true', noref = 'true',enlabelcate ='true', label =  get_property_label(property)}) 
			
		local s = {}
		--local items = {}
		--mw.log("find snak.property " .. property)
		for j, prop in pairs(snak[property]) do
			if prop.snaktype == 'value' then
				item = 'Q' .. prop.datavalue.value['numeric-id']
				--table.insert(items, item)
				faso =  wikidata({entityId = item, property = property, noref = 'true', conjunction = ', ',enlabelcate ='true'})
				table.insert( s, faso )
			end 
		end
		if property == "P143" then a = 'درآمد شدہ از ' end
		if property == "P248" then a = "'''مذکور'''" end
		--table.insert(s, wikidata({property = property, conjunction = ', ',enlabelcate ='true'}, snak))
		if #s > 0 then
			return (a or  '') .. "''':''' " .. table.concat(s, ', ')
		end
	end
end

--local function gettherest(snak, entity)
local function gettherest(snak)
	local s = {}
	for property, j in pairs(snak) do
		Known = false
		for k, l in pairs(Known_properties) do
			if property == l then 
				Known = true
			end
		end
		if not Known then
			local entity1 = mw.wikibase.getEntityObject( property )
			if entity1.claims and ( entity1.datatype == 'string' or entity1.datatype == 'external-id' ) then
				--local vaa =  GetValueFromEntityId(snak , entity , property , 'true' )
				local vaa =  GetValueFromEntityId(snak , property , 'true' )
				--mw.log("gettherest property:" .. property )
				table.insert(s, vaa) 
			end
		end
	end
	if #s > 0 then
		return table.concat(s, ' — ')
	end
end

function numbers( items, snak)
	local section  = GetNumberFromItem(items, snak, 'P958','باب: ')
	local volume  = GetNumberFromItem(items, snak, 'P478','جلد: ')
	local page = GetNumberFromItem(items, snak, 'P304','صفحہ: ')
	local issue = GetNumberFromItem(items, snak, 'P433','شمارہ: ')

	field = {}
		if section and section ~= '' then 	table.insert(field, section)	end
		if volume and volume ~= '' then 	table.insert(field, volume)	end
		if page and page ~= '' then 	table.insert(field, page)	end
		if issue and issue ~= '' then 	table.insert(field, issue)	end
	return table.concat(field, ' — ')
end

local function getISBN(items, snak)
	local ISBN13 = GetNumberFromItem(items, snak, 'P212' ,'ISBN ','yes') --ISBN 13
	local ISBN10 = GetNumberFromItem(items, snak, 'P957' ,'ISBN ','yes')  --ISBN 10
		if not ISBN13 or ISBN13 =='' then ISBN13 = ISBN10 end
	return ISBN13  
end

function doipmid( items, snak)
	local doi = GetValueFromItem(items, snak, "P356" )-- Digital Object Identifier
	local pmid = GetValueFromItem(items, snak, "P698" )-- Identifier for journal 
	local pmc = GetValueFromItem(items, snak,'P932')-- identifier issued by PubMed Central
	field = {}
	if doi and doi ~= '' then 	table.insert(field, doi)	end
	if pmid and pmid ~= '' then 	table.insert(field, pmid)	end
	if pmc and pmc ~= '' then 	table.insert(field, pmc)	end
	return table.concat(field, ' — ')
end

local function Getquall(snak , entity)
	local quall = getsomequall(entity, snak, "P143" )
	local quall1 = getsomequall(entity, snak, "P248" )
		if not quall or quall =='' then quall = quall1 end
	return quall
end

function getMultiLink(items, snak , entity)
	local title = GetItemValue(items, snak, 'P1476' ,'' ,'')
	local link = getLink(items, snak, 'P854',title)--,'حوالہ یو آر ایل'
	local link1 = getLink1(items, snak, 'P854') -- 
	--local therest = gettherest(snak, entity)
	local therest = gettherest(snak)
	local quall = Getquall(snak , entity)
	local fulltext = getLink1(items, snak, 'P953') -- 
	local accessdate =getdate(snak, 'P813','اخذ شدہ بتاریخ')
	local archive  = getLink(items, snak, 'P1065','')
	field = {}
	if link and link ~= '' 					then newtab = link  --We don't need to search for some links if they here already
	elseif therest and therest ~= ''  		then newtab = therest 
	elseif quall and quall ~= ''  			then newtab = quall 
	elseif link1 and link1 ~= ''  			then newtab = link1  -- last thing we want to see
	elseif fulltext and fulltext ~= ''  	then newtab = fulltext
	end
	if link and link ~='' then if archive and archive ~='' then archiveandlink = 't' end end
		if newtab and newtab ~= '' then
			table.insert(field, newtab) 
			if accessdate and accessdate ~= '' then table.insert(field, accessdate)  end
		end
	if archiveandlink and archiveandlink ~= '' 
	then 
		return '' 
	else
		return table.concat(field, ' — ')
	end
end

function getarchiveLink(items, snak , entity)
	local title = GetItemValue(items, snak, 'P1476' ,'' ,'')
	local link = getLink(items, snak, 'P854','')

	local archive  = getLink(items, snak, 'P1065','')
	local archive1  = getLink(items, snak, 'P1065','آرکیو یو آر ایل')
	local archivedate =getdate(snak, 'P2960','')-- تاريخ آرکیو
	local accessdate =getdate(snak, 'P813','اخذ شدہ بتاریخ')
	local aa =  geturl((archive or link),title)
	
	field = {}
	if archive and archive ~= '' then 
		if aa and aa ~= '' then table.insert(field, aa) end
		if link and link ~='' then
			org = geturl(link,'اصل')
			if accessdate and accessdate ~= '' then table.insert(field, accessdate)  end
		end
			a =  ' سے آرکائیو ' .. (org or 'اصل')
			if archivedate and archivedate ~= ''  then a =a ..   ' فی ' 	.. archivedate end
			table.insert(field, a)
	end
	return table.concat(field, ' — ')
end

function getreftable( items, snak , hash , options )
    local entity = options.entityId
	local author = GetValueFromItem(items, snak, 'P50','مصنف')
	--local editor = getEditor(items, snak )
	local editor = GetValueFromItem(items, snak, 'P98','مدیر')
	local title = gettitle(items, snak )
	local publisher = GetValueFromItem(items, snak, 'P123','ناشر')
	local creator = GetValueFromItem(items, snak, 'P170','خالق')
	local publishedin = GetValueFromItem(items, snak, 'P1433','شائع شدہ از')

	--local publishedin = getpublishedin(items, snak )
	--local publishdate = getPublishdate(items, snak )
	local publishdate = getdate( snak, 'P577','شائع شدہ از')
	local edition = getedition(items, snak )
	local number = numbers( items, snak)
	local doipmid = doipmid( items , snak)
	local isbn = getISBN(items, snak ) --0

	--local whatever= whatever(items, snak, "P212" )
	local import = getwhatever(snak, "P143" ) or getwhatever(snak, "P248" )

	local MultiLink = getMultiLink(items, snak , entity)
	local archiveLink = getarchiveLink(items, snak , entity)
	
	local license = GetItemValue(items, snak, 'P275','اجازت نامہ')
	local quote =  GetItemValue(items, snak, 'P1683' ,  'اقتباس' ,' ') --  
	if title and title ~= '' and subtitle and subtitle ~= '' then 
		--title = title .. ' : ' .. subtitle
	end
	for i, item in pairs(items) do
		if item == 'Q36578' 
			then edition,author  = nil,nil
		end
	end
	field = {}
	--if whatever and whatever ~= '' then table.insert(field,whatever) end
	if import and import ~= '' then table.insert(field, import) end
	
	if MultiLink and MultiLink ~= '' then table.insert(field, MultiLink)  end
	if archiveLink and archiveLink ~= '' then table.insert(field, archiveLink)  end

	if author and author ~= '' then table.insert(field, author) end
	if editor and editor ~= '' then table.insert(field, editor) end
	if title and title ~= '' then table.insert(field, title) end
	if edition and edition ~= '' then table.insert(field, edition) end
	if number and number ~= '' then 	table.insert(field, number)	end

	if publisher and publisher ~= '' then table.insert(field, publisher) end
	if creator and creator ~= '' then table.insert(field, creator) end
	if publishedin and publishedin ~= '' then table.insert(field, publishedin) end
	if publishdate and publishdate ~= '' then table.insert(field, publishdate) end
    if appliestopart and appliestopart ~= '' then table.insert(field, appliestopart) end
	if isbn and isbn ~= '' then 	table.insert(field, isbn)	end
	if doipmid and doipmid ~= '' then 	table.insert(field, doipmid)	end

	if license and license ~= '' then table.insert(field, license) end
	if quote and quote  ~= '' then table.insert(field, quote ) end
	
	local doo =  table.concat(field, ' — ')
	if doo and doo ~= '' then
		return doo --mw.getCurrentFrame():extensionTag( 'ref', doo, {name = hash} )
	end
end

local function findblacklist(items)
	 -- function to ignore Sister projects
	local val = 'false'
	local s = {}
		for i, item in pairs(items) do
			function qoo(item,property)
				return wikidata({entityId = item, property = property , noref = 'true',enbarten='1',formatting = 'raw'})
			end
			local wiki = qoo(item, 'P1800') or qoo(item, 'P1566') or qoo(item,'P21') -- all wikimedia site ,GeoNames ,gender
			local wik2 = qoo(item, 'P31')
			local blackk = {"Q20651139",  "Q465", "Q15241312"} 
			for k, b in pairs(blackk) do
				if item == b then  val = 'true' end
			end
			if wiki and wiki  ~= ''
				then val = 'true'
				elseif wik2 == 'Q5' -- Human is not a direct reference
					or wik2 == 'Q184188'  -- Also Canton
					or wik2 == 'Q1250464' then val = 'true' -- Also places
			end
	end
	return val
end

local ref_cash = {}

function p.citeitem( items, snak , hash , options , notag)
	Options = options
	if hash and hash ~= "" and ref_cash[hash] then 
		--mw.log("Module:Cite ref_cash[hash] = " .. hash)
		return ref_cash[hash] 
	end
	if not items and not snak then return nil end
	if type(items) == 'string' then
		items= {items}
	end
	items= {}
	if snak.P248 then
		for j, prop in pairs(snak.P248) do
			if prop.snaktype == 'value' then
				table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
			end 
		end
	elseif snak.P143 then
		for j, prop in pairs(snak.P143) do
			if prop.snaktype == 'value' then
			table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
			end 
		end
	end
	local blacklist1 = findblacklist(items)
	if blacklist1 == 'true' then return nil end
	--local findtype = FindTypeOfRefrence(items, snak, options)
	local refrence = getreftable( items, snak , hash , options )
	if refrence and refrence ~=''  then
		if notag and notag ~=''  then
			refrence = refrence
		else
			refrence = mw.getCurrentFrame():extensionTag( 'ref', refrence, {name = hash} )
		end
	end
	if hash and hash ~= "" then 
		ref_cash[hash] = refrence
	end
	return refrence
end

function p.citeitem2( ref , options , notag)
	if not ref then return nil end
	local hash = ref.hash
	local snak = ref.snaks
	local snnaks = ""
	if hash and hash ~= "" and ref_cash[hash] then 
		--mw.log("Module:Cite ref_cash[hash] = " .. hash)
		return ref_cash[hash] 
	end
	for Px, prope in pairs(snak) do
		snnaks = snnaks .. "," .. Px
	end
	--mw.log( "Citeitem2 hash: " ..  hash )
	--mw.log( "*snnaks : " ..  snnaks )
	items= {}
	if snak.P248 then
		for j, prop in pairs(snak.P248) do
			if prop.snaktype == 'value' then
				table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
			end 
		end
	elseif snak.P143 then
		for j, prop in pairs(snak.P143) do
			if prop.snaktype == 'value' then
			table.insert(items, 'Q' .. prop.datavalue.value['numeric-id'])
			end 
		end
	end
	local blacklist1 = findblacklist(items)
	if blacklist1 == 'true' then return nil end
	--local findtype = FindTypeOfRefrence(items, snak, options)
	local refrence = getreftable( items, snak , hash , options )
	if refrence and refrence ~='' then
		if notag and notag ~='' then
			refrence = refrence
			else
			refrence = mw.getCurrentFrame():extensionTag( 'ref', refrence, {name = hash} )
			end
		end
	if hash and hash ~= "" then 
		ref_cash[hash] = refrence
	end
	return refrence
end

function p.reflist(frame)
	local list = mw.text.split( frame.args.item, ' ')
	local s = {}
	for i, j in pairs(list) do
    	local item = mw.wikibase.getEntityObject( mw.text.trim(j) )
		local str = p.citeitem( {mw.text.trim(j)} , item.claims, mw.text.trim(j)..i , frame.args , 't')
		if str then table.insert(s, '*'.. str) end
	end
	return table.concat(s, '\n')
end

function p.cite(frame)
    	local item = mw.wikibase.getEntityObject( frame.args.item )
    	if not item then return 'no item ' end
    		return p.citeitem( {frame.args.item} , item.claims, frame.args.item, frame.args , 't')
end

function p.listquall(frame)
	local list = mw.html.create("table")
	list:addClass("wikitable sortable collapsible")
	local head = list:tag("tr")
	head:tag("th"):wikitext("#")
	head:tag("th"):wikitext("خاصیت")
	head:tag("th"):wikitext("خاصیت")
	local number = 0
	for v, nam in pairs(quall) do
		for _1, nam1 in pairs(nam) do
			number = number + 1
			local row = list:tag("tr")
			row:tag("td"):tag("span"):wikitext(number)
			local th = row:tag("td")
			local rr = row:tag("td")
			local dd = frame:preprocess("{{Q|Q".. v .."}}") 
			th:tag("span"):wikitext(dd)
			local u = frame:preprocess("{{P|".. nam1[1] .."}}") 
			rr:tag("span"):wikitext(u)
		end
	end
	return list
end	
return p