Module:Citation/CS1/Identifiers: Difference between revisions
sync from sandbox;
(sync from sandbox;) |
(sync from sandbox;) |
||
Line 87: | Line 87: | ||
if options.encode == true or options.encode == nil then | if options.encode == true or options.encode == nil then | ||
url_string = mw.uri.encode (url_string); | url_string = mw.uri.encode (url_string, 'PATH'); | ||
end | end | ||
Line 242: | Line 242: | ||
isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39 | isxn_str = { isxn_str:byte(1, 13) }; -- make a table of byte values '0' → 0x30 .. '9' → 0x39 | ||
for i, v in ipairs (isxn_str) do | for i, v in ipairs (isxn_str) do | ||
temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); | temp = temp + (3 - 2*(i % 2)) * tonumber (string.char (v) ); -- multiply odd index digits by 1, even index digits by 3 and sum; includes check digit | ||
end | end | ||
return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct | return temp % 10 == 0; -- sum modulo 10 is zero when ISBN-13/ISMN is correct | ||
Line 351: | Line 351: | ||
end | end | ||
if err_cat then | |||
options.coins_list_t['ARXIV'] = nil; -- when error, unset so not included in COinS | |||
end | |||
err_cat = err_cat and table.concat ({' ', set_message ('err_bad_arxiv')}) or ''; -- set error message if flag is true | err_cat = err_cat and table.concat ({' ', set_message ('err_bad_arxiv')}) or ''; -- set error message if flag is true | ||
Line 404: | Line 408: | ||
err_type = cfg.err_msg_supl.value; -- so value error | err_type = cfg.err_msg_supl.value; -- so value error | ||
else | else | ||
local next_year = tonumber (os.date ('%Y')) + 1; | local next_year = tonumber (os.date ('%Y')) + 1; -- get the current year as a number and add one for next year | ||
year = tonumber (year); -- convert year portion of bibcode to a number | year = tonumber (year); -- convert year portion of bibcode to a number | ||
if (1000 > year) or (year > next_year) then | if (1000 > year) or (year > next_year) then | ||
Line 417: | Line 421: | ||
if is_set (err_type) then -- if there was an error detected | if is_set (err_type) then -- if there was an error detected | ||
text = text .. ' ' .. set_message ('err_bad_bibcode', {err_type}); | text = text .. ' ' .. set_message ('err_bad_bibcode', {err_type}); | ||
options.coins_list_t['BIBCODE'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
return text; | return text; | ||
Line 462: | Line 468: | ||
end -- err_cat remains set here when no match | end -- err_cat remains set here when no match | ||
if err_cat then | |||
options.coins_list_t['BIORXIV'] = 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, | return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, | ||
prefix = handler.prefix, id = id, separator = handler.separator, | prefix = handler.prefix, id = id, separator = handler.separator, | ||
Line 487: | Line 497: | ||
if not matched then | if not matched then | ||
text = text .. ' ' .. set_message ('err_bad_citeseerx' ); | text = text .. ' ' .. set_message ('err_bad_citeseerx' ); | ||
options.coins_list_t['CITESEERX'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
return text; | return text; | ||
Line 548: | Line 559: | ||
local registrant_err_patterns = { -- these patterns are for code ranges that are not supported | 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 | '^[^1-3]%d%d%d%d%.%d%d*$', -- 5 digits with subcode (0xxxx, 40000+); accepts: 10000–39999 | ||
'^[^1- | '^[^1-5]%d%d%d%d$', -- 5 digits without subcode (0xxxx, 60000+); accepts: 10000–59999 | ||
'^[^1-9]%d%d%d%.%d%d*$', -- 4 digits with subcode (0xxx); accepts: 1000–9999 | '^[^1-9]%d%d%d%.%d%d*$', -- 4 digits with subcode (0xxx); accepts: 1000–9999 | ||
'^[^1-9]%d%d%d$', -- 4 digits without subcode (0xxx); accepts: 1000–9999 | '^[^1-9]%d%d%d$', -- 4 digits without subcode (0xxx); accepts: 1000–9999 | ||
Line 558: | Line 569: | ||
if not ignore_invalid then | if not ignore_invalid then | ||
if registrant then -- when DOI has proper form | if registrant then -- when DOI has proper form | ||
for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns | for i, pattern in ipairs (registrant_err_patterns) do -- spin through error patterns | ||
if registrant:match (pattern) then -- to validate registrant codes | if registrant:match (pattern) then -- to validate registrant codes | ||
err_cat = ' ' .. set_message ('err_bad_doi'); -- when found, mark this DOI as bad | err_cat = ' ' .. set_message ('err_bad_doi'); -- when found, mark this DOI as bad | ||
break; -- and done | break; -- and done | ||
end | end | ||
end | end | ||
else | else | ||
err_cat = ' ' .. set_message ('err_bad_doi'); -- invalid directory or malformed | err_cat = ' ' .. set_message ('err_bad_doi'); -- invalid directory or malformed | ||
end | end | ||
else | else | ||
Line 572: | Line 583: | ||
end | end | ||
if err_cat then | |||
options.coins_list_t['DOI'] = 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, | 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, | prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = access, | ||
Line 641: | Line 656: | ||
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 | 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 | ||
text = text .. ' ' .. set_message ('err_bad_hdl' ); | text = text .. ' ' .. set_message ('err_bad_hdl' ); | ||
options.coins_list_t['HDL'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
return text; | return text; | ||
Line 664: | Line 680: | ||
else -- here when not ignoring | else -- here when not ignoring | ||
if not check then -- and there is an error | 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 .. set_message ('err_bad_isbn', {err_type}, false, ' '); -- display an error message | return ISBN .. set_message ('err_bad_isbn', {err_type}, false, ' '); -- display an error message | ||
end | end | ||
Line 686: | Line 703: | ||
return return_result (false, cfg.err_msg_supl.form); | return return_result (false, cfg.err_msg_supl.form); | ||
end | end | ||
return return_result ( | if not is_valid_isxn (id, 10) then -- test isbn-10 for numerical validity | ||
return return_result (false, cfg.err_msg_supl.check); -- fail if isbn-10 is not numerically valid | |||
end | |||
if id:find ('^63[01]') then -- 630xxxxxxx and 631xxxxxxx are (apparently) not valid isbn group ids but are used by amazon as numeric identifiers (asin) | |||
return return_result (false, cfg.err_msg_supl.group); -- fail if isbn-10 begins with 630/1 | |||
end | |||
return return_result (true, cfg.err_msg_supl.check); -- pass if isbn-10 is numerically valid | |||
else | else | ||
if id:match ('^%d+$') == nil then | if id:match ('^%d+$') == nil then | ||
Line 709: | Line 732: | ||
Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit. | Error message if not 10 characters, if not ISBN-10, if mixed and first character is a digit. | ||
|asin=630....... | |asin=630....... and |asin=631....... are (apparently) not a legitimate ISBN though it checksums as one; these | ||
function to emit the maint_asin message | do not cause this function to emit the maint_asin message | ||
This function is positioned here because it calls isbn() | This function is positioned here because it calls isbn() | ||
Line 720: | Line 743: | ||
local domain = options.ASINTLD; | local domain = options.ASINTLD; | ||
local err_cat = | local err_cat = '' | ||
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 | 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 | ||
Line 726: | Line 749: | ||
else | 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 id:match("^%d%d%d%d%d%d%d%d%d[%dX]$") then -- if 10-digit numeric (or 9 digits with terminal X) | ||
if | if is_valid_isxn (id, 10) then -- see if ASIN value is or validates as ISBN-10 | ||
if not id:find ('^ | 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 | ||
set_message (' | err_cat = ' ' .. set_message ('err_bad_asin'); -- ASIN has ISBN-10 form but begins with something other than 630/1 so probably an isbn | ||
end | end | ||
elseif not is_set (err_cat) then | elseif not is_set (err_cat) then | ||
Line 737: | Line 760: | ||
end | end | ||
end | end | ||
if not is_set (domain) then | if (not is_set (domain)) or in_array (domain, {'us'}) then -- default: United States | ||
domain = "com"; | domain = "com"; | ||
elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom | elseif in_array (domain, {'jp', 'uk'}) then -- Japan, United Kingdom | ||
domain = "co." .. domain; | domain = "co." .. domain; | ||
elseif in_array (domain, {'au', 'br', 'mx'}) then | elseif in_array (domain, {'z.cn'}) then -- China | ||
domain = "cn"; | |||
elseif in_array (domain, {'au', 'br', 'mx', 'sg', 'tr'}) then -- Australia, Brazil, Mexico, Singapore, Turkey | |||
domain = "com." .. domain; | 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) | |||
err_cat = ' ' .. set_message ('err_bad_asin_tld'); -- unsupported asin-tld value | |||
end | end | ||
local handler = options.handler; | |||
if not is_set (err_cat) then | |||
options.coins_list_t['ASIN'] = handler.prefix .. domain .. "/dp/" .. id; -- experiment for asin coins | |||
else | |||
options.coins_list_t['ASIN'] = 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, | return external_link_id ({link = handler.link, label = handler.label, q = handler.q, redirect = handler.redirect, | ||
prefix = handler.prefix .. domain .. "/dp/", | prefix = handler.prefix .. domain .. "/dp/", | ||
Line 757: | Line 790: | ||
same check digit calculations. See http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf | same check digit calculations. See http://www.ismn-international.org/download/Web_ISMN_Users_Manual_2008-6.pdf | ||
section 2, pages 9–12. | section 2, pages 9–12. | ||
ismn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) | |||
or an identifier registered at info-uri.info (info:) | |||
]] | ]] | ||
Line 787: | Line 823: | ||
if false == valid_ismn then | 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 | |||
text = text .. ' ' .. set_message ('err_bad_ismn' ) -- add an error message if the ISMN is invalid | text = text .. ' ' .. set_message ('err_bad_ismn' ) -- add an error message if the ISMN is invalid | ||
end | end | ||
Line 839: | Line 876: | ||
else | else | ||
if false == valid_issn then | if false == valid_issn then | ||
options.coins_list_t['ISSN'] = nil; -- when error, unset so not included in COinS | |||
text = text .. ' ' .. set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- add an error message if the ISSN is invalid | text = text .. ' ' .. set_message ('err_bad_issn', (options.hkey == 'EISSN') and 'e' or ''); -- add an error message if the ISSN is invalid | ||
end | end | ||
Line 871: | Line 909: | ||
else | else | ||
err_cat = ' ' .. set_message ('err_bad_jfm' ); -- set an error message | err_cat = ' ' .. set_message ('err_bad_jfm' ); -- set an error message | ||
options.coins_list_t['JFM'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 892: | Line 931: | ||
if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then | if id:find ('[Jj][Ss][Tt][Oo][Rr]') or id:find ('^https?://') or id:find ('%s') then | ||
err_msg = ' ' .. set_message ('err_bad_jstor'); -- set an error message | err_msg = ' ' .. set_message ('err_bad_jstor'); -- set an error message | ||
options.coins_list_t['JSTOR'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 950: | Line 990: | ||
if not is_set (err_cat) and nil ~= lccn:find ('%s') then | if not is_set (err_cat) and nil ~= lccn:find ('%s') then | ||
err_cat = ' ' .. set_message ('err_bad_lccn'); -- lccn contains a space, set an error message | err_cat = ' ' .. set_message ('err_bad_lccn'); -- lccn contains a space, set an error message | ||
end | |||
if is_set (err_cat) then | |||
options.coins_list_t['LCCN'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 983: | Line 1,027: | ||
else | else | ||
err_cat = ' ' .. set_message ('err_bad_mr'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_mr'); -- set an error message | ||
options.coins_list_t['MR'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,025: | Line 1,070: | ||
else | else | ||
err_msg = ' ' .. set_message ('err_bad_oclc') -- add an error message if the id is malformed | err_msg = ' ' .. set_message ('err_bad_oclc') -- add an error message if the id is malformed | ||
options.coins_list_t['OCLC'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,057: | Line 1,103: | ||
ident = id; -- copy id to ident so that we display the flawed identifier | ident = id; -- copy id to ident so that we display the flawed identifier | ||
error_msg = ' ' .. set_message ('err_bad_ol'); | error_msg = ' ' .. set_message ('err_bad_ol'); | ||
end | |||
if not is_set (error_msg) then | |||
options.coins_list_t['OL'] = handler.prefix .. prefix[code] .. ident; -- experiment for ol coins | |||
else | |||
options.coins_list_t['OL'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,084: | Line 1,136: | ||
if id:match("[^%d]") then -- if OSTI has anything but digits | if id:match("[^%d]") then -- if OSTI has anything but digits | ||
err_cat = ' ' .. set_message ('err_bad_osti'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_osti'); -- set an error message | ||
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS | |||
else -- OSTI is only digits | else -- OSTI is only digits | ||
local id_num = tonumber (id); -- convert id to a number for range testing | 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 | if 1018 > id_num or handler.id_limit < id_num then -- if OSTI is outside test limit boundaries | ||
err_cat = ' ' .. set_message ('err_bad_osti'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_osti'); -- set an error message | ||
options.coins_list_t['OSTI'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
end | end | ||
Line 1,151: | Line 1,205: | ||
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 | 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, | prefix = handler.prefix, id = id, separator = handler.separator, encode = handler.encode, access = handler.access, | ||
auto_link = not err_cat and 'pmc' or nil | auto_link = not err_cat and 'pmc' or nil -- do not auto-link when PMC has error | ||
}) .. (err_cat and err_cat or ''); -- parentheses required | }) .. (err_cat and err_cat or ''); -- parentheses required | ||
end | end | ||
if err_cat then | |||
options.coins_list_t['PMC'] = nil; -- when error, unset so not included in COinS | |||
end | |||
return text; | return text; | ||
end | end | ||
Line 1,173: | Line 1,232: | ||
if id:match("[^%d]") then -- if PMID has anything but digits | if id:match("[^%d]") then -- if PMID has anything but digits | ||
err_cat = ' ' .. set_message ('err_bad_pmid'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_pmid'); -- set an error message | ||
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS | |||
else -- PMID is only digits | else -- PMID is only digits | ||
local id_num = tonumber (id); -- convert id to a number for range testing | 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 | if 1 > id_num or handler.id_limit < id_num then -- if PMID is outside test limit boundaries | ||
err_cat = ' ' .. set_message ('err_bad_pmid'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_pmid'); -- set an error message | ||
options.coins_list_t['PMID'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
end | end | ||
Line 1,202: | Line 1,263: | ||
if id:match("[^%d]") then -- if RFC has anything but digits | if id:match("[^%d]") then -- if RFC has anything but digits | ||
err_cat = ' ' .. set_message ('err_bad_rfc'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_rfc'); -- set an error message | ||
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS | |||
else -- RFC is only digits | else -- RFC is only digits | ||
local id_num = tonumber (id); -- convert id to a number for range testing | 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 | if 1 > id_num or handler.id_limit < id_num then -- if RFC is outside test limit boundaries | ||
err_cat = ' ' .. set_message ('err_bad_rfc'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_rfc'); -- set an error message | ||
options.coins_list_t['RFC'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
end | end | ||
Line 1,238: | Line 1,301: | ||
if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries | if handler.id_limit < id_num then -- if S2CID is outside test limit boundaries | ||
err_cat = ' ' .. set_message ('err_bad_s2cid'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_s2cid'); -- set an error message | ||
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
else -- when id format incorrect | else -- when id format incorrect | ||
err_cat = ' ' .. set_message ('err_bad_s2cid'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_s2cid'); -- set an error message | ||
options.coins_list_t['S2CID'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,254: | Line 1,319: | ||
9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits | 9-digit form of ISBN-10; uses same check-digit validation when SBN is prefixed with an additional '0' to make 10 digits | ||
sbn value not made part of COinS metadata because we don't have a url or isn't a COinS-defined identifier (rft.xxx) | |||
or an identifier registered at info-uri.info (info:) | |||
]] | ]] | ||
Line 1,266: | Line 1,334: | ||
if not ignore_invalid then -- if not ignoring SBN errors | if not ignore_invalid then -- if not ignoring SBN errors | ||
if not check 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 .. set_message ('err_bad_sbn', {err_type}, false, ' '); -- display an error message | return SBN .. set_message ('err_bad_sbn', {err_type}, false, ' '); -- display an error message | ||
end | end | ||
Line 1,278: | Line 1,347: | ||
end | end | ||
local ident = id:gsub ('[%s-]', ''); | local ident = id:gsub ('[%s-]', ''); -- remove hyphens and whitespace; they interfere with the rest of the tests | ||
if 9 ~= ident:len() then | if 9 ~= ident:len() then | ||
Line 1,315: | Line 1,384: | ||
if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries | if 100 > id_num or handler.id_limit < id_num then -- if SSRN is outside test limit boundaries | ||
err_cat = ' ' .. set_message ('err_bad_ssrn'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_ssrn'); -- set an error message | ||
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
else -- when id format incorrect | else -- when id format incorrect | ||
err_cat = ' ' .. set_message ('err_bad_ssrn'); -- set an error message | err_cat = ' ' .. set_message ('err_bad_ssrn'); -- set an error message | ||
options.coins_list_t['SSRN'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,343: | Line 1,414: | ||
if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>' | if not id:match('^.+@.+$') or not id:match('^[^<].*[^>]$') then -- doesn't have '@' or has one or first or last character is '< or '>' | ||
text = text .. ' ' .. set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid | text = text .. ' ' .. set_message ('err_bad_usenet_id') -- add an error message if the message id is invalid | ||
options.coins_list_t['USENETID'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,368: | Line 1,440: | ||
elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format? | elseif not id:match('^%d?%d?%d?%d%.%d%d%d%d%d$') then -- not temporary, is it normal format? | ||
err_cat = ' ' .. set_message ('err_bad_zbl'); -- no, set an error message | err_cat = ' ' .. set_message ('err_bad_zbl'); -- no, set an error message | ||
options.coins_list_t['ZBL'] = nil; -- when error, unset so not included in COinS | |||
end | end | ||
Line 1,414: | Line 1,487: | ||
if is_set (access_level) then | if is_set (access_level) then | ||
if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required | if not in_array (access_level, cfg.keywords_lists['id-access']) then -- exact match required | ||
table.insert (z.message_tail, { set_message (' | table.insert (z.message_tail, { set_message ('err_invalid_param_val', {access_param, access_level}, true) } ); | ||
access_level = nil; -- invalid so unset | access_level = nil; -- invalid so unset | ||
end | end | ||
Line 1,432: | Line 1,505: | ||
render the identifiers into a sorted sequence table | render the identifiers into a sorted sequence table | ||
< | <ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value | ||
<options_t> | <options_t> is a table of various k/v option pairs provided in the call to new_build_id_list(); | ||
modified by this function and passed to all identifier rendering functions | modified by this function and passed to all identifier rendering functions | ||
<access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid) | <access_levels_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value (if valid) | ||
returns a sequence table of sorted (by hkey) rendered identifier strings | returns a sequence table of sorted (by hkey - 'handler' key) rendered identifier strings | ||
]] | ]] | ||
local function build_id_list ( | local function build_id_list (ID_list_coins_t, options_t, access_levels_t) | ||
local | local ID_list_t = {}; | ||
local accept; | local accept; | ||
local func_map = { --function map points to functions associated with hkey identifier | local func_map = { --function map points to functions associated with hkey identifier | ||
Line 1,473: | Line 1,546: | ||
} | } | ||
for hkey, v in pairs ( | for hkey, v in pairs (ID_list_coins_t) do | ||
v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else | v, accept = has_accept_as_written (v); -- remove accept-as-written markup if present; accept is boolean true when markup removed; false else | ||
-- every function gets the options table with value v and accept boolean | -- every function gets the options table with value v and accept boolean | ||
Line 1,481: | Line 1,554: | ||
options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter | options_t.access = access_levels_t[hkey]; -- add the access level for those that have an |<identifier-access= parameter | ||
options_t.handler = cfg.id_handlers[hkey]; | 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 | |||
if func_map[hkey] then | if func_map[hkey] then | ||
table.insert ( | table.insert (ID_list_t, {hkey, func_map[hkey] (options_t)}); -- call the function and add the results to the output sequence table | ||
else | else | ||
error (cfg.messages['unknown_ID_key'] .. ' ' .. hkey); -- here when func_map doesn't have a function for hkey | error (cfg.messages['unknown_ID_key'] .. ' ' .. hkey); -- here when func_map doesn't have a function for hkey | ||
Line 1,495: | Line 1,567: | ||
end | end | ||
table.sort ( | table.sort (ID_list_t, comp); -- sequence table of tables sort | ||
for k, v in ipairs ( | for k, v in ipairs (ID_list_t) do -- convert sequence table of tables to simple sequence table of strings | ||
ID_list_t[k] = v[2]; -- v[2] is the identifier rendering from the call to the various functions in func_map{} | |||
end | end | ||
return | return ID_list_t; | ||
end | |||
--[[--------------------------< O P T I O N S _ C H E C K >---------------------------------------------------- | |||
check that certain option parameters have their associated identifier parameters with values | |||
<ID_list_coins_t> is a table of k/v pairs where k is same as key in cfg.id_handlers and v is the assigned value | |||
<ID_support_t> is a sequence table of tables created in citation0() where each subtable has four elements: | |||
[1] is the support parameter's assigned value; empty string if not set | |||
[2] is a text string same as key in cfg.id_handlers | |||
[3] is cfg.error_conditions key used to create error message | |||
[4] is original ID support parameter name used to create error message | |||
returns nothing; on error emits an appropriate error message | |||
]] | |||
local function options_check (ID_list_coins_t, ID_support_t) | |||
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 | |||
table.insert (z.message_tail, {set_message (v[3], (v[4]))}); -- emit the appropriate error message | |||
end | |||
end | |||
end | end | ||
Line 1,512: | Line 1,608: | ||
]] | ]] | ||
local function identifier_lists_get (args, options_t) | local function identifier_lists_get (args, options_t, ID_support_t) | ||
local ID_list_coins_t = extract_ids (args); -- get a table of identifiers and their values for use locally and for use in COinS | local ID_list_coins_t = extract_ids (args); -- get a table of identifiers and their values for use locally and for use in COinS | ||
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 (args, ID_list_coins_t); -- get a table of identifier access levels | local ID_access_levels_t = extract_id_access_levels (args, ID_list_coins_t); -- get a table of identifier 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 | 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 | ||
return ID_list_t, ID_list_coins_t; -- return the tables | return ID_list_t, ID_list_coins_t; -- return the tables |