Module:Citation/CS1/Date validation: Difference between revisions

Jump to navigation Jump to search
m (1 revision imported)
ww>Trappist the monk
(sync from sandbox;)
Line 185: Line 185:
end
end


year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to number for the comparison;
year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to number for the comparison
if year and (100 > year) then -- years less than 100 not supported
return false;
end
if 'pmc-embargo-date' == param then -- special case for |pmc-embargo-date=
if 'pmc-embargo-date' == param then -- special case for |pmc-embargo-date=
Line 321: Line 324:
local date; -- one date or first date in a range
local date; -- one date or first date in a range
local date2 = ''; -- end of range date
local date2 = ''; -- end of range date
input.year = tonumber (input.year) or lang_object:parseFormattedNumber (input.year); -- language-aware tonumber()
input.year2 = tonumber (input.year2) or lang_object:parseFormattedNumber (input.year2); -- COinS dates are pseudo-ISO 8601 so convert to Arabic numerals
-- start temporary Julian / Gregorian calendar uncertainty detection
-- start temporary Julian / Gregorian calendar uncertainty detection
local year = tonumber(input.year); -- this temporary code to determine the extent of sources dated to the Julian/Gregorian
local year = input.year; -- this temporary code to determine the extent of sources dated to the Julian/Gregorian
local month = tonumber(input.month); -- interstice 1 October 1582 – 1 January 1926
local month = tonumber(input.month); -- interstice 1 October 1582 – 1 January 1926
local day = tonumber (input.day);
local day = tonumber (input.day);
Line 332: Line 338:
end
end
-- end temporary Julian / Gregorian calendar uncertainty detection
-- end temporary Julian / Gregorian calendar uncertainty detection
if ((1582 == year) and (10 > month)) or (1582 > year) then -- if a Julian calendar date
if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only
tCOinS_date.rftdate = tostring (input.year); -- &rft.date gets year only
date = input.year;
return; -- done
end
-- here for all forms of Gregorian dates
if 20 < tonumber (input.month) then -- if season, quarter, or proper-name date
date = input.year; -- &rft.date gets year only
if 0 ~= input.year2 and input.year ~= input.year2 then -- if a range, only the second year portion when not the same as range start year
if 0 ~= input.year2 and input.year ~= input.year2 then -- if a range, only the second year portion when not the same as range start year
date = string.format ('%.4d/%.4d', tonumber(input.year), tonumber(input.year2)) -- assemble the date range
date = string.format ('%.4d/%.4d', input.year, input.year2) -- assemble the date range
end
end
if 20 < tonumber(input.month) then -- if season or proper-name date
 
local season = {[24] = 'winter', [21] = 'spring', [22] = 'summer', [23] = 'fall', [33] = '1', [34] = '2', [35] = '3', [36] = '4', [98] = 'Easter', [99] = 'Christmas'}; -- seasons lowercase, no autumn; proper-names use title case
local season = {[24] = 'winter', [21] = 'spring', [22] = 'summer', [23] = 'fall', [33] = '1', [34] = '2', [35] = '3', [36] = '4', [98] = 'Easter', [99] = 'Christmas'}; -- seasons lowercase, no autumn; proper-names use title case
if 0 == input.month2 then -- single season date
if 0 == input.month2 then -- single season, quarter, or proper-name date
if 40 < tonumber(input.month) then
if 40 < tonumber(input.month) then
tCOinS_date.rftchron = season[input.month]; -- proper-name dates
tCOinS_date.rftchron = season[input.month]; -- proper-name date; used in journal metadata only
elseif 30 < tonumber(input.month) then
elseif 30 < tonumber(input.month) then
tCOinS_date.rftquarter = season[input.month]; -- quarters
tCOinS_date.rftquarter = season[input.month]; -- quarter date; used in journal metadata only
else
else
tCOinS_date.rftssn = season[input.month]; -- seasons
tCOinS_date.rftssn = season[input.month]; -- season date; used in journal metadata only
end
end
else -- season range with a second season specified
else -- season ranges are lumped into &rft.chron; &rft.ssn and &rft.quarter are left blank
if input.year ~= input.year2 then -- season year – season year range or season year–year
if input.year ~= input.year2 then -- season year – season year range or season year–year
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
if 0 ~= input.month2 then
if 0~= input.month2 then
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2); -- used in journal metadata only
tCOinS_date.rftchron = string.format ('%s %s – %s %s', season[input.month], input.year, season[input.month2], input.year2);
end
else -- season–season year range
tCOinS_date.rftssn = season[input.month]; -- start of range season; keep this?
tCOinS_date.rftchron = season[input.month] .. '–' .. season[input.month2]; -- season–season year range
end
end
else -- season–season year range
tCOinS_date.rftchron = season[input.month] .. '–' .. season[input.month2]; -- season–season year range; used in journal metadata only
end
end
end
end
tCOinS_date.rftdate = date;
 
