تضامنًا مع حق الشعب الفلسطيني |
وحدة:Citation/CS1/sandbox
< وحدة:Citation | CS1
توثيق الوحدة[أنشئ] [محو الاختزان][استخدامات] [قوالب]
--require("Module:No globals") local languagescode = require("وحدة:Citation/CS1/lang") local fetchName = require("وحدة:لغات").getname local check_date_n = require("وحدة:Citation/CS1/dates").check_date local validation local utilities local z = {} local identifiers local metadata local cfg = {} local whitelist = {} local added_deprecated_cat local added_vanc_errs local added_generic_name_errs local Frame local is_preview_mode local is_sandbox local function first_set(list, count) local i = 1 while i <= count do if utilities.is_set(list[i]) then return list[i] end i = i + 1 end end local function add_vanc_error(source, position) if added_vanc_errs then return end added_vanc_errs = true utilities.set_message("err_vancouver", {source, position}) end local function is_scheme(scheme) return scheme and scheme:match("^%a[%a%d%+%.%-]*:") end local function is_domain_name(domain) if not domain then return false end domain = domain:gsub("^//", "") if not domain:match("^[%w]") then return false end if domain:match("^%a+:") then return false end local patterns = { "%f[%w][%w][%w%-]+[%w]%.%a%a+$", "%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$", "%f[%a][qxz]%.com$", "%f[%a][iq]%.net$", "%f[%w][%w]%.%a%a$", "%f[%w][%w][%w]%.%a%a+$", "^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?" } for _, pattern in ipairs(patterns) do if domain:match(pattern) then return true end end for _, d in ipairs({"cash", "company", "today", "org"}) do if domain:match("%f[%w][%w]%." .. d) then return true end end return false end local function is_url(scheme, domain) if utilities.is_set(scheme) then return is_scheme(scheme) and is_domain_name(domain) else return is_domain_name(domain) end end local function split_url(url_str) local scheme, authority, domain url_str = url_str:gsub("([%a%d])%.?[/%?#].*$", "%1") if url_str:match("^//%S*") then domain = url_str:match("^//(%S*)") elseif url_str:match("%S-:/*%S+") then scheme, authority, domain = url_str:match("(%S-:)(/*)(%S+)") if utilities.is_set(authority) then authority = authority:gsub("//", "", 1) if utilities.is_set(authority) then return scheme end else if not scheme:match("^news:") then return scheme end end domain = domain:gsub("(%a):%d+", "%1") end return scheme, domain end local function link_param_ok(value) local scheme, domain if value:find("[<>%[%]|{}]") then return false end scheme, domain = split_url(value) return not is_url(scheme, domain) end local function link_title_ok(link, lorig, title, torig) local orig if utilities.is_set(link) then if not link_param_ok(link) then orig = lorig elseif title:find("%[%[") then orig = torig elseif link:match("^%a+:") then local prefix = link:match("^(%a+):"):lower() if cfg.inter_wiki_map[prefix] then orig = lorig end end end if utilities.is_set(orig) then link = "" utilities.set_message("err_bad_paramlink", orig) end return link end local function check_url(url_str) if nil == url_str:match("^%S+$") then return false end local scheme, domain scheme, domain = split_url(url_str) if "news:" == scheme then return domain:match("^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$") end return is_url(scheme, domain) end local function is_parameter_ext_wikilink(value) local scheme, domain if value:match("%f[%[]%[%a%S*:%S+.*%]") then scheme, domain = split_url(value:match("%f[%[]%[(%a%S*:%S+).*%]")) elseif value:match("%f[%[]%[//%S+.*%]") then scheme, domain = split_url(value:match("%f[%[]%[(//%S+).*%]")) elseif value:match("%a%S*:%S+") then scheme, domain = split_url(value:match("(%a%S*:%S+)")) elseif value:match("//%S+") then scheme, domain = split_url(value:match("(//%S+)")) else return false end return is_url(scheme, domain) end local function check_for_url(parameter_list, error_list) for k, v in pairs(parameter_list) do if is_parameter_ext_wikilink(v) then table.insert(error_list, utilities.wrap_style("parameter", k)) end end end local function safe_for_url(str) if str:match("%[%[.-%]%]") ~= nil then utilities.set_message("err_wikilink_in_url", {}) end return str:gsub( "[%[%]\n]", { ["["] = "[", ["]"] = "]", ["\n"] = " " } ) end local function external_link(URL, label, source, access) local err_msg = "" local domain local path local base_url if not utilities.is_set(label) then label = URL if utilities.is_set(source) then utilities.set_message("err_bare_url_missing_title", {utilities.wrap_style("parameter", source)}) else error(cfg.messages["bare_url_no_origin"]) end end if not check_url(URL) then utilities.set_message("err_bad_url", {utilities.wrap_style("parameter", source)}) end domain, path = URL:match("^([/%.%-%+:%a%d]+)([/%?#].*)$") if path then path = path:gsub("[%[%]]", {["["] = "%5b", ["]"] = "%5d"}) URL = table.concat({domain, path}) end base_url = table.concat({"[", URL, " ", safe_for_url(label), "]"}) if utilities.is_set(access) then base_url = utilities.substitute( cfg.presentation["ext-link-access-signal"], {cfg.presentation[access].class, cfg.presentation[access].title, base_url} ) end return base_url end local function deprecated_parameter(name) if not added_deprecated_cat then added_deprecated_cat = true utilities.set_message("err_deprecated_params", {name}) end end local function kern_quotes(str) local cap = "" local wl_type, label, link wl_type, label, link = utilities.is_wikilink(str) if 1 == wl_type then if mw.ustring.match(str, '%[%[["“”\'‘’].+["“”\'‘’]%]%]') then str = utilities.substitute(cfg.presentation["kern-left"], str) str = utilities.substitute(cfg.presentation["kern-right"], str) elseif mw.ustring.match(str, '%[%[["“”\'‘’].+%]%]') then str = utilities.substitute(cfg.presentation["kern-left"], str) elseif mw.ustring.match(str, '%[%[.+["“”\'‘’]%]%]') then str = utilities.substitute(cfg.presentation["kern-right"], str) end else label = mw.ustring.gsub(label, "[“”]", '"') label = mw.ustring.gsub(label, "[‘’]", "'") cap = mw.ustring.match(label, '^(["\'][^\'].+)') if utilities.is_set(cap) then label = utilities.substitute(cfg.presentation["kern-left"], cap) end cap = mw.ustring.match(label, '^(.+[^\']["\'])$') if utilities.is_set(cap) then label = utilities.substitute(cfg.presentation["kern-right"], cap) end if 2 == wl_type then str = utilities.make_wikilink(link, label) else str = label end end return str end local function format_script_value(script_value, script_param) local lang = "" local name if script_value:match("^%l%l%l?%s*:") then lang = script_value:match("^(%l%l%l?)%s*:%s*%S.*") if not utilities.is_set(lang) then utilities.set_message("err_script_parameter", {script_param, "missing title part"}) return "" end name = fetchName(lang, "al") if name == lang then name = cfg.lang_code_remap[lang] or mw.language.fetchLanguageName(lang, cfg.this_wiki_code) end if utilities.is_set(name) then script_value = script_value:gsub("^%l+%s*:%s*", "") if utilities.in_array(lang, cfg.script_lang_codes) then utilities.add_prop_cat("script", {name, lang}) else utilities.set_message("err_script_parameter", {script_param, "unknown language code"}) end lang = ' lang="' .. lang .. '" ' else utilities.set_message("err_script_parameter", {script_param, "invalid language code"}) lang = "" end else utilities.set_message("err_script_parameter", {script_param, "missing prefix"}) end script_value = utilities.substitute(cfg.presentation["bdi"], {lang, script_value}) return script_value end local function script_concatenate(title, script, script_param) if utilities.is_set(script) then script = format_script_value(script, script_param) if utilities.is_set(script) then title = title .. " " .. script end end return title end local function wrap_msg(key, str, lower) if not utilities.is_set(str) then return "" end if true == lower then local msg msg = cfg.messages[key]:lower() return utilities.substitute(msg, str) else return utilities.substitute(cfg.messages[key], str) end end local function wikisource_url_make(str) local wl_type, D, L local ws_url, ws_label local wikisource_prefix = table.concat({"https://", cfg.this_wiki_code, ".wikisource.org/wiki/"}) wl_type, D, L = utilities.is_wikilink(str) if 0 == wl_type then str = D:match("^[Ww]ikisource:(.+)") or D:match("^[Ss]:(.+)") if utilities.is_set(str) then ws_url = table.concat( { wikisource_prefix, str } ) ws_label = str end elseif 1 == wl_type then str = D:match("^[Ww]ikisource:(.+)") or D:match("^[Ss]:(.+)") if utilities.is_set(str) then ws_url = table.concat( { wikisource_prefix, str } ) ws_label = str end elseif 2 == wl_type then str = L:match("^[Ww]ikisource:(.+)") or L:match("^[Ss]:(.+)") if utilities.is_set(str) then ws_label = D ws_url = table.concat( { wikisource_prefix, str } ) end end if ws_url then ws_url = mw.uri.encode(ws_url, "WIKI") ws_url = ws_url:gsub("%%23", "#") end return ws_url, ws_label, L or D end local function format_periodical(script_periodical, script_periodical_source, periodical, trans_periodical) if not utilities.is_set(periodical) then periodical = "" else periodical = utilities.wrap_style("italic-title", periodical) end periodical = script_concatenate(periodical, script_periodical, script_periodical_source) if utilities.is_set(trans_periodical) then trans_periodical = utilities.wrap_style("trans-italic-title", trans_periodical) if utilities.is_set(periodical) then periodical = periodical .. " " .. trans_periodical else periodical = trans_periodical utilities.set_message("err_trans_missing_title", {"periodical"}) end end return periodical end local function format_chapter_title( script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access) local ws_url, ws_label, L = wikisource_url_make(chapter) if ws_url then ws_label = ws_label:gsub("_", " ") chapter = ws_label end if not utilities.is_set(chapter) then chapter = "" else if false == no_quotes then chapter = kern_quotes(chapter) chapter = utilities.wrap_style("quoted-title", chapter) end end chapter = script_concatenate(chapter, script_chapter, script_chapter_source) if utilities.is_set(chapter_url) then chapter = external_link(chapter_url, chapter, chapter_url_source, access) elseif ws_url then chapter = external_link(ws_url, chapter .. " ", "ws link in chapter") chapter = utilities.substitute(cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], L, chapter}) end if utilities.is_set(trans_chapter) then trans_chapter = utilities.wrap_style("trans-quoted-title", trans_chapter) if utilities.is_set(chapter) then chapter = chapter .. " " .. trans_chapter else chapter = trans_chapter chapter_source = trans_chapter_source:match("trans%-?(.+)") utilities.set_message("err_trans_missing_title", {chapter_source}) end end return chapter end local function has_invisible_chars(param, v) local position = "" local capture local stripmarker capture = string.match(v, "[%w%p ]*") if capture == v then return end for _, invisible_char in ipairs(cfg.invisible_chars) do local char_name = invisible_char[1] local pattern = invisible_char[2] position, _, capture = mw.ustring.find(v, pattern) if position and (cfg.invisible_defs.zwj == capture) then if mw.ustring.find(v, cfg.indic_script) then position = nil elseif cfg.emoji[mw.ustring.codepoint(v, position + 1)] then position = nil end end if position then if "nowiki" == capture or "math" == capture or ("templatestyles" == capture and utilities.in_array(param, {"id", "quote"})) then stripmarker = true elseif true == stripmarker and cfg.invisible_defs.del == capture then position = nil else local err_msg if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then err_msg = capture .. " " .. char_name else err_msg = char_name .. " " .. "character" end utilities.set_message( "err_invisible_char", {err_msg, utilities.wrap_style("parameter", param), position} ) return end end end end local function argument_wrapper(args) local origin = {} return setmetatable( { ORIGIN = function(self, k) local dummy = self[k] return origin[k] end }, { __index = function(tbl, k) if origin[k] ~= nil then return nil end local args, list, v = args, cfg.aliases[k] if type(list) == "table" then v, origin[k] = utilities.select_one(args, list, "err_redundant_parameters") if origin[k] == nil then origin[k] = "" end elseif list ~= nil then v, origin[k] = args[list], list else error(cfg.messages["unknown_argument_map"] .. ": " .. k) end if v == nil then v = "" origin[k] = "" end tbl = rawset(tbl, k, v) return v end } ) end local function nowrap_date(date) local cap = "" local cap2 = "" if date:match("^%d%d%d%d%-%d%d%-%d%d$") then date = utilities.substitute(cfg.presentation["nowrap1"], date) elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match("^%d%d?%s*%a+%s+%d%d%d%d$") then cap, cap2 = string.match(date, "^(.*)%s+(%d%d%d%d)$") date = utilities.substitute(cfg.presentation["nowrap2"], {cap, cap2}) end return date end local function set_titletype(cite_class, title_type) if utilities.is_set(title_type) then if "none" == cfg.keywords_xlate[title_type] then title_type = "" end return title_type end return cfg.title_types[cite_class] or "" end local function safe_join(tbl, duplicate_char) local f = {} if 1 == #duplicate_char then f.gsub = string.gsub f.match = string.match f.sub = string.sub else f.gsub = mw.ustring.gsub f.match = mw.ustring.match f.sub = mw.ustring.sub end local str = "" local comp = "" local end_chr = "" local trim for _, value in ipairs(tbl) do if value == nil then value = "" end if str == "" then str = value elseif value ~= "" then if value:sub(1, 1) == "<" then comp = value:gsub("%b<>", "") else comp = value end if f.sub(comp, 1, 1) == duplicate_char then trim = false end_chr = f.sub(str, -1, -1) if end_chr == duplicate_char then str = f.sub(str, 1, -2) elseif end_chr == "'" then if f.sub(str, -3, -1) == duplicate_char .. "''" then str = f.sub(str, 1, -4) .. "''" elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then trim = true elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then trim = true end elseif end_chr == "]" then if f.sub(str, -3, -1) == duplicate_char .. "]]" then trim = true elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then trim = true elseif f.sub(str, -2, -1) == duplicate_char .. "]" then trim = true elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then trim = true end elseif end_chr == " " then if f.sub(str, -2, -1) == duplicate_char .. " " then str = f.sub(str, 1, -3) end end if trim then if value ~= comp then local dup2 = duplicate_char if f.match(dup2, "%A") then dup2 = "%" .. dup2 end value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1) else value = f.sub(value, 2, -1) end end end str = str .. value end end return str end local function is_suffix(suffix) if utilities.in_array(suffix, {"Jr", "Sr", "Jnr", "Snr", "1st", "2nd", "3rd"}) or suffix:match("^%dth$") then return true end return false end local function is_good_vanc_name(last, first, suffix, position) if not suffix then if first:find("[,%s]") then first = first:match("(.-)[,%s]+") suffix = first:match("[,%s]+(.+)$") end end if utilities.is_set(suffix) then if not is_suffix(suffix) then add_vanc_error(cfg.err_msg_supl.suffix, position) return false end end if nil == mw.ustring.find( last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%']*$" ) or nil == mw.ustring.find( first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143%-%s%'%.]*$" ) then add_vanc_error(cfg.err_msg_supl["non-Latin char"], position) return false end return true end local function reduce_to_initials(first, position) local name, suffix = mw.ustring.match(first, "^(%u+) ([%dJS][%drndth]+)$") if not name then name = mw.ustring.match(first, "^(%u+)$") end if name then if 3 > mw.ustring.len(name) then if suffix then if is_suffix(suffix) then return first else add_vanc_error(cfg.err_msg_supl.suffix, position) return first end else return first end end end local initials, names = {}, {} local i = 1 names = mw.text.split(first, "[%s,]+") while names[i] do if 1 < i and names[i]:match("[%dJS][%drndth]+%.?$") then names[i] = names[i]:gsub("%.", "") if is_suffix(names[i]) then table.insert(initials, " " .. names[i]) break end end if 3 > i then table.insert(initials, mw.ustring.sub(names[i], 1, 1)) end i = i + 1 end return table.concat(initials) end local function list_people(control, people, etal) local sep local namesep local format = control.format local maximum = control.maximum local name_list = {} if "vanc" == format then sep = cfg.presentation["sep_nl_vanc"] namesep = cfg.presentation["sep_name_vanc"] else sep = cfg.presentation["sep_nl"] namesep = cfg.presentation["sep_name"] end if sep:sub(-1, -1) ~= " " then sep = sep .. " " end if utilities.is_set(maximum) and maximum < 1 then return "", 0 end for i, person in ipairs(people) do if utilities.is_set(person.last) then local mask = person.mask local one local sep_one = sep if utilities.is_set(maximum) and i > maximum then etal = true break end if mask then local n = tonumber(mask) if n then one = 0 ~= n and string.rep("—", n) or nil person.link = nil else one = mask sep_one = " " end else one = person.last local first = person.first if utilities.is_set(first) then if ("vanc" == format) then one = one:gsub("%.", "") if not person.corporate and is_good_vanc_name(one, first, nil, i) then first = reduce_to_initials(first, i) end end one = one .. namesep .. first end end if utilities.is_set(person.link) then one = utilities.make_wikilink(person.link, one) end if one then table.insert(name_list, one) table.insert(name_list, sep_one) end end end local count = #name_list / 2 if 0 < count then if 1 < count and not etal then if "amp" == format then name_list[#name_list - 2] = " & " elseif "and" == format then if 2 == count then name_list[#name_list - 2] = cfg.presentation.sep_nl_and else name_list[#name_list - 2] = cfg.presentation.sep_nl_end end end end name_list[#name_list] = nil end local result = table.concat(name_list) if etal and utilities.is_set(result) then result = result .. sep .. " " .. cfg.messages["et al"] end return result, count end local function make_citeref_id(namelist, year) local names = {} for i, v in ipairs(namelist) do names[i] = v.last if i == 4 then break end end table.insert(names, year) local id = table.concat(names) if utilities.is_set(id) then return "CITEREF" .. id else return "" end end local function cite_class_attribute_make(cite_class, mode) local class_t = {} table.insert(class_t, "citation") if "citation" ~= cite_class then table.insert(class_t, cite_class) table.insert(class_t, utilities.is_set(mode) and mode or "cs1") else table.insert(class_t, utilities.is_set(mode) and mode or "cs2") end for _, prop_key in ipairs(z.prop_keys_t) do table.insert(class_t, prop_key) end return table.concat(class_t, " ") end local function name_has_etal(name, etal, nocat, param) if utilities.is_set(name) then local patterns = cfg.et_al_patterns for _, pattern in ipairs(patterns) do if name:match(pattern) then name = name:gsub(pattern, "") etal = true if not nocat then utilities.set_message("err_etal", {param}) end end end end return name, etal end local function name_is_numeric(name, list_name) if utilities.is_set(name) then if mw.ustring.match(name, "^[%A]+$") then utilities.set_message("maint_numeric_names", cfg.special_case_translation[list_name]) end end end local function name_has_mult_names(name, list_name) local _, commas, semicolons, nbsps if utilities.is_set(name) then _, commas = name:gsub(",", "") _, semicolons = name:gsub(";", "") _, nbsps = name:gsub(" ", "") if 1 < commas or 0 < (semicolons - nbsps) then utilities.set_message("maint_mult_names", cfg.special_case_translation[list_name]) end end end local function is_generic(item, value) local test_val for _, generic_value in ipairs(cfg.special_case_translation[item]) do test_val = generic_value["en"][2] and value:lower() or value if test_val:find(generic_value["en"][1], 1, generic_value["en"][2]) then return true elseif generic_value["local"] then test_val = generic_value["local"][2] and mw.ustring.lower(value) or value if mw.ustring.find(test_val, generic_value["local"][1], 1, generic_value["local"][2]) then return true end end end end local function name_is_generic(name, name_alias) if not added_generic_name_errs and is_generic("generic_names", name) then utilities.set_message("err_generic_name", name_alias) added_generic_name_errs = true end end local function name_checks(last, first, list_name, last_alias, first_alias) local accept_name if utilities.is_set(last) then last, accept_name = utilities.has_accept_as_written(last) if not accept_name then name_has_mult_names(last, list_name) name_is_numeric(last, list_name) name_is_generic(last, last_alias) end end if utilities.is_set(first) then first, accept_name = utilities.has_accept_as_written(first) if not accept_name then name_is_numeric(first, list_name) name_is_generic(first, first_alias) end local wl_type, D = utilities.is_wikilink(first) if 0 ~= wl_type then first = D utilities.set_message("err_bad_paramlink", first_alias) end end return last, first end local function extract_names(args, list_name) local names = {} local last local first local link local mask local i = 1 local n = 1 local count = 0 local etal = false local last_alias, first_alias, link_alias while true do last, last_alias = utilities.select_one(args, cfg.aliases[list_name .. "-Last"], "err_redundant_parameters", i) first, first_alias = utilities.select_one(args, cfg.aliases[list_name .. "-First"], "err_redundant_parameters", i) link, link_alias = utilities.select_one(args, cfg.aliases[list_name .. "-Link"], "err_redundant_parameters", i) mask = utilities.select_one(args, cfg.aliases[list_name .. "-Mask"], "err_redundant_parameters", i) last, etal = name_has_etal(last, etal, false, last_alias) first, etal = name_has_etal(first, etal, false, first_alias) last, first = name_checks(last, first, list_name, last_alias, first_alias) if first and not last then local alias = first_alias:find("given", 1, true) and "given" or "first" utilities.set_message( "err_first_missing_last", { first_alias, first_alias:gsub(alias, {["first"] = "last", ["given"] = "surname"}) } ) elseif not first and not last then count = count + 1 if 2 <= count then break end else local result link = link_title_ok(link, link_alias, last, last_alias) if first then link = link_title_ok(link, link_alias, first, first_alias) end names[n] = {last = last, first = first, link = link, mask = mask, corporate = false} n = n + 1 if 1 == count then utilities.set_message("err_missing_name", {list_name:match("(%w+)List"):lower(), i - 1}) end count = 0 end i = i + 1 end return names, etal end local function name_tag_get(lang_param) local lang_param_lc = mw.ustring.lower(lang_param) local name local tag --name = cfg.lang_code_remap[lang_param_lc] name = fetchName(lang_param_lc, "al") if name ~= lang_param_lc then return name, lang_param end tag = lang_param_lc:match("^(%a%a%a?)%-.*") --name = cfg.lang_code_remap[tag] if name then return name, tag end if cfg.lang_name_remap[lang_param_lc] then return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2] end tag = cfg.mw_languages_by_name_t[lang_param_lc] if tag then return cfg.mw_languages_by_tag_t[tag], tag end name = cfg.mw_languages_by_tag_t[lang_param_lc] if name then return name, lang_param end tag = lang_param_lc:match("^(%a%a%a?)%-.*") if tag then name = cfg.mw_languages_by_tag_t[tag] if name then return name, tag end end end local function language_parameter(lang) local tag local lang_subtag local name local language_list = {} local names_t = {} local this_wiki_name = mw.language.fetchLanguageName(cfg.this_wiki_code, cfg.this_wiki_code) names_t = mw.text.split(lang, "%s*,%s*") for _, lang in ipairs(names_t) do name, tag = name_tag_get(lang) if utilities.is_set(tag) then lang_subtag = tag:lower():gsub("^(%a%a%a?)%-.*", "%1") lang_subtag = languagescode[lang_subtag:lower()] or lang_subtag if cfg.this_wiki_code ~= lang_subtag then if 2 == lang_subtag:len() then utilities.add_prop_cat("foreign-lang-source", {name, lang_subtag}, lang_subtag) else utilities.add_prop_cat("foreign-lang-source-2", {lang_subtag}, lang_subtag) end elseif cfg.local_lang_cat_enable then utilities.add_prop_cat("local-lang-source", {name, lang_subtag}) end else name = lang utilities.set_message("maint_unknown_lang") end table.insert(language_list, name) name = "" end name = utilities.make_sep_list(#language_list, language_list) if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then return "" end return (" " .. wrap_msg("language", name)) end local function set_cs_style(postscript, mode) if utilities.is_set(postscript) then if mode == "cs1" and postscript == cfg.presentation["ps_" .. mode] then utilities.set_message("maint_postscript") end else postscript = cfg.presentation["ps_" .. mode] end return cfg.presentation["sep_" .. mode], postscript end local function set_style(mode, postscript, cite_class) local sep if "cs2" == mode then sep, postscript = set_cs_style(postscript, "cs2") elseif "cs1" == mode then sep, postscript = set_cs_style(postscript, "cs1") elseif "citation" == cite_class then sep, postscript = set_cs_style(postscript, "cs2") else sep, postscript = set_cs_style(postscript, "cs1") end if cfg.keywords_xlate[postscript:lower()] == "none" then if "cs2" == mode or "citation" == cite_class then utilities.set_message("maint_postscript") end postscript = "" end return sep, postscript end local function is_pdf(url) return url:match("%.pdf$") or url:match("%.PDF$") or url:match("%.pdf[%?#]") or url:match("%.PDF[%?#]") or url:match("%.PDF#") or url:match("%.pdf#") end local function style_format(format, url, fmt_param, url_param) if utilities.is_set(format) then format = utilities.wrap_style("format", format) if not utilities.is_set(url) then utilities.set_message("err_format_missing_url", {fmt_param, url_param}) end elseif is_pdf(url) then format = utilities.wrap_style("format", "PDF") else format = "" end return format end local function get_display_names(max, count, list_name, etal, param) if utilities.is_set(max) then if "etal" == max:lower():gsub("[ '%.]", "") then max = count + 1 etal = true elseif max:match("^%d+$") then max = tonumber(max) if max >= count then utilities.set_message("err_disp_name", {param, max}) max = nil end else utilities.set_message("err_disp_name", {param, max}) max = nil end end return max, etal end local function extra_text_in_page_check(val, name) if not val:match(cfg.vol_iss_pg_patterns.good_ppattern) then for _, pattern in ipairs(cfg.vol_iss_pg_patterns.bad_ppatterns) do if val:match(pattern) then utilities.set_message("err_extra_text_pages", name) return end end end end local function extra_text_in_vol_iss_check(val, name, selector) if not utilities.is_set(val) then return end local patterns = "v" == selector and cfg.vol_iss_pg_patterns.vpatterns or cfg.vol_iss_pg_patterns.ipatterns local handler = "v" == selector and "err_extra_text_volume" or "err_extra_text_issue" val = val:lower() for _, pattern in ipairs(patterns) do if val:match(pattern) then utilities.set_message(handler, name) return end end end local function get_v_name_table(vparam, output_table, output_link_table) local name_table = mw.text.split(vparam or "", "%s*,%s*") local wl_type, label, link local i = 1 while name_table[i] do if name_table[i]:match("^%(%(.*[^%)][^%)]$") then local name = name_table[i] i = i + 1 while name_table[i] do name = name .. ", " .. name_table[i] if name_table[i]:match("^.*%)%)$") then break end i = i + 1 end table.insert(output_table, name) table.insert(output_link_table, "") else wl_type, label, link = utilities.is_wikilink(name_table[i]) table.insert(output_table, label) if 1 == wl_type then table.insert(output_link_table, label) else table.insert(output_link_table, link) end end i = i + 1 end return output_table end local function parse_vauthors_veditors(args, vparam, list_name) local names = {} local v_name_table = {} local v_link_table = {} local etal = false local last, first, link, mask, suffix local corporate = false vparam, etal = name_has_etal(vparam, etal, true) v_name_table = get_v_name_table(vparam, v_name_table, v_link_table) for i, v_name in ipairs(v_name_table) do first = "" local accept_name v_name, accept_name = utilities.has_accept_as_written(v_name) if accept_name then last = v_name corporate = true elseif string.find(v_name, "%s") then if v_name:find("[;%.]") then add_vanc_error(cfg.err_msg_supl.punctuation, i) end local lastfirstTable = {} lastfirstTable = mw.text.split(v_name, "%s+") first = table.remove(lastfirstTable) if not mw.ustring.match(first, "^%u+$") then suffix = first first = table.remove(lastfirstTable) end last = table.concat(lastfirstTable, " ") if not utilities.is_set(last) then first = "" last = v_name add_vanc_error(cfg.err_msg_supl.name, i) end if mw.ustring.match(last, "%a+%s+%u+%s+%a+") then add_vanc_error(cfg.err_msg_supl["missing comma"], i) end if mw.ustring.match(v_name, " %u %u$") then add_vanc_error(cfg.err_msg_supl.initials, i) end else last = v_name end if utilities.is_set(first) then if not mw.ustring.match(first, "^%u?%u$") then add_vanc_error(cfg.err_msg_supl.initials, i) end is_good_vanc_name(last, first, suffix, i) if utilities.is_set(suffix) then first = first .. " " .. suffix suffix = "" end else if not corporate then is_good_vanc_name(last, "", nil, i) end end link = utilities.select_one(args, cfg.aliases[list_name .. "-Link"], "err_redundant_parameters", i) or v_link_table[i] mask = utilities.select_one(args, cfg.aliases[list_name .. "-Mask"], "err_redundant_parameters", i) names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate} end return names, etal end local function select_author_editor_source(vxxxxors, xxxxors, args, list_name) local lastfirst = false if utilities.select_one(args, cfg.aliases[list_name .. "-Last"], "none", 1) or utilities.select_one(args, cfg.aliases[list_name .. "-First"], "none", 1) or utilities.select_one(args, cfg.aliases[list_name .. "-Last"], "none", 2) or utilities.select_one(args, cfg.aliases[list_name .. "-First"], "none", 2) then lastfirst = true end if (utilities.is_set(vxxxxors) and true == lastfirst) or (utilities.is_set(vxxxxors) and utilities.is_set(xxxxors)) or (true == lastfirst and utilities.is_set(xxxxors)) then local err_name if "AuthorList" == list_name then err_name = "author" else err_name = "editor" end utilities.set_message("err_redundant_parameters", err_name .. "-name-list parameters") end if true == lastfirst then return 1 end if utilities.is_set(vxxxxors) then return 2 end if utilities.is_set(xxxxors) then return 3 end return 1 end local function is_valid_parameter_value(value, name, possible, ret_val, invert) if not utilities.is_set(value) then return ret_val end if (not invert and utilities.in_array(value, possible)) then return cfg.keywords_xlate[value] elseif invert and not utilities.in_array(value, possible) then return value else utilities.set_message("err_invalid_param_val", {name, value}) return ret_val end end local function terminate_name_list(name_list, sepc) if (string.sub(name_list, -3, -1) == sepc .. ". ") then return name_list elseif (string.sub(name_list, -1, -1) == sepc) or (string.sub(name_list, -3, -1) == sepc .. "]]") then return name_list .. " " else return name_list .. sepc .. " " end end local function format_volume_issue(volume, issue, cite_class, origin, sepc, lower) if not utilities.is_set(volume) and not utilities.is_set(issue) then return "" end local is_journal = "journal" == cite_class or (utilities.in_array(cite_class, {"citation", "map", "interview"}) and "journal" == origin) local is_numeric_vol = volume and (volume:match("^[MDCLXVI]+$") or volume:match("^%d+$")) local is_long_vol = volume and (4 < mw.ustring.len(volume)) if volume and (not is_numeric_vol and is_long_vol) then utilities.add_prop_cat("long-vol") end if is_journal then local vol = "" if utilities.is_set(volume) then if is_numeric_vol then vol = utilities.substitute(cfg.presentation["vol-bold"], {sepc, volume}) elseif is_long_vol then vol = utilities.substitute(cfg.messages["j-vol"], {sepc, utilities.hyphen_to_dash(volume)}) else vol = utilities.substitute(cfg.presentation["vol-bold"], {sepc, utilities.hyphen_to_dash(volume)}) end end if utilities.is_set(issue) then return vol .. utilities.substitute(cfg.messages["j-issue"], issue) end return vol end if "podcast" == cite_class and utilities.is_set(issue) then return wrap_msg("issue", {sepc, issue}, lower) end if utilities.is_set(volume) and utilities.is_set(issue) then return wrap_msg("vol-no", {sepc, utilities.hyphen_to_dash(volume), issue}, lower) elseif utilities.is_set(volume) then return wrap_msg("vol", {sepc, utilities.hyphen_to_dash(volume)}, lower) else return wrap_msg("issue", {sepc, issue}, lower) end end local function format_pages_sheets(page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower) if "map" == cite_class then if utilities.is_set(sheet) then if "journal" == origin then return "", "", wrap_msg("j-sheet", sheet, lower), "" else return "", "", wrap_msg("sheet", {sepc, sheet}, lower), "" end elseif utilities.is_set(sheets) then if "journal" == origin then return "", "", "", wrap_msg("j-sheets", sheets, lower) else return "", "", "", wrap_msg("sheets", {sepc, sheets}, lower) end end end local is_journal = "journal" == cite_class or (utilities.in_array(cite_class, {"citation", "map", "interview"}) and "journal" == origin) if utilities.is_set(page) then if is_journal then return utilities.substitute(cfg.messages["j-page(s)"], page), "", "", "" elseif not nopp then return utilities.substitute(cfg.messages["p-prefix"], {sepc, page}), "", "", "" else return utilities.substitute(cfg.messages["nopp"], {sepc, page}), "", "", "" end elseif utilities.is_set(pages) then if is_journal then return utilities.substitute(cfg.messages["j-page(s)"], pages), "", "", "" elseif tonumber(pages) ~= nil and not nopp then return "", utilities.substitute(cfg.messages["p-prefix"], {sepc, pages}), "", "" elseif not nopp then return "", utilities.substitute(cfg.messages["pp-prefix"], {sepc, pages}), "", "" else return "", utilities.substitute(cfg.messages["nopp"], {sepc, pages}), "", "" end end return "", "", "", "" end local function insource_loc_get(page, page_orig, pages, pages_orig, at) local ws_url, ws_label, coins_pages, L if utilities.is_set(page) then if utilities.is_set(pages) or utilities.is_set(at) then pages = "" at = "" end extra_text_in_page_check(page, page_orig) ws_url, ws_label, L = wikisource_url_make(page) if ws_url then page = external_link(ws_url, ws_label .. " ", "ws link in page") page = utilities.substitute( cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], L, page} ) coins_pages = ws_label end elseif utilities.is_set(pages) then if utilities.is_set(at) then at = "" end extra_text_in_page_check(pages, pages_orig) ws_url, ws_label, L = wikisource_url_make(pages) if ws_url then pages = external_link(ws_url, ws_label .. " ", "ws link in pages") pages = utilities.substitute( cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], L, pages} ) coins_pages = ws_label end elseif utilities.is_set(at) then ws_url, ws_label, L = wikisource_url_make(at) if ws_url then at = external_link(ws_url, ws_label .. " ", "ws link in at") at = utilities.substitute(cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], L, at}) coins_pages = ws_label end end return page, pages, at, coins_pages end local function is_unique_archive_url(archive, url, c_url, source, date) if utilities.is_set(archive) then if archive == url or archive == c_url then utilities.set_message("err_bad_url", {utilities.wrap_style("parameter", source)}) return "", "" end end return archive, date end local function archive_url_check(url, date) local err_msg = "" local path, timestamp, flag if (not url:match("//web%.archive%.org/")) and (not url:match("//liveweb%.archive%.org/")) then return url, date end if url:match("//web%.archive%.org/save/") then err_msg = cfg.err_msg_supl.save url = url:gsub("(//web%.archive%.org)/save/", "%1/*/", 1) elseif url:match("//liveweb%.archive%.org/") then err_msg = cfg.err_msg_supl.liveweb else path, timestamp, flag = url:match("//web%.archive%.org/([^%d]*)(%d+)([^/]*)/") if not path then err_msg = cfg.err_msg_supl.timestamp elseif 14 ~= timestamp:len() then err_msg = cfg.err_msg_supl.timestamp if "*" ~= flag then local replacement = timestamp:match("^%d%d%d%d%d%d") or timestamp:match("^%d%d%d%d") if replacement then replacement = replacement .. string.rep("0", 14 - replacement:len()) url = url:gsub("(//web%.archive%.org/[^%d]*)%d[^/]*", "%1" .. replacement .. "*", 1) end end elseif utilities.is_set(path) and "web/" ~= path then err_msg = cfg.err_msg_supl.path elseif utilities.is_set(flag) and not utilities.is_set(path) then err_msg = cfg.err_msg_supl.flag elseif utilities.is_set(flag) and not flag:match("%a%a_") then err_msg = cfg.err_msg_supl.flag else return url, date end end utilities.set_message("err_archive_url", {err_msg}) if is_preview_mode then return url, date else return "", "" end end local function place_check(param_val) if not utilities.is_set(param_val) then return param_val end if mw.ustring.find(param_val, "%d") then utilities.set_message("maint_location") end return param_val end local function is_archived_copy(title) title = mw.ustring.lower(title) if title:find(cfg.special_case_translation.archived_copy.en) then return true elseif cfg.special_case_translation.archived_copy["local"] then if mw.ustring.find(title, cfg.special_case_translation.archived_copy["local"]) then return true end end end local function citation0(CitationClass, args) local A = argument_wrapper(args) local i local author_etal local a = {} local Authors local NameListStyle = is_valid_parameter_value( A["NameListStyle"], A:ORIGIN("NameListStyle"), cfg.keywords_lists["name-list-style"], "" ) local Collaboration = A["Collaboration"] do local selected = select_author_editor_source(A["Vauthors"], A["Authors"], args, "AuthorList") if 1 == selected then a, author_etal = extract_names(args, "AuthorList") elseif 2 == selected then NameListStyle = "vanc" a, author_etal = parse_vauthors_veditors(args, args.vauthors, "AuthorList") elseif 3 == selected then Authors = A["Authors"] if "authors" == A:ORIGIN("Authors") then utilities.set_message("maint_authors") end end if utilities.is_set(Collaboration) then author_etal = true end end local editor_etal local e = {} do local selected = select_author_editor_source(A["Veditors"], nil, args, "EditorList") if 1 == selected then e, editor_etal = extract_names(args, "EditorList") elseif 2 == selected then NameListStyle = "vanc" e, editor_etal = parse_vauthors_veditors(args, args.veditors, "EditorList") end end local Chapter = A["Chapter"] local Chapter_origin = A:ORIGIN("Chapter") local Contribution if "contribution" == Chapter_origin then Contribution = Chapter end local c = {} if utilities.in_array(CitationClass, {"book", "citation"}) and not utilities.is_set(A["Periodical"]) then c = extract_names(args, "ContributorList") if 0 < #c then if not utilities.is_set(Contribution) then utilities.set_message("err_contributor_missing_required_param", "contribution") c = {} end if 0 == #a then utilities.set_message("err_contributor_missing_required_param", "author") c = {} end end else if utilities.select_one(args, cfg.aliases["ContributorList-Last"], "err_redundant_parameters", 1) then utilities.set_message("err_contributor_ignored") end Contribution = nil end local Title = A["Title"] local TitleLink = A["TitleLink"] local auto_select = "" local accept_link TitleLink, accept_link = utilities.has_accept_as_written(TitleLink, true) if (not accept_link) and utilities.in_array(TitleLink, {"none", "pmc", "doi"}) then auto_select = TitleLink TitleLink = "" end TitleLink = link_title_ok(TitleLink, A:ORIGIN("TitleLink"), Title, "title") local Section = "" if "map" == CitationClass and "section" == Chapter_origin then Section = A["Chapter"] Chapter = "" end local Periodical = A["Periodical"] local Periodical_origin = "" if utilities.is_set(Periodical) then Periodical_origin = A:ORIGIN("Periodical") local i Periodical, i = utilities.strip_apostrophe_markup(Periodical) if i then utilities.set_message("err_apostrophe_markup", {Periodical_origin}) end end if "mailinglist" == CitationClass then if utilities.is_set(Periodical) and utilities.is_set(A["MailingList"]) then utilities.set_message( "err_redundant_parameters", { utilities.wrap_style("parameter", Periodical_origin) .. " و " .. utilities.wrap_style("parameter", "mailinglist") } ) end Periodical = A["MailingList"] Periodical_origin = A:ORIGIN("MailingList") end local ScriptPeriodical = A["ScriptPeriodical"] if not (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)) then local p = {["journal"] = "journal", ["magazine"] = "magazine"} if p[CitationClass] then utilities.set_message("err_missing_periodical", {CitationClass, p[CitationClass]}) end end local Volume local ScriptPeriodical_origin = A:ORIGIN("ScriptPeriodical") if "citation" == CitationClass then if utilities.is_set(Periodical) then if not utilities.in_array(Periodical_origin, {"website", "mailinglist"}) then Volume = A["Volume"] end elseif utilities.is_set(ScriptPeriodical) then if "script-website" ~= ScriptPeriodical_origin then Volume = A["Volume"] end else Volume = A["Volume"] end elseif utilities.in_array(CitationClass, cfg.templates_using_volume) then Volume = A["Volume"] end extra_text_in_vol_iss_check(Volume, A:ORIGIN("Volume"), "v") local Issue if "citation" == CitationClass then if utilities.is_set(Periodical) and utilities.in_array(Periodical_origin, {"journal", "magazine", "newspaper", "periodical", "work"}) or utilities.is_set(ScriptPeriodical) and utilities.in_array( ScriptPeriodical_origin, {"script-journal", "script-magazine", "script-newspaper", "script-periodical", "script-work"} ) then Issue = utilities.hyphen_to_dash(A["Issue"]) end elseif utilities.in_array(CitationClass, cfg.templates_using_issue) then if not (utilities.in_array(CitationClass, {"conference", "map", "citation"}) and not (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical))) then Issue = utilities.hyphen_to_dash(A["Issue"]) end end extra_text_in_vol_iss_check(Issue, A:ORIGIN("Issue"), "i") local Page local Pages local At if not utilities.in_array(CitationClass, cfg.templates_not_using_page) then Page = A["Page"] Pages = utilities.hyphen_to_dash(A["Pages"]) At = A["At"] end local Edition = A["Edition"] local PublicationPlace = place_check(A["PublicationPlace"], A:ORIGIN("PublicationPlace")) local Place = place_check(A["Place"], A:ORIGIN("Place")) local PublisherName = A["PublisherName"] local PublisherName_origin = A:ORIGIN("PublisherName") if utilities.is_set(PublisherName) then local i = 0 PublisherName, i = utilities.strip_apostrophe_markup(PublisherName) if i then utilities.set_message("err_apostrophe_markup", {PublisherName_origin}) end end local Newsgroup = A["Newsgroup"] local Newsgroup_origin = A:ORIGIN("Newsgroup") if "newsgroup" == CitationClass then if utilities.is_set(PublisherName) then utilities.set_message("err_parameter_ignored", {PublisherName_origin}) end PublisherName = nil end local URL = A["URL"] local UrlAccess = is_valid_parameter_value(A["UrlAccess"], A:ORIGIN("UrlAccess"), cfg.keywords_lists["url-access"], nil) if not utilities.is_set(URL) and utilities.is_set(UrlAccess) then UrlAccess = nil utilities.set_message("err_param_access_requires_param", "url") end local ChapterURL = A["ChapterURL"] local ChapterUrlAccess = is_valid_parameter_value( A["ChapterUrlAccess"], A:ORIGIN("ChapterUrlAccess"), cfg.keywords_lists["url-access"], nil ) if not utilities.is_set(ChapterURL) and utilities.is_set(ChapterUrlAccess) then ChapterUrlAccess = nil utilities.set_message("err_param_access_requires_param", {A:ORIGIN("ChapterUrlAccess"):gsub("%-access", "")}) end local MapUrlAccess = is_valid_parameter_value(A["MapUrlAccess"], A:ORIGIN("MapUrlAccess"), cfg.keywords_lists["url-access"], nil) if not utilities.is_set(A["MapURL"]) and utilities.is_set(MapUrlAccess) then MapUrlAccess = nil utilities.set_message("err_param_access_requires_param", {"map-url"}) end local this_page = mw.title.getCurrentTitle() local no_tracking_cats = is_valid_parameter_value(A["NoTracking"], A:ORIGIN("NoTracking"), cfg.keywords_lists["yes_true_y"], nil) if not utilities.is_set(no_tracking_cats) then if utilities.in_array(this_page.nsText, cfg.uncategorized_namespaces) then no_tracking_cats = "true" end for _, v in ipairs(cfg.uncategorized_subpages) do if this_page.text:match(v) then no_tracking_cats = "true" break end end end utilities.select_one(args, {"page", "p", "pp", "pages", "at", "sheet", "sheets"}, "err_redundant_parameters") local coins_pages Page, Pages, At, coins_pages = insource_loc_get(Page, A:ORIGIN("Page"), Pages, A:ORIGIN("Pages"), At) local NoPP = is_valid_parameter_value(A["NoPP"], A:ORIGIN("NoPP"), cfg.keywords_lists["yes_true_y"], nil) if utilities.is_set(PublicationPlace) and utilities.is_set(Place) then utilities.add_prop_cat("location-test") if PublicationPlace == Place then Place = "" end elseif not utilities.is_set(PublicationPlace) and utilities.is_set(Place) then PublicationPlace = Place end if PublicationPlace == Place then Place = "" end local URL_origin = A:ORIGIN("URL") local ChapterURL_origin = A:ORIGIN("ChapterURL") local ScriptChapter = A["ScriptChapter"] local ScriptChapter_origin = A:ORIGIN("ScriptChapter") local Format = A["Format"] local ChapterFormat = A["ChapterFormat"] local TransChapter = A["TransChapter"] local TransChapter_origin = A:ORIGIN("TransChapter") local TransTitle = A["TransTitle"] local ScriptTitle = A["ScriptTitle"] local Encyclopedia = A["Encyclopedia"] if utilities.is_set(Encyclopedia) then if "encyclopaedia" ~= CitationClass and "citation" ~= CitationClass then utilities.set_message("err_parameter_ignored", {A:ORIGIN("Encyclopedia")}) Encyclopedia = nil end end if ("encyclopaedia" == CitationClass) or ("citation" == CitationClass and utilities.is_set(Encyclopedia)) then if utilities.is_set(Periodical) and utilities.is_set(Encyclopedia) then utilities.set_message( "err_redundant_parameters", { utilities.wrap_style("parameter", A:ORIGIN("Encyclopedia")) .. " و " .. utilities.wrap_style("parameter", Periodical_origin) } ) end if utilities.is_set(Encyclopedia) then Periodical = Encyclopedia Periodical_origin = A:ORIGIN("Encyclopedia") end if utilities.is_set(Periodical) then if utilities.is_set(Title) or utilities.is_set(ScriptTitle) then if not utilities.is_set(Chapter) then Chapter = Title ScriptChapter = ScriptTitle ScriptChapter_origin = A:ORIGIN("ScriptTitle") TransChapter = TransTitle ChapterURL = URL ChapterURL_origin = URL_origin ChapterUrlAccess = UrlAccess if not utilities.is_set(ChapterURL) and utilities.is_set(TitleLink) then Chapter = utilities.make_wikilink(TitleLink, Chapter) end Title = Periodical ChapterFormat = Format Periodical = "" TransTitle = "" URL = "" Format = "" TitleLink = "" ScriptTitle = "" end elseif utilities.is_set(Chapter) or utilities.is_set(ScriptChapter) then Title = Periodical Periodical = "" end end end local ID = A["ID"] if (CitationClass == "techreport") then if utilities.is_set(A["Number"]) then if not utilities.is_set(ID) then ID = A["Number"] else utilities.set_message( "err_redundant_parameters", {utilities.wrap_style("parameter", "id") .. " و " .. utilities.wrap_style("parameter", "number")} ) end end end local ChapterLink local Conference = A["Conference"] local BookTitle = A["BookTitle"] local TransTitle_origin = A:ORIGIN("TransTitle") if "conference" == CitationClass then if utilities.is_set(BookTitle) then Chapter = Title Chapter_origin = "title" ChapterURL = URL ChapterUrlAccess = UrlAccess ChapterURL_origin = URL_origin URL_origin = "" ChapterFormat = Format TransChapter = TransTitle TransChapter_origin = TransTitle_origin Title = BookTitle Format = "" TransTitle = "" URL = "" end elseif "speech" ~= CitationClass then Conference = "" end local Mode = is_valid_parameter_value(A["Mode"], A:ORIGIN("Mode"), cfg.keywords_lists["mode"], "") local sepc, PostScript = set_style(Mode:lower(), A["PostScript"], CitationClass) local use_lowercase = (sepc == ",") local Cartography = "" local Scale = "" local Sheet = A["Sheet"] or "" local Sheets = A["Sheets"] or "" if CitationClass == "map" then if utilities.is_set(Chapter) then utilities.set_message( "err_redundant_parameters", { utilities.wrap_style("parameter", "map") .. " و " .. utilities.wrap_style("parameter", Chapter_origin) } ) end Chapter = A["Map"] Chapter_origin = A:ORIGIN("Map") ChapterURL = A["MapURL"] ChapterURL_origin = A:ORIGIN("MapURL") TransChapter = A["TransMap"] ScriptChapter = A["ScriptMap"] ScriptChapter_origin = A:ORIGIN("ScriptMap") ChapterUrlAccess = MapUrlAccess ChapterFormat = A["MapFormat"] Cartography = A["Cartography"] if utilities.is_set(Cartography) then Cartography = sepc .. " " .. wrap_msg("cartography", Cartography, use_lowercase) end Scale = A["Scale"] if utilities.is_set(Scale) then Scale = sepc .. " " .. Scale end end local Series = A["Series"] if "episode" == CitationClass or "serial" == CitationClass then local SeriesLink = A["SeriesLink"] SeriesLink = link_title_ok(SeriesLink, A:ORIGIN("SeriesLink"), Series, "series") local Network = A["Network"] local Station = A["Station"] local s, n = {}, {} if utilities.is_set(Network) then table.insert(n, Network) end if utilities.is_set(Station) then table.insert(n, Station) end ID = table.concat(n, sepc .. " ") if "episode" == CitationClass then local Season = A["Season"] local SeriesNumber = A["SeriesNumber"] if utilities.is_set(Season) and utilities.is_set(SeriesNumber) then utilities.set_message( "err_redundant_parameters", { utilities.wrap_style("parameter", "season") .. " و " .. utilities.wrap_style("parameter", "seriesno") } ) SeriesNumber = "" end if utilities.is_set(Season) then table.insert(s, wrap_msg("season", Season, use_lowercase)) end if utilities.is_set(SeriesNumber) then table.insert(s, wrap_msg("seriesnum", SeriesNumber, use_lowercase)) end if utilities.is_set(Issue) then table.insert(s, wrap_msg("episode", Issue, use_lowercase)) end Issue = "" Chapter = Title ScriptChapter = ScriptTitle ScriptChapter_origin = A:ORIGIN("ScriptTitle") ChapterLink = TitleLink TransChapter = TransTitle ChapterURL = URL ChapterUrlAccess = UrlAccess ChapterURL_origin = URL_origin Title = Series TitleLink = SeriesLink Series = table.concat(s, sepc .. " ") if utilities.is_set(ChapterLink) and not utilities.is_set(ChapterURL) then Chapter = utilities.make_wikilink(ChapterLink, Chapter) elseif utilities.is_set(ChapterLink) and utilities.is_set(ChapterURL) then Series = utilities.make_wikilink(ChapterLink, Series) end URL = "" TransTitle = "" ScriptTitle = "" else Issue = "" Chapter = A["Episode"] if utilities.is_set(Series) and utilities.is_set(SeriesLink) then Series = utilities.make_wikilink(SeriesLink, Series) end Series = utilities.wrap_style("italic-title", Series) end end local TitleType = A["TitleType"] local Degree = A["Degree"] if utilities.in_array( CitationClass, { "AV-media-notes", "interview", "mailinglist", "map", "podcast", "pressrelease", "report", "speech", "techreport", "thesis" } ) then TitleType = set_titletype(CitationClass, TitleType) if utilities.is_set(Degree) and "Thesis" == TitleType then TitleType = Degree .. " " .. cfg.title_types["thesis"]:lower() end end if utilities.is_set(TitleType) then TitleType = utilities.substitute(cfg.messages["type"], TitleType) end local Date = A["Date"] local Date_origin local PublicationDate = A["PublicationDate"] local Year = A["Year"] if not utilities.is_set(Date) then Date = Year Year = nil if not utilities.is_set(Date) and utilities.is_set(PublicationDate) then Date = PublicationDate PublicationDate = "" Date_origin = A:ORIGIN("PublicationDate") else Date_origin = A:ORIGIN("Year") end else Date_origin = A:ORIGIN("Date") end if PublicationDate == Date then PublicationDate = "" end local DF = is_valid_parameter_value(A["DF"], A:ORIGIN("DF"), cfg.keywords_lists["df"], "") if not utilities.is_set(DF) then DF = cfg.global_df end local ArchiveURL local ArchiveDate local ArchiveFormat = A["ArchiveFormat"] ArchiveURL, ArchiveDate = archive_url_check(A["ArchiveURL"], A["ArchiveDate"]) ArchiveFormat = style_format(ArchiveFormat, ArchiveURL, "archive-format", "archive-url") ArchiveURL, ArchiveDate = is_unique_archive_url(ArchiveURL, URL, ChapterURL, A:ORIGIN("ArchiveURL"), ArchiveDate) local AccessDate = A["AccessDate"] local LayDate = A["LayDate"] local COinS_date = {} local DoiBroken = A["DoiBroken"] local Embargo = A["Embargo"] local anchor_year do local error_message = "" if utilities.is_set(AccessDate) then AccessDate = check_date_n(AccessDate) end if utilities.is_set(ArchiveDate) then ArchiveDate = check_date_n(ArchiveDate) end if utilities.is_set(Date) then Date = check_date_n(Date) end if utilities.is_set(LayDate) then LayDate = check_date_n(LayDate) end if utilities.is_set(PublicationDate) then PublicationDate = check_date_n(PublicationDate) end local date_parameters_list = { ["access-date"] = {val = AccessDate, name = A:ORIGIN("AccessDate")}, ["archive-date"] = {val = ArchiveDate, name = A:ORIGIN("ArchiveDate")}, ["date"] = {val = Date, name = Date_origin}, ["doi-broken-date"] = {val = DoiBroken, name = A:ORIGIN("DoiBroken")}, ["pmc-embargo-date"] = {val = Embargo, name = A:ORIGIN("Embargo")}, ["lay-date"] = {val = LayDate, name = A:ORIGIN("LayDate")}, ["publication-date"] = {val = PublicationDate, name = A:ORIGIN("PublicationDate")}, ["year"] = {val = Year, name = A:ORIGIN("Year")} } --mw.log("AccessDate: " .. AccessDate) local error_list = {} anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list) if COinS_date.inter_cal_cat then utilities.add_prop_cat("jul-greg-uncertainty") end if utilities.is_set(Year) and utilities.is_set(Date) then validation.year_date_check(Year, A:ORIGIN("Year"), Date, A:ORIGIN("Date"), error_list) end if 0 == #error_list then mw.log(" 0 == #error_list" ) local modified = false if utilities.is_set(DF) then mw.log(" start reformat_dates" ) modified = validation.reformat_dates(date_parameters_list, DF) end if true == validation.date_hyphen_to_dash(date_parameters_list) then modified = true utilities.set_message("maint_date_format") end if cfg.date_name_auto_xlate_enable and validation.date_name_xlate(date_parameters_list, cfg.date_digit_auto_xlate_enable) then utilities.set_message("maint_date_auto_xlated") modified = true end if modified then AccessDate = date_parameters_list["access-date"].val ArchiveDate = date_parameters_list["archive-date"].val Date = date_parameters_list["date"].val DoiBroken = date_parameters_list["doi-broken-date"].val LayDate = date_parameters_list["lay-date"].val PublicationDate = date_parameters_list["publication-date"].val end else utilities.set_message("err_bad_date", {utilities.make_sep_list(#error_list, error_list)}) end end local ID_list = {} local ID_list_coins = {} local Class = A["Class"] local ID_support = { {A["ASINTLD"], "ASIN", "err_asintld_missing_asin", A:ORIGIN("ASINTLD")}, {DoiBroken, "DOI", "err_doibroken_missing_doi", A:ORIGIN("DoiBroken")}, {Embargo, "PMC", "err_embargo_missing_pmc", A:ORIGIN("Embargo")} } ID_list, ID_list_coins = identifiers.identifier_lists_get( args, {DoiBroken = DoiBroken, ASINTLD = A["ASINTLD"], Embargo = Embargo, Class = Class}, ID_support ) if utilities.in_array(CitationClass, whitelist.preprint_template_list) then if not utilities.is_set(ID_list_coins[CitationClass:upper()]) then utilities.set_message("err_" .. CitationClass .. "_missing") end Periodical = ({ ["arxiv"] = "arXiv", ["biorxiv"] = "bioRxiv", ["citeseerx"] = "CiteSeerX", ["ssrn"] = "Social Science Research Network" })[CitationClass] end if CitationClass == "journal" and not utilities.is_set(URL) and not utilities.is_set(TitleLink) and not utilities.in_array(cfg.keywords_xlate[Title], {"off", "none"}) then if "none" ~= cfg.keywords_xlate[auto_select] then if identifiers.auto_link_urls[auto_select] then URL = identifiers.auto_link_urls[auto_select] URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1] elseif identifiers.auto_link_urls["pmc"] then URL = identifiers.auto_link_urls["pmc"] URL_origin = cfg.id_handlers["PMC"].parameters[1] elseif identifiers.auto_link_urls["doi"] then URL = identifiers.auto_link_urls["doi"] URL_origin = cfg.id_handlers["DOI"].parameters[1] end end if utilities.is_set(URL) and utilities.is_set(AccessDate) then utilities.set_message("err_accessdate_missing_url") AccessDate = "" end end if not utilities.is_set(Title) and not utilities.is_set(TransTitle) and not utilities.is_set(ScriptTitle) then utilities.set_message("err_citation_missing_title", {"episode" == CitationClass and "series" or "title"}) end if utilities.in_array(cfg.keywords_xlate[Title], {"off", "none"}) and utilities.in_array(CitationClass, {"journal", "citation"}) and (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)) and ("journal" == Periodical_origin or "script-journal" == ScriptPeriodical_origin) then Title = "" utilities.set_message("maint_untitled") end local coins_chapter = Chapter local coins_title = Title if "encyclopaedia" == CitationClass or ("citation" == CitationClass and utilities.is_set(Encyclopedia)) then if utilities.is_set(Chapter) and utilities.is_set(Title) and utilities.is_set(Periodical) then coins_chapter = Title coins_title = Periodical end end local coins_author = a if 0 < #c then coins_author = c end local QuotePage = A["QuotePage"] local QuotePages = utilities.hyphen_to_dash(A["QuotePages"]) local OCinSoutput = metadata.COinS( { ["Periodical"] = utilities.strip_apostrophe_markup(Periodical), ["Encyclopedia"] = Encyclopedia, ["Chapter"] = metadata.make_coins_title(coins_chapter, ScriptChapter), ["Degree"] = Degree, ["Title"] = metadata.make_coins_title(coins_title, ScriptTitle), ["PublicationPlace"] = PublicationPlace, ["Date"] = COinS_date.rftdate, ["Season"] = COinS_date.rftssn, ["Quarter"] = COinS_date.rftquarter, ["Chron"] = COinS_date.rftchron or (not COinS_date.rftdate and Date) or "", ["Series"] = Series, ["Volume"] = Volume, ["Issue"] = Issue, ["Pages"] = coins_pages or metadata.get_coins_pages(first_set({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), ["Edition"] = Edition, ["PublisherName"] = PublisherName or Newsgroup, ["URL"] = first_set({ChapterURL, URL}, 2), ["Authors"] = coins_author, ["ID_list"] = ID_list_coins, ["RawPage"] = this_page.prefixedText }, CitationClass ) if utilities.in_array(CitationClass, whitelist.preprint_template_list) then Periodical = "" end if "newsgroup" == CitationClass and utilities.is_set(Newsgroup) then PublisherName = utilities.substitute( cfg.messages["newsgroup"], external_link("news:" .. Newsgroup, Newsgroup, Newsgroup_origin, nil) ) end local Editors local EditorCount local Contributors local contributor_etal local Translators local translator_etal local t = {} t = extract_names(args, "TranslatorList") local Interviewers local interviewers_list = {} interviewers_list = extract_names(args, "InterviewerList") local interviewer_etal do local last_first_list local control = { format = NameListStyle, maximum = nil, mode = Mode } do control.maximum, editor_etal = get_display_names(A["DisplayEditors"], #e, "editors", editor_etal, A:ORIGIN("DisplayEditors")) Editors, EditorCount = list_people(control, e, editor_etal) if 1 == EditorCount and (true == editor_etal or 1 < #e) then EditorCount = 2 end end do control.maximum, interviewer_etal = get_display_names( A["DisplayInterviewers"], #interviewers_list, "interviewers", interviewer_etal, A:ORIGIN("DisplayInterviewers") ) Interviewers = list_people(control, interviewers_list, interviewer_etal) end do control.maximum, translator_etal = get_display_names( A["DisplayTranslators"], #t, "translators", translator_etal, A:ORIGIN("DisplayTranslators") ) Translators = list_people(control, t, translator_etal) end do control.maximum, contributor_etal = get_display_names( A["DisplayContributors"], #c, "contributors", contributor_etal, A:ORIGIN("DisplayContributors") ) Contributors = list_people(control, c, contributor_etal) end do control.maximum, author_etal = get_display_names(A["DisplayAuthors"], #a, "authors", author_etal, A:ORIGIN("DisplayAuthors")) last_first_list = list_people(control, a, author_etal) if utilities.is_set(Authors) then Authors, author_etal = name_has_etal(Authors, author_etal, false, "authors") if author_etal then Authors = Authors .. " " .. cfg.messages["et al"] end else Authors = last_first_list end end if utilities.is_set(Authors) and utilities.is_set(Collaboration) then Authors = Authors .. " (" .. Collaboration .. ")" end end local ConferenceFormat = A["ConferenceFormat"] local ConferenceURL = A["ConferenceURL"] ConferenceFormat = style_format(ConferenceFormat, ConferenceURL, "conference-format", "conference-url") Format = style_format(Format, URL, "format", "url") if not (utilities.in_array( CitationClass, { "web", "news", "journal", "magazine", "pressrelease", "podcast", "newsgroup", "arxiv", "biorxiv", "citeseerx", "ssrn" } ) or ("citation" == CitationClass and (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)) and not utilities.is_set(Encyclopedia))) then ChapterFormat = style_format(ChapterFormat, ChapterURL, "chapter-format", "chapter-url") end if not utilities.is_set(URL) then if utilities.in_array(CitationClass, {"web", "podcast", "mailinglist"}) or ("citation" == CitationClass and ("website" == Periodical_origin or "script-website" == ScriptPeriodical_origin)) then utilities.set_message("err_cite_web_url") end if utilities.is_set(AccessDate) and not utilities.is_set(ChapterURL) then utilities.set_message("err_accessdate_missing_url") AccessDate = "" end end local UrlStatus = is_valid_parameter_value(A["UrlStatus"], A:ORIGIN("UrlStatus"), cfg.keywords_lists["url-status"], "") local OriginalURL local OriginalURL_origin local OriginalFormat local OriginalAccess UrlStatus = UrlStatus:lower() if utilities.is_set(ArchiveURL) then if utilities.is_set(ChapterURL) then OriginalURL = ChapterURL OriginalURL_origin = ChapterURL_origin OriginalFormat = ChapterFormat if "live" ~= UrlStatus then ChapterURL = ArchiveURL ChapterURL_origin = A:ORIGIN("ArchiveURL") ChapterFormat = ArchiveFormat or "" ChapterUrlAccess = nil end elseif utilities.is_set(URL) then OriginalURL = URL OriginalURL_origin = URL_origin OriginalFormat = Format OriginalAccess = UrlAccess if "live" ~= UrlStatus then URL = ArchiveURL URL_origin = A:ORIGIN("ArchiveURL") Format = ArchiveFormat or "" UrlAccess = nil end end elseif utilities.is_set(UrlStatus) then utilities.set_message("maint_url_status") end if utilities.in_array( CitationClass, { "web", "news", "journal", "magazine", "pressrelease", "podcast", "newsgroup", "arxiv", "biorxiv", "citeseerx", "ssrn" } ) or ("citation" == CitationClass and (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)) and not utilities.is_set(Encyclopedia)) then local chap_param if utilities.is_set(Chapter) then chap_param = A:ORIGIN("Chapter") elseif utilities.is_set(TransChapter) then chap_param = A:ORIGIN("TransChapter") elseif utilities.is_set(ChapterURL) then chap_param = A:ORIGIN("ChapterURL") elseif utilities.is_set(ScriptChapter) then chap_param = ScriptChapter_origin else utilities.is_set(ChapterFormat) chap_param = A:ORIGIN("ChapterFormat") end if utilities.is_set(chap_param) then utilities.set_message("err_chapter_ignored", {chap_param}) Chapter = "" TransChapter = "" ChapterURL = "" ScriptChapter = "" ChapterFormat = "" end else local no_quotes = false if utilities.is_set(Contribution) and 0 < #c then if utilities.in_array(Contribution:lower(), cfg.keywords_lists.contribution) then no_quotes = true end end Chapter = format_chapter_title( ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess ) if utilities.is_set(Chapter) then Chapter = Chapter .. ChapterFormat if "map" == CitationClass and utilities.is_set(TitleType) then Chapter = Chapter .. " " .. TitleType end Chapter = Chapter .. sepc .. " " elseif utilities.is_set(ChapterFormat) then Chapter = ChapterFormat .. sepc .. " " end end local plain_title = false local accept_title Title, accept_title = utilities.has_accept_as_written(Title, true) if accept_title and ("" == Title) then Title = cfg.messages["notitle"] ScriptTitle = "" TransTitle = "" plain_title = true utilities.set_message("maint_untitled") end if not accept_title then if "..." == Title:sub(-3) then Title = Title:gsub("(%.%.%.)%.+$", "%1") elseif not mw.ustring.find(Title, "%.%s*%a%.$") and not mw.ustring.find(Title, "%s+%a%.$") then Title = mw.ustring.gsub(Title, "%" .. sepc .. "$", "") end if utilities.is_set(ArchiveURL) and is_archived_copy(Title) then utilities.set_message("maint_archived_copy") end if is_generic("generic_titles", Title) then utilities.set_message("err_generic_title") end end if (not plain_title) and (utilities.in_array( CitationClass, { "web", "news", "journal", "magazine", "pressrelease", "podcast", "newsgroup", "mailinglist", "interview", "arxiv", "biorxiv", "citeseerx", "ssrn" } ) or ("citation" == CitationClass and (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)) and not utilities.is_set(Encyclopedia)) or ("map" == CitationClass and (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical)))) then Title = kern_quotes(Title) Title = utilities.wrap_style("quoted-title", Title) Title = script_concatenate(Title, ScriptTitle, "script-title") TransTitle = utilities.wrap_style("trans-quoted-title", TransTitle) elseif plain_title or ("report" == CitationClass) then Title = script_concatenate(Title, ScriptTitle, "script-title") TransTitle = utilities.wrap_style("trans-quoted-title", TransTitle) else Title = utilities.wrap_style("italic-title", Title) Title = script_concatenate(Title, ScriptTitle, "script-title") TransTitle = utilities.wrap_style("trans-italic-title", TransTitle) end if utilities.is_set(TransTitle) then if utilities.is_set(Title) then TransTitle = " " .. TransTitle else utilities.set_message("err_trans_missing_title", {"title"}) end end if utilities.is_set(Title) then if utilities.is_set(TitleLink) and utilities.is_set(URL) then utilities.set_message("err_wikilink_in_url") TitleLink = "" end if not utilities.is_set(TitleLink) and utilities.is_set(URL) then Title = external_link(URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format URL = "" Format = "" elseif utilities.is_set(TitleLink) and not utilities.is_set(URL) then local ws_url ws_url = wikisource_url_make(TitleLink) if ws_url then Title = external_link(ws_url, Title .. " ", "ws link in title-link") Title = utilities.substitute( cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], TitleLink, Title} ) Title = Title .. TransTitle else Title = utilities.make_wikilink(TitleLink, Title) .. TransTitle end else local ws_url, ws_label, L ws_url, ws_label, L = wikisource_url_make(Title:gsub('^[\'"]*(.-)[\'"]*$', "%1")) if ws_url then Title = Title:gsub("%b[]", ws_label) Title = external_link(ws_url, Title .. " ", "ws link in title") Title = utilities.substitute( cfg.presentation["interwiki-icon"], {cfg.presentation["class-wikisource"], L, Title} ) Title = Title .. TransTitle else Title = Title .. TransTitle end end else Title = TransTitle end if utilities.is_set(Place) then Place = " " .. wrap_msg("written", Place, use_lowercase) .. sepc .. " " end local ConferenceURL_origin = A:ORIGIN("ConferenceURL") if utilities.is_set(Conference) then if utilities.is_set(ConferenceURL) then Conference = external_link(ConferenceURL, Conference, ConferenceURL_origin, nil) end Conference = sepc .. " " .. Conference .. ConferenceFormat elseif utilities.is_set(ConferenceURL) then Conference = sepc .. " " .. external_link(ConferenceURL, nil, ConferenceURL_origin, nil) end local Position = "" if not utilities.is_set(Position) then local Minutes = A["Minutes"] local Time = A["Time"] if utilities.is_set(Minutes) then if utilities.is_set(Time) then utilities.set_message( "err_redundant_parameters", { utilities.wrap_style("parameter", "minutes") .. " و " .. utilities.wrap_style("parameter", "time") } ) end Position = " " .. Minutes .. " " .. cfg.messages["minutes"] else if utilities.is_set(Time) then local TimeCaption = A["TimeCaption"] if not utilities.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 Page, Pages, Sheet, Sheets = format_pages_sheets( Page, Pages, Sheet, Sheets, CitationClass, Periodical_origin, sepc, NoPP, use_lowercase ) At = utilities.is_set(At) and (sepc .. " " .. At) or "" Position = utilities.is_set(Position) and (sepc .. " " .. Position) or "" if CitationClass == "map" then local Sections = A["Sections"] local Inset = A["Inset"] if utilities.is_set(Inset) then Inset = sepc .. " " .. wrap_msg("inset", Inset, use_lowercase) end if utilities.is_set(Sections) then Section = sepc .. " " .. wrap_msg("sections", Sections, use_lowercase) elseif utilities.is_set(Section) then Section = sepc .. " " .. wrap_msg("section", Section, use_lowercase) end At = At .. Inset .. Section end local Others = A["Others"] if utilities.is_set(Others) and 0 == #a and 0 == #e then if CitationClass == "AV-media-notes" or CitationClass == "audio-visual" then utilities.set_message("maint_others_avm") else utilities.set_message("maint_others") end end Others = utilities.is_set(Others) and (sepc .. " " .. Others) or "" if utilities.is_set(Translators) then Others = safe_join({sepc .. " ", wrap_msg("translated", Translators, use_lowercase), Others}, sepc) end if utilities.is_set(Interviewers) then Others = safe_join({sepc .. " ", wrap_msg("interview", Interviewers, use_lowercase), Others}, sepc) end local TitleNote = A["TitleNote"] TitleNote = utilities.is_set(TitleNote) and (sepc .. " " .. TitleNote) or "" if utilities.is_set(Edition) then if Edition:match("%f[%a][Ee]d%n?%.?$") or Edition:match("%f[%a][Ee]dition$") then utilities.set_message("err_extra_text_edition") end Edition = " " .. wrap_msg("edition", Edition) else Edition = "" end Series = utilities.is_set(Series) and wrap_msg("series", {sepc, Series}) or "" local Agency = A["Agency"] Agency = utilities.is_set(Agency) and wrap_msg("agency", {sepc, Agency}) or "" Volume = format_volume_issue(Volume, Issue, CitationClass, Periodical_origin, sepc, use_lowercase) if utilities.is_set(AccessDate) then local retrv_text = " " .. cfg.messages["retrieved"] --AccessDate = check_date_n(AccessDate) AccessDate = nowrap_date(AccessDate) --if (sepc ~= ".") then retrv_text = retrv_text:lower() end AccessDate = utilities.substitute(retrv_text, AccessDate) AccessDate = utilities.substitute(cfg.presentation["accessdate"], {sepc, AccessDate}) end if utilities.is_set(ID) then ID = sepc .. " " .. ID end local Docket = A["Docket"] if "thesis" == CitationClass and utilities.is_set(Docket) then ID = sepc .. " Docket " .. Docket .. ID end if "report" == CitationClass and utilities.is_set(Docket) then ID = sepc .. " " .. Docket end if utilities.is_set(URL) then URL = " " .. external_link(URL, nil, URL_origin, UrlAccess) end local Quote = A["Quote"] local TransQuote = A["TransQuote"] local ScriptQuote = A["ScriptQuote"] if utilities.is_set(Quote) or utilities.is_set(TransQuote) or utilities.is_set(ScriptQuote) then if utilities.is_set(Quote) then if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then Quote = Quote:sub(2, -2) end end Quote = utilities.wrap_style("quoted-text", Quote) if utilities.is_set(ScriptQuote) then Quote = script_concatenate(Quote, ScriptQuote, "script-quote") end if utilities.is_set(TransQuote) then if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then TransQuote = TransQuote:sub(2, -2) end Quote = Quote .. " " .. utilities.wrap_style("trans-quoted-title", TransQuote) end if utilities.is_set(QuotePage) or utilities.is_set(QuotePages) then local quote_prefix = "" if utilities.is_set(QuotePage) then extra_text_in_page_check(QuotePage, "quote-page") if not NoPP then quote_prefix = utilities.substitute(cfg.messages["p-prefix"], {sepc, QuotePage}), "", "", "" else quote_prefix = utilities.substitute(cfg.messages["nopp"], {sepc, QuotePage}), "", "", "" end elseif utilities.is_set(QuotePages) then extra_text_in_page_check(QuotePages, "quote-pages") if tonumber(QuotePages) ~= nil and not NoPP then quote_prefix = utilities.substitute(cfg.messages["p-prefix"], {sepc, QuotePages}), "", "" elseif not NoPP then quote_prefix = utilities.substitute(cfg.messages["pp-prefix"], {sepc, QuotePages}), "", "" else quote_prefix = utilities.substitute(cfg.messages["nopp"], {sepc, QuotePages}), "", "" end end Quote = quote_prefix .. ": " .. Quote else Quote = sepc .. " " .. Quote end PostScript = "" end if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then utilities.set_message("maint_postscript") end local Archived if utilities.is_set(ArchiveURL) then local arch_text if not utilities.is_set(ArchiveDate) then utilities.set_message("err_archive_missing_date") ArchiveDate = "" --else --ArchiveDate = check_date_n(ArchiveDate) end if "live" == UrlStatus then arch_text = cfg.messages["archived"] --if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set(ArchiveDate) then Archived = sepc .. " " .. utilities.substitute( cfg.messages["archived-live"], { external_link(ArchiveURL, arch_text, A:ORIGIN("ArchiveURL"), nil) .. ArchiveFormat, ArchiveDate } ) else Archived = "" end if not utilities.is_set(OriginalURL) then utilities.set_message("err_archive_missing_url") Archived = "" end elseif utilities.is_set(OriginalURL) then if utilities.in_array(UrlStatus, {"unfit", "usurped", "bot: unknown"}) then arch_text = cfg.messages["archived-unfit"] --if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. " " .. arch_text .. ArchiveDate if "bot: unknown" == UrlStatus then utilities.set_message("maint_bot_unknown") else utilities.set_message("maint_unfit") end else arch_text = cfg.messages["archived-dead"] --if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set(ArchiveDate) then Archived = sepc .. " " .. utilities.substitute( arch_text, { external_link( OriginalURL, cfg.messages["original"], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ) else Archived = "" end end else arch_text = cfg.messages["archived-missing"] --if sepc ~= "." then arch_text = arch_text:lower() end utilities.set_message("err_archive_missing_url") Archived = "" end elseif utilities.is_set(ArchiveFormat) then Archived = ArchiveFormat else Archived = "" end local Lay = "" local LaySource = A["LaySource"] local LayURL = A["LayURL"] local LayFormat = A["LayFormat"] LayFormat = style_format(LayFormat, LayURL, "lay-format", "lay-url") if utilities.is_set(LayURL) then if utilities.is_set(LayDate) then LayDate = " (" .. LayDate .. ")" end if utilities.is_set(LaySource) then LaySource = " – ''" .. utilities.safe_for_italics(LaySource) .. "''" else LaySource = "" end if sepc == "." then Lay = sepc .. " " .. external_link(LayURL, cfg.messages["lay summary"], A:ORIGIN("LayURL"), nil) .. LayFormat .. LaySource .. LayDate else Lay = sepc .. " " .. external_link(LayURL, cfg.messages["lay summary"]:lower(), A:ORIGIN("LayURL"), nil) .. LayFormat .. LaySource .. LayDate end elseif utilities.is_set(LayFormat) then Lay = sepc .. LayFormat end local TranscriptURL = A["TranscriptURL"] local TranscriptFormat = A["TranscriptFormat"] TranscriptFormat = style_format(TranscriptFormat, TranscriptURL, "transcript-format", "transcripturl") local Transcript = A["Transcript"] local TranscriptURL_origin = A:ORIGIN("TranscriptURL") if utilities.is_set(Transcript) then if utilities.is_set(TranscriptURL) then Transcript = external_link(TranscriptURL, Transcript, TranscriptURL_origin, nil) end Transcript = sepc .. " " .. Transcript .. TranscriptFormat elseif utilities.is_set(TranscriptURL) then Transcript = external_link(TranscriptURL, nil, TranscriptURL_origin, nil) end local Publisher if utilities.is_set(PublicationDate) then -- PublicationDate = wrap_msg("published", PublicationDate) PublicationDate = "تاريخ النشر: ".. PublicationDate end if utilities.is_set(PublisherName) then if utilities.is_set(PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. "، " .. PublicationDate else Publisher = sepc .. " " .. PublisherName .. "، " .. PublicationDate end elseif utilities.is_set(PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. "، " .. PublicationDate else Publisher = PublicationDate end local TransPeriodical = A["TransPeriodical"] local TransPeriodical_origin = A:ORIGIN("TransPeriodical") if (utilities.is_set(Periodical) or utilities.is_set(ScriptPeriodical) or utilities.is_set(TransPeriodical)) then if utilities.is_set(Title) or utilities.is_set(TitleNote) then Periodical = sepc .. " " .. format_periodical( ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin ) else Periodical = format_periodical( ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin ) end end local Language = A["Language"] if utilities.is_set(Language) then Language = language_parameter(Language) else Language = "" end if "speech" == CitationClass then TitleNote = TitleType TitleType = "" if utilities.is_set(Periodical) then if utilities.is_set(Conference) then Conference = Conference .. sepc .. " " end end end local tcommon local tcommon2 if utilities.in_array(CitationClass, {"journal", "citation"}) and utilities.is_set(Periodical) then if utilities.is_set(Others) then Others = safe_join({Others, sepc .. " "}, sepc) end tcommon = safe_join( { Others, Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Edition, Publisher, Agency, Volume }, sepc ) elseif utilities.in_array(CitationClass, {"book", "citation"}) and not utilities.is_set(Periodical) then if utilities.is_set(Contributors) then tcommon = safe_join({Title, TitleNote}, sepc) tcommon2 = safe_join( { Conference, Periodical, Format, TitleType, Series, Language, Others, Edition, Publisher, Agency, Volume }, sepc ) else tcommon = safe_join( { Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Others, Edition, Publisher, Agency, Volume }, sepc ) end elseif "map" == CitationClass then if utilities.is_set(Chapter) then tcommon = safe_join( {Title, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ) elseif utilities.is_set(Periodical) then tcommon = safe_join( {Title, TitleType, Format, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc ) else tcommon = safe_join( {Title, TitleType, Format, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc ) end elseif "episode" == CitationClass then tcommon = safe_join({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc) else tcommon = safe_join( { Title, TitleNote, Conference, Periodical, Format, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency }, sepc ) end if #ID_list > 0 then ID_list = safe_join({sepc .. " ", table.concat(ID_list, sepc .. " "), ID}, sepc) else ID_list = ID end local Via = A["Via"] Via = utilities.is_set(Via) and wrap_msg("via", Via) or "" local idcommon if "audio-visual" == CitationClass or "episode" == CitationClass then idcommon = safe_join({ID_list, URL, Archived, Transcript, AccessDate, Via, Lay, Quote}, sepc) else idcommon = safe_join({ID_list, URL, Archived, AccessDate, Via, Lay, Quote}, sepc) end local text local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At local OrigDate = A["OrigDate"] OrigDate = utilities.is_set(OrigDate) and wrap_msg("origdate", OrigDate) or "" if utilities.is_set(Date) then if utilities.is_set(Authors) or utilities.is_set(Editors) then Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " " else if (string.sub(tcommon, -1, -1) == sepc) then Date = " " .. Date .. OrigDate else Date = sepc .. " " .. Date .. OrigDate end end end if utilities.is_set(Authors) then if (not utilities.is_set(Date)) then Authors = terminate_name_list(Authors, sepc) end if utilities.is_set(Editors) then local in_text = " " local post_text = "" if utilities.is_set(Chapter) and 0 == #c then in_text = in_text .. cfg.messages["in"] .. " " --if (sepc ~= ".") then in_text = in_text:lower() end end if EditorCount <= 1 then post_text = " (" .. cfg.messages["editor"] .. ")" else post_text = " (" .. cfg.messages["editors"] .. ")" end Editors = terminate_name_list(in_text .. Editors .. post_text, sepc) end if utilities.is_set(Contributors) then local by_text = sepc .. " " .. cfg.messages["by"] .. " " --if (sepc ~= ".") then by_text = by_text:lower() end Authors = by_text .. Authors if utilities.is_set(Editors) and utilities.is_set(Date) then Authors = terminate_name_list(Authors, sepc) end if (not utilities.is_set(Date)) then Contributors = terminate_name_list(Contributors, sepc) end text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon}, sepc ) else text = safe_join({Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon}, sepc) end elseif utilities.is_set(Editors) then if utilities.is_set(Date) then if EditorCount <= 1 then Editors = Editors .. ", " .. cfg.messages["editor"] else Editors = Editors .. ", " .. cfg.messages["editors"] end else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages["editor"] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages["editors"] .. ")" .. sepc .. " " end end text = safe_join({Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc) else if utilities.in_array(CitationClass, {"journal", "citation"}) and utilities.is_set(Periodical) then text = safe_join({Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc) else text = safe_join({Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc) end end if utilities.is_set(PostScript) and PostScript ~= sepc then text = safe_join({text, sepc}, sepc) text = text:sub(1, -sepc:len() - 1) end text = safe_join({text, PostScript}, sepc) local options_t = {} options_t.class = cite_class_attribute_make(CitationClass, Mode) local Ref = is_valid_parameter_value(A["Ref"], A:ORIGIN("Ref"), cfg.keywords_lists["ref"], nil, true) if "none" ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ""] then local namelist_t = {} local year = first_set({Year, anchor_year}, 2) if #c > 0 then namelist_t = c elseif #a > 0 then namelist_t = a elseif #e > 0 then namelist_t = e end local citeref_id if #namelist_t > 0 then citeref_id = make_citeref_id(namelist_t, year) if mw.uri.anchorEncode(citeref_id) == ((Ref and mw.uri.anchorEncode(Ref)) or "") then utilities.set_message("maint_ref_duplicates_default") end else citeref_id = "" end options_t.id = Ref or citeref_id end if string.len(text:gsub("%b<>", "")) <= 2 then z.error_cats_t = {} z.error_msgs_t = {} OCinSoutput = nil text = "" utilities.set_message("err_empty_citation") end local render_t = {} if utilities.is_set(options_t.id) then table.insert( render_t, utilities.substitute( cfg.presentation["cite-id"], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text} ) ) else table.insert(render_t, utilities.substitute(cfg.presentation["cite"], {mw.text.nowiki(options_t.class), text})) end if OCinSoutput then table.insert(render_t, utilities.substitute(cfg.presentation["ocins"], OCinSoutput)) end local template_name = ("citation" == CitationClass) and "citation" or "cite " .. (cfg.citation_class_map_t[CitationClass] or CitationClass) template_name = cfg.ar_temps_names[template_name:lower()] or template_name local template_link = "[[Template:" .. template_name .. "|" .. template_name .. "]]" local msg_prefix = '<code class="cs1-code">{{' .. template_link .. "}}</code>: " if 0 ~= #z.error_msgs_t then mw.addWarning(utilities.substitute(cfg.messages.warning_msg_e, template_link)) table.insert(render_t, " ") table.sort(z.error_msgs_t) local hidden = true for _, v in ipairs(z.error_msgs_t) do if v:find("cs1-visible-error", 1, true) then hidden = false break end end z.error_msgs_t[1] = table.concat({utilities.error_comment(msg_prefix, hidden), z.error_msgs_t[1]}) table.insert(render_t, table.concat(z.error_msgs_t, "، ")) end if 0 ~= #z.maint_cats_t then mw.addWarning(utilities.substitute(cfg.messages.warning_msg_m, template_link)) table.sort(z.maint_cats_t) local maint_msgs_t = {} if 0 == #z.error_msgs_t then table.insert(maint_msgs_t, msg_prefix) end for _, v in ipairs(z.maint_cats_t) do table.insert( maint_msgs_t, table.concat({v, " (", utilities.substitute(cfg.messages[":cat wikilink"], v), ")"}) ) end table.insert(render_t, utilities.substitute(cfg.presentation["hidden-maint"], table.concat(maint_msgs_t, " "))) end if not no_tracking_cats then for _, v in ipairs(z.error_cats_t) do table.insert(render_t, utilities.substitute(cfg.messages["cat wikilink"], v)) end for _, v in ipairs(z.maint_cats_t) do table.insert(render_t, utilities.substitute(cfg.messages["cat wikilink"], v)) end for _, v in ipairs(z.prop_cats_t) do table.insert(render_t, utilities.substitute(cfg.messages["cat wikilink"], v)) end end return table.concat(render_t) end local function validate(name, cite_class, empty) local name = tostring(name) local enum_name local state local function state_test(state, name) if true == state then return true end if false == state then if empty then return nil end deprecated_parameter(name) return true end if "tracked" == state then local base_name = name:gsub("%d", "") utilities.add_prop_cat("tracked-param", {base_name}, base_name) return true end return nil end if name:find("#") then return nil end if utilities.in_array(cite_class, whitelist.preprint_template_list) then state = whitelist.limited_basic_arguments[name] if true == state_test(state, name) then return true end state = whitelist.preprint_arguments[cite_class][name] if true == state_test(state, name) then return true end enum_name = name:gsub("%d+", "#") state = whitelist.limited_numbered_arguments[enum_name] if true == state_test(state, name) then return true end return false end if utilities.in_array(cite_class, whitelist.unique_param_template_list) then state = whitelist.unique_arguments[cite_class][name] if true == state_test(state, name) then return true end end state = whitelist.basic_arguments[name] if true == state_test(state, name) then return true end enum_name = name:gsub("%d+", "#") state = whitelist.numbered_arguments[enum_name] if true == state_test(state, name) then return true end --mw.log('validate(' .. name .. ', cite_class, empty) == false') return false end local function inter_wiki_check(parameter, value) local prefix = value:match("%[%[(%a+):") local _ if prefix and cfg.inter_wiki_map[prefix:lower()] then utilities.set_message("err_bad_paramlink", parameter) _, value, _ = utilities.is_wikilink(value) end return value end local function missing_pipe_check(parameter, value) local capture value = value:gsub("%b<>", "") capture = value:match("%s+(%a[%w%-]+)%s*=") or value:match("^(%a[%w%-]+)%s*=") if capture and validate(capture) then utilities.set_message("err_missing_pipe", parameter) end end local function has_extraneous_punc(param, value) if "number" == type(param) then return end param = param:gsub("%d+", "#") if cfg.punct_skip[param] then return end if value:match("[,;:]$") then utilities.set_message("maint_extra_punct") end if value:match("^=") then utilities.set_message("maint_extra_punct") end end local function has_extraneous_url(url_param_t) local url_error_t = {} check_for_url(url_param_t, url_error_t) if 0 ~= #url_error_t then table.sort(url_error_t) utilities.set_message("err_param_has_ext_link", {utilities.make_sep_list(#url_error_t, url_error_t)}) end end local function citation(frame) Frame = frame; -- save a copy in case we need to display an error message in preview mode is_sandbox = nil ~= string.find (frame:getTitle(), 'sandbox', 1, true); local pframe = frame:getParent() local styles; if is_sandbox then -- did the {{#invoke:}} use sandbox version? --mw.log('sandbox') cfg = mw.loadData ('Module:Citation/CS1/Configuration/sandbox'); -- load sandbox versions of support modules whitelist = mw.loadData ('Module:Citation/CS1/Whitelist/sandbox'); utilities = require ('Module:Citation/CS1/Utilities/sandbox'); validation = require ('Module:Citation/CS1/Date_validation/sandbox'); identifiers = require ('Module:Citation/CS1/Identifiers/sandbox'); metadata = require ('Module:Citation/CS1/COinS/sandbox'); styles = 'Module:Citation/CS1/sandbox/styles.css'; else -- otherwise cfg = mw.loadData ('Module:Citation/CS1/Configuration'); -- load live versions of support modules whitelist = mw.loadData ('Module:Citation/CS1/Whitelist'); utilities = require ('Module:Citation/CS1/Utilities'); validation = require ('Module:Citation/CS1/Date_validation'); identifiers = require ('Module:Citation/CS1/Identifiers'); metadata = require ('Module:Citation/CS1/COinS'); styles = 'Module:Citation/CS1/styles.css'; end utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}')); local allargs = {}; -- table where we store all of the template's arguments local args = {}; -- table where we store all of the template's arguments local suggestions = {}; -- table where we store suggestions if we need to loadData them local error_text; -- used as a flag if is_sandbox then -- did the {{#invoke:}} use sandbox version? suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions/sandbox' ); -- use the sandbox version else suggestions = mw.loadData( 'Module:Citation/CS1/Suggestions' ); -- use the live version end local config = {}; -- table to store parameters from the module {{#invoke:}} for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame if k == "CitationClass" then config[k] = v; else --k = suggestions.suggestions[k] or k allargs[k] = v; end end -- table to store parameters from the module {{#invoke:}} for yk, vy in pairs( pframe.args ) do if yk ~= "وصلة مكسورة" then --yk = suggestions.suggestions[yk] or yk args[yk] = vy; allargs[yk] = vy; end end local CitationClass = config.CitationClass local capture; -- the single supported capture when matching unknown parameters using patterns local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing for k, v in pairs( allargs ) do -- get parameters from the parent (template) frame v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string if v ~= '' then if ('string' == type (k)) then k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9 end if not validate( k, CitationClass ) then --mw.log('not validate( k, CitationClass )' .. k ) if type (k) ~= 'string' then -- exclude empty numbered parameters if v:match("%S+") ~= nil then error_text = utilities.set_message ('err_text_ignored', {v}); end elseif validate(k:lower(), CitationClass) then --error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter else for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match(pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate(param, CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) --error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message else error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template v = ''; -- unset end end end if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion? if (suggestions.suggestions[ k:lower() ] ~= nil) and validate(suggestions.suggestions[ k:lower() ], CitationClass) then --utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]}); else utilities.set_message ('err_parameter_ignored', {k}); v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists) end end end end args[k] = v; -- save this parameter and its value elseif not utilities.is_set (v) then -- for empty parameters if not validate(k, CitationClass, true) then -- is this empty parameter a valid parameter local valid = false for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match(pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate(param, CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) valid = true break end end end if valid == false then -- user:Mr. Ibrahem if (suggestions.suggestions[ k:lower() ] ~= nil) and validate(suggestions.suggestions[ k:lower() ], CitationClass) then else k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text table.insert (empty_unknowns, k); end end end end end if 0 ~= #empty_unknowns then -- create empty unknown error message utilities.set_message ('err_param_unknown_empty', empty_unknowns --{ 1 == #empty_unknowns and '' or 's',utilities.make_sep_list (#empty_unknowns, empty_unknowns)} ); end local url_param_t = {}; for k, v in pairs( args ) do if 'string' == type (k) then -- don't evaluate positional parameters has_invisible_chars (k, v); -- look for invisible characters end has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe? args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table url_param_t[k] = v; -- make a parameter/value list for extraneous url check end end has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong return table.concat ({ frame:extensionTag ('templatestyles', '', {src=styles}), citation0( CitationClass, args) }); end return {citation = citation}