local z =
-- Include translation message hooks, ID and error handling configuration settings.-- Note that require has tested to be significantly faster than loadData for this -- usage. This might be a side effect of the unnecessary cloning described -- in bugzilla 47300.local cfg = require('Module:Citation/CS1/Configuration');
-- Contains a list of all recognized parameterslocal whitelist = mw.loadData('Module:Citation/CS1/Whitelist');
-- LOCALfunction is_zh(str) return not not str:find('[\128-\255]')end-- END LOCAL
-- Whether variable is set or notfunction is_set(var) return not (var
);end
-- First set variable or nil if nonefunction first_set(...) local list = ; for _, var in pairs(list) do if is_set(var) then return var; end endend
-- Whether needle is in haystackfunction inArray(needle, haystack) if needle
needle then return n; end end return false;end
-- Populates numbered arguments in a message string using an argument table.function substitute(msg, args) return args and tostring(mw.message.newRawMessage(msg, args)) or msg;end
-- Wraps a string using a message_list configuration taking one argumentfunction wrap(key, str) if not is_set(str) then return ""; elseif inArray(key,) then str = safeforitalics(str); end return substitute(cfg.messages[key],);end
--Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple namescan be transparently aliased to single internal variable.function argument_wrapper(args) local origin = ; return setmetatable;end
-- Checks that parameter name is valid using the whitelistfunction validate(name) name = tostring(name); -- Normal arguments if whitelist.basic_arguments[name ] then return true; end -- Arguments with numbers in them name = name:gsub("%d+", "#"); if whitelist.numbered_arguments[name ] then return true; end -- Not found, argument not supported. return falseend
-- Formats a comment for error trappingfunction errorcomment(content, hidden) return wrap(hidden and 'hidden-error' or 'visible-error', content);end
--Sets an error condition and returns the appropriate error message. The actual placementof the error message in the output is the responsibility of the calling function.function seterror(error_id, arguments, raw, prefix, suffix) local error_state = cfg.error_conditions[error_id ]; prefix = prefix or ""; suffix = suffix or ""; if error_state
true then return message, error_state.hidden; end return errorcomment(message, error_state.hidden);end
-- Formats a wiki style external linkfunction externallinkid(options) local url_string = options.id; if options.encode
nil then url_string = mw.uri.encode(url_string); end return mw.ustring.format('%s%s[%s%s%s %s]', options.link, options.label, options.separator or " ", options.prefix, url_string, options.suffix or "", mw.text.nowiki(options.id));end
-- Formats a wiki style internal linkfunction internallinkid(options) return mw.ustring.format('%s%s%s', options.link, options.label, options.separator or " ", options.prefix, options.id, options.suffix or "", mw.text.nowiki(options.id));end
-- Format an external link with error checkingfunction externallink(URL, label, source) local error_str = ""; if not is_set(label) then label = URL; if is_set(source) then error_str = seterror('bare_url_missing_title',, false, " "); else error(cfg.messages["bare_url_no_origin"]); end end if not checkurl(URL) then error_str = seterror('bad_url',, false, " ") .. error_str; end return table.concat;end
-- Formats a link to Amazonfunction amazon(id, domain) if not is_set(domain) then domain = "com" elseif ("jp"
domain) then domain = "co." .. domain end local handler = cfg.id_handlers['ASIN']; return externallinkidend
-- Formats a DOI and checks for DOI errors.function doi(id, inactive) local cat = "" local handler = cfg.id_handlers['DOI']; local text; if is_set(inactive) then text = "" .. handler.label .. ":" .. id; table.insert(z.error_categories, "Pages with DOIs inactive since " .. selectyear(inactive)); inactive = " (" .. cfg.messages['inactive'] .. " " .. inactive .. ")" else text = externallinkid inactive = "" end if (string.sub(id,1,3) ~= "10.") then cat = seterror('bad_doi'); end return text .. inactive .. cat end
-- Formats an OpenLibrary link, and checks for associated errors.function openlibrary(id) local code = id:sub(-1,-1) local handler = cfg.id_handlers['OL']; if (code
"M") then return externallinkid elseif (code
--Determines whether an URL string is valid
At present the only check is whether the string appears to be prefixed with a URI scheme. It is not determined whether the URI scheme is valid or whether the URL is otherwise well formed.
function checkurl(url_str) -- Protocol-relative or URL scheme return url_str:sub(1,2)-- Removes irrelevant text and dashes from ISBN number-- Similar to that used for Special:BookSourcesfunction cleanisbn(isbn_str) return isbn_str:gsub("[^-0-9X]", "");end
-- Determines whether an ISBN string is validfunction checkisbn(isbn_str) isbn_str = cleanisbn(isbn_str):gsub("-", ""); local len = isbn_str:len; if len ~= 10 and len ~= 13 then return false; end local temp = 0; if len
nil then return false; end isbn_str = ; for i, v in ipairs(isbn_str) do if v
0; else if isbn_str:match("^%d*$")
0; endend
-- Gets the display text for a wikilink like B or B gives Bfunction removewikilink(str) return (str:gsub("%[%[([^%[%]]*)%]%]", function(l) return l:gsub("^[^|]*|(.*)$", "%1"):gsub("^%s*(.-)%s*$", "%1"); end));end
-- Escape sequences for content that will be used for URL descriptionsfunction safeforurl(str) do return str end -- LOCAL HACK https://en.wikipedia.org/w/index.php?title=Module_talk:Citation/CS1&diff=552318417&oldid=552202448 if str:match("%[%[.-%]%]") ~= nil then table.insert(z.message_tail,); end return str:gsub('[%[%]\n]',);end
-- Converts a hyphen to a dashfunction hyphentodash(str) if not is_set(str) or str:match("[%[%]<>]") ~= nil then return str; end return str:gsub('-', '–');end
-- Protects a string that will be wrapped in wiki italic markup ... function safeforitalics(str) -- if not is_set(str) then return str; else if str:sub(1,1)
--Joins a sequence of strings together while checking for duplicate separationcharacters.function safejoin(tbl, duplicate_char) -- local str = ; local comp = ; local end_chr = ; local trim; for _, value in ipairs(tbl) do if value
then str = value; elseif value ~= then if value:sub(1,1)
duplicate_char then trim = false; end_chr = str:sub(-1,-1); -- str = str .. " "'" then if str:sub(-3,-1) duplicate_char .. "]]" then trim = true; elseif str:sub(-4,-1) "]" then if str:sub(-3,-1) duplicate_char .. "]" then trim = true; end elseif end_chr duplicate_char .. " " then str = str:sub(1,-3); end end if trim then if value ~= comp then local dup2 = duplicate_char; if dup2:match("%A") then dup2 = "%" .. dup2; end value = value:gsub("(%b<>)" .. dup2, "%1", 1) else value = value:sub(2, -1); end end end str = str .. value; end end return str;end --Return the year portion of a date string, if possible. Returns empty string if the argument can not be interpretedas a year.function selectyear(str) -- Is the input a simple number? local num = tonumber(str); if num ~= nil and num > 0 and num < 2100 and num -- Attempts to convert names to initials.function reducetoinitials(first) local initials = for word in string.gmatch(first, "%S+") do table.insert(initials, string.sub(word,1,1)) -- Vancouver format does not include full stops. end return table.concat(initials) -- Vancouver format does not include spaces.end -- Formats a list of people (e.g. authors / editors) function listpeople(control, people) local sep = control.sep; local namesep = control.namesep local format = control.format local maximum = control.maximum local lastauthoramp = control.lastauthoramp; local text = local etal = false; if sep:sub(-1,-1) ~= " " then sep = sep .. " " end if maximum ~= nil and maximum < 1 then return "", 0; end for i,person in ipairs(people) do if is_set(person.last) then local mask = person.mask local one local sep_one = sep; if maximum ~= nil and i > maximum then etal = true; break; elseif (mask ~= nil) then local n = tonumber(mask) if (n ~= nil) then one = string.rep(" - ",n) else one = mask; sep_one = " "; end else one = person.last local first = person.first if is_set(first) then if ("vanc" local count = #text / 2; if count > 0 then if count > 1 and is_set(lastauthoramp) and not etal then text[#text-2] = " & "; end text[#text] = nil; end local result = table.concat(text) -- construct list if etal then local etal_text = is_zh(result) and cfg.messages['et al'] or 'et al.'; -- LOCAL result = result .. " " .. etal_text; end -- if necessary wrap result in -- Generates a CITEREF anchor ID.function anchorid(options) return "CITEREF" .. table.concat(options);end -- Gets name list from the input argumentsfunction extractnames(args, list_name) local names = ; local i = 1; local last; while true do last = selectone(args, cfg.aliases[list_name .. '-Last'], 'redundant_parameters', i); if not is_set(last) then -- just in case someone passed in an empty parameter break; end names[i] = ; i = i + 1; end return names;end -- Populates ID table from arguments using configuration settingsfunction extractids(args) local id_list = ; for k, v in pairs(cfg.id_handlers) do v = selectone(args, v.parameters, 'redundant_parameters'); if is_set(v) then id_list[k] = v; end end return id_list;end -- Takes a table of IDs and turns it into a table of formatted ID outputs.function buildidlist(id_list, options) local new_list, handler = ; function fallback(k) return end; for k, v in pairs(id_list) do -- fallback to read-only cfg handler = setmetatable(fallback(k)); if handler.mode 'internal' then table.insert(new_list,); elseif handler.mode ~= 'manual' then error(cfg.messages['unknown_ID_mode']); elseif k 'ASIN' then table.insert(new_list,); elseif k 'ISBN' then local ISBN = internallinkid(handler); if not checkisbn(v) and not is_set(options.IgnoreISBN) then ISBN = ISBN .. seterror('bad_isbn',, false, " ", ""); end table.insert(new_list,); else error(cfg.messages['unknown_manual_ID']); end end function comp(a, b) return a[1] < b[1]; end table.sort(new_list, comp); for k, v in ipairs(new_list) do new_list[k] = v[2]; end return new_list;end -- Chooses one matching parameter from a list of parameters to consider-- Generates an error if more than one match is present.function selectone(args, possible, error_condition, index) local value = nil; local selected = ; local error_list = ; if index ~= nil then index = tostring(index); end -- Handle special case of "#" replaced by empty string if index -- COinS metadata (see 'ISBN' then value = cleanisbn(v); else value = v; end if string.sub(id or "", 1, 4) 1 then if is_set(last) then OCinSoutput["rft.aulast"] = last; end if is_set(first) then OCinSoutput["rft.aufirst"] = first; end end if is_set(last) and is_set(first) then OCinSoutput["rft.au"] = table.concat; elseif is_set(last) then OCinSoutput["rft.au"] = last; end end OCinSoutput.rft_id = data.URL; OCinSoutput.rfr_id = table.concat; OCinSoutput = setmetatable(OCinSoutput, nil); -- sort with version string always first, and combine. table.sort(OCinSoutput); table.insert(OCinSoutput, 1, "ctx_ver=" .. ctx_ver); -- such as "Z39.88-2004" return table.concat(OCinSoutput, "&");end --This is the main function foing the majority of the citationformatting.function citation0(config, args, frame) -- LOCAL --Load Input Parameters The argment_wrapper facillitates the mapping of multiple aliases to single internal variable. local A = argument_wrapper(args); local i local PPrefix = A['PPrefix'] local PPPrefix = A['PPPrefix'] if is_set(A['NoPP']) then PPPrefix = "" PPrefix = "" end -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. -- LOCAL local PSuffix = A['PSuffix'] local PPSuffix = A['PPSuffix'] if (nil ~= A['NoPP']) then PPSuffix = "" PSuffix = "" end -- END LOCAL -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. local Authors = A['Authors']; local a = extractnames(args, 'AuthorList'); local Coauthors = A['Coauthors']; local Others = A['Others']; local Editors = A['Editors']; local e = extractnames(args, 'EditorList'); local Year = A['Year']; local PublicationDate = A['PublicationDate']; local OrigYear = A['OrigYear']; local Date = A['Date']; local LayDate = A['LayDate']; ------------------------------------------------- Get title data local Title = A['Title']; local BookTitle = A['BookTitle']; local Conference = A['Conference']; local TransTitle = A['TransTitle']; local TitleNote = A['TitleNote']; local TitleLink = A['TitleLink']; local Chapter = A['Chapter']; local ChapterLink = A['ChapterLink']; local TransChapter = A['TransChapter']; local TitleType = A['TitleType']; local ArchiveURL = A['ArchiveURL']; local URL = A['URL'] local URLorigin = A:ORIGIN('URL'); local ChapterURL = A['ChapterURL']; local ChapterURLorigin = A:ORIGIN('ChapterURL'); local ConferenceURL = A['ConferenceURL']; local ConferenceURLorigin = A:ORIGIN('ConferenceURL'); local Periodical = A['Periodical']; if (config.CitationClass local Series = A['Series']; local Volume = A['Volume']; local Issue = A['Issue']; local Position = ; local Page, Pages, At, page_type; Page = A['Page']; Pages = hyphentodash(A['Pages']); At = A['At']; if is_set(Page) then if is_set(Pages) or is_set(At) then Page = Page .. " " .. seterror('extra_pages'); Pages = ; At = ; end elseif is_set(Pages) then if is_set(At) then Pages = Pages .. " " .. seterror('extra_pages'); At = ; end end local Edition = A['Edition']; local PublicationPlace = A['PublicationPlace'] local Place = A['Place']; if not is_set(PublicationPlace) and is_set(Place) then PublicationPlace = Place; end if PublicationPlace local ID_list = extractids(args); local Quote = A['Quote']; local PostScript = A['PostScript']; local LayURL = A['LayURL']; local LaySource = A['LaySource']; local Transcript = A['Transcript']; local TranscriptURL = A['TranscriptURL'] local TranscriptURLorigin = A:ORIGIN('TranscriptURL'); local sepc = A['Separator']; local LastAuthorAmp = A['LastAuthorAmp']; local no_tracking_cats = A['NoTracking']; local this_page = mw.title.getCurrentTitle; --Also used for COinS if not is_set(no_tracking_cats) then for k, v in pairs(cfg.uncategorized_namespaces) do if this_page.nsText if (config.CitationClass -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. -- Account for the oddity that is, before generation of COinS data. if is_set(BookTitle) then Chapter = Title; ChapterLink = TitleLink; TransChapter = TransTitle; Title = BookTitle; TitleLink = ; TransTitle = ; end -- Account for the oddity that is, before generation of COinS data. if config.CitationClass if is_set(Periodical) and not is_set(Chapter) and is_set(Title) then Chapter = Title; ChapterLink = TitleLink; TransChapter = TransTitle; Title = ; TitleLink = ; TransTitle = ; end -- Now perform various field substitutions. -- We also add leading spaces and surrounding markup and punctuation to the -- various parts of the citation, but only when they are non-nil. if not is_set(Authors) then local Maximum = tonumber(A['DisplayAuthors']); -- Preserve old-style implicit et al. if not is_set(Maximum) and #a 4 then Maximum = 3; table.insert(z.message_tail,); elseif not is_set(Maximum) then Maximum = #e + 1; end local control = ; Editors, EditorCount = listpeople(control, e); else EditorCount = 1; end if not is_set(Date) then Date = Year; if is_set(Date) then local Month = A['Month']; if is_set(Month) then Date = Date .. '.' .. Month; -- LOCAL local Day = A['Day'] if is_set(Day) then Date = Date .. '.' .. Month end -- LOCAL end end end if inArray(PublicationDate,) then PublicationDate = ; end if not is_set(Date) and is_set(PublicationDate) then Date = PublicationDate; PublicationDate = ; end -- Captures the value for Date prior to adding parens or other textual transformations local DateIn = Date; if not is_set(URL) and not is_set(ChapterURL) and not is_set(ArchiveURL) and not is_set(ConferenceURL) and not is_set(TranscriptURL) then -- Test if cite web is called without giving a URL if (config.CitationClass -- LOCAL if not is_set(Language) or Language:lower 'zh-' then xLCFlags = 'zh;zh-hans;zh-hant' else xLCFlags = 'R' end if is_set(Chapter) then Chapter = '--' end if is_set(Title) then Title = '--' end -- END LOCAL if is_set(Chapter) and is_set(ChapterLink) then Chapter = "" .. Chapter .. ""; end if is_set(Periodical) and is_set(Title) then Chapter = wrap('italic-title', Chapter); TransChapter = wrap('trans-italic-title', TransChapter); else Chapter = wrap('quoted-title', Chapter); TransChapter = wrap('trans-quoted-title', TransChapter); end local TransError = "" if is_set(TransChapter) then if not is_set(Chapter) then TransError = " " .. seterror('trans_missing_chapter'); else TransChapter = " " .. TransChapter; end end Chapter = Chapter .. TransChapter; if is_set(Chapter) then if not is_set(ChapterLink) then if is_set(ChapterURL) then Chapter = externallink(ChapterURL, Chapter) .. TransError; if not is_set(URL) then Chapter = Chapter .. Format; Format = ""; end elseif is_set(URL) then Chapter = externallink(URL, Chapter) .. TransError .. Format; URL = ""; Format = ""; else Chapter = Chapter .. TransError; end elseif is_set(ChapterURL) then Chapter = Chapter .. " " .. externallink(ChapterURL, nil, ChapterURLorigin) .. TransError; else Chapter = Chapter .. TransError; end if is_set(Title) then -- LOCAL Chapter = Chapter .. '//' -- LOCAL else -- LOCAL Chapter = Chapter .. sepc .. " " -- with end-space end -- LOCAL elseif is_set(ChapterURL) then Chapter = " " .. externallink(ChapterURL, nil, ChapterURLorigin) .. sepc .. " "; end -- Format main title. if is_set(TitleLink) and is_set(Title) then Title = "" .. Title .. "" end if is_set(Periodical) then Title = wrap('quoted-title', Title); TransTitle = wrap('trans-quoted-title', TransTitle); elseif inArray(config.CitationClass,) and not is_set(Chapter) then Title = wrap('quoted-title', Title); TransTitle = wrap('trans-quoted-title', TransTitle); else Title = wrap('italic-title', Title); TransTitle = wrap('trans-italic-title', TransTitle); end TransError = ""; if is_set(TransTitle) then if not is_set(Title) then TransError = " " .. seterror('trans_missing_title'); else TransTitle = " " .. TransTitle; end end Title = Title .. TransTitle; if is_set(Title) then if not is_set(TitleLink) and is_set(URL) then Title = externallink(URL, Title) .. TransError .. Format URL = ""; Format = ""; else Title = Title .. TransError; end end if is_set(Place) then if sepc "news" then -- LOCAL Pages = ": (" .. Pages .. ")" -- LOCAL elseif config.CitationClass "news" then -- LOCAL Page = ": (" .. Page .. ")" -- LOCAL elseif config.CitationClass 'zh-' then langNameInLang = languageCode end local languageName = mw.language.fetchLanguageName(languageCode, langNameInLang) if languageName if is_set(URL) then URL = " " .. externallink(URL, nil, URLorigin); end if is_set(Quote) then if Quote:sub(1,1) '"' then Quote = Quote:sub(2,-2); end Quote = sepc .." " .. wrap('quoted-text', Quote); PostScript = ""; elseif PostScript:lower DeadURL then local arch_text = cfg.messages['archived']; if sepc ~= "." then arch_text = arch_text:lower end Archived = substitute(cfg.messages['archived-not-dead'],); if not is_set(OriginalURL) then Archived = Archived .. " " .. seterror('archive_missing_url'); end elseif is_set(OriginalURL) then local arch_text = cfg.messages['archived-dead']; if sepc ~= "." then arch_text = arch_text:lower end Archived = sepc .. " " .. substitute(arch_text,); else local arch_text = cfg.messages['archived-missing']; if sepc ~= "." then arch_text = arch_text:lower end Archived = substitute(arch_text,); -- LOCAL end else Archived = "" end local Lay if is_set(LayURL) then if is_set(LayDate) then LayDate = " (" .. LayDate .. ")" end if is_set(LaySource) then LaySource = " - " .. safeforitalics(LaySource) .. ""; else LaySource = ""; end if sepc -- Piece all bits together at last. Here, all should be non-nil. -- We build things this way because it is more efficient in LUA -- not to keep reassigning to the same string variable over and over. local tcommon if inArray(config.CitationClass,) and is_set(Periodical) then if is_set(Others) then Others = Others .. sepc .. " " end tcommon = safejoin(sepc); -- LOCAL else tcommon = safejoin(sepc); -- LOCAL end if #ID_list > 0 then ID_list = safejoin(sepc); else ID_list = ID; end -- LOCAL local xDate = Date local pgtext = Page .. Pages .. At if (is_set(Periodical) and Date ~= and not inArray(config.CitationClass,)) or (inArray(config.CitationClass,)) then if inArray(config.CitationClass,) and (Volume ~= or Issue ~= ) then xDate = xDate .. ',' .. Volume .. Issue end xDate = xDate .. pgtext pgtext = end if PublicationDate and PublicationDate ~= then xDate = xDate .. ' (' .. PublicationDate .. ')' end if OrigYear ~= then xDate = xDate .. OrigYear end if AccessDate ~= then xDate = xDate .. ' ' .. AccessDate end if xDate ~= then xDate = sepc .. ' ' .. xDate end -- END LOCAL local idcommon = safejoin(sepc); -- LOCAL local text; -- LOCAL local pgtext = Page .. Pages .. At; if is_set(Authors) then if is_set(Coauthors) then Authors = Authors .. A['AuthorSeparator'] .. " " .. Coauthors end --LOCAL if is_set(Date) then Date = " ("..Date..")" .. OrigYear .. sepc .. " " elseif string.sub(Authors,-1,-1) sepc) or ed_is_zh -- LOCAL then Editors = in_text .. Editors .. " " else Editors = in_text .. Editors .. sepc .. " " end -- LOCAL if ed_is_zh then Editors = Editors .. ' ' .. cfg.messages['in'] .. sepc .. ' ' end -- END LOCAL end text = safejoin(sepc); -- LOCAL text = safejoin(sepc); elseif is_set(Editors) then --LOCAL if is_set(Date) then if EditorCount <= 1 then Editors = Editors .. ", " .. cfg.messages['editor']; else Editors = Editors .. ", " .. cfg.messages['editors']; end Date = " (" .. Date ..")" .. OrigYear .. sepc .. " " else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " " end --LOCAL end text = safejoin(sepc); -- LOCAL text = safejoin(sepc); else --LOCAL if is_set(Date) then if (string.sub(tcommon,-1,-1) ~= sepc) then Date = sepc .." " .. Date .. OrigYear else Date = " " .. Date .. OrigYear end end if config.CitationClass -- Now enclose the whole thing in a 4 then break end end elseif is_set(Editors) then for i,v in ipairs(e) do names[i] = v.last if i local empty_span = ' -- This is used by templates such as Book: to create the actual citation text.function z.citation(frame) local pframe = frame:getParent local args = ; local suggestions = ; local error_text, error_state; local config = ; for k, v in pairs(frame.args) do config[k] = v; args[k] = v; end for k, v in pairs(pframe.args) do if v ~= then if not validate(k) then error_text = ""; if type(k) ~= 'string' then -- Exclude empty numbered parameters if v:match("%S+") ~= nil then error_text, error_state = seterror('text_ignored',, true); end elseif validate(k:lower) then error_text, error_state = seterror('parameter_ignored_suggest',, true); else if #suggestions 'postscript') then args[k] = v; end end return citation0(config, args, frame) -- LOCALend return zduplicate_char then str = str:sub(1,-2); elseif end_chr
duplicate_char .. "" then str = str:sub(1, -4) .. ""; elseif str:sub(-5,-1)
duplicate_char .. "]" then trim = true; end elseif end_chr
duplicate_char .. "]]" then trim = true; elseif str:sub(-2,-1)
" " then if str:sub(-2,-1)
math.floor(num) then return str; else -- Use formatDate to interpret more complicated formats local lang = mw.getContentLanguage; local good, result; good, result = pcall(lang.formatDate, lang, 'Y', str) if good then return result; else -- Can't make sense of this input, return blank. return ""; end endend
format) then first = reducetoinitials(first) end one = one .. namesep .. first end if is_set(person.link) then one = "" .. one .. "" end end table.insert(text, one) table.insert(text, sep_one) end end
format) then result = '
' .. result .. ''; end return result, countend'external' then table.insert(new_list,); elseif handler.mode
'DOI' then table.insert(new_list,); elseif k
'OL' then table.insert(new_list,); elseif k
'1' then for _, v in ipairs(possible) do v = v:gsub("#", ""); if is_set(args[v]) then if value ~= nil and selected ~= v then table.insert(error_list, v); else value = args[v]; selected = v; end end end end for _, v in ipairs(possible) do if index ~= nil then v = v:gsub("#", index); end if is_set(args[v]) then if value ~= nil and selected ~= v then table.insert(error_list, v); else value = args[v]; selected = v; end end end if #error_list > 0 then local error_str = ""; for _, k in ipairs(error_list) do if error_str ~= "" then error_str = error_str .. cfg.messages['parameter-separator'] end error_str = error_str .. wrap('parameter', k); end if #error_list > 1 then error_str = error_str .. cfg.messages['parameter-final-separator']; else error_str = error_str .. cfg.messages['parameter-pair-separator']; end error_str = error_str .. wrap('parameter', selected); table.insert(z.message_tail,); end return value, selected;end
next(data) then return ; end local ctx_ver = "Z39.88-2004"; -- treat table strictly as an array with only set values. local OCinSoutput = setmetatable; if is_set(data.Chapter) then OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; OCinSoutput["rft.genre"] = "bookitem"; OCinSoutput["rft.btitle"] = data.Chapter; OCinSoutput["rft.atitle"] = data.Title; elseif is_set(data.Periodical) then OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:journal"; OCinSoutput["rft.genre"] = "article"; OCinSoutput["rft.jtitle"] = data.Periodical; OCinSoutput["rft.atitle"] = data.Title; else OCinSoutput.rft_val_fmt = "info:ofi/fmt:kev:mtx:book"; OCinSoutput["rft.genre"] = "book" OCinSoutput["rft.btitle"] = data.Title; end OCinSoutput["rft.place"] = data.PublicationPlace; OCinSoutput["rft.date"] = data.Date; OCinSoutput["rft.series"] = data.Series; OCinSoutput["rft.volume"] = data.Volume; OCinSoutput["rft.issue"] = data.Issue; OCinSoutput["rft.pages"] = data.Pages; OCinSoutput["rft.edition"] = data.Edition; OCinSoutput["rft.pub"] = data.PublisherName; for k, v in pairs(data.ID_list) do local id, value = cfg.id_handlers[k].COinS; if k
'info' then OCinSoutput["rft_id"] = table.concat; else OCinSoutput[id ] = value; end end local last, first; for k, v in ipairs(data.Authors) do last, first = v.last, v.first; if k
"encyclopaedia") then if not is_set(Chapter) then if not is_set(Title) then Title = Periodical; Periodical = ; else Chapter = Title TransChapter = TransTitle Title = ; TransTitle = ; end end end
Place then Place = ; end local PublisherName = A['PublisherName']; local SubscriptionRequired = A['SubscriptionRequired']; local Via = A['Via']; local AccessDate = A['AccessDate']; local ArchiveDate = A['ArchiveDate']; local Agency = A['Agency']; local DeadURL = A['DeadURL'] local Language = A['Language']; local Format = A['Format']; local Ref = A['Ref']; local DoiBroken = A['DoiBroken']; local ID = A['ID']; local ASINTLD = A['ASINTLD']; local IgnoreISBN = A['IgnoreISBN'];
v then no_tracking_cats = "true"; break; end end end
"journal") then if not is_set(URL) and is_set(ID_list['PMC']) then local Embargo = A['Embargo']; if is_set(Embargo) then local lang = mw.getContentLanguage; local good1, result1, good2, result2; good1, result1 = pcall(lang.formatDate, lang, 'U', Embargo); good2, result2 = pcall(lang.formatDate, lang, 'U'); if good1 and good2 and tonumber(result1) < tonumber(result2) then URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC']; URLorigin = cfg.id_handlers['PMC'].parameters[1]; end else URL = "http://www.ncbi.nlm.nih.gov/pmc/articles/PMC" .. ID_list['PMC']; URLorigin = cfg.id_handlers['PMC'].parameters[1]; end end end
"episode" then local AirDate = A['AirDate']; local SeriesLink = A['SeriesLink']; local Season = A['Season']; local SeriesNumber = A['SeriesNumber']; local Network = A['Network']; local Station = A['Station']; local s, n =, ; local Sep = (first_set(A["SeriesSeparator"], A["Separator"]) or "") .. " "; if is_set(Issue) then table.insert(s, cfg.messages["episode"] .. " " .. Issue); Issue = ; end if is_set(Season) then table.insert(s, cfg.messages["season"] .. " " .. Season); end if is_set(SeriesNumber) then table.insert(s, cfg.messages["series"] .. " " .. SeriesNumber); end if is_set(Network) then table.insert(n, Network); end if is_set(Station) then table.insert(n, Station); end Date = Date or AirDate; Chapter = Title; ChapterLink = TitleLink; TransChapter = TransTitle; Title = Series; TitleLink = SeriesLink; TransTitle = ; Series = table.concat(s, Sep); ID = table.concat(n, Sep); end -- COinS metadata (see
9 then Maximum = 8; table.insert(z.message_tail,); elseif not is_set(Maximum) then Maximum = #a + 1; end local control = ; -- If the coauthor field is also used, prevent ampersand and et al. formatting. if is_set(Coauthors) then control.lastauthoramp = nil; control.maximum = #a + 1; end Authors = listpeople(control, a) end local EditorCount if not is_set(Editors) then local Maximum = tonumber(A['DisplayEditors']); -- Preserve old-style implicit et al. if not is_set(Maximum) and #e
"web") then table.insert(z.message_tail,); end -- Test if accessdate is given without giving a URL if is_set(AccessDate) then table.insert(z.message_tail,); AccessDate = ; end -- Test if format is given without giving a URL if is_set(Format) then Format = Format .. seterror('format_missing_url'); end end -- Test if citation has no title if not is_set(Chapter) and not is_set(Title) and not is_set(Periodical) and not is_set(Conference) and not is_set(TransTitle) and not is_set(TransChapter) then table.insert(z.message_tail,); end Format = is_set(Format) and " (" .. Format .. ")" or ""; local OriginalURL = URL DeadURL = DeadURL:lower; if is_set(ArchiveURL) then if (DeadURL ~= "no") then URL = ArchiveURL URLorigin = A:ORIGIN('ArchiveURL') end end -- Format chapter / article title
'zh' or Language:sub(1, 3):lower
'.' then Place = " " .. wrap('written', Place) .. sepc .. " "; else Place = " " .. substitute(cfg.messages['written']:lower,) .. sepc .. " "; end end if is_set(Conference) then if is_set(ConferenceURL) then Conference = externallink(ConferenceURL, Conference); end Conference = " " .. Conference elseif is_set(ConferenceURL) then Conference = " " .. externallink(ConferenceURL, nil, ConferenceURLorigin); end if not is_set(Position) then local Minutes = A['Minutes']; if is_set(Minutes) then Position = " " .. Minutes .. " " .. cfg.messages['minutes']; else local Time = A['Time']; if is_set(Time) then local TimeCaption = A['TimeCaption'] if not is_set(TimeCaption) then TimeCaption = cfg.messages['event']; if sepc ~= '.' then TimeCaption = TimeCaption:lower; end end Position = " " .. TimeCaption .. " " .. Time; end end else Position = " " .. Position; At = ; end if not is_set(Page) then if is_set(Pages) then if is_set(Periodical) and not inArray(config.CitationClass,) then Pages = ": " .. Pages; elseif config.CitationClass
"book" then -- LOCAL Pages = ": " .. Pages -- LOCAL elseif tonumber(Pages) ~= nil then Pages = sepc .." " .. PPrefix .. Pages .. PSuffix; -- LOCAL else Pages = sepc .." " .. PPPrefix .. Pages .. PPSuffix; -- LOCAL end end else if is_set(Periodical) and not inArray(config.CitationClass,) then Page = ": " .. Page; else if config.CitationClass
"news" then -- LOCAL Page = ": " .. Page -- LOCAL else -- LOCAL Page = sepc .." " .. PPrefix .. Page .. PSuffix; -- LOCAL end -- LOCAL end end At = is_set(At) and (sepc .. " " .. At) or ""; Others = is_set(Others) and (sepc .. " " .. Others) or ""; TitleType = is_set(TitleType) and (", " .. TitleType) or ""; -- LOCAL TitleNote = is_set(TitleNote) and (sepc .. " " .. TitleNote) or ""; -- LOCAL if is_set(Language) then local langNameInLang = mw.getContentLanguage:getCode local languageCode = Language:lower if languageCode:sub(1, 3)
then languageName = Language end Language = " " .. wrap('language', languageName) else Language = "" end -- END LOCAL Edition = is_set(Edition) and (" " .. wrap('edition', Edition)) or ""; Issue = is_set(Issue) and (" (" .. Issue .. ")") or ""; Series = is_set(Series) and (sepc .. " " .. Series) or ""; OrigYear = is_set(OrigYear) and (" [" .. OrigYear .. "]") or ""; Agency = is_set(Agency) and (sepc .. " " .. Agency) or ""; if is_set(Volume) then if (mw.ustring.len(Volume) > 4) then Volume = sepc .." " .. Volume; else Volume = " " .. hyphentodash(Volume) .. ""; end end ------------------------------------ totally unrelated data if is_set(Via) then Via = " " .. wrap('via', Via); end if is_set(AccessDate) then local retrv_text = " " .. cfg.messages['retrieved'] if (sepc ~= ".") then retrv_text = retrv_text:lower end AccessDate = '
' -- LOCAL .. sepc .. substitute(retrv_text,) .. '' end if is_set(SubscriptionRequired) then SubscriptionRequired = sepc .. " " .. cfg.messages['subscription']; end if is_set(ID) then ID = sepc .." ".. ID; end ID_list = buildidlist(ID_list,);'"' and Quote:sub(-1,-1)
"none" then PostScript = ""; end local Archived if is_set(ArchiveURL) then if not is_set(ArchiveDate) then ArchiveDate = seterror('archive_missing_date'); end if "no"
'.' then Lay = sepc .. " " .. externallink(LayURL, cfg.messages['lay summary']) .. LaySource .. LayDate else Lay = sepc .. " " .. externallink(LayURL, cfg.messages['lay summary']:lower) .. LaySource .. LayDate end else Lay = ""; end if is_set(Transcript) then if is_set(TranscriptURL) then Transcript = externallink(TranscriptURL, Transcript); end elseif is_set(TranscriptURL) then Transcript = externallink(TranscriptURL, nil, TranscriptURLorigin); end local Publisher; if is_set(Periodical) and not inArray(config.CitationClass,) then if is_set(PublisherName) then if is_set(PublicationPlace) then Publisher = PublicationPlace .. ": " .. PublisherName; else Publisher = PublisherName; end elseif is_set(PublicationPlace) then Publisher= PublicationPlace; else Publisher = ""; end --LOCAL if is_set(PublicationDate) then if is_set(Publisher) then Publisher = Publisher .. ", " .. wrap('published', PublicationDate); else Publisher = PublicationDate; end end if is_set(Publisher) then Publisher = " (" .. Publisher .. ")"; end else --LOCAL if is_set(PublicationDate) then PublicationDate = " (" .. wrap('published', PublicationDate) .. ")"; end if is_set(PublisherName) then if is_set(PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName -- LOCAL .. PublicationDate; else Publisher = sepc .. " " .. PublisherName -- LOCAL .. PublicationDate; end elseif is_set(PublicationPlace) then Publisher= sepc .. " " .. PublicationPlace -- LOCAL .. PublicationDate; else Publisher = -- LOCAL .. PublicationDate; end end -- Several of the above rely upon detecting this as nil, so do it last. if is_set(Periodical) then if is_set(Title) or is_set(TitleNote) then Periodical = sepc .. " " .. wrap('italic-title', Periodical) else Periodical = wrap('italic-title', Periodical) end end
sepc then Authors = Authors .. " " else Authors = Authors .. sepc .. " " end if is_set(Editors) then local ed_is_zh = is_zh(Editors) -- LOCAL local in_text = ed_is_zh and or "In " -- LOCAL if (sepc ~= '.') then in_text = in_text:lower end if (string.sub(Editors,-1,-1)
"journal" and is_set(Periodical) then text = safejoin(sepc); text = safejoin(sepc); -- LOCAL else text = safejoin(sepc); -- LOCAL text = safejoin(sepc); end end if is_set(PostScript) and PostScript ~= sepc then text = safejoin(sepc); --Deals with italics, spaces, etc. text = text:sub(1,-2); --Remove final seperator end text = safejoin(sepc);
Ref) then local names = --table of last names & year if is_set(Authors) then for i,v in ipairs(a) do names[i] = v.last if i
4 then break end end end names[#names + 1 ] = Year; id = anchorid(names) end options.id = id; end if string.len(text:gsub("
/]*>.-", ""):gsub("%b<>","")) <= 2 then z.error_categories = ; text = seterror('empty_citation'); z.message_tail = ; end if is_set(options.id) then text = '' .. text .. ""; else text = '' .. text .. ""; end #z.message_tail then text = text .. errorcomment(v[1], v[2]); else text = text .. errorcomment(v[1] .. "; ", v[2]); end end end end no_tracking_cats = no_tracking_cats:lower; if inArray(no_tracking_cats,) then for _, v in ipairs(z.error_categories) do text = text .. ''; end end return textend
0 then suggestions = mw.loadData('Module:Citation/CS1/Suggestions'); end if suggestions[k:lower ] ~= nil then error_text, error_state = seterror('parameter_ignored_suggest',, true); else error_text, error_state = seterror('parameter_ignored',, true); end end if error_text ~= then table.insert(z.message_tail,); end end args[k] = v; elseif args[k] ~= nil or (k