tCOinS_date.rftdate = tostring (date);
return; -- done
return; -- done
end
end
-- here for gregorian calendar dates
if 0 ~= input.day then
if 0 ~= input.day then
date = string.format ('%s-%.2d-%.2d', input.year, tonumber(input.month), tonumber(input.day)); -- whole date
date = string.format ('%s-%.2d-%.2d', input.year, tonumber(input.month), tonumber(input.day)); -- whole date
Line 621: Line 629:
year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['y4-y2'][1]);
year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['y4-y2'][1]);
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years
if in_array (param, {'date', 'publication-date', 'year'}) then
add_prop_cat ('year-range-abbreviated');
end


if 13 > tonumber(year2) then return false; end -- don't allow 2003-05 which might be May 2003
if 13 > tonumber(year2) then return false; end -- don't allow 2003-05 which might be May 2003
Line 630: Line 634:
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if tonumber(year) >= tonumber(year2) then return false; end -- left to right, earlier to later, not the same
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
if not is_valid_year(year2) then return false; end -- no year farther in the future than next year
if in_array (param, {'date', 'publication-date', 'year'}) then -- here when 'valid' abbreviated year range; if one of these parameters
add_prop_cat ('year-range-abbreviated'); -- add properties cat
end


elseif mw.ustring.match(date_string, patterns['y'][1]) then -- year; here accept either YYY or YYYY
elseif mw.ustring.match(date_string, patterns['y'][1]) then -- year; here accept either YYY or YYYY
Line 647: Line 655:
end
end


if 'access-date' == param then -- test accessdate here because we have numerical date parts
if 'access-date' == param then -- test access-date here because we have numerical date parts
if 0 ~= year and 0 ~= month and 0 ~= day and -- all parts of a single date required
if 0 ~= year and 0 ~= month and 0 ~= day and -- all parts of a single date required
0 == year2 and 0 == month2 and 0 == day2 then -- none of these; accessdate must not be a range
0 == year2 and 0 == month2 and 0 == day2 then -- none of these; access-date must not be a range
if not is_valid_accessdate(year .. '-' .. month .. '-' .. day) then
if not is_valid_accessdate(year .. '-' .. month .. '-' .. day) then
return false; -- return false when accessdate out of bounds
return false; -- return false when access-date out of bounds
end
end
else
else
return false; -- return false when accessdate is a range of two dates
return false; -- return false when access-date is a range of two dates
end
end
 
if 'archive-date' == param then -- test archive-date here because we have numerical date parts
if not (0 ~= year and 0 ~= month and 0 ~= day and -- all parts of a single date required
0 == year2 and 0 == month2 and 0 == day2) then -- none of these; archive-date must not be a range
return false; -- return false when archive-date is a range of two dates
end
end
end
end
Line 1,031: Line 1,046:
date_parameters_list[param_name].val = new_date; -- update date in date list
date_parameters_list[param_name].val = new_date; -- update date in date list
result = true; -- and announce that changes have been made
result = true; -- and announce that changes have been made
break;
end
end
end -- if
end -- if
Line 1,142: Line 1,158:


cfg = cfg_table_ptr; -- import tables from selected Module:Citation/CS1/Configuration
cfg = cfg_table_ptr; -- import tables from selected Module:Citation/CS1/Configuration
end
--[[--------------------------< A R C H I V E _ D A T E _ C H E C K >------------------------------------------
Compare value in |archive-date= with the timestamp in Wayback machine urls.  Emits an error message when |archive-date=
does not match the timestamp.
]]
local function archive_date_check (archive_date, archive_url_timestamp)
local good, archive_date_ts = pcall (lang_object.formatDate, lang_object, 'Ymd', archive_date); -- |archive-date= value to YYYYMMDD format
-- local archive_date_ts = lang_object:formatDate ('Ymd', archive_date); -- |archive-date= value to YYYYMMDD format
if good then
if not archive_url_timestamp:find (archive_date_ts, 1, true) then -- plain text find; begin search at position 1
set_message ('err_archive_date_url_ts_mismatch'); -- emit an error message
end
end
end
end


Line 1,149: Line 1,184:


return { -- return exported functions
return { -- return exported functions
archive_date_check = archive_date_check,
date_hyphen_to_dash = date_hyphen_to_dash,
date_name_xlate = date_name_xlate,
dates = dates,
dates = dates,
reformat_dates = reformat_dates,
set_selected_modules = set_selected_modules,
year_date_check = year_date_check,
year_date_check = year_date_check,
reformat_dates = reformat_dates,
date_hyphen_to_dash = date_hyphen_to_dash,
date_name_xlate = date_name_xlate,
set_selected_modules = set_selected_modules
}
}