Moduł:Cytuj: Różnice pomiędzy wersjami
Przejdź do nawigacji
Przejdź do wyszukiwania
m 1 wersja |
pl>Paweł Ziemian |
||
Linia 1: | Linia 1: | ||
local resources = | local resources = mw.loadData("Moduł:Cytuj/dane") | ||
local access = mw.loadData("Moduł:Cytuj/dostęp") | |||
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 function softNoWiki(text) | ||
local result, count = string.gsub(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 | return result | ||
end | end | ||
Linia 218: | Linia 30: | ||
local result, count = string.gsub(text, "</?[Ss][Pp][Aa][Nn][^>]*>", "") | local result, count = string.gsub(text, "</?[Ss][Pp][Aa][Nn][^>]*>", "") | ||
return result | return result | ||
end | |||
local function first(data) | |||
return type(data) == "table" and data[1] or data | |||
end | end | ||
Linia 250: | Linia 66: | ||
end | end | ||
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 | for i, v in ipairs(detector) do | ||
if detector[i] then | if detector[i] then | ||
-- | -- if type is determined more than once | ||
-- use only the first one without COinS | |||
-- use only the first one | return i, false | ||
return i, | |||
end | end | ||
end | end | ||
Linia 293: | Linia 122: | ||
return false | return false | ||
end | end | ||
Linia 334: | Linia 147: | ||
end | end | ||
if initials then | if initials then | ||
before:tag("span"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials)) | before:tag("span"):css("display", "none"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials)) | ||
end | end | ||
before:wikitext(" ") | before:wikitext(" ") | ||
Linia 342: | Linia 155: | ||
if not namefirst and (name or initials) then | if not namefirst and (name or initials) then | ||
local after = data.familynamefirst and builder or builder:tag("span"):addClass("cite-name-after") | local after = data.familynamefirst and builder or builder:tag("span"):css("display", "none"):addClass("cite-name-after") | ||
after:wikitext(" ") | after:wikitext(" ") | ||
if name then | if name then | ||
Linia 350: | Linia 163: | ||
after:tag("span"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials)) | after:tag("span"):addClass("cite-name-initials"):attr("title", namehint):wikitext(softNoWiki(data.nameinitials)) | ||
end | end | ||
if data.js then | |||
after:wikitext(",") | |||
end | |||
end | |||
if data.js then | |||
builder:wikitext(" ", data.js) | |||
end | end | ||
Linia 378: | Linia 198: | ||
local function makeInitials(name) | local function makeInitials(name) | ||
local nameinitials = mw.ustring.gsub(name, "(%w[Hh]?)([% | 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", "") | 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. ") | 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) | 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 | end | ||
local function parseAuthor(author) | local function parseAuthor(author) | ||
local result = {} | 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 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 | if resources.exactAuthors[author] then | ||
result.exact = author | result.exact = author | ||
Linia 420: | Linia 278: | ||
end | end | ||
local | local prefix1, rest = mw.ustring.match(author, "^([%l%p%s]+)(.+)$") | ||
if not | if not prefix1 then | ||
rest = author | rest = author | ||
prefix1 = "" | |||
end | end | ||
prefix = mw.text.trim(prefix0.." ".. | local prefix = mw.text.trim(prefix0.." "..prefix1) | ||
if #prefix > 0 then | if #prefix > 0 then | ||
if mw.ustring.sub(prefix, -1) == "#" then | if mw.ustring.sub(prefix, -1) == "#" then | ||
Linia 446: | Linia 304: | ||
if #suffix > 0 then | if #suffix > 0 then | ||
result.suffix = mw.ustring.gsub(suffix, "%s+", " ") -- collapse spaces | 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 | end | ||
local lastname, name = mw.ustring.match(rest2, "%s*([^,]-)%s*,%s*(.-)%s*$") | local lastname, name = mw.ustring.match(rest2, "%s*([^,]-)%s*,%s*(.-)%s*$") | ||
if not lastname then | if not lastname then | ||
Linia 453: | Linia 327: | ||
lastname, name = mw.ustring.match(rest2, "%s*(%u[%l%d%p]*)%s+(.-)%s*$") | lastname, name = mw.ustring.match(rest2, "%s*(%u[%l%d%p]*)%s+(.-)%s*$") | ||
else | else | ||
name, lastname = mw.ustring.match(rest2, "%s*(.-)%s+(%u[%w%p]-)%s*$") | 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 | end | ||
elseif resources.lastnamePrefixes[prefix1] then | |||
lastname = prefix1 .. lastname | |||
elseif resources.lastnamePrefixes[prefix1] == false then | |||
name = name.." "..mw.text.trim(prefix1) | |||
end | end | ||
Linia 460: | Linia 342: | ||
result.lastname = mw.text.trim(rest2) | result.lastname = mw.text.trim(rest2) | ||
else | else | ||
result.name = name | result.name = fixInitials(name) | ||
result.lastname = lastname | result.lastname = lastname | ||
result.nameinitials = makeInitials(name) | result.nameinitials = makeInitials(name) | ||
Linia 583: | Linia 465: | ||
end | end | ||
local function | local function collectAuthors(author, checkForAltFormat) | ||
if not author then | |||
return | |||
if author | |||
end | end | ||
if | -- Obsługa cudzysłowów w autorach (treat quoted authors as-is) | ||
return | 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 | end | ||
local | |||
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 | end | ||
local | local etal = false | ||
if | 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 | end | ||
function decodeEntity(s) | |||
local result = nil | |||
local hex = string.match(s, "^&#[xX]([0-9A-Fa-f]+);$") | |||
local | if hex then | ||
result = mw.ustring.char(tonumber(hex, 16)) | |||
return | 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 | end | ||
local authorHead = #author <= 500 and author or string.sub(author, 1, findUtf8CharAt(author, 500) - 1) | |||
local result = {} | local result = {} | ||
local splitter = string.match( | local esc1 = string.gsub(authorHead, "\\", "\\\\") | ||
local authors = mw.text.split(author, splitter, true) | local esc2 = string.gsub(esc1, "&#?[a-zA-Z0-9]+;", decodeEntity) | ||
for | 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) | local author = parseAuthor(v) | ||
if author then | if author then | ||
Linia 629: | Linia 595: | ||
end | 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 | end | ||
local function formatAuthors(authors, useDecorations, nextgroup) | local function formatAuthors(authors, useDecorations, nextgroup, etalForm) | ||
local count = #authors | local count = #authors.items | ||
if count == 0 then | if count == 0 then | ||
return nil | 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 | end | ||
Linia 641: | Linia 641: | ||
local a = author:format(nextgroup) | local a = author:format(nextgroup) | ||
local r = author.link and ("[["..author.link.."|"..a.."]]") or a | local r = author.link and ("[["..author.link.."|"..a.."]]") or a | ||
return r..suffix(author) | |||
end | end | ||
if count == 1 then | 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 | end | ||
local result = {} | local result = {} | ||
table.insert(result, formatter(authors[1])) | table.insert(result, formatter(authors.items[1])) | ||
if not authors.etal and (count <= 3) then | |||
if count <= 3 then | |||
table.insert(result, ", "); | table.insert(result, ", "); | ||
table.insert(result, formatter(authors[2])) | table.insert(result, formatter(authors.items[2])) | ||
if count == 3 then | if count == 3 then | ||
table.insert(result, ", "); | table.insert(result, ", "); | ||
table.insert(result, formatter(authors[3])) | table.insert(result, formatter(authors.items[3])) | ||
end | end | ||
return table.concat(result, "") | 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 | end | ||
table.insert(result, "<span class=\"cite- | 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") | |||
table.insert( | |||
end | end | ||
table.insert(result, "\">") | |||
table.insert(result, etalForm or " i inni") | |||
table.insert(result, "</span>") | table.insert(result, "</span>") | ||
return table.concat(result, ""), true | |||
end | end | ||
Linia 706: | Linia 711: | ||
end | end | ||
local link, description = mw.ustring.match(text, "^%[( | local link, description = mw.ustring.match(text, "^%[(%S*)%s+(.-)%]$") | ||
if link then | if link and checkUri(link) then | ||
return description, false, link | return description, false, link | ||
end | end | ||
Linia 715: | Linia 720: | ||
local function detectArchive(url) | local function detectArchive(url) | ||
local | local defaultDecoder = resources.archiveDecoders.defaultDecoder | ||
for i, v in ipairs(resources.archiveDecoders) do | |||
local pattern = type(v) == "string" and v or v.pattern | |||
local decoder = type(v) == "table" and v or defaultDecoder | |||
local items = { mw.ustring.match(url, pattern) } | |||
if #items > 0 then | |||
return items[decoder.link], items[decoder.year].."-"..items[decoder.month].."-"..items[decoder.day] | |||
end | |||
end | end | ||
return false, false | 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 true | |||
end | |||
end | |||
end | |||
end | |||
return false | |||
end | end | ||
Linia 743: | Linia 770: | ||
result.missing = v.name | result.missing = v.name | ||
end | 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 | end | ||
Linia 748: | Linia 788: | ||
-- translate some parameters | -- translate some parameters | ||
result.chapterauthor | local altAuthorParser = false | ||
result.author | 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.lang = collectLanguages(result.lang) | ||
result.editor | result.editor = collectAuthors(result.editor, false) | ||
result.others | result.others = collectAuthors(result.others, false) | ||
-- parse main bibliographic date | |||
if result.date then | if result.date then | ||
result. | 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 | end | ||
-- fix other dates | -- fix other dates | ||
result.accessdate = parseDate(result.accessdate or "", false, false, false) | if result.accessdate then | ||
result.accessdate = parseDate(result.accessdate or "", false, false, false) | |||
result.accessdate = | 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 | end | ||
Linia 782: | Linia 875: | ||
if url or result.titlelink then | if url or result.titlelink then | ||
if result.url and (#result.url > 0) and (result.url ~= "{{{url}}}") then | if result.url and (#result.url > 0) and (result.url ~= "{{{url}}}") then | ||
result.urlWarning = true | result.urlWarning = true | ||
end | end | ||
Linia 793: | Linia 885: | ||
end | end | ||
if result.journal then | 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 = splitWikiLink(result.journal) | result.journal, result.journallink, result.journalurl = 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 and isAutoGeneratedUrl(result.url) then | |||
result.rejectedurl = true | |||
result.url = false | |||
end | |||
if result.chapterurl and isAutoGeneratedUrl(result.chapterurl) then | |||
result.rejectedurl = true | |||
result.chapterurl = false | |||
end | |||
if result.journalurl and isAutoGeneratedUrl(result.journalurl) then | |||
result.rejectedurl = true | |||
result.journalurl = false | |||
end | end | ||
Linia 799: | Linia 918: | ||
local al, ad = detectArchive(result.url) | local al, ad = detectArchive(result.url) | ||
if al then | if al then | ||
result.archiveurl = true | |||
result.archive = result.url | result.archive = result.url | ||
result.url = al | result.url = al | ||
if ad then result.archived = ad end | if ad then result.archived = ad end | ||
end | end | ||
elseif result.archive and (not result. | 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) | local al, ad = detectArchive(result.archive) | ||
if ad and not result.archived then result.archived = ad end | 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 | end | ||
result.archived = parseDate(result.archived or "", false, false, false) | if result.archived then | ||
result.archived = parseDate(result.archived or "", false, false, false) | |||
result.archived = | 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 | end | ||
if result. | if result.edition and result.journal and not result.volume and not result.issue then | ||
local volume, issue = mw.ustring.match(result. | local volume, issue = mw.ustring.match(result.edition, "^%s*([^%(]+)%s+%((.-)%)%s*$"); | ||
if volume then | if volume then | ||
result. | result.volume = volume | ||
result.issue = issue | result.issue = issue | ||
result.edition = nil | |||
end | 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ł:Brudnopis/Paweł Ziemian/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 | end | ||
Linia 837: | Linia 1056: | ||
data.diferentiator = mw.ustring.match(data.odn, "^([a-z])$") or false | data.diferentiator = mw.ustring.match(data.odn, "^([a-z])$") or false | ||
if data.odn ~= "tak" and not data.diferentiator then | if data.odn ~= "tak" and not data.diferentiator then | ||
-- TODO return only CITEREF... | -- TODO return only CITEREF... | ||
Linia 850: | Linia 1068: | ||
return "CITEREF" | return "CITEREF" | ||
.. (authors[1] and (authors[1].lastname or authors[1].exact) or "") | .. (authors.items[1] and (authors.items[1].lastname or authors.items[1].exact) or "") | ||
.. (authors[2] and (authors[2].lastname or authors[2].exact) or "") | .. (authors.items[2] and (authors.items[2].lastname or authors.items[2].exact) or "") | ||
.. (authors[3] and (authors[3].lastname or authors[3].exact) or "") | .. (authors.items[3] and (authors.items[3].lastname or authors.items[3].exact) or "") | ||
.. (authors[4] and (authors[4].lastname or authors[4].exact) or "") | .. (authors.items[4] and (authors.items[4].lastname or authors.items[4].exact) or "") | ||
.. (data.date and data.date. | .. (data.date and data.date.odn or "") | ||
.. (data.diferentiator or "") | .. (data.diferentiator or "") | ||
end | end | ||
Linia 875: | Linia 1093: | ||
end | end | ||
if authors then | if authors then | ||
if authors[1].lastname then result["rft.aulast"] = authors[1].lastname end | if authors.items[1].lastname then result["rft.aulast"] = authors.items[1].lastname end | ||
if authors[1].name then result["rft.aufirst"] = authors[1].name end | if authors.items[1].name then result["rft.aufirst"] = authors.items[1].name end | ||
if authors[1].exact then result["rft.au"] = authors[1].exact end | if authors.items[1].exact then result["rft.au"] = authors.items[1].exact end | ||
end | end | ||
if data.date then | if data.date and data.date.coins then | ||
result["rft.date"] = data.date. | result["rft.date"] = data.date.coins | ||
end | end | ||
if data. | 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.publisher then result["rft.pub"] = data.publisher end | ||
if data.place then result["rft.place"] = data.place end | if data.place then result["rft.place"] = data.place end | ||
Linia 896: | Linia 1114: | ||
if data.oclc then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:oclcnum/"..data.oclc})) end | if data.oclc then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:oclcnum/"..data.oclc})) end | ||
if data.doi then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/".. | 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.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.pmid then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmid/"..data.pmid})) end | ||
Linia 913: | Linia 1135: | ||
result["rft.jtitle"] = plainText(data.journal) | result["rft.jtitle"] = plainText(data.journal) | ||
if data.chapter then result["rft.atitle"] = plainText(data.chapter) end | if data.chapter then result["rft.atitle"] = plainText(data.chapter) end | ||
if data.date then | if data.date and data.date.coins then | ||
result["rft.date"] = data.date. | result["rft.date"] = data.date.coins | ||
end | end | ||
if data.title and author then | if data.title and author then | ||
Linia 922: | Linia 1143: | ||
if author[1].exact then result["rft.au"] = author[1].exact end | if author[1].exact then result["rft.au"] = author[1].exact end | ||
end | end | ||
if data. | if data.volume then result["rft.volume"] = data.volume end | ||
if data.issue then result["rft.edition"] = data.issue end | if data.issue then result["rft.edition"] = data.issue end | ||
if data.publisher then result["rft.pub"] = data.publisher end | if data.publisher then result["rft.pub"] = data.publisher end | ||
Linia 936: | Linia 1157: | ||
if data.pmid then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmid/"..data.pmid})) end | 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.pmc then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:pmc/"..data.pmc})) end | ||
if data.doi then table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/".. | 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.url then table.insert(params, mw.uri.buildQueryString( {rft_id = data.url})) end | ||
Linia 949: | Linia 1174: | ||
if data.title then result["rft.atitle"] = plainText(data.title) end | if data.title then result["rft.atitle"] = plainText(data.title) end | ||
result["rft.jtitle"] = plainText(data.published) | result["rft.jtitle"] = plainText(data.published) | ||
if data.date then | if data.date and data.date.coins then | ||
result["rft.date"] = data.date. | result["rft.date"] = data.date.coins | ||
end | end | ||
if data.title and author then | if data.title and author then | ||
Linia 968: | Linia 1192: | ||
return coinsData; | return coinsData; | ||
end | 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) | local function COinS(data, coinsFormat) | ||
if (coinsFormat == "info:ofi/fmt:kev:mtx:book") and data.title and (#data.title > 0) then | 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 | -- title is mandatory element for books | ||
return bookCOinS(data) | return bookCOinS(data) | ||
Linia 978: | Linia 1233: | ||
elseif coinsFormat == "info:ofi/fmt:kev:mtx:journal" and data.published and (#data.published > 0) then | elseif coinsFormat == "info:ofi/fmt:kev:mtx:journal" and data.published and (#data.published > 0) then | ||
return webCOinS(data) | 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 | elseif data.title and (#data.title > 0) then | ||
-- treat web or unrecognized citations as book | -- treat web or unrecognized citations as book | ||
Linia 986: | Linia 1243: | ||
end | end | ||
local function Cite(p, mode) | local function Cite(p, mode, appendText) | ||
-- debug helper | -- debug helper | ||
if p.args[3] then mw.log(p.args[3]) end | if p.args[3] then mw.log(p.args[3]) end | ||
local customMode = mode | |||
-- try to determine type basing on passed parameters | -- try to determine type basing on passed parameters | ||
Linia 1006: | Linia 1264: | ||
end | end | ||
local builder = mw.html.create(" | local builder = mw.html.create("cite") | ||
builder | builder | ||
:addClass("citation") | :addClass("citation") | ||
:addClass(resources.cite[mode] or nil) | |||
:addClass(access.class[data.accessKind]) | |||
:attr("id", prepareOdnIdentifier(data)) | :attr("id", prepareOdnIdentifier(data)) | ||
--:wikitext(access.render[data.accessKind], ' ') | |||
local needDot = false | local needDot = false | ||
local nextAuthorGroup = false | local nextAuthorGroup = false | ||
if data.title then | if data.title or data.patent then | ||
if data.chapter then | if data.chapter then | ||
local authors = data.editor and data.author or data.chapterauthor | local authors = data.editor and data.author or data.chapterauthor | ||
if authors then | if authors then | ||
local list, etal = formatAuthors(authors, false, nextAuthorGroup, nil) | |||
builder:wikitext(list, ", ") | |||
nextAuthorGroup = true | nextAuthorGroup = true | ||
end | end | ||
Linia 1024: | Linia 1286: | ||
local title = softNoWiki(data.chapter) | local title = softNoWiki(data.chapter) | ||
if data.chapterurl then | if data.chapterurl then | ||
builder:wikitext("[", escapeUrl( | builder:wikitext("[", escapeUrl(data.archivechapter and data.archive or data.chapterurl), " ''", title, "'']") | ||
elseif data.chapterlink then | elseif data.chapterlink then | ||
builder:wikitext("[[", data.chapterlink, "|''", title, "'']]") | builder:wikitext("[[", data.chapterlink, "|''", title, "'']]") | ||
Linia 1031: | Linia 1293: | ||
end | end | ||
if | if data.format then | ||
builder:wikitext(",") | builder:wikitext(" [", data.format, "]") | ||
end | end | ||
builder:wikitext(" [w:] ") | builder:wikitext(", [w:] ") | ||
end | end | ||
Linia 1047: | Linia 1309: | ||
end | end | ||
if authors then | 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 | nextAuthorGroup = true | ||
if editor then | if editor and not etal and not authors.etal then | ||
builder:wikitext(" (red.)") | builder:wikitext(" (red.)") | ||
end | end | ||
builder:wikitext(", ") | builder:wikitext(", ") | ||
end | 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 | end | ||
if not | |||
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 | needDot = true | ||
end | end | ||
local | if data.others then | ||
local list, etal = formatAuthors(data.others, true, true, nil) | |||
builder:wikitext(" | builder:wikitext(needDot and ", " or " ", data.patent and resources.patent.inventor.." " or "", list) | ||
needDot = true | needDot = true | ||
end | end | ||
if | 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) | |||
builder:wikitext(", ", | |||
needDot = true | needDot = true | ||
end | end | ||
elseif data.journal and data.author then | |||
local list, etal = formatAuthors(data.author, false, false, nil) | |||
builder:wikitext(list, ", ") | |||
end | end | ||
if data.work then | if data.work then | ||
builder:wikitext(", [w:] ", data.work, (not data.mediatype and data.url) and " [online]" or "") | builder:wikitext((data.title or data.patent) and ", " or "", "[w:] ", data.work, (not data.mediatype and data.url) and " [online]" or "") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.journal and (not data.published or (data.journal ~= data.published)) then | 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) | local title = softNoWiki(data.journal) | ||
if data.journalurl then | if data.journalurl or data.archivejournal then | ||
builder:wikitext("[", escapeUrl(data.journalurl), " ", title, "]") | builder:wikitext("[", escapeUrl(data.archivejournal and data.archive or data.journalurl), " „", title, "”]") | ||
elseif data.journallink then | elseif data.journallink then | ||
builder:wikitext("[[", data.journallink, "|", title, "]]") | builder:wikitext("„[[", data.journallink, "|", title, "]]”") | ||
else | else | ||
builder:wikitext(title) | builder:wikitext("„", title, "”") | ||
end | end | ||
needDot = true | needDot = true | ||
end | end | ||
Linia 1108: | Linia 1394: | ||
end | end | ||
if data. | if data.edition then | ||
builder:wikitext(data.journal and ", " or ", wyd. ", data.edition) | |||
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 | needDot = true | ||
end | end | ||
Linia 1141: | Linia 1431: | ||
end | end | ||
if data.date then | if data.date then | ||
if data. | local shortDate = data.journal and (data.doi or data.pmid or data.pmc) | ||
builder:wikitext(place and " " or ", ", data. | 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 | elseif data.date.day then | ||
builder:wikitext(", ", tostring(data.date.day), " ", resources.months[data.date.month].d, " ", tostring(data.date.year)) | builder:wikitext(", ", tostring(data.date.day), " ", resources.months[data.date.month].d, " ", tostring(data.date.year)) | ||
Linia 1148: | Linia 1445: | ||
builder:wikitext(", ", resources.months[data.date.month].m, " ", tostring(data.date.year)) | builder:wikitext(", ", resources.months[data.date.month].m, " ", tostring(data.date.year)) | ||
else | else | ||
builder:wikitext(place and " " or ", ", data.year) | builder:wikitext(place and " " or ", ", data.date.year) | ||
end | end | ||
builder:wikitext(data.diferentiator or "") | builder:wikitext(data.diferentiator or "") | ||
Linia 1154: | Linia 1451: | ||
end | 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 | if data.p and #data.p > 0 then | ||
local isNonStandardPageNumber = mw.ustring.match(data.p, "[^%s0-9,%-–]") | local isNonStandardPageNumber = mw.ustring.match(data.p, "[^%s0-9,%-–]") | ||
Linia 1161: | Linia 1466: | ||
if data.doi then | if data.doi then | ||
builder:wikitext(", [[DOI (identyfikator cyfrowy)|DOI]]: | 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 | needDot = true | ||
end | end | ||
Linia 1167: | Linia 1478: | ||
if data.isbn then | if data.isbn then | ||
for i,v in ipairs(data.isbn) do | for i,v in ipairs(data.isbn) do | ||
builder:wikitext(", ISBN ", v) | builder:wikitext(", ") | ||
require("Moduł:ISBN").link(builder, v) | |||
end | end | ||
needDot = true | needDot = true | ||
end | end | ||
if data.lccn then | if data.lccn then | ||
builder:wikitext(", [[Biblioteka Kongresu | builder:wikitext(", [[Biblioteka Kongresu|LCCN]] [", first(resources.params.lccn.link), mw.uri.encode(data.lccn), " ", data.lccn, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.issn then | if data.issn then | ||
builder:wikitext(", [[International Standard Serial Number|ISSN]] [ | builder:tag("span"):addClass("issn"):wikitext(", [[International Standard Serial Number|ISSN]] [", first(resources.params.issn.link), data.issn, " ", data.issn, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.pmid then | if data.pmid then | ||
builder:wikitext(", [[PMID]]: [ | builder:addClass("pmid"):wikitext(", [[PMID]]: [", first(resources.params.pmid.link), data.pmid, " ", data.pmid, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.pmc then | if data.pmc then | ||
builder:wikitext(", [[PMCID]]: [ | builder:addClass("pmc"):wikitext(", [[PMCID]]: [", first(resources.params.pmc.link), data.pmc, "/ PMC", data.pmc, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.bibcode then | if data.bibcode then | ||
builder:wikitext(", [[Bibcode]]: [ | builder:wikitext(", [[Bibcode]]: [", first(resources.params.bibcode.link), data.bibcode, " ", data.bibcode, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.oclc then | if data.oclc then | ||
builder:wikitext(", [[Online Computer Library Center|OCLC]] [ | builder:wikitext(", [[Online Computer Library Center|OCLC]] [", first(resources.params.oclc.link), mw.uri.encode(data.oclc), " ", data.oclc, "]") | ||
needDot = true | needDot = true | ||
end | end | ||
Linia 1206: | Linia 1519: | ||
local eprint, class = mw.ustring.match(data.arxiv, "^(%S+)%s+%[([^%[%]]+)%]$") | local eprint, class = mw.ustring.match(data.arxiv, "^(%S+)%s+%[([^%[%]]+)%]$") | ||
if eprint then | if eprint then | ||
builder:wikitext("[ | builder:wikitext("[", first(resources.params.arxiv.link), eprint, " ", eprint, "] [[//arxiv.org/archive/", class, " ", class, "]]" ) | ||
else | else | ||
builder:wikitext("[ | builder:wikitext("[", first(resources.params.arxiv.link), data.arxiv, " ", data.arxiv, "]" ) | ||
end | 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 | needDot = true | ||
end | end | ||
Linia 1219: | Linia 1542: | ||
if data.accessdate then | if data.accessdate then | ||
builder:wikitext(" [dostęp ", string.format("%04d-%02d-%02d", data.accessdate.year, data.accessdate.month, data.accessdate.day), "]") | builder:tag("span"):addClass("accessdate"):wikitext(" [dostęp ", string.format("%04d-%02d-%02d", data.accessdate.year, data.accessdate.month, data.accessdate.day), "]") | ||
needDot = true | needDot = true | ||
end | end | ||
if data.url and data. | 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 | if data.archived and data.archived.day then | ||
builder:wikitext(" ", string.format("%04d-%02d-%02d", data.archived.year, data.archived.month, data.archived.day)) | builder:wikitext(" ", string.format("%04d-%02d-%02d", data.archived.year, data.archived.month, data.archived.day)) | ||
Linia 1246: | Linia 1573: | ||
builder:wikitext(" ", languages) | builder:wikitext(" ", languages) | ||
needDot = true | 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 | end | ||
Linia 1252: | Linia 1587: | ||
end | end | ||
if appendText then | |||
builder:wikitext(appendText) | |||
end | |||
-- categories | -- categories | ||
local addCategories = mw.title.getCurrentTitle().namespace == 0 | local addCategories = mw.title.getCurrentTitle().namespace == 0 | ||
local problems = {} | local problems = {} | ||
if mode == 1 then | if not customMode and (mode == 1) then | ||
builder:wikitext(resources.categories.undetermined) | builder:wikitext(resources.categories.undetermined) | ||
table.insert(problems, "???") | table.insert(problems, "???") | ||
Linia 1270: | Linia 1609: | ||
table.insert(problems, resources.categories.sameJournalAndPublished) | table.insert(problems, resources.categories.sameJournalAndPublished) | ||
end | 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 | end | ||
Linia 1278: | Linia 1621: | ||
table.insert(problems, data.missing) | table.insert(problems, data.missing) | ||
missing = true | missing = true | ||
elseif needurl and not data.url and not data.chapterurl and not data.arxiv then | 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 | -- build in support for missing external link for page citation | ||
table.insert(problems, resources.params.url.name) | table.insert(problems, resources.params.url.name) | ||
Linia 1296: | Linia 1639: | ||
builder:wikitext(string.format(resources.categories.missingArg, resources.modes[mode])) | builder:wikitext(string.format(resources.categories.missingArg, resources.modes[mode])) | ||
end | end | ||
if data. | 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 | if addCategories then | ||
builder:wikitext(resources.categories.suspectedComma) | builder:wikitext(resources.categories.suspectedComma) | ||
end | end | ||
end | |||
table.insert(problems, " | if data.author and (data.author.comma == "alt") then | ||
table.insert(problems, "a?") | |||
if addCategories then | |||
builder:wikitext(resources.categories.altAuthor) | |||
end | |||
end | |||
if data.originalJournal then | |||
table.insert(problems, "c?") | |||
if addCategories then | |||
builder:wikitext(resources.categories.altJournal) | |||
end | |||
end | |||
local citewiki = (data.journal and mw.ustring.match(data.journal, "[Ww]ikipedia")) | |||
or (data.publisher and mw.ustring.match(data.publisher, "[Ww]ikipedia")) | |||
or (data.published and mw.ustring.match(data.published, "[Ww]ikipedia")) | |||
or (data.url and mw.ustring.match(data.url, "%.wikipedia%.org")) | |||
if citewiki then | |||
table.insert(problems, "wiki?") | |||
if addCategories then | |||
builder:wikitext(resources.categories.wiki) | |||
end | |||
end | |||
if data.unknownAccess then | |||
table.insert(problems, "dostęp?") | |||
if addCategories then | |||
builder:wikitext(resources.categories.unknownAccess) | |||
end | |||
end | |||
if data.rejectedurl then | |||
table.insert(problems, "<s>url</s>") | |||
if addCategories then | |||
builder:wikitext(resources.categories.rejectedUrl) | |||
end | |||
end | end | ||
if data.urlWarning then | if data.urlWarning then | ||
table.insert(problems, "Url") | |||
if addCategories then | if addCategories then | ||
builder:wikitext(resources.categories.unusedUrl) | builder:wikitext(resources.categories.unusedUrl) | ||
end | end | ||
end | end | ||
if data.patchCitoidDate then | if data.patchCitoidDate then | ||
table.insert(problems, "1 stycznia") | 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(resources.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(resources.categories.etal) | |||
end | |||
end | end | ||
if #problems > 0 then | if #problems > 0 then | ||
local info = builder:tag("span"):addClass("problemy-w-cytuj") | local info = builder:tag("span") | ||
:addClass("problemy") | |||
:addClass("problemy-w-cytuj") | |||
:attr("aria-hidden", "true") | |||
:attr("data-nosnippet", "") | |||
info:wikitext(table.concat(problems,", ")) | info:wikitext(table.concat(problems,", ")) | ||
end | end | ||
Linia 1328: | Linia 1725: | ||
end | end | ||
local | return { | ||
auto = function(frame) | |||
return Cite(frame:getParent(), nil, nil) | |||
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 = resources.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) | |||
return Cite(frame | end, | ||
end | |||
} |
Wersja z 21:54, 16 mar 2022
Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Cytuj/opis
local resources = mw.loadData("Moduł:Cytuj/dane")
local access = mw.loadData("Moduł:Cytuj/dostęp")
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"})
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 splitWikiLink(text)
local link, description = mw.ustring.match(text, "^%[%[(.-)%|(.-)%]%]$")
if link then
return description, link, false
end
local link = mw.ustring.match(text, "^%[%[(.-)%]%]$")
if link then
return link, link, false
end
local link, description = mw.ustring.match(text, "^%[(%S*)%s+(.-)%]$")
if link and checkUri(link) then
return description, false, link
end
return text, false, false
end
local function detectArchive(url)
local defaultDecoder = resources.archiveDecoders.defaultDecoder
for i, v in ipairs(resources.archiveDecoders) do
local pattern = type(v) == "string" and v or v.pattern
local decoder = type(v) == "table" and v or defaultDecoder
local items = { mw.ustring.match(url, pattern) }
if #items > 0 then
return items[decoder.link], items[decoder.year].."-"..items[decoder.month].."-"..items[decoder.day]
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 true
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 = 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 = 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 = 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 and isAutoGeneratedUrl(result.url) then
result.rejectedurl = true
result.url = false
end
if result.chapterurl and isAutoGeneratedUrl(result.chapterurl) then
result.rejectedurl = true
result.chapterurl = false
end
if result.journalurl and isAutoGeneratedUrl(result.journalurl) then
result.rejectedurl = true
result.journalurl = false
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ł:Brudnopis/Paweł Ziemian/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
local function Cite(p, mode, appendText)
-- 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
return resources.categories.empty
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(data.journal and ", " or ", wyd. ", data.edition)
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. ", 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(resources.categories.undetermined)
table.insert(problems, "???")
end
if data.publisher and data.published then
table.insert(problems, "p?")
if addCategories then
table.insert(problems, resources.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, resources.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(resources.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(resources.categories.suspectedComma)
end
end
if data.author and (data.author.comma == "alt") then
table.insert(problems, "a?")
if addCategories then
builder:wikitext(resources.categories.altAuthor)
end
end
if data.originalJournal then
table.insert(problems, "c?")
if addCategories then
builder:wikitext(resources.categories.altJournal)
end
end
local citewiki = (data.journal and mw.ustring.match(data.journal, "[Ww]ikipedia"))
or (data.publisher and mw.ustring.match(data.publisher, "[Ww]ikipedia"))
or (data.published and mw.ustring.match(data.published, "[Ww]ikipedia"))
or (data.url and mw.ustring.match(data.url, "%.wikipedia%.org"))
if citewiki then
table.insert(problems, "wiki?")
if addCategories then
builder:wikitext(resources.categories.wiki)
end
end
if data.unknownAccess then
table.insert(problems, "dostęp?")
if addCategories then
builder:wikitext(resources.categories.unknownAccess)
end
end
if data.rejectedurl then
table.insert(problems, "<s>url</s>")
if addCategories then
builder:wikitext(resources.categories.rejectedUrl)
end
end
if data.urlWarning then
table.insert(problems, "Url")
if addCategories then
builder:wikitext(resources.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(resources.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(resources.categories.etal)
end
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)
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 = resources.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)
end,
}