Module:Citation/CS1/Identifiers: Difference between revisions
Content deleted Content added
Johnrdorazio (talk | contribs) m 1 revision imported |
update per RfC; |
||
Line 1:
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
Line 180 ⟶ 179:
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser
apparently doesn't understand non-English date month names. This function will always return false when the date
contains a non-English month name because good1 is false after the call to
around that call this function with date parts and create a YYYY-MM-DD format
]=]
local function is_valid_biorxiv_date (
local biorxiv_date = table.concat ({y, m, d}, '-'); -- make ymd date
local good1, good2;
local biorxiv_ts, tomorrow_ts; -- to hold Unix timestamps representing the dates
Line 260:
Returns a normalized LCCN for lccn() to validate. There is no error checking (step 3.b.1) performed in this function.
]]
Line 311 ⟶ 312:
<date code> and <version> are as defined for 0704-1412
<number> is a five-digit number
]]
Line 318 ⟶ 320:
local handler = options.handler;
local year, month, version;
local
local text; -- output text
Line 327 ⟶ 329:
if ((not (90 < year or 8 > year)) or (1 > month or 12 < month)) or -- if invalid year or invalid month
((91 == year and 7 > month) or (7 == year and 3 < month)) then -- if years ok, are starting and ending months ok?
end
Line 336 ⟶ 338:
if ((7 > year) or (14 < year) or (1 > month or 12 < month)) or -- is year invalid or is month invalid? (doesn't test for future years)
((7 == year) and (4 > month)) then -- when year is 07, is month invalid (before April)?
end
Line 344 ⟶ 346:
month = tonumber (month);
if ((15 > year) or (1 > month or 12 < month)) then -- is year invalid or is month invalid? (doesn't test for future years)
end
else
end
if
options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS
end
set_message ('err_bad_arxiv');
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access})
if is_set (class) then
Line 364 ⟶ 369:
text = table.concat ({text, ' [[//arxiv.org/archive/', class, ' ', class, ']]'}); -- external link within square brackets, not wikilink
else
end
end
return text;
end
Line 395 ⟶ 400:
local handler = options.handler;
local err_type;
local year;
Line 420 ⟶ 426:
if is_set (err_type) then -- if there was an error detected
options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS
end
return text;
end
Line 446 ⟶ 453:
local id = options.id;
local handler = options.handler;
local
local patterns = {
Line 459 ⟶ 466:
if m then -- m is nil when id is the six-digit form
if not is_valid_biorxiv_date (y
break; -- date fail; break out early so we don't unset the error message
end
end
break; -- and done
end
end -- err_cat remains set here when no match
if
options.coins_list_t['BIORXIV'] = nil; -- when error, unset so not included in COinS
set_message ('err_bad_biorxiv'); -- and set the error message
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator,
encode = handler.encode, access = handler.access}
end
Line 483 ⟶ 491:
The description of the structure of this identifier can be found at Help_talk:Citation_Style_1/Archive_26#CiteSeerX_id_structure
]]
Line 489 ⟶ 498:
local handler = options.handler;
local matched;
local text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode,
Line 496 ⟶ 505:
matched = id:match ("^10%.1%.1%.[1-9]%d?%d?%d?%.[1-9]%d?%d?%d?$");
if not matched then
options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS
end
return text;
end
Line 526 ⟶ 536:
local ignore_invalid = options.accept;
local handler = options.handler;
local
local text;
Line 555 ⟶ 565:
end
local registrant =
local registrant_err_patterns = { -- these patterns are for code ranges that are not supported
'^[^1-3]%d%d%d%d%.%d%d*$', -- 5 digits with subcode (0xxxx, 40000+); accepts: 10000–39999
Line 572 ⟶ 582:
for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns
if registrant:match (pattern) then -- to validate registrant codes
break; -- and done
end
end
else
end
else
Line 583 ⟶ 593:
end
if
options.coins_list_t['DOI'] = nil; -- when error, unset so not included in COinS
end
Line 589 ⟶ 599:
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access,
auto_link = not (
}) .. (inactive or '');
return text;▼
end
Line 655 ⟶ 665:
if nil == id:match("^[^%s–]-/[^%s–]-[^%.,]$") then -- HDL must contain a forward slash, must not contain spaces, endashes, and must not end with period or comma
options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS
end
return text;
end
Line 681 ⟶ 692:
if not check then -- and there is an error
options.coins_list_t['ISBN'] = nil; -- when error, unset so not included in COinS
return ISBN; -- return id text
end
end
return ISBN; -- return id text
end
Line 743 ⟶ 755:
local domain = options.ASINTLD;
local
if not id:match("^[%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u][%d%u]$") then
else
if id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X)
if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10
if not id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not a valid isbn prefixes but are used by amazon as a numeric identifier
end
elseif not is_set (
end
elseif not id:match("^%u[%d%u]+$") then
end
end
Line 769 ⟶ 781:
domain = "com." .. domain;
elseif not in_array (domain, {'ae', 'ca', 'cn', 'de', 'es', 'fr', 'in', 'it', 'nl', 'pl', 'sa', 'se', 'co.jp', 'co.uk', 'com', 'com.au', 'com.br', 'com.mx', 'com.sg', 'com.tr'}) then -- Arabic Emirates, Canada, China, Germany, Spain, France, Indonesia, Italy, Netherlands, Poland, Saudi Arabia, Sweden (as of 2021-03 Austria (.at), Liechtenstein (.li) and Switzerland (.ch) still redirect to the German site (.de) with special settings, so don't maintain local ASINs for them)
end
local handler = options.handler;
if not is_set (
options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; --
else
options.coins_list_t['ASIN'] = nil; -- when error, unset so not included in COinS
Line 781 ⟶ 793:
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix .. domain .. "/dp/",
id = id, encode = handler.encode, separator = handler.separator})
end
Line 824 ⟶ 836:
if false == valid_ismn then
options.coins_list_t['ISMN'] = nil; -- when error, unset so not included in COinS; not really necessary here because ismn not made part of COinS
end
Line 877 ⟶ 889:
if false == valid_issn then
options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS
end
end
return text;
end
Line 895 ⟶ 907:
local handler = options.handler;
local id_num;
▲ local err_cat = '';
id_num = id:match ('^[Jj][Ff][Mm](.*)$'); -- identifier with jfm prefix; extract identifier
Line 908 ⟶ 919:
id = id_num; -- jfm matches pattern
else
options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
end
Line 927 ⟶ 938:
local access = options.access;
local handler = options.handler;
▲ local err_msg = '';
if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then
options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access})
end
Line 956 ⟶ 966:
local lccn = options.id;
local handler = options.handler;
local
local id = lccn; -- local copy of the LCCN
Line 964 ⟶ 974:
if 8 == len then
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits)
end
elseif 9 == len then -- LCCN should be adddddddd
if nil == id:match("%l%d%d%d%d%d%d%d%d") then -- does it match our pattern?
end
elseif 10 == len then -- LCCN should be aadddddddd or dddddddddd
if id:match("[^%d]") then -- if LCCN has anything but digits (nil if only digits) ...
if nil == id:match("^%l%l%d%d%d%d%d%d%d%d") then -- ... see if it matches our pattern
end
end
elseif 11 == len then -- LCCN should be aaadddddddd or adddddddddd
if not (id:match("^%l%l%l%d%d%d%d%d%d%d%d") or id:match("^%l%d%d%d%d%d%d%d%d%d%d")) then -- see if it matches one of our patterns
end
elseif 12 == len then -- LCCN should be aadddddddddd
if not id:match("^%l%l%d%d%d%d%d%d%d%d%d%d") then -- see if it matches our pattern
end
else
end
if not is_set (
end
if is_set (
options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = lccn, separator = handler.separator, encode = handler.encode})
end
Line 1,012 ⟶ 1,022:
local id_num;
local id_len;
▲ local err_cat = '';
id_num = id:match ('^[Mm][Rr](%d+)$'); -- identifier with mr prefix
Line 1,026 ⟶ 1,035:
id = string.rep ('0', 7-id_len) .. id_num; -- zero-fill leading digits
else
options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
end
Line 1,046 ⟶ 1,055:
local handler = options.handler;
local number;
if id:match('^ocm%d%d%d%d%d%d%d%d$') then -- ocm prefix and 8 digits; 001 field (12 characters)
number = id:match('ocm(%d+)'); -- get the number
Line 1,069 ⟶ 1,077:
id = number; -- exclude prefix, if any, from external link
else
options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS
end
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
▲ return text;
end
Line 1,091 ⟶ 1,097:
local handler = options.handler;
local ident, code = id:gsub('^OL', ''):match("^(%d+([AMW]))$"); -- strip optional OL prefix followed immediately by digits followed by 'A', 'M', or 'W';
local
local prefix = { -- these are appended to the handler.prefix according to code
['A']='authors/OL',
Line 1,102 ⟶ 1,108:
code = 'X'; -- no code or id completely invalid
ident = id; -- copy id to ident so that we display the flawed identifier
end
if not is_set (
options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins
else
Line 1,114 ⟶ 1,120:
prefix = handler.prefix .. prefix[code],
id = ident, separator = handler.separator, encode = handler.encode,
access = access})
end
Line 1,132 ⟶ 1,138:
local access = options.access;
local handler = options.handler;
if id:match("[^%d]") then -- if OSTI has anything but digits
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
else -- OSTI is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS
end
Line 1,146 ⟶ 1,151:
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access})
end
Line 1,171 ⟶ 1,176:
local embargo = options.Embargo; -- TODO: lowercase?
local handler = options.handler;
local
local id_num;
local text;
Line 1,186 ⟶ 1,191:
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMC is outside test limit boundaries
else
id = tostring (id_num); -- make sure id is a string
end
else -- when id format incorrect
end
Line 1,200 ⟶ 1,205:
handler.separator,
id,
});
else
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, -- no embargo date or embargo has expired, ok to link to article
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access,
auto_link = not
});
end
if
options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS
end
Line 1,228 ⟶ 1,232:
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if PMID has anything but digits
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
else -- PMID is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS
end
Line 1,242 ⟶ 1,245:
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
end
Line 1,259 ⟶ 1,262:
local id = options.id;
local handler = options.handler;
if id:match("[^%d]") then -- if RFC has anything but digits
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
else -- RFC is only digits
local id_num = tonumber (id); -- convert id to a number for range testing
if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS
end
Line 1,273 ⟶ 1,275:
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access})
end
Line 1,291 ⟶ 1,293:
local access = options.access;
local handler = options.handler;
local id_num;
local text;
Line 1,300 ⟶ 1,301:
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access})
return text;
Line 1,329:
local ignore_invalid = options.accept;
local handler = options.handler;
local function return_result (check, err_type)
local SBN = internal_link_id ({link = handler.link, label = handler.label, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator});
if not ignore_invalid then
if not check then
options.coins_list_t['SBN'] = nil; -- when error, unset so not included in COinS; not really necessary here because sbn not made part of COinS
return SBN;
end
else
Line 1,374 ⟶ 1,375:
local id = options.id;
local handler = options.handler;
local id_num;
local text;
Line 1,383:
id_num = tonumber (id_num); -- convert id_num to a number for range testing
if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
else -- when id format incorrect
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS
end
text = external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access =
return text;
Line 1,413:
if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>'
options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS
end
return text;
end
Line 1,434:
local id = options.id;
local handler = options.handler;
if id:match('^%d%d%d%d%d%d%d%d$') then -- is this identifier using temporary format?
set_message ('maint_zbl'); -- yes, add maint cat
elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format?
options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS
end
return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect,
prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode})
end
Line 1,487 ⟶ 1,486:
if is_set (access_level) then
if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required
access_level = nil; -- invalid so unset
end
if not is_set (id_list[k]) then -- identifier access-level must have a matching identifier
end
id_accesses_list[k] = cfg.keywords_xlate[access_level]; -- get translated keyword
Line 1,555 ⟶ 1,554:
options_t.handler = cfg.id_handlers[hkey];
options_t.coins_list_t = ID_list_coins_t; -- pointer to ID_list_coins_t; for |asin= and |ol=; also to keep erroneous values out of the citation's metadata
options_t.coins_list_t[hkey] = v; -- id value without accept-as-written markup for metadata
if options_t.handler.access and not in_array (options_t.handler.access, cfg.keywords_lists['id-access']) then
error (cfg.messages['unknown_ID_access'] .. options_t.handler.access); -- here when handler access key set to a value not listed in list of allowed id access keywords
end
if func_map[hkey] then
table.insert (ID_list_t, {hkey, id_text}); -- add identifier text to the output sequence table
else
error (cfg.messages['unknown_ID_key']
end
end
Line 1,594 ⟶ 1,599:
for _, v in ipairs (ID_support_t) do
if is_set (v[1]) and not ID_list_coins_t[v[2]] then -- when support parameter has a value but matching identifier parameter is missing or empty
end
end
Line 1,608 ⟶ 1,613:
]]
local function identifier_lists_get (
local ID_list_coins_t = extract_ids (
options_check (ID_list_coins_t, ID_support_t); -- ID support parameters must have matching identifier parameters
local ID_access_levels_t = extract_id_access_levels (
local ID_list_t = build_id_list (ID_list_coins_t, options_t, ID_access_levels_t); -- get a sequence table of rendered identifier strings
Line 1,645 ⟶ 1,650:
auto_link_urls = auto_link_urls, -- table of identifier URLs to be used when auto-linking |title=
identifier_lists_get = identifier_lists_get, -- experiment to replace individual calls to build_id_list(), extract_ids, extract_id_access_levels
is_embargoed = is_embargoed;
set_selected_modules = set_selected_modules;
|