Moduł:Cytuj

Z VatoWiki
Wersja z dnia 10:08, 22 cze 2016 autorstwa Admin (dyskusja | edycje) (1 wersja)
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Przejdź do nawigacji Przejdź do wyszukiwania

local resources = { modes = { "auto", "książkę", "pismo", "stronę" },

COinS = { false, -- auto "info:ofi/fmt:kev:mtx:book", -- książkę "info:ofi/fmt:kev:mtx:journal", -- pismo "info:ofi/fmt:kev:mtx:journal", -- stronę },

categories = { empty = "", undetermined = "", missingArg = "", suspectedComma = "", unusedUrl = "", unusedPublished = "", sameJournalAndPublished = "", },

--[[ ; name : name of the parameter used in the template ; used : indicator whether the parameter is used in specific citation mode list of modes is declared in variable 'modes' at the top of the module the first entry is reserved for automatic full citation mode, which accepts all parameters ; "!" : mandatory ; false : not used ; otherwise : optional ; "+" : only in one mode, and written differently for easier notice ; "*" : additional support in the code (in url and published for now) --]] params = { chapterauthor = { name = "autor r", used = { true, "+", false, false, }, }, chapter = { name = "rozdział", used = { true, "+", false, false, }, }, author = { name = "autor", used = { true, true, true, true, }, }, editor = { name = "redaktor", used = { true, true, true, true, }, }, url = { name = "url", used = { true, true, true, "*", }, }, title = { name = "tytuł", used = { true, "!", true, "!", }, }, others = { name = "inni", used = { true, "+", false, false, }, }, work = { name = "praca", used = { true, false, false, "+", }, }, journal = { name = "czasopismo", used = { true, false, "!", false, }, }, mediatype = { name = "typ nośnika", used = { true, true, true, true, }, }, responsibility = { name = "odpowiedzialność", used = { true, false, "+", false, }, }, issue = { name = "wydanie", used = { true, true, true, false, }, }, description = { name = "opis", used = { true, "+", false, false, }, }, place = { name = "miejsce", used = { true, true, true, false, }, }, published = { name = "opublikowany", used = { true, "*", "*", "*", }, }, publisher = { name = "wydawca", used = { true, true, true, false, }, }, date = { name = "data", used = { true, true, true, true, }, }, p = { name = "s", used = { true, true, true, true, }, }, doi = { name = "doi", used = { true, true, true, false, }, }, isbn = { name = "isbn", used = { true, "+", false, false, }, }, lccn = { name = "lccn", used = { true, "+", false, false, }, }, issn = { name = "issn", used = { true, true, true, false, }, }, pmid = { name = "pmid", used = { true, false, "+", false, }, }, pmc = { name = "pmc", used = { true, false, "+", false, }, }, bibcode = { name = "bibcode", used = { true, false, "+", false, }, }, oclc = { name = "oclc", used = { true, true, true, false, }, }, arxiv = { name = "arxiv", used = { true, false, false, true, }, }, id = { name = "id", used = { true, true, true, true, }, }, accessdate= { name = "data dostępu", used = { true, true, true, true, }, }, archive = { name = "archiwum", used = { true, true, true, true, }, }, archived = { name = "zarchiwizowano", used = { true, true, true, true, }, }, quotation = { name = "cytat", used = { true, true, true, true, }, }, lang = { name = "język", used = { true, true, true, true, }, }, odn = { name = "odn", used = { true, true, true, true, }, }, },

monthparser = { ["styczeń"] = 1, ["stycznia"] = 1, ["sty"] = 1, ["i"] = 1, ["luty"] = 2, ["lutego"] = 2, ["lut"] = 2, ["ii"] = 2, ["marzec"] = 3, ["marca"] = 3, ["mar"] = 3, ["iii"] = 3, ["kwiecień"] = 4, ["kwietnia"] = 4, ["kwi"] = 4, ["iv"] = 4, ["maj"] = 5, ["maja"] = 5, ["v"] = 5, ["czerwiec"] = 6, ["czerwca"] = 6, ["cze"] = 6, ["vi"] = 6, ["lipiec"] = 7, ["lipca"] = 7, ["lip"] = 7, ["vii"] = 7, ["sierpień"] = 8, ["sierpnia"] = 8, ["sie"] = 8, ["viii"] = 8, ["wrzesień"] = 9, ["września"] = 9, ["wrz"] = 9, ["ix"] = 9, ["październik"] = 10, ["października"] = 10, ["paź"] = 10, ["x"] = 10, ["listopad"] = 11, ["listopada"] = 11, ["lis"] = 11, ["xi"] = 11, ["grudzień"] = 12, ["grudnia"] = 12, ["gru"] = 12, ["xii"] = 12, },

months = { [1] = { m="styczeń", d="stycznia", }, [2] = { m="luty", d="lutego", }, [3] = { m="marzec", d="marca", }, [4] = { m="kwiecień", d="kwietnia", }, [5] = { m="maj", d="maja", }, [6] = { m="czerwiec", d="czerwca", }, [7] = { m="lipiec", d="lipca", }, [8] = { m="sierpień", d="sierpnia", }, [9] = { m="wrzesień", d="września", }, [10] = { m="październik", d="października", }, [11] = { m="listopad", d="listopada", }, [12] = { m="grudzień", d="grudnia", }, },

exactAuthors = { ["Praca zbiorowa"] = true, ["Gall Anonim"] = true, } }

