وحدة:Citation/CS1/sandbox
< وحدة:Citation | CS1
توثيق الوحدة [أنشئ] [محو الاختزان][استخدامات] [قوالب]
--require("strict")
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}