Moduł:Brudnopis/Paweł Ziemian/Cytuj
Wygląd
Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Brudnopis/Paweł Ziemian/Cytuj/opis
local resources = mw.loadData("Moduł:Cytuj/dane")
local access = mw.loadData("Moduł:Cytuj/dostęp")
local function createCategories()
local result = {}
local mt = {
__index = function(t,k)
return resources.categories[k]
or resources.categories.check
end,
__newindex = function(t,k,v)
error("Kategorie są tylko do odczytu")
end,
}
setmetatable(result, mt)
return result
end
local categories = createCategories()
local function killLinkInterwiki(value)
-- usuń z treści wikilinki generowane przez szablon link-interwiki
-- szablon oznacza jako podejrzane wartości z tekstem "Wikipedia"
local result, count = string.gsub(value, "%[%[:d:Q[0-9]+#sitelinks%-wikipedia|%(inne języki%)%]%]", "")
return result
end
local function checkUri(uri)
local urilen = #uri
for _,v in ipairs(resources.supportedUriSchemas) do
if (#v < urilen) and (string.lower(string.sub(uri,1, #v)) == v) then
return not string.match(uri, '%s')
end
end
end
local function softNoWiki(text)
local result, count = string.gsub(text, "['%[%]{|}\"]", { ["\""] = """, ["'"] = "'", ["["] = "[", ["]"] = "]", ["{"] = "{", ["|"] = "|", ["}"] = "}"})
-- przywróc [[szablon:J]] z kursywą tak/nie
result, count = string.gsub(result, "<span +style="font%-style: ?([a-z]+);?" +lang="([a-z%-]+)" *>", "<span style=\"font-style: %1;\" lang=\"%2\">")
-- przywróc [[szablon:J]] goły
result, count = string.gsub(result, "<span +lang="([a-z%-]+)" *>", "<span lang=\"%1\">")
-- przywróć nowiki
result, count = string.gsub(result, "\127'"`UNIQ%-%-(nowiki%-[0-9A-F]+)%-QINU`"'\127", "\127'\"`UNIQ--%1-QINU`\"'\127")
return result
end
local function escapeUrl(url)
local result, count = string.gsub(url, "[ '%[%]\"]", { [" "] = "%20", ["'"] = "%27", ["["] = "%5B", ["]"] = "%5D", ["\""] = "%22"})
return result
end
local function plainText(text)
local result, count = string.gsub(text, "</?[Ss][Pp][Aa][Nn][^>]*>", "")
return result
end
local function first(data)
return type(data) == "table" and data[1] or data
end
local function determineMode(p)
local detector = {}
local count = 0
for i, v in ipairs(resources.modes) do
detector[i] = v
count = count + 1
end
detector[1] = false -- skip 'auto'
count = count - 1
for k, v in pairs(resources.params) do
local arg = p.args[v.name]
for i, w in ipairs(v.used) do
if not w and arg then
-- unexpected argument
if detector[i] then
detector[i] = false
count = count - 1
if count == 0 then
-- the mode cannot be determined
break
end
end
end
end
if count == 0 then
-- the mode cannot be determined
break
end
end
if count == 1 then
for i, v in ipairs(detector) do
if detector[i] then
return i, resources.COinS[i]
end
end
end
if detector[4] -- web?
and p.args[resources.params.url.name]
then
-- promote to web but without COinS
return 4, false
end
for i, v in ipairs(detector) do
if detector[i] then
-- if type is determined more than once
-- use only the first one without COinS
return i, false
end
end
-- in case nothing is selected
-- use the auto mode as default fallback
return 1
end
local authorMetatable = {}
local authorMethodtable = {}
authorMetatable.__index = authorMethodtable
local function checkPatterns(author, prefixes, suffixes)
if author.exact then
return false
end
if author.prefix and prefixes then
for _, v in ipairs(prefixes) do
if mw.ustring.match(author.prefix, v) then
return true
end
end
end
if author.suffix and suffixes then
for _, v in ipairs(suffixes) do
if mw.ustring.match(author.suffix, v) then
return true
end
end
end
return false
end
authorMethodtable.format = function(data, namefirst)
if data.exact then
return data.exact
end
if namefirst and data.familynamefirst then
namefirst = false
end
local builder = mw.html.create()
local name = data.name and (#data.name > 0)
local initials = data.nameinitials and (#data.nameinitials > 0)
local namehint = nil
if name and initials and (data.name ~= data.nameinitials) then
namehint = data.name
end
if not data.familynamefirst and (name or initials) then
local before = namefirst and builder or builder:tag("span"):addClass("cite-name-before")
if name then
before:tag("span"):addClass("cite-name-full"):wikitext(softNoWiki(data.name))
end
if initials then
before:tag("span"):css("display", "none"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials))
end
before:wikitext(" ")
end
builder:tag("span"):addClass("cite-lastname"):wikitext(softNoWiki(data.lastname))
if not namefirst and (name or initials) then
local after = data.familynamefirst and builder or builder:tag("span"):css("display", "none"):addClass("cite-name-after")
after:wikitext(" ")
if name then
after:tag("span"):addClass("cite-name-full"):wikitext(softNoWiki(data.name))
end
if initials then
after:tag("span"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials))
end
if data.js then
after:wikitext(",")
end
end
if data.js then
builder:wikitext(" ", data.js)
end
return tostring(builder)
end
authorMethodtable.towiki = function(data)
if data.exact then
return data.exact
end
local result = {}
local name = data.name and (#data.name > 0)
if not data.familynamefirst and name then
table.insert(result,softNoWiki(data.name))
table.insert(result, " ")
end
table.insert(result, softNoWiki(data.lastname))
if data.familynamefirst and name then
table.insert(result, " ")
table.insert(result, softNoWiki(data.name))
end
return table.concat(result)
end
local function makeInitials(name)
local nameinitials = mw.ustring.gsub(name, "(%w[Hh]?)[%w]*%.?([%s%-–—]?)%s*", "%1. ") -- zostaw początki słów (jedna litera + opcjonalne następujące 'h')
nameinitials = mw.ustring.gsub(nameinitials, "%f[%w]%l%.%s", "") -- usuń inicjały z małych liter
nameinitials = mw.ustring.gsub(nameinitials, "([^C%W])[Hh]%.?%s", "%1. ") -- usuń drugie 'h' jeśli nie zaczyna się na 'C'
nameinitials = mw.ustring.gsub(nameinitials, "(%u[Hh]?)[%.%s]*", "%1.") -- dodaj brakujące kropki i usuń zbędne spacje
return mw.text.trim(nameinitials)
end
local function fixInitials(name)
local result, _ = mw.ustring.gsub(name, "^(%uh?)%.?%s+(%uh?)%.", "%1.%2.") -- popraw inicjały na początku
result, _ = mw.ustring.gsub(result, "%f[%a](%uh?)%.%s+(%uh?)%.", "%1.%2.") -- popraw inicjały w środku
result, _ = mw.ustring.gsub(result, "%f[%a](%uh?)%.%s+(%uh?)%.", "%1.%2.") -- popraw kolejne inicjały w środku
return result
end
local function isInQuotes(text)
if (string.len(text) < 2) then
return false;
end
local tstart = text:sub(1, 1);
if (tstart ~= '"') then
return false;
end
local tend = text:sub(-1);
if (tend ~= '"') then
return false;
end
return true;
end
local function parseAuthor(author)
local result = {}
if string.match(author, "\127") then -- wpisy z <nowiki> nie są analizowane
result.exact = author
setmetatable(result, authorMetatable)
return result
end
local author = mw.text.trim(author)
local a = string.gsub(author, "\\[\\%.:]", { ["\\\\"]="\\", ["\\."]=",", ["\\:"]=";", })
if a ~= author then
result.exact = a
setmetatable(result, authorMetatable)
return result
end
if resources.exactAuthors[author] then
result.exact = author
setmetatable(result, authorMetatable)
return result
end
local exactName = mw.ustring.match(author, "^%s*%*%s*(.*)$")
if exactName then
result.exact = mw.text.trim(exactName)
if #result.exact == 0 then
return nil
end
setmetatable(result, authorMetatable)
return result
end
local prefix0, link, description, suffix0 = mw.ustring.match(author, "^(.-)%[%[(.-)%|(.-)%]%](.*)$")
if prefix0 then
result.link = link
author = description
else
prefix0, link, suffix0 = mw.ustring.match(author, "^(.-)%[%[(.-)%]%](.*)$")
if prefix0 then
author = link
result.link = link
else
prefix0 = ""
suffix0 = ""
end
end
local prefix1, rest = mw.ustring.match(author, "^([%l%p%s]+)(.+)$")
if not prefix1 then
rest = author
prefix1 = ""
end
local prefix = mw.text.trim(prefix0.." "..prefix1)
if #prefix > 0 then
if mw.ustring.sub(prefix, -1) == "#" then
result.familynamefirst = true
prefix = mw.text.trim(mw.ustring.match(prefix, "^(.-)#$"))
end
if #prefix > 0 then
result.prefix = mw.ustring.gsub(prefix, "%s+", " ") -- collapse spaces
end
end
local rest2, suffix = mw.ustring.match(rest, "^([%w%-%.%s]-)%s([%l%p%s]-)$")
if not suffix then
rest2 = rest
suffix = ""
end
suffix = mw.text.trim(suffix.." "..suffix0)
if #suffix > 0 then
result.suffix = mw.ustring.gsub(suffix, "%s+", " ") -- collapse spaces
suffix = " "..result.suffix
for i, v in ipairs(resources.js) do
if mw.ustring.match(suffix, v[1]) then
result.suffix = mw.text.trim(mw.ustring.gsub(suffix, v[1], ""))
result.js = v[2]
break
end
end
else
for i, v in ipairs(resources.js) do
if mw.ustring.match(rest2, v[1]) then
rest2 = mw.text.trim(mw.ustring.gsub(rest2, v[1], ""))
result.js = v[2]
break
end
end
end
local lastname, name = mw.ustring.match(rest2, "%s*([^,]-)%s*,%s*(.-)%s*$")
if not lastname then
if result.familynamefirst then
lastname, name = mw.ustring.match(rest2, "%s*(%u[%l%d%p]*)%s+(.-)%s*$")
else
local prefix2
name, lastname, prefix2 = mw.ustring.match(rest2, "%s*(.-)%s+((%l[%l%p]%l?)%u[%w%p]-)%s*$")
if not resources.lastnamePrefixes[prefix2] then
name, lastname = mw.ustring.match(rest2, "%s*(.-)%s+(%u[%w%p]-)%s*$")
end
end
elseif resources.lastnamePrefixes[prefix1] then
lastname = prefix1 .. lastname
elseif resources.lastnamePrefixes[prefix1] == false then
name = name.." "..mw.text.trim(prefix1)
end
if not lastname then
result.lastname = mw.text.trim(rest2)
else
result.name = fixInitials(name)
result.lastname = lastname
result.nameinitials = makeInitials(name)
end
if #result.lastname == 0 then
return nil
end
setmetatable(result, authorMetatable)
return result
end
local function parseDate(date, month, year, patch)
local result = {}
-- parse full date
local y, m, d = false, false, false
y, m, d = mw.ustring.match(date, "(%d%d%d%d)[%-%s%./](%d%d?)[%-%s%./](%d%d?)")
if y and patch and (date == (y.."-01-01")) then
result.year = tonumber(y)
result.month = false
result.day = false
return result, true
end
if not y then
d, m, y = mw.ustring.match(date, "(%d%d?)[%-%s%.](%d%d?)[%-%s%.](%d%d%d%d)")
if not y then
y, m, d = mw.ustring.match(date, "(%d%d%d%d)%s*(%w+)%s*(%d%d?)")
if not y then
d, m, y = mw.ustring.match(date, "(%d%d?)%s*(%w+)%s*(%d%d%d%d)")
end
if m then
m = resources.monthparser[mw.ustring.lower(m)]
if not m then
y = false
m = false
d = false
end
end
end
end
if y then
y = tonumber(y)
m = tonumber(m)
d = tonumber(d)
end
if y and ((d > 31) or (m > 12) or (d < 1) or (m < 1)) then
y = false
m = false
d = false
elseif y then
result.year = y
result.month = m
result.day = d
return result, false
end
-- parse year and month
y, m = mw.ustring.match(date, "(%d%d%d%d)[%-%s%./](%d%d?)")
if not y then
m, y = mw.ustring.match(date, "(%d%d?)[%-%s%./](%d%d%d%d)")
if not y then
y, m = mw.ustring.match(date, "(%d%d%d%d)%s*(%w+)")
if not y then
m, y = mw.ustring.match(date, "(%w+)%s*(%d%d%d%d)")
end
if m then
m = resources.monthparser[mw.ustring.lower(m)]
if not m then
y = false
m = false
end
end
end
end
if y then
y = tonumber(y)
m = tonumber(m)
end
if y and ((m > 12) or (m < 1)) then
y = false
m = false
elseif y then
result.year = y
result.month = m
return result, false
end
-- try any method to extract year or month
if not y then
y = mw.ustring.match(date, "[%s%p%-–]?(%d%d%d%d)[%s%p%-–]?")
if y then
y = tonumber(y)
end
if y then
result.year = y
end
end
if y then
if not m then
m = mw.ustring.match(date, "[%s%p%-–]?(%w+)[%s%p%-–]?")
if m then
m = resources.monthparser[mw.ustring.lower(m)]
end
if m then
result.month = m
end
end
else
-- reset only month
result.month = nil
end
if y then
return result, false
end
end
local function collectAuthors(author, checkForAltFormat)
if not author then
return
end
-- Obsługa cudzysłowów w autorach (treat quoted authors as-is)
if (isInQuotes(mw.text.trim(author))) then
local strippedAuthor = mw.text.trim(author, '"\t\r\n\f ')
return { items = {strippedAuthor}, more=false, comma=false, etal=false, separator="" }
end
function findUtf8CharAt(text, at)
local back = false
if at < 0 then
at = #text + at + 1
back = true
end
while at > 1 do
local b = string.byte(text, at, at)
if (b < 128) or (b >= 192) then
break
end
at = at - 1
end
return back and at - #text - 1 or at
end
local etal = false
local authorTail = #author <= 50 and author or string.sub(author, findUtf8CharAt(author, -50))
for i, p in ipairs(resources.etalPatterns) do
local a, e = string.match(authorTail, p)
if a then
author = string.sub(author, 1, #author-#e)
etal = e
break
end
end
function decodeEntity(s)
local result = nil
local hex = string.match(s, "^&#[xX]([0-9A-Fa-f]+);$")
if hex then
result = mw.ustring.char(tonumber(hex, 16))
else
local dec = string.match(s, "^&#([0-9]+);$")
if dec then
result = mw.ustring.char(tonumber(dec, 10))
elseif resources.htmlEntities[s] then
result = mw.ustring.char(resources.htmlEntities[s])
else
return string.gsub(s, ";", "\\:")
end
end
if result == ";" then
return "\\:"
elseif result == "," then
return "\\."
elseif result == "\\" then
return "\\\\"
else
return result
end
end
local authorHead = #author <= 500 and author or string.sub(author, 1, findUtf8CharAt(author, 500) - 1)
local result = {}
local esc1 = string.gsub(authorHead, "\\", "\\\\")
local esc2 = string.gsub(esc1, "&#?[a-zA-Z0-9]+;", decodeEntity)
local splitter = string.match(esc2, ";") and ";" or ","
local authors = mw.text.split(esc2, splitter.."%s*", false)
local nth = false
local count = #authors
if (#authorHead < #author) and (count > 4) then
if count > 5 then
table.remove(authors, count)
count = count - 1
end
local at, _ = string.find(authorHead, authors[count], 1, true)
nth = string.sub(author, at)
table.remove(authors, count)
count = count - 1
end
local alt = false
if (splitter == ",") and checkForAltFormat then
local altAuthors = {}
alt = true
for i, v in ipairs(authors) do
local n0 = ""
local s, n = mw.ustring.match(v, "^(%u%l+)%s(%u+)%.?$")
if not s then
s, n = mw.ustring.match(v, "^(%u%l+[%s%-–]%u%l+)%s(%u+)%.?$")
end
if not s then
n0, s, n = mw.ustring.match(v, "^(%l%l%l?)%s(%u%l+)%s(%u+)%.?$") -- de, von, van, der etc.
end
if not s then
alt = false
break
end
local initials, _ = mw.ustring.gsub(n, "(%u)", "%1.")
if #n0 > 0 then
n0 = " "..n0
end
table.insert(altAuthors, s..", "..initials..n0)
end
if alt then
authors = altAuthors
splitter = ";"
end
end
for i, v in ipairs(authors) do
local author = parseAuthor(v)
if author then
table.insert(result, author)
end
end
if #result == 0 then
return
end
local check = false
if alt then
check = "alt"
elseif (#result == 2) and (splitter == ",") then
check = not result[1].link and not result[1].exact and not result[1].name
or not result[2].link and not result[2].exact and not result[2].name
if check then
if result[1].lastname and not result[1].name and not result[2].exact
and not mw.ustring.match(result[1].lastname, "%S%s+%S") then
local oneAuthor = parseAuthor(author)
if oneAuthor then
table.remove(result,2)
result[1] = oneAuthor
check = false
end
end
end
if check then
mw.logObject(result,"przecinek u autora")
end
end
return { items = result, more=nth, comma = check, etal = etal, separator=splitter.." " }
end
local function formatAuthors(authors, useDecorations, nextgroup, etalForm)
local count = #authors.items
if count == 0 then
return nil, false
end
local suffix = function(author)
if useDecorations then
for _, v in ipairs(resources.authorFunc) do
if checkPatterns(author, v.prefixes, v.suffixes) then
return v.append
end
end
end
return ""
end
local formatter = function(author)
local a = author:format(nextgroup)
local r = author.link and ("[["..author.link.."|"..a.."]]") or a
return r..suffix(author)
end
if count == 1 then
local a1 = formatter(authors.items[1])
local etal = authors.etal and (etalForm or " i inni") or ""
return a1..etal, false
end
local result = {}
table.insert(result, formatter(authors.items[1]))
if not authors.etal and (count <= 3) then
table.insert(result, ", ");
table.insert(result, formatter(authors.items[2]))
if count == 3 then
table.insert(result, ", ");
table.insert(result, formatter(authors.items[3]))
end
return table.concat(result, ""), false
end
local title = {}
for i = 1, count do
table.insert(title, authors.items[i]:towiki()..suffix(authors.items[i]))
end
if authors.more then
table.insert(title, authors.more)
end
table.insert(result, "<span class=\"cite-at-al\" title=\"")
table.insert(result, table.concat(title, authors.separator))
if authors.etal then
table.insert(result, etalForm or " i inni")
end
table.insert(result, "\">")
table.insert(result, etalForm or " i inni")
table.insert(result, "</span>")
return table.concat(result, ""), true
end
local function collectLanguages(value)
if value then
local result = {}
local values = mw.text.split(value, "%s+")
for _, v in ipairs(values) do
if #v > 0 then
table.insert(result, v)
end
end
if #result > 0 then
return result
end
end
return nil
end
local function splitFileLink(link)
local linkTitle = string.match(link, "^:(.+)$")
if not linkTitle then
return link, false
end
local title = mw.title.new(link)
if not title then
return link, false
end
mw.logObject(title.text, "splitFileLink - title.text")
if title.namespace == 6 then
local name, ext = mw.ustring.match(title.text, "(.-)%.(%a+)$")
if ext and resources.wikilinks.extensions[mw.ustring.lower(ext)] then
return name, ext
end
elseif #title.interwiki > 0 then
local prefix, name, ext = mw.ustring.match(title.text, "(%a+):(.-)%.(%a+)$")
if prefix and resources.wikilinks.files[mw.ustring.upper(prefix)] and ext and resources.wikilinks.extensions[mw.ustring.lower(ext)] then
return name, ext
end
end
return link, false
end
local function splitWikiLink(text)
local link, description = mw.ustring.match(text, "^%[%[(.-)%|(.-)%]%]$")
if link then
local name, ext = splitFileLink(link)
return description, link, false, ext
end
local link = mw.ustring.match(text, "^%[%[(.-)%]%]$")
if link then
local name, ext = splitFileLink(link)
return name or link, link, false, ext
end
local link, description = mw.ustring.match(text, "^%[(%S*)%s+(.-)%]$")
if link and checkUri(link) then
return description, false, link, false
end
return text, false, false, false
end
local function detectArchive(url)
local uri = mw.uri.new(url)
local detectors = resources.archiveDecoders.services[resources.archiveDecoders.hosts[uri.host]]
if detectors then
--mw.logObject(uri.host,"detectArchive uri.host")
--mw.logObject(uri.relativePath,"detectArchive uri.relativePath")
--mw.logObject(resources.archiveDecoders.hosts[uri.host],"detectArchive service")
for i, v in ipairs(detectors) do
local pattern = v.pattern
local decoder = resources.archiveDecoders.decoders[v.decoder]
if pattern and decoder then
local items = { mw.ustring.match(uri.relativePath, pattern) }
if #items > 0 then
--mw.logObject(items[decoder.link],"detectArchive link")
--mw.logObject(items[decoder.year].."-"..items[decoder.month].."-"..items[decoder.day],"detectArchive date")
return items[decoder.link], items[decoder.year].."-"..items[decoder.month].."-"..items[decoder.day]
end
end
end
end
return false, false
end
local function isAutoGeneratedUrl(url)
local address = string.gsub(url, "^https?:", "")
for k, v in pairs(resources.params) do
if v.link then
local links = type(v.link) == "table" and v.link or { v.link }
for _, vlink in ipairs(links) do
local prefix = string.gsub(vlink, "^https?:", "")
if (#address > #prefix) and (string.sub(address, 1, #prefix) == prefix) then
return v.name
end
end
end
end
return false
end
local function loadCitation(frame, mode)
local result = {}
-- copy parameters
for k, v in pairs(resources.params) do
if v.used[mode] then
local value = frame.args[v.name]
if value then
value = mw.text.trim(value)
if #value > 0 then
result[k] = value
end
end
if (v.used[mode] == "!") and not result[k] then
-- simulate missing mandatory parameter
result[k] = "{{{"..v.name.."}}}"
if not result.missing then
result.missing = v.name
end
end
end
end
-- check url argument
if result.url == "nie" then
result.url = false
elseif result.url then
if not checkUri(result.url) then
local unstrip = mw.text.unstripNoWiki( result.url )
result.url = false
if unstrip then
result.urlnowiki = checkUri(unstrip)
end
end
end
-- translate some parameters
local altAuthorParser = false
if result.journal and result.pmid and result.author and not result.chapterauthor and not result.editor and not result.others then
altAuthorParser = true
end
result.chapterauthor = collectAuthors(result.chapterauthor, false)
result.author = collectAuthors(result.author, altAuthorParser)
result.lang = collectLanguages(result.lang)
result.editor = collectAuthors(result.editor, false)
result.others = collectAuthors(result.others, false)
-- parse main bibliographic date
if result.date then
local bibDate = false
local bibDateHint = false
local coinsDate = false
local odnDate = false
for _, v in ipairs(resources.bibDates) do
for _, p in ipairs(v.patterns) do
local bib, c = mw.ustring.gsub(result.date, p, v.show)
if bib and (c > 0) then
bibDate = bib
bibDateHint = v.hint
if v.coins then
local cd, cc = mw.ustring.gsub(result.date, p, v.coins)
if cd and (cc > 0) then
coinsDate = cd
end
end
if v.odn then
local od, oc = mw.ustring.gsub(result.date, p, v.odn)
if od and (oc > 0) then
odnDate = od
end
end
break
end
if bibDate then
break
end
end
end
if bibDate then
result.date = { bib = bibDate, hint = bibDateHint, coins = coinsDate, odn = odnDate }
else
local date, patch = parseDate(result.date or "", false, false, true)
if date then
date.coins = (patch and date.year)
or (date.day and string.format("%04d-%02d-%02d", date.year, date.month, date.day))
or (date.month and string.format("%04d-%02d", date.year, date.month))
or date.year
date.odn = date.year
elseif result.date then
result.badDate = true
end
result.date = date
result.patchCitoidDate = patch
end
end
-- fix other dates
if result.accessdate then
result.accessdate = parseDate(result.accessdate or "", false, false, false)
if result.accessdate and not result.accessdate.day then
result.badAccessDate = true
result.accessdate = nil
elseif not result.accessdate then
result.badAccessDate = true
end
end
-- allow more ISBN numbers
if result.isbn then
-- TODO allow "(info)" for custom description followed each identifier
result.isbn = mw.text.split(result.isbn, "%s+")
end
if result.title then
local url
result.title, result.titlelink, url, result.titleext = splitWikiLink(result.title)
if url or result.titlelink then
if result.url and (#result.url > 0) and (result.url ~= "{{{url}}}") then
result.urlWarning = true
end
result.url = url
end
end
if result.chapter then
result.chapter, result.chapterlink, result.chapterurl, result.chapterext = splitWikiLink(result.chapter)
end
if result.journal then
local journalAbbr, _ = mw.ustring.gsub(result.journal, "[%.%s]+", " ")
mw.logObject(journalAbbr, "journalAbbr")
if mw.ustring.match(journalAbbr, "^[%a%s]+[,:]?[%a%s]+%d?$") -- kandydat na skrót powinien mieć tylko litery z opcjonalnymi odstępami i co najwyżej jednym dwukropkiem lub przecinkiem
or mw.ustring.match(journalAbbr, "^[%a%s]+%([%a%s,]+%)$") then -- opcjonalnie jakieś dookreślenie w nawiasie
local expandedJournal = mw.loadData("Moduł:Cytuj/czasopisma")[mw.text.trim(journalAbbr)]
if expandedJournal then
result.originalJournal = result.journal
result.journal = expandedJournal
end
end
result.journal, result.journallink, result.journalurl, result.journalext = splitWikiLink(result.journal)
end
if result.journal and not result.journallink and not result.journalurl and not result.title and result.url then
result.journalurl = result.url
result.url = false
end
if result.url then
local n = isAutoGeneratedUrl(result.url)
if n then
result.rejectedurl = true
if result[n] then
result.url = false
end
end
end
if result.chapterurl then
local n = isAutoGeneratedUrl(result.chapterurl)
if n then
result.rejectedurl = true
if result[n] then
result.chapterurl = false
end
end
end
if result.journalurl then
local n = isAutoGeneratedUrl(result.journalurl)
if n then
result.rejectedurl = true
if result[n] then
result.journalurl = false
end
end
end
if not result.archive and result.url then
local al, ad = detectArchive(result.url)
if al then
result.archiveurl = true
result.archive = result.url
result.url = al
if ad then result.archived = ad end
end
elseif not result.archive and result.chapterurl then
local al, ad = detectArchive(result.chapterurl)
if al then
result.archivechapter = true
result.archive = result.chapterurl
result.chapterurl = al
if ad then result.archived = ad end
end
elseif not result.archive and result.journalurl then
local al, ad = detectArchive(result.journalurl)
if al then
result.archivejournal = true
result.archive = result.journalurl
result.journalurl = al
if ad then result.archived = ad end
end
elseif result.archive and not result.archived then
local al, ad = detectArchive(result.archive)
if ad and not result.archived then result.archived = ad end
end
if result.archive then
if result.chapterurl and not result.url then
result.archivechapter = true
elseif result.title then
result.archiveurl = true
elseif result.journal then
result.archivejournal = true
end
end
if result.archived then
result.archived = parseDate(result.archived or "", false, false, false)
if result.archived and not result.archived.day then
result.badArchivedDate = true
result.archived = null
elseif not result.archived then
result.badArchivedDate = true
end
end
if result.edition and result.journal and not result.volume and not result.issue then
local volume, issue = mw.ustring.match(result.edition, "^%s*([^%(]+)%s+%((.-)%)%s*$");
if volume then
result.volume = volume
result.issue = issue
result.edition = nil
end
end
if result.pmc and (#result.pmc > 3) and (mw.ustring.sub(result.pmc, 1, 3) == "PMC") then
result.pmc = mw.ustring.sub(result.pmc, 4, #result.pmc)
end
if result.accessKind then
result.accessKind = access.choice[result.accessKind]
result.unknownAccess = not result.accessKind
else
result.accessKind = (result.pmc and "open")
or access.doi[doiPrefix]
or access.journals[result.journal]
end
if result.doi then
result.doi = mw.text.split(result.doi, '%s+', false)
for i, v in ipairs(result.doi) do
local doiPrefix
local doiSuffix
doiPrefix, doiSuffix = mw.ustring.match(v, "^10%.([^/]+)/(.+)$")
if (doiPrefix == "2307") and not result.jstor then
result.jstor = doiSuffix
end
if not result.accessKind and not result.unknownAccess then
result.accessKind = access.doi[doiPrefix]
end
end
end
if result.patent then
mw.logObject(result.patent,"input:patent")
local patentPatterns = mw.loadData("Moduł:Cytuj/patent")
local patent = nil
for _, v in ipairs(patentPatterns) do
if string.match(result.patent, v.pattern) then
local patentNumber, _ = string.gsub(result.patent, v.pattern, v.number or "%1")
local patentCountry, _ = string.gsub(result.patent, v.pattern, v.country)
local patentInfo = v.info or patentPatterns.ccinfo[patentCountry]
if (result.url == nil) and v.url then
local url, _ = string.gsub(result.patent, v.pattern, v.url)
if checkUri(url) then
result.url = url
end
end
local patentTitle
if v.title then
patentTitle, _ = string.gsub(result.patent, v.pattern, v.title)
elseif patentInfo then
patentTitle = string.format('<span title="%s">%s %s</span>', patentInfo, patentCountry, patentNumber)
else
patentTitle = patentCountry.." "..patentNumber
end
patent = {
number = patentNumber,
application = v.application,
country = patentCountry,
title = patentTitle,
}
break
end
end
result.patent = patent
mw.logObject(result.patent,"parsed:patent")
end
-- return collected parameters if there is any
for k, v in pairs(result) do
return result
end
-- there are no supported parameters
return nil
end
local function prepareOdnIdentifier(data)
if not data.odn or (#data.odn == 0) or (data.odn == "nie") then
return nil
end
data.diferentiator = mw.ustring.match(data.odn, "^([a-z])$") or false
if data.odn ~= "tak" and not data.diferentiator then
-- TODO return only CITEREF...
return data.odn
end
local authors = data.chapterauthor or data.author or data.editor
if not authors then
-- required custom identifier
return nil
end
return "CITEREF"
.. (authors.items[1] and (authors.items[1].lastname or authors.items[1].exact) or "")
.. (authors.items[2] and (authors.items[2].lastname or authors.items[2].exact) or "")
.. (authors.items[3] and (authors.items[3].lastname or authors.items[3].exact) or "")
.. (authors.items[4] and (authors.items[4].lastname or authors.items[4].exact) or "")
.. (data.date and data.date.odn or "")
.. (data.diferentiator or "")
end
local function bookCOinS(data)
local authors = data.chapterauthor or data.author
local result = {}
result["rft_val_fmt"] = "info:ofi/fmt:kev:mtx:book"
if data.chapter and (#data.chapter > 0) then
result["rft.gengre"] = "bookitem"
result["rft.atitle"] = plainText(data.chapter)
result["rft.btitle"] = plainText(data.title)
elseif data.work and (#data.work > 0) then
result["rft.gengre"] = "bookitem"
result["rft.atitle"] = plainText(data.title)
result["rft.btitle"] = plainText(data.work)
else
result["rft.btitle"] = plainText(data.title)
result["rft.gengre"] = "book"
end
if authors then
if authors.items[1].lastname then result["rft.aulast"] = authors.items[1].lastname end
if authors.items[1].name then result["rft.aufirst"] = authors.items[1].name end
if authors.items[1].exact then result["rft.au"] = authors.items[1].exact end
end
if data.date and data.date.coins then
result["rft.date"] = data.date.coins
end
if data.series then result["rft.series"] = data.series end
if data.edition then result["rft.edition"] = data.edition end
if data.publisher then result["rft.pub"] = data.publisher end
if data.place then result["rft.place"] = data.place end
if data.pages then result["rft.pages"] = data.pages end
if data.isbn then result["rft.isbn"] = data.isbn[1] end
if data.issn then result["rft.issn"] = data.issn end
local params = {
"ctx_ver=Z39.88-2004",
mw.uri.buildQueryString(result),
}
if data.oclc then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:oclcnum/"..data.oclc})) end
if data.doi then
for _, v in ipairs(data.doi) do
table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/"..v}))
end
end
if data.url then table.insert(params, mw.uri.buildQueryString( {rft_id = data.url})) end
if data.pmid then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmid/"..data.pmid})) end
if data.lccn then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:lccn/"..data.lccn})) end
local coinsData = table.concat(params, "&")
return coinsData;
end
local function journalCOinS(data)
local result = {}
result["rft_val_fmt"] = "info:ofi/fmt:kev:mtx:journal"
local gengre = (data.arxiv and (#data.arxiv > 0)) and "preprint" or "article"
result["rft.gengre"] = data.title and gengre or "journal"
if data.title then result["rft.atitle"] = plainText(data.title) end
result["rft.jtitle"] = plainText(data.journal)
if data.chapter then result["rft.atitle"] = plainText(data.chapter) end
if data.date and data.date.coins then
result["rft.date"] = data.date.coins
end
if data.title and author then
if author[1].lastname then result["rft.aulast"] = author[1].lastname end
if author[1].name then result["rft.aufirst"] = author[1].name end
if author[1].exact then result["rft.au"] = author[1].exact end
end
if data.volume then result["rft.volume"] = data.volume end
if data.issue then result["rft.edition"] = data.issue end
if data.publisher then result["rft.pub"] = data.publisher end
if data.place then result["rft.place"] = data.place end
if data.pages then result["rft.pages"] = data.pages end
if data.issn then result["rft.issn"] = data.issn end
local params = {
"ctx_ver=Z39.88-2004",
mw.uri.buildQueryString(result),
}
if data.pmid then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmid/"..data.pmid})) end
if data.pmc then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmc/"..data.pmc})) end
if data.doi then
for _, v in ipairs(data.doi) do
table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/"..v}))
end
end
if data.url then table.insert(params, mw.uri.buildQueryString( {rft_id = data.url})) end
local coinsData = table.concat(params, "&")
return coinsData;
end
local function webCOinS(data)
local result = {}
result["rft_val_fmt"] = "info:ofi/fmt:kev:mtx:journal"
result["rft.gengre"] = "unknown"
if data.title then result["rft.atitle"] = plainText(data.title) end
result["rft.jtitle"] = plainText(data.published)
if data.date and data.date.coins then
result["rft.date"] = data.date.coins
end
if data.title and author then
if author[1].lastname then result["rft.aulast"] = author[1].lastname end
if author[1].name then result["rft.aufirst"] = author[1].name end
if author[1].exact then result["rft.au"] = author[1].exact end
end
local params = {
"ctx_ver=Z39.88-2004",
mw.uri.buildQueryString(result),
}
if data.url then table.insert(params, mw.uri.buildQueryString( {rft_id = data.url})) end
local coinsData = table.concat(params, "&")
return coinsData;
end
local function patentCOinS(data)
local result = {}
result["rft_val_fmt"] = "info:ofi/fmt:kev:mtx:journal"
if data.title then result["rft.title"] = plainText(data.title) end
result[data.patent.application and "rft.applnumber" or "rft.number"] = data.patent.number
result["rft.cc"] = data.patent.country
if data.date and data.date.coins then
result[data.patent.application and "rft.appldate" or "rft.date"] = data.date.coins
end
if author then
if author[1].lastname then result["rft.aulast"] = author[1].lastname end
if author[1].name then result["rft.aufirst"] = author[1].name end
if author[1].exact then result["rft.au"] = author[1].exact end
end
-- rft.assignee = author (wszyscy?)
-- rft.inventor = others (wszyscy?)
local params = {
"ctx_ver=Z39.88-2004",
mw.uri.buildQueryString(result),
}
if data.url then table.insert(params, mw.uri.buildQueryString( {rft_id = data.url})) end
local coinsData = table.concat(params, "&")
return coinsData;
end
local function COinS(data, coinsFormat)
if resources.abbrTitles[data.title] then
-- full citation is elsewhere
return false
elseif (coinsFormat == "info:ofi/fmt:kev:mtx:book") and data.title and (#data.title > 0) then
-- title is mandatory element for books
return bookCOinS(data)
elseif coinsFormat == "info:ofi/fmt:kev:mtx:journal" and data.journal and (#data.journal > 0) and (not data.published or (data.journal ~= data.published)) then
-- journal title is mandatory element for journals
return journalCOinS(data)
elseif coinsFormat == "info:ofi/fmt:kev:mtx:journal" and data.published and (#data.published > 0) then
return webCOinS(data)
elseif coinsFormat == "info:ofi/fmt:kev:mtx:patent" and data.patent then
return patentCOinS(data)
elseif data.title and (#data.title > 0) then
-- treat web or unrecognized citations as book
return bookCOinS(data)
else
return false
end
end
--[[
Format edition (number or marc 250$a).
Different for journal.
Tests: Wikipedysta:Nux/test Cytuj wydanie
--]]
local function formatEdition(edition, journal)
local prefix = false
if not journal then
prefix = true
if string.find(edition, "[Ww]yd[a. ]") then
prefix = false
elseif string.find(edition, "[Ee]dition") then
prefix = false
end
end
return (prefix and "wyd. " or "") .. edition
end
--[[
Main.
--]]
local function Cite(p, mode, appendText, firewall)
-- debug helper
if p.args[3] then mw.log(p.args[3]) end
local customMode = mode
-- try to determine type basing on passed parameters
local coinsFormat = resources.COinS[mode]
if not mode then
mode, coinsFormat = determineMode(p)
end
local data = loadCitation(p, mode)
if not data then
local result = mw.html.create("span")
:addClass("problemy")
:attr("aria-hidden", "true")
:attr("data-nosnippet", "")
:attr("data-problemy", "Brak wyników w szablonie cytowania")
if mw.title.getCurrentTitle().namespace == 0 then
result:wikitext(categories.empty)
end
result:wikitext(" ") -- thin space
return tostring(result)
end
if data.missing then
-- do not produce any COiNS info
-- if some mandatory argument is missing
coinsFormat = false
end
local builder = mw.html.create("cite")
builder
:addClass("citation")
:addClass(resources.cite[mode] or nil)
:addClass(access.class[data.accessKind])
:attr("id", prepareOdnIdentifier(data))
--:wikitext(access.render[data.accessKind], ' ')
local needDot = false
local nextAuthorGroup = false
if data.title or data.patent then
if data.chapter then
local authors = data.editor and data.author or data.chapterauthor
if authors then
local list, etal = formatAuthors(authors, false, nextAuthorGroup, nil)
builder:wikitext(list, ", ")
nextAuthorGroup = true
end
local title = softNoWiki(data.chapter)
if data.chapterurl then
builder:wikitext("[", escapeUrl(data.archivechapter and data.archive or data.chapterurl), " ''", title, "'']")
elseif data.chapterlink then
builder:wikitext("[[", data.chapterlink, "|''", title, "'']]")
else
builder:wikitext("''", title, "''")
end
if data.format then
builder:wikitext(" [", data.format, "]")
end
builder:wikitext(", [w:] ")
end
local authors = false
local editor = false
if not data.chapter and data.author then
authors = data.author
else
authors = data.editor or data.author
editor = data.editor
end
if authors then
local list, etal = formatAuthors(authors, not (editor or false), nextAuthorGroup, editor and " i inni red." or nil)
builder:wikitext(list)
nextAuthorGroup = true
if editor and not etal and not authors.etal then
builder:wikitext(" (red.)")
end
builder:wikitext(", ")
end
if customMode and data.authorextra then
builder:wikitext(data.authorextra, ", ")
end
if resources.abbrTitles[data.title] then
local title = resources.abbrTitles[data.title]
builder:wikitext(title)
needDot = not mw.ustring.match(title, "%.%]%]$")
and not mw.ustring.match(title, "%.$")
elseif data.title then
local title = softNoWiki(data.title)
if data.url or data.archiveurl then
builder:wikitext("[", escapeUrl(data.archiveurl and data.archive or data.url), " ''", title, "'']")
elseif data.titlelink then
builder:wikitext("[[", data.titlelink, "|''", title, "'']]")
else
builder:wikitext("''", title, "''")
end
if not data.chapter and data.format then
builder:wikitext(" [", data.format, "]")
needDot = true
elseif not mw.ustring.match(plainText(title), "[%.,!?]$") then
needDot = true
end
local showmediatype = data.mediatype and (#data.mediatype > 0)
if showmediatype then
builder:wikitext(" [", data.mediatype, "]")
needDot = true
end
end
if not editor and data.editor then
local list, etal = formatAuthors(data.editor, false, true, " i inni red.")
builder:wikitext(needDot and ", " or " ", list, (etal or data.editor.etal) and "" or " (red.)")
needDot = true
end
if data.others then
local list, etal = formatAuthors(data.others, true, true, nil)
builder:wikitext(needDot and ", " or " ", data.patent and resources.patent.inventor.." " or "", list)
needDot = true
end
if data.patent then
local title = (not data.title and data.url) and string.format("[%s %s]", escapeUrl(data.url), data.patent.title) or data.patent.title
builder:wikitext(needDot and ", " or " ", resources.patent[data.patent.application], " ", title)
needDot = true
end
elseif data.journal and data.author then
local list, etal = formatAuthors(data.author, false, false, nil)
builder:wikitext(list, ", ")
end
if data.work then
builder:wikitext((data.title or data.patent) and ", " or "", "[w:] ", data.work, (not data.mediatype and data.url) and " [online]" or "")
needDot = true
end
if data.journal and (not data.published or (data.journal ~= data.published)) then
builder:wikitext((data.title or data.work) and ", " or "")
local title = softNoWiki(data.journal)
if data.journalurl or data.archivejournal then
builder:wikitext("[", escapeUrl(data.archivejournal and data.archive or data.journalurl), " „", title, "”]")
elseif data.journallink then
builder:wikitext("„[[", data.journallink, "|", title, "]]”")
else
builder:wikitext("„", title, "”")
end
needDot = true
end
if data.responsibility then
builder:wikitext(", ", data.responsibility)
needDot = true
end
if data.edition then
builder:wikitext(", ", formatEdition(data.edition, data.journal))
needDot = true
end
if data.volume then
builder:wikitext(data.journal and ", " or ", t. ", data.volume)
needDot = true
end
if data.journal and data.issue then
builder:wikitext(" (", data.issue, ")")
needDot = true
end
if data.description and (#data.description > 0) then
builder:wikitext(", ", data.description)
needDot = true
end
if data.published and not data.publisher then
builder:wikitext(", ", data.published)
needDot = true
end
local place = false
if data.place then
builder:wikitext(", ", data.place)
needDot = true
place = true
end
if data.publisher then
builder:wikitext(place and ": " or ", ", data.publisher)
needDot = true
place = false
end
if data.date then
local shortDate = data.journal and (data.doi or data.pmid or data.pmc)
if data.date.bib and data.date.hint then
builder:wikitext(place and " " or ", "):tag("span"):attr("title", data.date.hint):wikitext(data.date.bib)
elseif data.date.bib then
builder:wikitext(place and " " or ", ", data.date.bib)
elseif data.date.day and shortDate then
builder:wikitext(place and " " or ", "):tag("span"):attr("title", tostring(data.date.day).." "..resources.months[data.date.month].d.." "..tostring(data.date.year)):wikitext(data.date.year)
elseif data.date.month and shortDate then
builder:wikitext(place and " " or ", "):tag("span"):attr("title", resources.months[data.date.month].m.." "..tostring(data.date.year)):wikitext(data.date.year)
elseif data.date.day then
builder:wikitext(", ", tostring(data.date.day), " ", resources.months[data.date.month].d, " ", tostring(data.date.year))
elseif data.date.month then
builder:wikitext(", ", resources.months[data.date.month].m, " ", tostring(data.date.year))
else
builder:wikitext(place and " " or ", ", data.date.year)
end
builder:wikitext(data.diferentiator or "")
needDot = true
end
if not data.journal and (data.series or data.issue) then
builder:wikitext(" (", data.series or "", (data.series and data.issue) and "; " or "", data.issue or "", ")")
needDot = true
elseif data.journal and data.series then
builder:wikitext(" (", data.series, ")")
needDot = true
end
if data.p and #data.p > 0 then
local isNonStandardPageNumber = mw.ustring.match(data.p, "[^%s0-9,%-–]")
builder:wikitext(isNonStandardPageNumber and ", " or ", s.\194\160", data.p)
needDot = true
end
if data.doi then
local separator = " "
builder:addClass("doi"):wikitext(", [[DOI (identyfikator cyfrowy)|DOI]]:")
local doiLink = first(resources.params.doi.link)
for _, v in ipairs(data.doi) do
builder:wikitext(separator, "[", doiLink, mw.uri.encode(v), " ", softNoWiki(v), "]")
separator = ", "
end
needDot = true
end
if data.isbn then
for i,v in ipairs(data.isbn) do
builder:wikitext(", ")
require("Moduł:ISBN").link(builder, v)
end
needDot = true
end
if data.lccn then
builder:wikitext(", [[Biblioteka Kongresu|LCCN]] [", first(resources.params.lccn.link), mw.uri.encode(data.lccn), " ", data.lccn, "]")
needDot = true
end
if data.issn then
builder:tag("span"):addClass("issn"):wikitext(", [[International Standard Serial Number|ISSN]] [", first(resources.params.issn.link), data.issn, " ", data.issn, "]")
needDot = true
end
if data.pmid then
builder:addClass("pmid"):wikitext(", [[PMID]]: [", first(resources.params.pmid.link), data.pmid, " ", data.pmid, "]")
needDot = true
end
if data.pmc then
builder:addClass("pmc"):wikitext(", [[PMCID]]: [", first(resources.params.pmc.link), data.pmc, "/ PMC", data.pmc, "]")
needDot = true
end
if data.bibcode then
builder:wikitext(", [[Bibcode]]: [", first(resources.params.bibcode.link), data.bibcode, " ", data.bibcode, "]")
needDot = true
end
if data.oclc then
builder:wikitext(", [[Online Computer Library Center|OCLC]] [", first(resources.params.oclc.link), mw.uri.encode(data.oclc), " ", data.oclc, "]")
needDot = true
end
if data.arxiv then
builder:wikitext(", [[arXiv]]:")
local eprint, class = mw.ustring.match(data.arxiv, "^(%S+)%s+%[([^%[%]]+)%]$")
if eprint then
builder:wikitext("[", first(resources.params.arxiv.link), eprint, " ", eprint, "] [[//arxiv.org/archive/", class, " ", class, "]]" )
else
builder:wikitext("[", first(resources.params.arxiv.link), data.arxiv, " ", data.arxiv, "]" )
end
needDot = true
end
if data.jstor then
builder:tag("span"):addClass("jstor"):wikitext(", [[JSTOR]]: [", first(resources.params.jstor.link), data.jstor, " ", data.jstor, "]")
needDot = true
end
if data.ol then
builder:tag("span"):addClass("open-library"):wikitext(", [[Open Library|OL]]: [", first(resources.params.ol.link), data.ol, " ", data.ol, "]")
needDot = true
end
if data.id then
builder:wikitext(", ", data.id)
needDot = true
end
if data.accessdate then
builder:tag("span"):addClass("accessdate"):wikitext(" [dostęp ", string.format("%04d-%02d-%02d", data.accessdate.year, data.accessdate.month, data.accessdate.day), "]")
needDot = true
end
if data.archive then
builder:wikitext(" [zarchiwizowane")
local url = data.archiveurl and data.url or (data.archivechapter and data.chapterurl or data.journalurl)
if url then
builder:wikitext(" z [", escapeUrl(url), " adresu]")
end
if data.archived and data.archived.day then
builder:wikitext(" ", string.format("%04d-%02d-%02d", data.archived.year, data.archived.month, data.archived.day))
end
builder:wikitext("]")
needDot = true
end
if data.quotation then
builder:wikitext(", Cytat: ", data.quotation)
needDot = true
end
local coinsData = COinS(data, coinsFormat)
if coinsData then
builder:tag("span"):addClass("Z3988"):attr("title",coinsData):css("display","none"):wikitext(" ")
end
if data.lang then
local languages = require("Moduł:Lang").lang({args = data.lang})
builder:wikitext(" ", languages)
needDot = true
end
if data.fullStop then
if not mw.ustring.match(data.fullStop, "^[%.!?,;:]") then
builder:wikitext(", ")
end
builder:wikitext(data.fullStop)
needDot = mw.ustring.match(data.fullStop, "[%.!?,;:]$") == nil
end
if needDot then
builder:wikitext(".")
end
if appendText then
builder:wikitext(appendText)
end
-- categories
local addCategories = mw.title.getCurrentTitle().namespace == 0
local problems = {}
if not customMode and (mode == 1) then
builder:wikitext(categories.undetermined)
table.insert(problems, "???")
end
if data.publisher and data.published then
table.insert(problems, "p?")
if addCategories then
table.insert(problems, categories.unusedPublished)
end
end
if data.journal and data.published and (data.journal == data.published) then
table.insert(problems, "j?")
if addCategories then
table.insert(problems, categories.sameJournalAndPublished)
end
end
if (not data.url and not data.chapterurl) or (not data.title and not data.journalurl) then
builder:addClass(data.urlnowiki and "urlnowiki" or "nourl")
end
local missing = false
local needurl = ((resources.params.published.used[mode] == "*") and data.published) or (resources.params.url.used[mode] == "*")
if data.missing then
-- usually missing title, this is the first check for mandatory arguments
table.insert(problems, data.missing)
missing = true
elseif needurl and not data.url and not data.chapterurl and not data.arxiv and not data.archive then
-- build in support for missing external link for page citation
table.insert(problems, resources.params.url.name)
missing = true
else
-- any other missing value (first catch)
for k, v in pairs(resources.params) do
if (v.used[mode] == "!") and (not data[k] or (#data[k] == 0)) then
table.insert(problems, v.name)
missing = true
break
end
end
end
if missing and addCategories then
builder:wikitext(string.format(categories.missingArg, resources.modes[mode]))
end
if (data.chapterauthor and data.chapterauthor.comma)
or (data.author and (data.author.comma == true))
or (data.editor and data.editor.comma)
or (data.others and data.others.comma) then
table.insert(problems, "!!!")
if addCategories then
builder:wikitext(categories.suspectedComma)
end
end
if data.author and (data.author.comma == "alt") then
table.insert(problems, "a?")
if addCategories then
builder:wikitext(categories.altAuthor)
end
end
if data.originalJournal then
builder:addClass("c") -- CSS dla lokalizacji w treści
if addCategories then
builder:wikitext(categories.altJournal)
end
end
local citewiki = (data.url and mw.ustring.match(data.url, "%.wikipedia%.org"))
or (data.journal and mw.ustring.match(killLinkInterwiki(data.journal), "[Ww]ikipedia"))
or (data.publisher and mw.ustring.match(killLinkInterwiki(data.publisher), "[Ww]ikipedia"))
or (data.published and mw.ustring.match(killLinkInterwiki(data.published), "[Ww]ikipedia"))
if citewiki then
local justification = false
local acceptedLinks = mw.loadData("Moduł:Cytuj/wiki")[mw.wikibase.getEntityIdForCurrentPage()] or {}
for i, v in ipairs(acceptedLinks) do
justification = (v == data.url) or (v == data.archive)
if justification then
break
end
end
if not justification then
table.insert(problems, "wiki?")
if addCategories then
builder:wikitext(categories.wiki)
end
end
end
if data.unknownAccess then
table.insert(problems, "dostęp?")
if addCategories then
builder:wikitext(categories.unknownAccess)
end
end
if data.rejectedurl then
table.insert(problems, "<s>url</s>")
if addCategories then
builder:wikitext(categories.rejectedUrl)
end
end
if data.urlWarning then
table.insert(problems, "Url")
if addCategories then
builder:wikitext(categories.unusedUrl)
end
end
if data.patchCitoidDate then
table.insert(problems, "1 stycznia")
end
if data.badDate then
table.insert(problems, "data?")
end
if data.badAccessDate then
table.insert(problems, "data dostępu?")
end
if data.badArchivedDate then
table.insert(problems, "zarchiwizowano?")
end
if addCategories and (data.badDate or data.badAccessDate or data.badArchiveDate) then
builder:wikitext(categories.badDate)
end
if (data.author and data.author.etal)
or (data.chapterauthor and data.chapterauthor.etal)
or (data.editor and data.editor.etal)
or (data.others and data.others.etal) then
table.insert(problems, "i inni")
if addCategories then
builder:wikitext(categories.etal)
end
end
if firewall then
local reportFirewall = function(report)
if report then
table.insert(problems, report.info)
if addCategories and report.cat then
local cat = mw.ustring.format(categories.firewall, report.cat)
builder:wikitext(cat)
end
end
end
local reportCommonsFile = function(ext)
mw.logObject(ext, "ext")
if ext and (firewall.commonsFile[ext] ~= false) then
local issue = firewall.commonsFile[ext] or firewall.commonsFile[true]
reportFirewall(firewall.reports[issue])
end
end
if data.url and firewall.url[data.url] ~= false then
local uri = mw.uri.new(data.url)
local issue = firewall.url[data.url]
or firewall.host[uri.host]
or firewall.path[uri.relativePath]
reportFirewall(firewall.reports[issue])
end
reportCommonsFile(data.chapterext)
reportCommonsFile(data.titleext)
reportCommonsFile(data.journalext)
end
if #problems > 0 then
local info = builder:tag("span")
:addClass("problemy")
:addClass("problemy-w-cytuj")
:attr("aria-hidden", "true")
:attr("data-nosnippet", "")
info:wikitext(table.concat(problems,", "))
end
return builder:done()
end
return {
auto = function(frame)
return Cite(frame:getParent(), nil, nil, mw.loadData("Moduł:Cytuj/firewall"))
end,
custom = function(frame)
local traceCategory = false
local pagename = mw.title.getCurrentTitle()
if (pagename.namespace == 10) and frame.getParent then
local template = mw.title.new( frame:getParent():getTitle(), "Szablon" )
if mw.title.compare(template, pagename) == 0 then
traceCategory = categories.traceInvokeCustom
end
end
local customMode = frame.args[1]
local mode = 1
if customMode then
customMode = mw.text.trim(customMode)
for i, v in ipairs(resources.modes) do
if customMode == v then
mode = i
break
end
end
end
return Cite(frame, mode, traceCategory, null)
end,
}