Difference between pages "Module:Citation/CS1" and "Module:Citation/CS1/sandbox"
m (1 revision) |
m (1 revision) |
||
Line 1: | Line 1: | ||
+ | --[[ | ||
+ | History of changes since last sync: 2014-03-30 | ||
+ | 2014-04-04: firstn/lastn mismatch; | ||
+ | |||
+ | 2014-03-30: normalize lccn identifiers; | ||
+ | ]] | ||
+ | |||
local z = { | local z = { | ||
error_categories = {}; | error_categories = {}; | ||
Line 4: | Line 11: | ||
message_tail = {}; | message_tail = {}; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
-- Whether variable is set or not | -- Whether variable is set or not | ||
Line 264: | Line 263: | ||
encode=handler.encode, separator = handler.separator}) | encode=handler.encode, separator = handler.separator}) | ||
end | end | ||
+ | |||
+ | |||
+ | --[[ | ||
+ | lccn normalization (http://www.loc.gov/marc/lccn-namespace.html#normalization) | ||
+ | 1. Remove all blanks. | ||
+ | 2. If there is a forward slash (/) in the string, remove it, and remove all characters to the right of the forward slash. | ||
+ | 3. If there is a hyphen in the string: | ||
+ | a. Remove it. | ||
+ | b. Inspect the substring following (to the right of) the (removed) hyphen. Then (and assuming that steps 1 and 2 have been carried out): | ||
+ | 1. All these characters should be digits, and there should be six or less. (not done in this function) | ||
+ | 2. If the length of the substring is less than 6, left-fill the substring with zeros until the length is six. | ||
+ | |||
+ | Returns a normalized lccn for lccn() to validate. There is no error checking (step 3.b.1) performed in this function. | ||
+ | ]] | ||
+ | |||
+ | function normalize_lccn (lccn) | ||
+ | lccn = lccn:gsub ("%s", ""); -- 1. strip whitespace | ||
+ | |||
+ | if nil ~= string.find (lccn,'/') then | ||
+ | lccn = lccn:match ("(.-)/"); -- 2. remove forward slash and all character to the right of it | ||
+ | end | ||
+ | |||
+ | local prefix | ||
+ | local suffix | ||
+ | prefix, suffix = lccn:match ("(.+)%-(.+)"); -- 3.a remove hyphen by splitting the string into prefix and suffix | ||
+ | |||
+ | if nil ~= suffix then -- if there was a hyphen | ||
+ | suffix=string.rep("0", 6-string.len (suffix)) .. suffix; -- 3.b.2 left fill the suffix with 0s if suffix length less than 6 | ||
+ | lccn=prefix..suffix; -- reassemble the lccn | ||
+ | end | ||
+ | |||
+ | return lccn; | ||
+ | end | ||
--[[ | --[[ | ||
Line 276: | Line 308: | ||
]] | ]] | ||
− | function lccn( | + | function lccn(lccn) |
local handler = cfg.id_handlers['LCCN']; | local handler = cfg.id_handlers['LCCN']; | ||
local err_cat = ''; -- presume that LCCN is valid | local err_cat = ''; -- presume that LCCN is valid | ||
+ | local id = lccn; -- local copy of the lccn | ||
+ | id = normalize_lccn (id); -- get canonical form (no whitespace, hyphens, forward slashes) | ||
local len = id:len(); -- get the length of the lccn | local len = id:len(); -- get the length of the lccn | ||
Line 306: | Line 340: | ||
else | else | ||
err_cat = ' ' .. seterror( 'bad_lccn' ); -- wrong length, set an error message | err_cat = ' ' .. seterror( 'bad_lccn' ); -- wrong length, set an error message | ||
+ | end | ||
+ | |||
+ | if not is_set (err_cat) and nil ~= lccn:find ('%s') then | ||
+ | err_cat = ' ' .. seterror( 'bad_lccn' ); -- lccn contains a space, set an error message | ||
end | end | ||
return externallinkid({link = handler.link, label = handler.label, | return externallinkid({link = handler.link, label = handler.label, | ||
− | prefix=handler.prefix,id= | + | prefix=handler.prefix,id=lccn,separator=handler.separator, encode=handler.encode}) .. err_cat; |
end | end | ||
Line 792: | Line 830: | ||
end | end | ||
− | -- Gets name list from the input arguments | + | --[[ |
+ | Gets name list from the input arguments | ||
+ | |||
+ | Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. | ||
+ | Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't | ||
+ | find |last4= and |last5= then the search is done. | ||
+ | |||
+ | This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= | ||
+ | are present but |last2= is missing, an error message is emitted. |lastn= is not required ot have a matching |firstn=. | ||
+ | ]] | ||
function extractnames(args, list_name) | function extractnames(args, list_name) | ||
− | + | local names = {}; -- table of names | |
− | + | local i = 1; -- loop counter/indexer | |
− | + | local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors) | |
− | + | ||
+ | local err_msg_list_name = list_name:match ("(%w+)List") .. 's list'; -- modify AuthorList or EditorList for use in error messages if necessary | ||
+ | |||
while true do | while true do | ||
− | last = selectone( args, cfg.aliases[list_name .. '-Last'], 'redundant_parameters', i ) | + | names[i] = -- search through args for name components beginning at 1 |
− | + | { | |
− | + | last = selectone( args, cfg.aliases[list_name .. '-Last'], 'redundant_parameters', i ), | |
− | + | first = selectone( args, cfg.aliases[list_name .. '-First'], 'redundant_parameters', i ), | |
− | + | link = selectone( args, cfg.aliases[list_name .. '-Link'], 'redundant_parameters', i ), | |
− | + | mask = selectone( args, cfg.aliases[list_name .. '-Mask'], 'redundant_parameters', i ) | |
− | + | }; | |
− | + | if names[i].first and not names[i].last then -- if there is a firstn without a matching lastn | |
− | + | names[i].first = nil; -- set first to nil so we don't confuse the implict et al message code | |
− | + | table.insert( z.message_tail, { seterror( 'first_missing_last', {err_msg_list_name, i}, true ) } ); -- add this error message | |
− | + | break; -- and done because lastn not found | |
− | + | elseif not names[i].first and not names[i].last then -- if both firstn and lastn aren't found, are we done? | |
− | + | count = count + 1; -- number of times we haven't found last and first | |
− | + | if 2 == count then -- two missing names and we give up | |
+ | break; -- normal exit or there is a two-name hole in the list; can't tell which | ||
+ | end | ||
+ | else -- last with or without a first | ||
+ | if 1 == count then -- if the previous name was missing | ||
+ | table.insert( z.message_tail, { seterror( 'missing_name', {err_msg_list_name, i-1}, true ) } ); -- add this error message | ||
+ | end | ||
+ | count = 0; -- reset the counter, we're looking for two consecutive missing names | ||
+ | end | ||
+ | |||
+ | i = i + 1; -- bump to the next name | ||
+ | end | ||
+ | return names; -- all done, return our list of names | ||
end | end | ||
Line 1,211: | Line 1,272: | ||
end | end | ||
− | -- check for | + | -- check for special case where |separator=none |
if 'none' == sepc:lower() then -- if |separator=none | if 'none' == sepc:lower() then -- if |separator=none | ||
sepc = ''; -- then set it to a empty string | sepc = ''; -- then set it to a empty string | ||
Line 2,056: | Line 2,117: | ||
local pframe = frame:getParent() | local pframe = frame:getParent() | ||
− | + | if nil ~= string.find( frame:getTitle(), 'sandbox', 1, true ) then -- did the {{#invoke:}} use sandbox version? | |
− | -- | + | cfg = mw.loadData( 'Module:Citation/CS1/Configuration/sandbox' ); -- load sandbox versions of Configuration and Whitelist and ... |
− | -- | + | whitelist = mw.loadData( 'Module:Citation/CS1/Whitelist/sandbox' ); |
− | + | dates = require('Module:Citation/CS1/Date_validation/sandbox').dates -- ... sandbox version of date validation code | |
− | + | else -- otherwise | |
− | -- | + | cfg = mw.loadData( 'Module:Citation/CS1/Configuration' ); -- load live versions of Configuration and Whitelist and ... |
− | |||
− | cfg = mw.loadData( 'Module:Citation/CS1/Configuration' ); | ||
whitelist = mw.loadData( 'Module:Citation/CS1/Whitelist' ); | whitelist = mw.loadData( 'Module:Citation/CS1/Whitelist' ); | ||
− | dates = require('Module:Citation/CS1/Date_validation').dates | + | dates = require('Module:Citation/CS1/Date_validation').dates -- ... live version of date validation code |
− | -- end | + | end |
local args = {}; | local args = {}; |