local function softNoWiki(text) local result, count = string.gsub(text, "['%[%]{|}\"]", { ["\""] = """, ["'"] = "'", ["["] = "[", ["]"] = "]", ["{"] = "{", ["|"] = "|", ["}"] = "}"}) 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 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

for i, v in ipairs(detector) do if detector[i] then -- the type is succesfully determined -- but in case more than one is possible -- use only the first one -- include COinS format if this is the only determined type return i, count == 1 and resources.COinS[i] or 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.isIlustrator = function(author) return checkPatterns(author, {"il%.?", "ilus%.?", "ilustrator" }, {"[%(%[]il%.?[%)%]]", "[%(%[]ilus%.?[%)%]]", "[%(%[]ilustrator[%)%]]" }) end

authorMethodtable.isTranslator = function(author) return checkPatterns(author, {"tłum%.?", "tłumacz" }, {"[%(%[]tłum%.?[%)%]]", "[%(%[]tłumacz[%)%]]" }) end

authorMethodtable.isEditor = function(author) return checkPatterns(author, {"red%.?", "redaktor", "pod red%.?", "pod redakcją" }, {"[%(%[]red%.?[%)%]]", "[%(%[]redaktor[%)%]]" }) end

authorMethodtable.isDeveloper = function(author) return checkPatterns(author, {"oprac%.?", "opracowała?" }, {"[%(%[]oprac%.?[%)%]]", "[%(%[]opracowała?[%)%]]" }) 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"):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"):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 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*", "%1. ") nameinitials = mw.ustring.gsub(nameinitials, "%f[%w]%l%.%s", "") nameinitials = mw.ustring.gsub(nameinitials, "([^C%W])[Hh]%.%s", "%1. ") return mw.text.trim(nameinitials) end

local function parseAuthor(author) local result = {}

local author = mw.text.trim(author) 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 prefix, rest = mw.ustring.match(author, "^([%l%p%s]+)(.+)$") if not prefix then rest = author prefix = "" end

prefix = mw.text.trim(prefix0.." "..prefix) 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 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 name, lastname = mw.ustring.match(rest2, "%s*(.-)%s+(%u[%w%p]-)%s*$") end end

if not lastname then result.lastname = mw.text.trim(rest2) else result.name = 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 loadAuthor(frame, params, index) local argAuthor = formatDynamicArgName(params.author.name, index)

local result = false local author = frame.args[argAuthor] if author and (#author > 0) then result = parseAuthor(author) end

if not result then return end

local first = frame.args[argFirst] if first and (#first > 0) then result.name = first result.nameinitials = makeInitials(first) end

local link = frame.args[argLink] if link and (#link > 0) then result.link = link end

return result end

local function collectAuthors(author) if not author then return end

local result = {} local splitter = string.match(author, ";") and ";" or "," local authors = mw.text.split(author, splitter, true) for _, v in ipairs(authors) do local author = parseAuthor(v) if author then table.insert(result, author) end end

if #result == 0 then return end

return result, (#result == 2) and (separator == ",") end

local function formatAuthors(authors, useDecorations, nextgroup) local count = #authors if count == 0 then return nil end

local formatter = function(author) local a = author:format(nextgroup) local r = author.link and (""..a.."") or a local s = useDecorations and (author:isEditor() and " (red.)" or (author:isTranslator() and " (tłum.)" or (author:isIlustrator() and " (ilust.)" or (author:isDeveloper() and " (oprac.)" or "")))) or "" return r..s end

if count == 1 then return formatter(authors[1]) end

local result = {} table.insert(result, formatter(authors[1]))

if count <= 3 then table.insert(result, ", "); table.insert(result, formatter(authors[2])) if count == 3 then table.insert(result, ", "); table.insert(result, formatter(authors[3])) end

return table.concat(result, "") end

table.insert(result, "") local title = {} for i = 2, count do table.insert(result, ", "); table.insert(result, formatter(authors[i])) table.insert(title, authors[i]:towiki()) end table.insert(result, "") table.insert(result, " i inni") return table.concat(result, "") 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, "^%[([hH][tT][tT][pP][sS]?://%S*)%s+(.-)%]$") if link then return description, false, link end

return text, false, false end

local function detectArchive(url) local y, m, d, link = mw.ustring.match(url, "^https?://web%.archive%.org/web/(%d%d%d%d)(%d%d)(%d%d)%d%d%d%d%d%d/(https?://.*)$") if y then return link, y.."-"..m.."-"..d end

return false, 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

-- translate some parameters result.chapterauthor, result.chapterComma = collectAuthors(result.chapterauthor) result.author, result.authorComma = collectAuthors(result.author) result.lang = collectLanguages(result.lang) result.editor, result.editorComma = collectAuthors(result.editor) result.others, result.othersComma = collectAuthors(result.others)

local yearRange = false if result.date and mw.ustring.match(result.date, "[12]%d%d%d[-–—][12]%d%d%d") then yearRange = result.date end

result.date, result.patchCitoidDate = parseDate(result.date or "", false, false, true) if result.date then result.year = tostring(result.date.year) result.yearRange = yearRange end

-- fix other dates result.accessdate = parseDate(result.accessdate or "", false, false, false) if result.accessdate and not result.accessdate.day then result.accessdate = nil 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 mw.logObject(result.url, "UNUSED URL") 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 result.journal, result.journallink, result.journalurl = splitWikiLink(result.journal) end

if not result.archive and result.url then local al, ad = detectArchive(result.url) if al then result.archive = result.url result.url = al if ad then result.archived = ad end end elseif result.archive and (not result.url or not result.archived) then local al, ad = detectArchive(result.archive) if al and not result.url then result.url = al end if ad and not result.archived then result.archived = ad end end

result.archived = parseDate(result.archived or "", false, false, false) if result.archived and not result.archived.day then result.archived = null end

if result.issue and result.journal then local volume, issue = mw.ustring.match(result.issue, "^%s*([^%(]+)%s+%((.-)%)%s*$"); if volume then result.journalvolume = volume result.issue = issue end 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[1] and (authors[1].lastname or authors[1].exact) or "") .. (authors[2] and (authors[2].lastname or authors[2].exact) or "") .. (authors[3] and (authors[3].lastname or authors[3].exact) or "") .. (authors[4] and (authors[4].lastname or authors[4].exact) or "") .. (data.date and data.date.year 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[1].lastname then result["rft.aulast"] = authors[1].lastname end if authors[1].name then result["rft.aufirst"] = authors[1].name end if authors[1].exact then result["rft.au"] = authors[1].exact end end if data.date then result["rft.date"] = data.date.day and string.format("%04d-%02d-%02d", data.date.year, data.date.month, data.date.day) or (data.date.month and string.format("%04d-%02d", data.date.year, data.date.month) or data.date.year) 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.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 table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/"..data.doi})) 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 then result["rft.date"] = data.date.day and string.format("%04d-%02d-%02d", data.date.year, data.date.month, data.date.day) or (data.date.month and string.format("%04d-%02d", data.date.year, data.date.month) or data.date.year) 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.journalvolume then result["rft.volume"] = data.journalvolume 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 table.insert(params, mw.uri.buildQueryString( {rft_id = "info:doi/"..data.doi})) 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 then result["rft.date"] = data.date.day and string.format("%04d-%02d-%02d", data.date.year, data.date.month, data.date.day) or (data.date.month and string.format("%04d-%02d", data.date.year, data.date.month) or data.date.year) 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 COinS(data, coinsFormat) if (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 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) -- debug helper if p.args[3] then mw.log(p.args[3]) end

-- 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("span") builder :addClass("citation") :attr("id", prepareOdnIdentifier(data))

local needDot = false local nextAuthorGroup = false if data.title then

if data.chapter then local authors = data.editor and data.author or data.chapterauthor if authors then builder:wikitext(formatAuthors(authors, false, nextAuthorGroup), ", ") nextAuthorGroup = true end

local title = softNoWiki(data.chapter) if data.chapterurl then builder:wikitext("[", escapeUrl((not data.url and data.archive) and data.archive or data.chapterurl), " ", title, "]") elseif data.chapterlink then builder:wikitext("", title, "") else builder:wikitext("", title, "") end

if not mw.ustring.match(plainText(data.chapter), ",$") then builder:wikitext(",") 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 builder:wikitext(formatAuthors(authors, not (editor or false), nextAuthorGroup)) nextAuthorGroup = true if editor then builder:wikitext(" (red.)") end builder:wikitext(", ") end

local title = softNoWiki(data.title) if data.url then builder:wikitext("[", escapeUrl(data.archive or data.url), " ", title, "]") elseif data.titlelink then builder:wikitext("", title, "") else builder:wikitext("", title, "") end if not mw.ustring.match(plainText(title), "%p$") then needDot = true end

local showmediatype = data.mediatype and (#data.mediatype > 0) if showmediatype then builder:wikitext(" [", data.mediatype, "]") needDot = true end

if not editor and data.editor then builder:wikitext(", ", formatAuthors(data.editor, false, true), " (red.)") end

if data.others then builder:wikitext(", ", formatAuthors(data.others, true, true)) needDot = true end end

if data.work then builder:wikitext(", [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 ", [w:] „" or "„") builder:wikitext((data.title or data.work) and ", „" or "„") local title = softNoWiki(data.journal) if data.journalurl then builder:wikitext("[", escapeUrl(data.journalurl), " ", title, "]") elseif data.journallink then builder:wikitext("", title, "") else builder:wikitext(title) end builder:wikitext("”") needDot = true end

if data.responsibility then builder:wikitext(", ", data.responsibility) needDot = true end

if data.issue then if data.journalvolume then builder:wikitext(", ", data.journalvolume, " (", data.issue, ")") elseif data.journal then builder:wikitext(", ", data.issue) else builder:wikitext(", wyd. ", data.issue) end 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 if data.yearRange then builder:wikitext(place and " " or ", ", data.yearRange) 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.year) end builder:wikitext(data.diferentiator or "") 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 builder:wikitext(", DOI", data.doi, " ", data.doi, "") needDot = true end

if data.isbn then for i,v in ipairs(data.isbn) do builder:wikitext(", ISBN ", v) end needDot = true end

if data.lccn then builder:wikitext(", LCCN ", mw.uri.encode(data.lccn), " ", data.lccn, "") needDot = true end

if data.issn then builder:wikitext(", ISSN ", data.issn, " ", data.issn, "") needDot = true end

if data.pmid then builder:wikitext(", PMID", data.pmid, " ", data.pmid, "") needDot = true end

if data.pmc then builder:wikitext(", PMCID", data.pmc, "/ PMC", data.pmc, "") needDot = true end

if data.bibcode then builder:wikitext(", Bibcode", data.bibcode, " ", data.bibcode, "") needDot = true end

if data.oclc then builder:wikitext(", OCLC ", 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("", eprint, " ", eprint, " [", class, " ", class, "]" ) else builder:wikitext("", data.arxiv, " ", data.arxiv, "" ) end needDot = true end

if data.id then builder:wikitext(", ", data.id) needDot = true end

if data.accessdate then builder:wikitext(" [dostęp ", string.format("%04d-%02d-%02d", data.accessdate.year, data.accessdate.month, data.accessdate.day), "]") needDot = true end

if data.url and data.archive then builder:wikitext(" [zarchiwizowane z [", escapeUrl(data.url), " adresu]") 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 needDot then builder:wikitext(".") end

-- categories local addCategories = mw.title.getCurrentTitle().namespace == 0 local problems = {} if 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

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 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.chapterComma or data.authorComma or data.editorComma or data.othersComma or data.othersbookvolumeComma then if addCategories then builder:wikitext(resources.categories.suspectedComma) end

table.insert(problems, "!!!") end if data.urlWarning then if addCategories then builder:wikitext(resources.categories.unusedUrl) end

table.insert(problems, "Url") end if data.patchCitoidDate then table.insert(problems, "1 stycznia") end

if #problems > 0 then local info = builder:tag("span"):addClass("problemy-w-cytuj") if addCategories then info:css("display","none") else info:css("color", "red") end

info:wikitext(table.concat(problems,", ")) end

return builder:done() end

local module = {}

module.auto = function(frame) return Cite(frame:getParent(), nil) end

return module