وحدة:Cite Q/ملعب
المظهر
| هذه صفحة ملعب الوحدة لصفحة وحدة:Cite Q (فرق). |
--[[ Cite Q
النسخة العربية
مشتق من النسخة الإنجليزية
]]
require('strict')
local sandbox = '/ملعب'
local WdItem = require('Module:WdItem' .. sandbox)
local cfg = mw.loadData('Module:Cite Q/config' .. sandbox)
local ref_cash = {}
local rtl_lang = {
ar = true,
fa = true,
ur = true,
ku = true,
he = true,
arc = true,
dv = true,
ha = true,
khw = true,
ks = true,
ps = true,
yi = true,
ota = true
}
-- ________________________________ General Utility Functions ______________________________________
-------------------------------------------------------------------------------
-- makeOrdinal needs to be internationalised along with cfg.i18n_t
-- takes cardinal number as a numeric and returns the ordinal as a string
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.
-------------------------------------------------------------------------------
local makeOrdinal = function(cardinal)
local card = tonumber(cardinal)
if not card then return cardinal end
local ordsuffix = cfg.i18n_t.ordinal.default
if card % 10 == 1 then
ordsuffix = cfg.i18n_t.ordinal[1]
elseif card % 10 == 2 then
ordsuffix = cfg.i18n_t.ordinal[2]
elseif card % 10 == 3 then
ordsuffix = cfg.i18n_t.ordinal[3]
end
-- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th'
-- similarly for 12 and 13, etc.
if (card % 100 == 11) or (card % 100 == 12) or (card % 100 == 13) then
ordsuffix = cfg.i18n_t.ordinal.default
end
return card .. ordsuffix
end
--[[--------------------------< I S _ S E T >--------------------------------------------------------------
Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
]]
local function is_set(var)
return not (var == nil or var == '')
end
local function has_value(var)
return not (var == nil or var == '' or var == 'novalue' or var == 'somevalue')
end
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
Whether needle is in haystack (taken from Module:Citation/CS1/Utilities)
]]
local function in_array(needle, haystack)
if needle == nil then
return false
end
for n, v in ipairs(haystack) do
if v == needle then
return n
end
end
return false
end
-- wraps a string in nowiki unless disable flag is set
local function wrap_nowiki(str, disable)
if disable then return str or '' end
return mw.text.nowiki(str or '')
end
-- sort sequence table whose values are key-value pairs by key
local function comp_key(a, b)
local param_a, enum_a = a[1]:match('(%D+)(%d+)$'); -- get param name and enumerator from <a>
local param_b, enum_b = b[1]:match('(%D+)(%d+)$'); -- get param name and enumerator from <b>
if enum_a and enum_b then -- if both parameters have neumerators
if param_a == param_b then -- are parameter names the same?
return tonumber(enum_a) < tonumber(enum_b); -- yes: compare enumerators
end
end
return a[1] < b[1]; -- alpha sort if here
end
local function set_archive_args(arcurl, args)
if has_value(arcurl) then
local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)")
if arcy and arcm and arcd then
args["archive-url"] = arcurl
args["archive-date"] = arcy .. '-' .. arcm .. '-' .. arcd
end
end
end
--________________________________ Language Functions ______________________________________
local function getLanguages(languageArg)
local langcodes = {}
if languageArg then
-- check these are a supported language codes
for lc in mw.text.gsplit(languageArg, "[,، ]+", false) do --modified
langcodes[#langcodes + 1] = mw.language.isSupportedLanguage(lc) and lc
end
end
return langcodes
end
local function simplify_langauges(langs_t)
local newlangs = {}
for k,v in ipairs(langs_t) do
newlangs[#newlangs + 1] = v
local main_lang = v:match("^[^_-]+")
if main_lang ~= v then newlangs[#newlangs + 1] = main_lang; end
end
return newlangs
end
local function _getLangOfSnakProp(snak, pid)
if not pid or not snak then return {} end
local out = {}
local props = snak[pid]
for i, v in ipairs(props) do
if v.datatype == "monolingualtext" and v.datavalue then
out[#out + 1] = v.datavalue.value.language
end
end
return out
end
local function getLangOfProp(frame)
local pid = frame.args.pid or mw.text.trim(frame.args[1] or "")
if pid == "" then return end
local qid = frame.args.qid
if qid == "" then qid = nil end
local Q = WdItem.new(qid, { fwd = "ALL", onlysourced = false, noicon = true })
return table.concat(Q:getLangOfProp(pid), ", ")
end
-- gets the language codes of a Wikidata entry as a table
local function _lang_code(Qitem)
local lc = Qitem:getRawPropOfProp("P407", "P424")
if lc and #lc > 0 then return lc end
lc = Qitem:getRawPropOfProp("P407", "P218")
if lc and #lc > 0 then return lc end
return Qitem:getLangOfProp("P1476")
end
--________________________________ Author/Editor Display Functions ______________________________________
local function set_display_authors(args, contribtype)
local contrib_count = 0
for k, v in pairs(args) do
if k:find("^" .. contribtype .. "%d+$") then
contrib_count = contrib_count + 1
end
end
local key = 'display-' .. contribtype .. 's'
if contrib_count > 8 then -- convention in astronomy journals, optional mode for this?
if 'all' == args[key] then
args[key] = nil; -- unset because no longer needed
else
args[key] = args[key] or 3 -- limit to three displayed names
end
end
end
--[=[-------------------------< G E T _ N A M E _ L I S T >----------------------------------------------------
get_name_list -- adapted from getAuthors code taken from Module:RexxS
arguments:
nl_type - type of name list to fetch: nl_type = 'author' for authors; 'editor' for editors; 'translator' for translators
args - pointer to the parameter arguments table from the template call
qid - value from |qid= parameter; the Q-id of the source (book, etc.) in qid
wdlinks - value from the |wdlinks= parameter; a Boolean passed to enable links to Wikidata when no article exists
returns nothing; modifies the args table
]=]
local function get_name_list(nl_type, args, Q, wdlinks, lang)
local propertyID = "P50"
local fallbackID = "P2093" -- author name string
if nl_type == "author" then
propertyID = 'P50' -- for authors
fallbackID = 'P2093' -- author-string
elseif nl_type == "editor" then
propertyID = 'P5769' -- "editor-in-chief"
fallbackID = 'P98' -- for editors - So-called "fallbacks" are actually a second set of properties processed
-- TBD. Take book series editors into account as well (if they have a separate P code as well)?
elseif nl_type == "translator" then
propertyID = 'P655' -- for translators
fallbackID = nil
-- elseif 'contributor' == nl_type then
-- f.e. author of forewords (P2679) and afterwords (P2680); requires |contribution=, |title= and |author=
-- propertyID = 'P' -- for contributors
-- fallbackID = nil
else
return -- not specified so return
end
-- wdlinks is a Boolean passed to enable links to Wikidata when no article exists
-- if "false" or "no" or "0" is passed set it false
-- if nothing or an empty string is passed set it false
if wdlinks and (#wdlinks > 0) then
wdlinks = wdlinks:lower()
wdlinks = in_array(wdlinks, { "false", "no", "0" })
else
-- wdlinks is empty, so
wdlinks = false
end
local statements = Q:getStatements(propertyID)
if statements:count() == 0 and fallbackID then
statements = Q:getStatements(fallbackID)
end
-- Make sure it actually has at least one of the properties requested
if statements:count() == 0 then
return nil
end
-- So now we have something to return:
-- table 'out' is going to store the names(s):
-- and table 'link' will store any links to the name's article
local out = {}
local link = {}
local maxpos = 0
for _, s in statements:iter() do
-- maxpos = makelink(v, out, link, maxpos, wdlinks, lang)
local qnumber = s:getRawValue()
if qnumber ~= 'novalue' then
local label = s:getValue({ linked = false })
local slink
if label == 'somevalue' or label == 'Unknown' then
label = cfg.i18n_t["unknown-author"][lang] or cfg.i18n_t["unknown-author"]["ar"]
elseif mw.ustring.match(qnumber, '^Q%d+$') and qnumber ~= 'Q2818964' then
slink = mw.wikibase.getSitelink(qnumber, cfg.config_t.linksproject)
end
local position = maxpos + 1 -- Default to 'next' author.
position = tonumber(s:getRawQual("P1545")[1]) or position
maxpos = math.max(maxpos, position)
out[position] = label
if slink then link[position] = cfg.config_t.wikilinkprefix .. slink; end
end
end
-- if there's anything to return, then insert the additions in the template arguments table
-- in the form |author1=firstname secondname |author2= ...
-- Renumber, in case we have inconsistent numbering
local keys = {}
for k, v in pairs(out) do
keys[#keys + 1] = k
end
table.sort(keys) -- as they might be out of order
for i, k in ipairs(keys) do
out[k] = out[k]:gsub(''', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character
if args[nl_type .. i] then -- name gets overwritten
-- pull corresponding -link only if overwritten name is same as WD name
if link[k] and (args[nl_type .. i] == out[k]) then
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
end
else -- name does not get overwritten, so pull name from WD
args[nl_type .. i] = out[k]
if link[k] then
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
end
end
end
end
--________________________________ filtering functions ______________________________________
-- ref filtering for citing from wikidata
local function is_rejected(item)
-- rejected Q
if cfg.rejected_t.sources[item] == true then
return true;
end
-- rejected Properties
local item_entity = mw.wikibase.getEntity(item);
for _, v in pairs(cfg.rejected_t.properties) do
if (#item_entity:getAllStatements(v) > 0) then
return true;
end
end
-- Rejected InatanceOf
local instance = item_entity:getAllStatements("P31")
for _, v in pairs(instance) do
local vsnak = v.mainsnak or v
if cfg.rejected_t.instances[vsnak.datavalue.value.id] then
return true;
end
end
--No used Properties
local has_properties = false
for k, _ in pairs(cfg.used_properties_t) do
if (#item_entity:getAllStatements(k) > 0) then
has_properties = true;
break;
end
end
return not has_properties;
end
--________________________________ main functions ______________________________________
--[[-------------------------< C I T E _ W E B >------------------------------------------------------------------
used to pass wikidata reference claims to cite web template.
--]]
local function _cite_web(citeq_args)
local Q
local refsnak = citeq_args.snak
citeq_args.snak = nil
-- retrieve all the parameters
local pqid = citeq_args.pqid
citeq_args.pqid = nil
local wdlinks = false
local qid = nil
local multi_args = {
P50 = "author",
P2093 = "author",
P5769 = "editor",
P98 = "editor",
P655 = "translator",
}
local fallbackurls = {}
Q = WdItem.newSnakItem(refsnak,
{ fwd = "ALL", onlysourced = false, noicon = true, linksproject = cfg.config_t.linksproject, wikilinkprefix = cfg
.config_t.wikilinkprefix })
-- find language
local langcodes = getLanguages(citeq_args.language)
if refsnak["P1476"] then
langcodes = _getLangOfSnakProp(refsnak, "P1476")
citeq_args.language = citeq_args.language or table.concat(langcodes, ", ")
end
langcodes = simplify_langauges(langcodes)
for _, l in ipairs({ 'ar', 'en', 'mul' }) do
if not in_array(l, langcodes) then
langcodes[#langcodes + 1] = l
end
end
Q:setOptions({ langs = langcodes })
local labellang = langcodes[1]
local rtl = rtl_lang[langcodes[1]] or false
local oth = {}
for i in pairs(refsnak) do
local label = ""
-- multiple authors may be given
if refsnak[i][1].snaktype ~= 'novalue' then
if multi_args[i] then
get_name_list(multi_args[i], citeq_args, Q, wdlinks, labellang)
elseif cfg.used_properties_t[i] and type(cfg.used_properties_t[i]) == "table" then
local data = cfg.used_properties_t[i]
local langidx = 1
citeq_args[data.arg] = Q:getValue(i,
{ maxvals = data.maxvals, linked = data.linked, rank = data.rank or "best" })
if not citeq_args[data.arg] or citeq_args[data.arg]:find('^Q%d+$') then
citeq_args[data.arg] = Q:getValue(i, { maxvals = data.maxvals, linked = data.linked })
if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned
-- try fallback to qid's native language
local qid_languages = _lang_code(WdItem.newItem(citeq_args[data.arg],
{ fwd = "ALL", onlysourced = false, noicon = true }))
citeq_args[data.arg] = Q:getValue(i,
{ maxvals = data.maxvals, linked = data.linked, langs = qid_languages })
if citeq_args[data.arg]:find('^Q%d+$') then -- qid was returned again
citeq_args[data.arg] = nil
else
-- record the language found if no lang specified
citeq_args.language = citeq_args.language or qid_languages[1]
end
end
end
--- translate unknown value
if citeq_args[data.arg] == "Unknown" then
if rtl then
citeq_args[data.arg] = cfg.i18n_t.ar["unknown-" .. data.arg] or cfg.i18n_t.ar["unknown"]
else
citeq_args[data.arg] = mw.wikibase.getLabelByLang("Q4233718", langcodes[1]):gsub("^%l",
mw.ustring.upper)
end
end
-----------------
if data.others then
oth[#oth + 1] = citeq_args[data.arg] and
((rtl and cfg.i18n_t.ar[data.arg] or data.arg:gsub("^%l", string.upper)) .. ": " .. citeq_args[data.arg])
citeq_args[data.arg] = nil
end
elseif cfg.used_properties_t[i] then
if i == "P648" then
citeq_args.ol = (Q:getValue("P648", { maxvals = 1 }) or ''):gsub("^OL(.+)$", "%1")
if citeq_args.ol == "" then
citeq_args.ol = nil
end
elseif i == "P957" then
citeq_args.isbn = Q:getValue("P957", { maxvals = 1 })
elseif in_array(i, { "P854", "P953", "P856", "P2699" }) then
local url;
for _, pr in ipairs({ "P854", "P953", "P856", "P2699" }) do
url = Q:getStatements(pr):getBestOne():getRawValue()
if has_value(url) then
citeq_args.url = url
break;
end
end
end
end
if refsnak[i][1].datatype == "external-id" then
fallbackurls[#fallbackurls+1] = {
url = Q:getValue(i, { maxvals = 1, fullidurl=true}),
arg = cfg.used_properties_t[i] and cfg.used_properties_t[i].arg
}
end
end
end
if not citeq_args.url and #fallbackurls>0 then
for _,v in ipairs(fallbackurls) do
if not v.arg then
citeq_args.url = v.url
break;
end
end
if not citeq_args.url then
citeq_args.url = fallbackurls[1].url
citeq_args[fallbackurls[1].arg] = nil
end
end
if citeq_args.url then
if refsnak["P813"] then
citeq_args.accessdate = Q:getValue("P813", { maxvals = 1 })
end
if refsnak["P1065"] and refsnak["P2960"] then
citeq_args["archive-url"] = Q:getValue("P1065", { maxvals = 1 })
citeq_args["archive-date"] = Q:getValue("P2960", { maxvals = 1 })
elseif refsnak["P1065"] then
set_archive_args(Q:getValue("P1065", { maxvals = 1 }), citeq_args)
end
end
citeq_args.others = citeq_args.others or table.concat(oth, ". ")
if citeq_args.others == "" then
citeq_args.others = nil
end
citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv)
-- if url then see if there's an archive: citeq_args.url
local url
local title_display = citeq_args.title
if citeq_args.url then
citeq_args.title = wrap_nowiki(title_display)
end
-- TBD: incorporate |at, |sheets= and |sheet= here as well
-- Sort out what should happen if several of them are given at the same time
if citeq_args.page or citeq_args.p then -- let single take precedence over multiple
citeq_args.pages = nil
citeq_args.pp = nil
end
if citeq_args.pages then
local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "")
if count == 1 then
citeq_args.page = citeq_args.pages
citeq_args.pages = nil
end
end
-- replace no-break space by space, User:Mr. Ibrahem
if citeq_args.title then
citeq_args.title = mw.ustring.gsub(citeq_args.title, "\194\160", " ")
end
set_display_authors( citeq_args, 'author' )
set_display_authors( citeq_args, 'editor' )
-- code to make a guess what template to use from the supplied parameters
-- (first draft for proof-of-concept)
local template = "بويب"
-- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list
local list_sep = '. '
if citeq_args.mode ~= 'cs1' then
list_sep = ', '
end
-- clean up any blank parameters
for k, v in pairs(citeq_args) do
if v == "" then citeq_args[k] = nil end
end
if template then
-- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous
template = "استشهاد " .. template
else
-- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous
template = "استشهاد"
end
citeq_args['no-tracking'] = 'true' -- لإيقاف ظهور تصانيف التتبع
return mw.getCurrentFrame():expandTemplate { title = template, args = citeq_args } -- render the template
end
--[[-------------------------< C I T E _ Q >------------------------------------------------------------------
Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1=
are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to
{{citation}} for rendering.
--]]
local function _cite_q(in_citeq_args)
local frame = mw.getCurrentFrame()
local citeq_args = {}
local origin_args = {}
local Q
-- parameters that don't get passed to Citation
local expand = in_citeq_args.expand -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code>
local qid = in_citeq_args.qid or in_citeq_args[1]
local wdlinks = in_citeq_args.wdlinks
local template = in_citeq_args.template
local cite_class = 'citation'
local rtl = true
local snak = in_citeq_args.snak or {}
local pqid = in_citeq_args.pqid
local page_offset = 0
in_citeq_args.expand = nil
in_citeq_args[1] = nil
in_citeq_args.qid = nil
in_citeq_args.wdlinks = nil
in_citeq_args.template = nil
in_citeq_args.snak = nil
in_citeq_args.pqid = nil
if in_citeq_args.wikidatacite then
citeq_args = in_citeq_args
else
local A = require("Module:Argument Wrapper")(cfg.aliases_t, { in_citeq_args }, cfg.numbered_aliases_t)
-- local A = argument_wrapper(in_citeq_args)
local loaded_args = {}
for _, args_table in pairs({ cfg.simple_properties_t, cfg.used_args_t }) do
for k, _ in pairs(args_table) do
if A[k] then
citeq_args[k] = A[k]
if k ~= A:ORIGIN(k) then
origin_args[k] = A:ORIGIN(k)
loaded_args[#loaded_args + 1] = A:ORIGIN(k)
else
loaded_args[#loaded_args + 1] = k
end
end
end
end
for k, v in pairs(in_citeq_args) do
if not in_array(k, loaded_args) then
citeq_args[k] = v
end
end
end
-- if title supplied, flag to not read html title
local titleforced = (citeq_args.title ~= nil)
local default_opt = { rank = "preferred normal", fetchwikidata = "ALL", onlysourced = false, noicon = true, linksproject =
cfg.config_t.linksproject, wikilinkprefix = cfg.config_t.wikilinkprefix }
if citeq_args.volume or citeq_args.volume then
local qualifiedaspossible = {}
if citeq_args.volume then
qualifiedaspossible['P478'] = citeq_args.volume
end
if citeq_args.chapter then
qualifiedaspossible['P792'] = citeq_args.chapter
end
default_opt.qualifiedaspossible = qualifiedaspossible
end
Q = WdItem.WdItem:new(qid, default_opt, snak)
local oth = {}
-- put the language codes into a sequential table langcodes[]
local langcodes = getLanguages(citeq_args.language)
if not langcodes[1] then
-- try to find language of work
langcodes = _lang_code(Q)
end
if not langcodes[1] then
-- try fallback to journal's language
local journal_qid = Q:followQid("P1433")
langcodes = journal_qid and _lang_code(journal_qid) or {}
end
citeq_args.language = citeq_args.language or table.concat(langcodes, ", ")
langcodes = simplify_langauges(langcodes)
Q:setOptions({ langs = langcodes });
local labellang = langcodes[1] or 'ar'
rtl = rtl_lang[langcodes[1]] or false
-- loop through list of simple properties and get their values in citeq_args
for name, data in pairs(cfg.simple_properties_t) do
local opt = { maxvals = data.maxvals, linked = data.linked, qual = data.qual, hijri = data.hijri }
if data.no_vol_qual then opt.qualifiedaspossible = {}; end
citeq_args[name] = citeq_args[name] or Q:getValue(data.id, opt)
if not citeq_args[name] and data.populate_from_journal then
local publishedin = Q:getValue("P1433", { maxvals = 0, qual = data.id, qualsonly = true })
citeq_args[name] = publishedin or Q:getPropOfProp("P1433", data.id, { maxvals = data.maxvals })
end
if citeq_args[name] and snak[data.id] then
snak[data.id] = nil
end
--- translate unknown value
if citeq_args[name] == "Unknown" and rtl then
mw.log(name,"unknown")
citeq_args[name] = cfg.i18n_t.ar["unknown-" .. name] or cfg.i18n_t.ar["unknown"]
end
-----------------
if data.others then
oth[#oth + 1] = citeq_args[name] and
((rtl and cfg.i18n_t.ar[name] or name:gsub("^%l", string.upper)) .. ": " .. citeq_args[name])
citeq_args[name] = nil
end
end
citeq_args.others = citeq_args.others or table.concat(oth, ". ")
if citeq_args.others == "" then
citeq_args.others = nil
end
citeq_args.journal = citeq_args.journal and
citeq_args.journal:gsub("^''", ""):gsub("''$", ""):gsub("|''", "|"):gsub("'']]", "]]")
citeq_args.ol = citeq_args.ol or (Q:getValue("P648", { maxvals = 1 }) or ''):gsub("^OL(.+)$", "%1")
if citeq_args.ol == "" then
citeq_args.ol = nil
end
-- TBD. Take care of |ol-access=?
citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv)
citeq_args.isbn = citeq_args.isbn or
Q:getValue("P957", { maxvals = 1, rank = "best" }) -- try ISBN 10 (only one value accepted)
if citeq_args.page then -- let single take precedence over multiple
citeq_args.pages = nil
citeq_args.pp = nil
end
if citeq_args.pages then
local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "")
if count == 1 then
citeq_args.page = citeq_args.pages
citeq_args.pages = nil
end
end
-- Orginal Date
if not citeq_args['orig-date'] then
local work, origdate, origDateS = Q:getStatements('P629'):getBestOne():getRawValue()
local origOpt = { rank = "best", maxvals = 1, onlysourced = false, noicon = true }
local ishijri = false;
if has_value(work) then
local workQ = WdItem.newItem(work, origOpt)
origDateS = workQ:getStatements('P577', { df = 'y', qualifiedaspossible = { P4241 = '*' } }):getBestOne()
origdate = origDateS:getValue({ df = 'y', hijri = true })
if origdate then
ishijri = true
else
origdate = origDateS:getValue({ df = 'y' })
end
end
if not has_value(origdate) then
local author = Q:getStatements('P50'):getBestOne():getRawValue()
if has_value(author) then
local authorQ = WdItem.newItem(author, origOpt)
origDateS = authorQ:getStatements('P570', { df = 'y', qualifiedaspossible = { P4241 = '*' } })
:getBestOne()
origdate = origDateS:getValue({ df = 'y', hijri = true })
if has_value(origdate) then
ishijri = true
else
origdate = origDateS:getValue({ df = 'y' })
end
end
end
if has_value(origdate) then
local printDateS, printDate = Q:getStatements("P577", { df = 'y', qualifiedaspossible = { P4241 = '*' } })
:getBestOne()
if ishijri then
printDate = printDateS:getValue({ hijri = true })
if has_value(printDate) then
if (tonumber(origdate) or 3000) < (tonumber(printDate) or 0) then
citeq_args['orig-date'] = origdate .. 'هـ'
end
else
if (tonumber(origDateS:getValue()) or 3000) < (tonumber(printDateS:getValue()) or 0) then
citeq_args['orig-date'] = origdate .. 'هـ'
end
end
else
printDate = printDateS:getValue()
if (has_value(printDate) and ((tonumber(origdate) or 3000) < (tonumber(printDate) or 0)))
or not has_value(printDate) then
citeq_args['orig-date'] = origdate
end
end
end
end
local url
--find formatted url
if citeq_args.url == nil then
if snak ~= {} then
for k, v in pairs(snak) do
if (v[1].datatype == "external-id") then
citeq_args.url = mw.ustring.match(mw.wikibase.formatValue(v[1]), "%[(https?://[^%s%]]+)")
snak[k] = nil
break;
end
end
end
if citeq_args.url == nil and pqid and qid then
local refproperty = Q:getStatements("P1687"):getRawValue()
for k, p in ipairs(refproperty) do
if has_value(p) then
local refval = WdItem.WdItem:new(pqid):getValue(p, {fullidurl=true})
if has_value(refval) then
citeq_args.url = refval
break;
end
end
end
end
end
if not citeq_args.url then
local S953 = Q:getStatements("P953"):getBestOne()
local S953_val = S953:getRawValue()
citeq_args.url = has_value(S953_val) and S953_val or nil
if citeq_args.url then
if mw.ustring.match(citeq_args.url, "archive.org/details/") and citeq_args.page then
page_offset = tonumber(S953:getRawQual('P8330')[1]) or 0
if not citeq_args.volume or
(citeq_args.volume and (citeq_args.volume == S953:getRawQual('P478')[1])) then
citeq_args.url = mw.ustring.gsub(citeq_args.url, "/?$", "") ..
"/page/n" .. (tonumber(citeq_args.page) + page_offset - 1) .. "/mode/1up"
end
end
set_archive_args(S953:getRawQual('P1065')[1], citeq_args)
end
end
if not citeq_args.url then
for i, pr in ipairs({ "P856", "P2699" }) do
local surl = Q:getStatements(pr):getBestOne()
if surl then
local url = surl:getRawValue()
if has_value(url) then
citeq_args.url = url
set_archive_args(surl:getRawQual('P1065')[1], citeq_args)
break;
end
end
end
end
if not titleforced then
-- Handle subtitle.
if citeq_args.title then
local subtitle = Q:getValue('P1680');
if subtitle then
citeq_args.title = citeq_args.title .. ": " .. subtitle
end
end
local htmltitle = Q:getValue("P1476", { qual = "P6833", maxvals = 1, qualsonly = true })
if htmltitle then
citeq_args.title = htmltitle:gsub("</?i>", "''")
else
local title_display = citeq_args.title
or (langcodes[1] and mw.wikibase.getLabelByLang(qid, langcodes[1]))
or mw.wikibase.getLabel(qid)
if title_display and snak and snak.P1810 then
title_display = title_display .. " | " .. snak.P1810[1].datavalue.value
snak.P1810 = nil
end
title_display = title_display or ("No label or title -- debug: " .. qid)
if citeq_args.url then
citeq_args.title = wrap_nowiki(title_display)
else
local slink = mw.wikibase.getSitelink(qid, cfg.config_t.linksproject)
local slink_flag = false
local wrap_title = ''
local wslink = false
if not slink then
-- See if we have wikisource
if not citeq_args.url then
local wikisource_sitelink = mw.wikibase.getSitelink(qid, cfg.i18n_t.wikisource) or nil
if wikisource_sitelink then
slink = ':s:' .. wikisource_sitelink
wslink = true
end
end
end
if citeq_args.title then
if slink then
wrap_title = wrap_nowiki(citeq_args.title)
slink_flag = true
else
citeq_args.title = wrap_nowiki(citeq_args.title)
end
else
if slink and not wslink then
if slink:lower() == title_display:lower() then
citeq_args.title = '[[' .. slink .. ']]'
else
wrap_title = wrap_nowiki(slink:gsub("%s%(.+%)$", ""):gsub(",.+$", ""))
slink_flag = true
end
elseif wslink then
wrap_title = wrap_nowiki(title_display)
slink_flag = true
else
citeq_args.title = wrap_nowiki(title_display)
end
end
if slink_flag then
if slink == wrap_title and not wslink then -- direct link
citeq_args.title = '[[' .. slink .. ']]'
else -- piped link
citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]'
end
end
end
end
end
-- replace no-break space by space, User:Mr. Ibrahem
if citeq_args.title then
citeq_args.title = mw.ustring.gsub(citeq_args.title, "\194\160", " ")
end
if is_set(qid) then
if not is_set(citeq_args.author) and not is_set(citeq_args.author1) then -- if neither are set, try to get authors from Wikidata
get_name_list('author', citeq_args, Q, wdlinks, labellang) -- modify citeq_args table with authors from Wikidata
end
if not is_set(citeq_args.editor) and not is_set(citeq_args.editor1) then -- if neither are set, try to get editors from Wikidata
get_name_list('editor', citeq_args, Q, wdlinks, labellang) -- modify citeq_args table with editors from Wikidata
end
if not is_set(citeq_args.translator) and not is_set(citeq_args.translator1) then -- if neither are set, try to get translators from Wikidata
get_name_list('translator', citeq_args, Q, wdlinks, labellang) -- modify citeq_args table with translators from Wikidata
end
end
for k, v in pairs(citeq_args) do
if in_array(v, { '(())', 'unset', 'ignore' }) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}}
citeq_args[k] = nil
elseif in_array(v, { '((unset))', '((ignore))' }) then -- strip off markup for free-text values clashing with local keywords
citeq_args[k] = 'unset'
end
end
set_display_authors( citeq_args, 'author' )
set_display_authors( citeq_args, 'editor' )
-- change edition to ordinal if it's set and numeric
if (rtl == false) then citeq_args.edition = citeq_args.edition and makeOrdinal(citeq_args.edition) end
-- code to make a guess what template to use from the supplied parameters
-- (first draft for proof-of-concept)
if citeq_args.journal then
template = template or "بدورية محكمة"
elseif citeq_args.isbn then
template = template or "بكتاب"
citeq_args.asin = nil -- suppress ASIN if ISBN exists
elseif citeq_args.website then
template = template or "بويب"
end
-- template is CS1 designator: journal, web, news, etc.
if template then
-- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous
local citeclasses = { ["بدورية محكمة"] = 'journal', ["بكتاب"] = "book", ["بويب"] = "web" }
cite_class = cfg.citation_class_map_t[template] and template or citeclasses[template]
template = cfg.citation_class_map_t[template] or ("استشهاد " .. template)
else
-- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous
template = "استشهاد"
end
-- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list
local list_sep = '. '
if citeq_args.mode ~= 'cs1' then
list_sep = ', '
end
local id = cfg.i18n_t.wdq .. ':[[:d:' .. qid .. '|' .. qid .. ']]'
local old_id = citeq_args.id
if wdlinks then -- show WD logo
id = id .. '[[ملف:Wikidata-logo.svg|16px|alt=|link=]]' -- possibly replace by WD edit icon?
end
if is_set(old_id) then
citeq_args.id = old_id .. list_sep .. id -- append to user-specified contents
else
citeq_args.id = id
end
-- clean up any blank parameters
for k, v in pairs(citeq_args) do
if v == "" then citeq_args[k] = nil end
end
-- use real param names for CS1 messages
for k, v in pairs(origin_args) do
if citeq_args[k] and citeq_args[k] == in_citeq_args[v] then
citeq_args[v] = citeq_args[k]
citeq_args[k] = nil
end
end
-- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like
if expand then
local expand_args = { "{{" .. template .. "\n" } -- init with citation template
if expand == "self" then
citeq_args.id = old_id -- restore original |id= parameter
expand_args = { cfg.i18n_t.cite_q .. qid } -- expand to itself
end
-- make a sortable table and sort it by param name
local sorttable = {}
for param, val in pairs(citeq_args) do
sorttable[#sorttable + 1] = { param, val }
end
table.sort(sorttable, comp_key)
-- add contents to expand_args
for idx, val in ipairs(sorttable) do
expand_args[#expand_args + 1] = val[1] .. '=' .. val[2] .. "\n"
end
-- make the nowiki'd string and done
return frame:preprocess(table.concat({ '<syntaxhighlight lang="wikitext" inline="1">', table.concat(expand_args,
' |') .. '}}', '</syntaxhighlight>' }));
end
local erratumid = Q:getPropertyIDs("P2507", { maxvals = 1 })
if erratumid then
erratumid = " [[d:" .. erratumid .. "|" .. cfg.i18n_t.erratum .. "]]" .. cfg.i18n_t.trackingcats.erratum
else
erratumid = ""
end
local opt_cat = ''
if Q:getValue("P5824") then
opt_cat = cfg.i18n_t.trackingcats.retracted
end
if Q:getValue("P1366") then
opt_cat = opt_cat .. cfg.i18n_t.trackingcats.replaced
end
if not citeq_args.title then -- emit category link if missing title
opt_cat = opt_cat .. cfg.i18n_t.trackingcats['no-label-or-title'];
end
if citeq_args.wikidatacite then
return frame:expandTemplate { title = template, args = citeq_args } ..
erratumid .. opt_cat -- render the template
else
local CS = require("Module:Citation/CS1" .. sandbox)
return CS._citation(frame, citeq_args, { ['CitationClass'] = cite_class }) .. erratumid .. opt_cat
end
end
--[[-------------------------< C I T E W I K I D A T A >------------------------------------------------------------------
format wikidata reference
--]]
local function _cite_wikidata(ref, pqid, expand)
-- early exit
if not ref then
return nil
end
local snak = ref.snaks
-- مراجع غير مقبولة
if snak.P143 or snak.P3452 then
return nil
end
local hash = ref.hash
if not is_set(hash) then
mw.log ("hash is not set")
return nil
end
local hashpre = (is_set(sandbox) and 'wikidata-s-' or 'wikidata-')
local frame = mw.getCurrentFrame()
if ref_cash[hash] ~= nil then
if ref_cash[hash] == false then
return nil
end
return frame:extensionTag("ref", '' , { name = hashpre .. hash })
end
local citeq_args = {}
-- مذكور في
if snak.P248 then
for _, prop in pairs(snak.P248) do
if prop.snaktype == "value" then
citeq_args.qid = prop.datavalue.value.id
break;
end
end
snak.P248 = nil;
end
if citeq_args.qid and is_rejected(citeq_args.qid) == true then
return nil
end
local reference
citeq_args.snak = snak
citeq_args.pqid = pqid
citeq_args.wikidatacite = 1
citeq_args.expand = expand
if citeq_args.qid then
reference = _cite_q(citeq_args)
else
local has_properties = false
for k, _ in pairs(cfg.used_properties_t) do
if snak[k] then
has_properties = true;
break;
end
end
reference = (has_properties and _cite_web(citeq_args) or nil)
end
if is_set(reference) then
reference = frame:extensionTag("ref", reference, { name = hashpre .. hash })
ref_cash[hash] = true
else
ref_cash[hash] = false
end
return reference
end
local function cite_q(frame)
local args = {}
for k, v in pairs(frame:getParent().args) do
if v ~= "" then args[k] = v end
end
for k, v in pairs(frame.args) do
if v ~= "" then args[k] = v end
end
args.qid = args.qid or args[1] or ""
if args.qid == "" then return nil end
args[1] = nil
local citesep = (args.citesep or "")
if citesep == "" then citesep = ", " end
citesep = citesep:gsub('"', '') -- strip double quotes after setting default to allow |citesep="" as a blank separator
args.citesep = nil
local tag = args.tag or ""
if tag == "" then tag = nil end
args.tag = nil
local list = args.list or ""
if list == "" then list = nil end
args.list = nil
args.language = args.language or args.lang
args.lang = nil
local cites = {}
for q in args.qid:gmatch("Q%d+") do
-- make a new copy of the arguments
local newargs = {}
for k, v in pairs(args) do
if k ~= "qid" then
newargs[k] = v
end
end
newargs.qid = q
if tag == "ref" then
cites[#cites + 1] = frame:callParserFunction { name = "#tag:ref", args = { _cite_q(newargs), name = q } }
-- expand like this: args = { _cite_q(newargs), name = 'foo', group = 'bar' }
else
cites[#cites + 1] = _cite_q(newargs)
end
end
if list then
return frame:expandTemplate { title = list, args = cites }
else
return table.concat(cites, citesep)
end
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
makeOrdinal = makeOrdinal,
getLangOfProp = getLangOfProp,
_cite_wikidata = _cite_wikidata,
_cite_q = _cite_q,
cite_q = cite_q
}