16,599
edits
>IceWelder (Avoid Lua errors should Wikidata not be available (tested via sandbox & testcases)) |
Ajay Kumar (talk | contribs) (Trying to fix some issues.) |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
-- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]]. | -- Original module located at [[:en:Module:Wd]] and [[:en:Module:Wd/i18n]]. | ||
require("strict") | |||
local p = {} | local p = {} | ||
local arg = ... | local arg = ... | ||
Line 72: | Line 73: | ||
image = "P18", | image = "P18", | ||
author = "P50", | author = "P50", | ||
authorNameString = "P2093", | |||
publisher = "P123", | publisher = "P123", | ||
importedFrom = "P143", | importedFrom = "P143", | ||
wikimediaImportURL = "P4656", | |||
statedIn = "P248", | statedIn = "P248", | ||
pages = "P304", | pages = "P304", | ||
Line 94: | Line 97: | ||
inferredFrom = "P3452", | inferredFrom = "P3452", | ||
typeOfReference = "P3865", | typeOfReference = "P3865", | ||
column = "P3903" | column = "P3903", | ||
subjectNamedAs = "P1810", | |||
wikidataProperty = "P1687", | |||
publishedIn = "P1433" | |||
} | } | ||
Line 148: | Line 154: | ||
} | } | ||
local | local function replaceAlias(id) | ||
if aliasesP[id] then | |||
id = aliasesP[id] | |||
end | |||
return id | |||
end | |||
local function errorText(code, param) | |||
local text = i18n["errors"][code] | |||
if param then text = mw.ustring.gsub(text, "$1", param) end | |||
return text | |||
end | |||
local function throwError(errorMessage, param) | |||
error(errorText(errorMessage, param)) | |||
end | |||
local function replaceDecimalMark(num) | |||
return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1) | |||
end | |||
local function padZeros(num, numDigits) | |||
local numZeros | |||
local negative = false | |||
if num < 0 then | |||
negative = true | |||
num = num * -1 | |||
end | |||
num = tostring(num) | |||
numZeros = numDigits - num:len() | |||
for _ = 1, numZeros do | |||
num = "0"..num | |||
end | |||
if negative then | |||
num = "-"..num | |||
end | |||
return num | |||
end | |||
local function replaceSpecialChar(chr) | |||
if chr == '_' then | |||
return | -- replace underscores with spaces | ||
return ' ' | |||
else | |||
return chr | |||
end | |||
end | end | ||
local | local function replaceSpecialChars(str) | ||
local chr | |||
local esc = false | |||
local strOut = "" | |||
for i = 1, #str do | |||
chr = str:sub(i,i) | |||
if not esc then | |||
if chr == '\\' then | |||
esc = true | |||
else | |||
strOut = strOut .. replaceSpecialChar(chr) | |||
end | |||
else | |||
strOut = strOut .. chr | |||
esc = false | |||
end | |||
end | |||
return strOut | |||
end | |||
local function buildWikilink(target, label) | |||
if not label or target == label then | |||
return "[[" .. target .. "]]" | |||
else | |||
return "[[" .. target .. "|" .. label .. "]]" | |||
end | |||
end | |||
-- used to make frame.args mutable, to replace #frame.args (which is always 0) | |||
-- with the actual amount and to simply copy tables | |||
local function copyTable(tIn) | |||
if not tIn then | |||
return nil | |||
end | |||
local tOut = {} | |||
for i, v in pairs(tIn) do | |||
tOut[i] = v | |||
end | end | ||
return | return tOut | ||
end | end | ||
local function | -- used to merge output arrays together; | ||
-- note that it currently mutates the first input array | |||
local function mergeArrays(a1, a2) | |||
return | for i = 1, #a2 do | ||
a1[#a1 + 1] = a2[i] | |||
end | |||
return a1 | |||
end | end | ||
local function | local function split(str, del) | ||
local out = {} | |||
end | local i, j = str:find(del) | ||
if i and j then | |||
out[1] = str:sub(1, i - 1) | |||
out[2] = str:sub(j + 1) | |||
else | |||
out[1] = str | |||
end | |||
return out | |||
return | |||
end | end | ||
local function | local function parseWikidataURL(url) | ||
local | local id | ||
if url:match('^http[s]?://') then | |||
id = split(url, "Q") | |||
if id[2] then | |||
return "Q" .. id[2] | |||
end | |||
end | end | ||
return nil | |||
end | |||
local function parseDate(dateStr, precision) | |||
precision = precision or "d" | |||
local i, j, index, ptr | |||
local parts = {nil, nil, nil} | |||
if | if dateStr == nil then | ||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | end | ||
-- 'T' for snak values, '/' for outputs with '/Julian' attached | |||
i, j = dateStr:find("[T/]") | |||
if i then | |||
if | dateStr = dateStr:sub(1, i-1) | ||
- | |||
end | end | ||
local | local from = 1 | ||
if dateStr:sub(1,1) == "-" then | |||
-- this is a negative number, look further ahead | |||
from = 2 | |||
end | |||
index = 1 | |||
ptr = 1 | |||
i, j = dateStr:find("-", from) | |||
if i then | |||
-- year | |||
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) -- explicitly give base 10 to prevent error | |||
if parts[index] == -0 then | |||
parts[index] = tonumber("0") -- for some reason, 'parts[index] = 0' may actually store '-0', so parse from string instead | |||
end | end | ||
if precision == "y" then | |||
end | -- we're done | ||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | |||
index = index + 1 | |||
ptr = i + 1 | |||
- | i, j = dateStr:find("-", ptr) | ||
-- | |||
if i then | |||
-- month | |||
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10) | |||
if precision == "m" then | |||
-- we're done | |||
return parts[1], parts[2], parts[3] -- year, month, day | |||
end | |||
index = index + 1 | |||
ptr = i + 1 | |||
end | |||
end | end | ||
if dateStr:sub(ptr) ~= "" then | |||
-- day if we have month, month if we have year, or year | |||
parts[index] = tonumber(dateStr:sub(ptr), 10) | |||
end | end | ||
return | return parts[1], parts[2], parts[3] -- year, month, day | ||
end | end | ||
local function datePrecedesDate(aY, aM, aD, bY, bM, bD) | |||
if aY == nil or bY == nil then | |||
local function | return nil | ||
end | end | ||
aM = aM or 1 | |||
aD = aD or 1 | |||
bM = bM or 1 | |||
bD = bD or 1 | |||
return | if aY < bY then | ||
end | return true | ||
end | |||
if aY > bY then | |||
return false | |||
end | |||
if | if aM < bM then | ||
return true | |||
end | end | ||
return | if aM > bM then | ||
end | return false | ||
end | |||
if aD < bD then | |||
return true | |||
end | |||
return false | |||
end | |||
local function getHookName(param, index) | |||
if hookNames[param] then | |||
return hookNames[param][index] | |||
elseif param:len() > 2 then | |||
return hookNames[param:sub(1, 2).."\\d"][index] | |||
else | |||
return nil | |||
end | end | ||
end | |||
return | local function alwaysTrue() | ||
return true | |||
end | end | ||
function | -- The following function parses a format string. | ||
-- | |||
-- The example below shows how a parsed string is structured in memory. | |||
-- Variables other than 'str' and 'child' are left out for clarity's sake. | |||
-- | |||
-- Example: | |||
-- "A %p B [%s[%q1]] C [%r] D" | |||
-- | |||
-- Structure: | |||
-- [ | |||
-- { | |||
-- str = "A " | |||
-- }, | |||
-- { | |||
-- str = "%p" | |||
-- }, | |||
-- { | |||
-- str = " B ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%s", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%q1" | |||
-- } | |||
-- ] | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " C ", | |||
-- child = | |||
-- [ | |||
-- { | |||
-- str = "%r" | |||
-- } | |||
-- ] | |||
-- }, | |||
-- { | |||
-- str = " D" | |||
-- } | |||
-- ] | |||
-- | |||
local function parseFormat(str) | |||
local chr, esc, param, root, cur, prev, new | |||
local params = {} | |||
local function newObject(array) | |||
local obj = {} -- new object | |||
obj.str = "" | |||
array[#array + 1] = obj -- array{object} | |||
obj.parent = array | |||
return obj | |||
end | |||
local function endParam() | |||
if param > 0 then | |||
if | if cur.str ~= "" then | ||
cur.str = "%"..cur.str | |||
cur.param = true | |||
params[cur.str] = true | |||
cur.parent.req[cur.str] = true | |||
prev = cur | |||
cur = newObject(cur.parent) | |||
end | end | ||
param = 0 | |||
end | end | ||
end | end | ||
root = {} -- array | |||
root.req = {} | |||
cur = newObject(root) | |||
prev = nil | |||
esc = false | |||
param = 0 | |||
for i = 1, #str do | |||
chr = str:sub(i,i) | |||
if not esc then | |||
if chr == '\\' then | |||
endParam() | |||
esc = true | |||
elseif chr == '%' then | |||
endParam() | |||
if cur.str ~= "" then | |||
cur = newObject(cur.parent) | |||
end | |||
param = 2 | |||
elseif chr == '[' then | |||
endParam() | |||
if prev and cur.str == "" then | |||
table.remove(cur.parent) | |||
cur = prev | |||
end | |||
cur.child = {} -- new array | |||
cur.child.req = {} | |||
cur.child.parent = cur | |||
cur = newObject(cur.child) | |||
elseif chr == ']' then | |||
endParam() | |||
if cur.parent.parent then | |||
new = newObject(cur.parent.parent.parent) | |||
if cur.str == "" then | |||
table.remove(cur.parent) | |||
end | |||
cur = new | |||
end | |||
else | |||
if param > 1 then | |||
param = param - 1 | |||
elseif param == 1 then | |||
if not chr:match('%d') then | |||
endParam() | |||
end | |||
end | |||
cur.str = cur.str .. replaceSpecialChar(chr) | |||
end | end | ||
else | |||
cur.str = cur.str .. chr | |||
esc = false | |||
end | |||
prev = nil | |||
end | |||
endParam() | |||
-- make sure that at least one required parameter has been defined | |||
if not next(root.req) then | |||
throwError("missing-required-parameter") | |||
end | |||
-- make sure that the separator parameter "%s" is not amongst the required parameters | |||
if root.req[parameters.separator] then | |||
throwError("extra-required-parameter", parameters.separator) | |||
end | end | ||
return root, params | |||
end | end | ||
local function | local function sortOnRank(claims) | ||
local rankPos | |||
local ranks = {{}, {}, {}, {}} -- preferred, normal, deprecated, (default) | |||
local sorted = {} | |||
for _, v in ipairs(claims) do | |||
rankPos = rankTable[v.rank] or 4 | |||
ranks[rankPos][#ranks[rankPos] + 1] = v | |||
end | |||
sorted = ranks[1] | |||
sorted = mergeArrays(sorted, ranks[2]) | |||
sorted = mergeArrays(sorted, ranks[3]) | |||
return sorted | |||
end | |||
-- | |||
local Config = {} | |||
-- | -- allows for recursive calls | ||
function Config:new() | |||
local cfg = {} | |||
setmetatable(cfg, self) | |||
self.__index = self | |||
cfg.separators = { | |||
-- single value objects wrapped in arrays so that we can pass by reference | |||
["sep"] = {copyTable(defaultSeparators["sep"])}, | |||
["sep%s"] = {copyTable(defaultSeparators["sep%s"])}, | |||
["sep%q"] = {copyTable(defaultSeparators["sep%q"])}, | |||
["sep%r"] = {copyTable(defaultSeparators["sep%r"])}, | |||
["punc"] = {copyTable(defaultSeparators["punc"])} | |||
} | |||
cfg.entity = nil | |||
cfg.entityID = nil | |||
cfg.propertyID = nil | |||
cfg.propertyValue = nil | |||
cfg.qualifierIDs = {} | |||
cfg.qualifierIDsAndValues = {} | |||
cfg.bestRank = true | |||
cfg.ranks = {true, true, false} -- preferred = true, normal = true, deprecated = false | |||
cfg.foundRank = #cfg.ranks | |||
cfg.flagBest = false | |||
cfg.flagRank = false | |||
cfg.periods = {true, true, true} -- future = true, current = true, former = true | |||
cfg.flagPeriod = false | |||
cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))} -- today as {year, month, day} | |||
cfg.mdyDate = false | |||
cfg.singleClaim = false | |||
cfg.sourcedOnly = false | |||
cfg.editable = false | |||
cfg.editAtEnd = false | |||
cfg.inSitelinks = false | |||
cfg.langCode = mw.language.getContentLanguage().code | |||
cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode) | |||
cfg.langObj = mw.language.new(cfg.langCode) | |||
cfg.siteID = mw.wikibase.getGlobalSiteId() | |||
cfg.states = {} | |||
cfg.states.qualifiersCount = 0 | |||
cfg.curState = nil | |||
cfg.prefetchedRefs = nil | |||
return cfg | |||
end | |||
local State = {} | |||
function State:new(cfg, type) | |||
local stt = {} | |||
setmetatable(stt, self) | |||
self.__index = self | |||
stt.conf = cfg | |||
stt.type = type | |||
stt.results = {} | |||
stt.parsedFormat = {} | |||
stt.separator = {} | |||
stt.movSeparator = {} | |||
stt.puncMark = {} | |||
stt.linked = false | |||
stt.rawValue = false | |||
stt.shortName = false | |||
stt.anyLanguage = false | |||
stt.unitOnly = false | |||
stt.singleValue = false | |||
return stt | |||
end | |||
-- if id == nil then item connected to current page is used | |||
function Config:getLabel(id, raw, link, short) | |||
local label = nil | |||
local prefix, title= "", nil | |||
if not id then | |||
id = mw.wikibase.getEntityIdForCurrentPage() | |||
if not id then | |||
return "" | |||
end | |||
end | end | ||
-- | id = id:upper() -- just to be sure | ||
if raw then | |||
end | -- check if given id actually exists | ||
if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then | |||
label = id | |||
end | |||
prefix, title = "d:Special:EntityPage/", label -- may be nil | |||
else | |||
-- try short name first if requested | |||
if short then | |||
label = p._property{aliasesP.shortName, [p.args.eid] = id} -- get short name | |||
if label == "" then | |||
label = nil | |||
end | |||
end | |||
-- get label | |||
if not label then | |||
label = mw.wikibase.getLabelByLang(id, self.langCode) -- XXX: should use fallback labels? | |||
-- get label | |||
if not label then | |||
label = mw.wikibase.getLabelByLang(id, self.langCode) | |||
end | end | ||
end | end | ||
Line 704: | Line 703: | ||
elseif id:sub(1,1) == "P" then | elseif id:sub(1,1) == "P" then | ||
-- properties have no sitelink, link to Wikidata instead | -- properties have no sitelink, link to Wikidata instead | ||
title | prefix, title = "d:Special:EntityPage/", id | ||
end | end | ||
end | end | ||
label = mw.text.nowiki(label) -- escape raw label text so it cannot be wikitext markup | |||
if title then | if title then | ||
label = buildWikilink(prefix .. title, label) | label = buildWikilink(prefix .. title, label) | ||
Line 745: | Line 744: | ||
value = value .. "#" .. self.propertyID | value = value .. "#" .. self.propertyID | ||
elseif self.inSitelinks then | elseif self.inSitelinks then | ||
value = value .. "#sitelinks- | value = value .. "#sitelinks-bharatpedia" | ||
end | end | ||
Line 877: | Line 876: | ||
if not unitOnly then | if not unitOnly then | ||
-- get value and strip + signs from front | -- get value and strip + signs from front | ||
value = mw.ustring.gsub(datavalue['amount'], "^ | value = mw.ustring.gsub(datavalue['amount'], "^%+(.+)$", "%1") | ||
if raw then | if raw then | ||
Line 1,289: | Line 1,288: | ||
lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_") | lonLink = table.concat({lonDegrees, lonMinutes, lonSeconds}, "_") | ||
value = "[https:// | value = "[https://geohack.toolforge.org/geohack.php?language="..self.langCode.."¶ms="..latLink.."_"..latDirectionEN.."_"..lonLink.."_"..lonDirectionEN.."_globe:"..globe.." "..value.."]" | ||
end | end | ||
Line 1,811: | Line 1,810: | ||
local value = "" | local value = "" | ||
local ref = {} | local ref = {} | ||
local referenceEmpty = true -- will be set to false if at least one parameter is left unremoved | |||
local numAuthorParameters = 0 | |||
local numAuthorNameStringParameters = 0 | |||
local tempLink | |||
local additionalRefProperties = {} -- will hold properties of the reference which are not in statement.snaks, namely backup title from "subject named as" and URL from an external ID | |||
local wikidataPropertiesOfSource -- will contain "Wikidata property" properties of the item in stated in, if any | |||
local version = | local version = 4 -- increment this each time the below logic is changed to avoid conflict errors | ||
if statement.snaks then | if statement.snaks then | ||
Line 1,818: | Line 1,823: | ||
if statement.snaks[aliasesP.importedFrom] then | if statement.snaks[aliasesP.importedFrom] then | ||
statement.snaks[aliasesP.importedFrom] = nil | statement.snaks[aliasesP.importedFrom] = nil | ||
end | |||
-- don't include "Wikimedia import URL" | |||
if statement.snaks[aliasesP.wikimediaImportURL] then | |||
statement.snaks[aliasesP.wikimediaImportURL] = nil | |||
-- don't include "retrieved" if no "referenceURL" is present, | |||
-- as "retrieved" probably belongs to "Wikimedia import URL" | |||
if statement.snaks[aliasesP.retrieved] and not statement.snaks[aliasesP.referenceURL] then | |||
statement.snaks[aliasesP.retrieved] = nil | |||
end | |||
end | end | ||
Line 1,834: | Line 1,849: | ||
statement.snaks[aliasesP.image] = nil | statement.snaks[aliasesP.image] = nil | ||
end | end | ||
-- don't include "language" if it is equal to the local one | -- don't include "language" if it is equal to the local one | ||
if self:getReferenceDetail(statement.snaks, aliasesP.language) == self.conf.langName then | if self:getReferenceDetail(statement.snaks, aliasesP.language) == self.conf.langName then | ||
statement.snaks[aliasesP.language] = nil | statement.snaks[aliasesP.language] = nil | ||
end | end | ||
-- retrieve all the parameters | if statement.snaks[aliasesP.statedIn] and not statement.snaks[aliasesP.referenceURL] then | ||
for i in pairs(statement.snaks) do | -- "stated in" was given but "reference URL" was not. | ||
label = "" | -- get "Wikidata property" properties from the item in "stated in" | ||
-- if any of the returned properties of the external-id datatype is in statement.snaks, generate a URL from it and use the URL in the reference | |||
-- multiple authors may be given | |||
if i == aliasesP.author then | -- find the "Wikidata property" properties in the item from "stated in" | ||
params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true) -- link = true/false, anyLang = true | wikidataPropertiesOfSource = mw.text.split(p._properties{p.flags.raw, aliasesP.wikidataProperty, [p.args.eid] = self.conf:getValue(statement.snaks[aliasesP.statedIn][1], true, false)}, ", ", true) | ||
else | for i, wikidataPropertyOfSource in pairs(wikidataPropertiesOfSource) do | ||
params[i] = {self:getReferenceDetail(statement.snaks, i, false, (self.linked or (i == aliasesP.statedIn)) and (statement.snaks[i][1].datatype ~= 'url'), true)} -- link = true/false, anyLang = true | if statement.snaks[wikidataPropertyOfSource] and statement.snaks[wikidataPropertyOfSource][1].datatype == "external-id" then | ||
end | tempLink = self.conf:getValue(statement.snaks[wikidataPropertyOfSource][1], false, true) -- not raw, linked | ||
if mw.ustring.match(tempLink, "^%[%Z- %Z+%]$") then -- getValue returned a URL. | |||
if #params[i] == 0 then | additionalRefProperties[aliasesP.referenceURL] = mw.ustring.gsub(tempLink, "^%[(%Z-) %Z+%]$", "%1") -- the URL is in wiki markup, so strip the square brackets and the display text | ||
params[i] = nil | statement.snaks[wikidataPropertyOfSource] = nil | ||
else | break | ||
if statement.snaks[i][1].datatype == 'external-id' then | end | ||
key = "external-id" | end | ||
label = self.conf:getLabel(i) | end | ||
end | |||
if label ~= "" then | |||
label = label .. " " | -- don't include "subject named as", but use it as the title when "title" is not present but a URL is | ||
end | if statement.snaks[aliasesP.subjectNamedAs] then | ||
if not statement.snaks[aliasesP.title] and (statement.snaks[aliasesP.referenceURL] or additionalRefProperties[aliasesP.referenceURL]) then | |||
additionalRefProperties[aliasesP.title] = statement.snaks[aliasesP.subjectNamedAs][1].datavalue.value | |||
end | |||
statement.snaks[aliasesP.subjectNamedAs] = nil | |||
end | |||
-- retrieve all the parameters | |||
for i in pairs(statement.snaks) do | |||
label = "" | |||
-- multiple authors may be given | |||
if i == aliasesP.author or i == aliasesP.authorNameString then | |||
params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true) -- link = true/false, anyLang = true | |||
else | |||
params[i] = {self:getReferenceDetail(statement.snaks, i, false, (self.linked or (i == aliasesP.statedIn)) and (statement.snaks[i][1].datatype ~= 'url'), true)} -- link = true/false, anyLang = true | |||
end | |||
if #params[i] == 0 then | |||
params[i] = nil | |||
else | |||
referenceEmpty = false | |||
if statement.snaks[i][1].datatype == 'external-id' then | |||
key = "external-id" | |||
label = self.conf:getLabel(i) | |||
if label ~= "" then | |||
label = label .. " " | |||
end | |||
else | |||
key = i | |||
end | |||
-- add the parameter to each matching type of citation | |||
for j in pairs(citeParams) do | |||
-- do so if there was no mismatch with a previous parameter | |||
if not citeMismatch[j] then | |||
-- check if this parameter is not mismatching itself | |||
if i18n['cite'][j][key] then | |||
-- continue if an option is available in the corresponding cite template | |||
if i18n['cite'][j][key] ~= "" then | |||
-- handle non-author properties (and author properties ("author" and "author name string"), if they don't use the same template parameter) | |||
if (i ~= aliasesP.author and i ~= aliasesP.authorNameString) or (i18n['cite'][j][aliasesP.author] ~= i18n['cite'][j][aliasesP.authorNameString]) then | |||
citeParams[j][i18n['cite'][j][key]] = label .. params[i][1] | |||
-- to avoid problems with non-author multiple parameters (if existent), the following old code is retained | |||
for k=2, #params[i] do | |||
citeParams[j][i18n['cite'][j][key]..k] = label .. params[i][k] | |||
end | |||
-- handle "author" and "author name string" specially if they use the same template parameter | |||
elseif i == aliasesP.author or i == aliasesP.authorNameString then | |||
if params[aliasesP.author] ~= nil then | |||
numAuthorParameters = #params[aliasesP.author] | |||
else | |||
numAuthorParameters = 0 | |||
end | |||
if params[aliasesP.authorNameString] ~= nil then | |||
numAuthorNameStringParameters = #params[aliasesP.authorNameString] | |||
else | |||
numAuthorNameStringParameters = 0 | |||
end | |||
-- execute only if both "author" and "author name string" satisfy this condition: the property is both in params and in statement.snaks or it is neither in params nor in statement.snaks | |||
-- reason: parameters are added to params each iteration of the loop, not before the loop | |||
if ((statement.snaks[aliasesP.author] == nil) == (numAuthorParameters == 0)) and ((statement.snaks[aliasesP.authorNameString] == nil) == (numAuthorNameStringParameters == 0)) then | |||
for k=1, numAuthorParameters + numAuthorNameStringParameters do | |||
if k <= numAuthorParameters then -- now handling the authors from the "author" property | |||
citeParams[j][i18n['cite'][j][aliasesP.author]..k] = label .. params[aliasesP.author][k] | |||
else -- now handling the authors from "author name string" | |||
citeParams[j][i18n['cite'][j][aliasesP.authorNameString]..k] = label .. params[aliasesP.authorNameString][k - numAuthorParameters] | |||
end | |||
end | |||
end | |||
end | |||
end | |||
else | |||
citeMismatch[j] = true | |||
end | |||
end | |||
end | |||
end | |||
end | |||
-- use additional properties | |||
for i in pairs(additionalRefProperties) do | |||
for j in pairs(citeParams) do | |||
if not citeMismatch[j] and i18n["cite"][j][i] then | |||
citeParams[j][i18n["cite"][j][i]] = additionalRefProperties[i] | |||
else | else | ||
citeMismatch[j] = true | |||
end | end | ||
end | end | ||
Line 1,920: | Line 2,002: | ||
end | end | ||
-- (3) | -- (3) if the citation couldn't be displayed using Cite web or Cite Q, but has properties other than the removed ones, throw an error | ||
elseif | elseif not referenceEmpty then | ||
value = "<span style=\"color: crimson\">" .. errorText("malformed-reference") .. "</span>" | |||
end | end | ||
if value ~= "" then | if value ~= "" then | ||
value = {value} -- create one value object | value = {value} -- create one value object |