| Line 1: |
Line 1: |
| − |
| |
| | --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- | | --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- |
| | ]] | | ]] |
| Line 55: |
Line 54: |
| | return false; -- accessdate out of range | | return false; -- accessdate out of range |
| | end | | end |
| − | end
| |
| − |
| |
| − |
| |
| − | --[[--------------------------< I S _ V A L I D _ E M B A R G O _ D A T E >------------------------------------
| |
| − |
| |
| − | returns true and date value if that value has proper dmy, mdy, ymd format.
| |
| − |
| |
| − | returns false and 9999 (embargoed forever) when date value is not proper format; assumes that when |pmc-embargo-date= is
| |
| − | set, the editor intended to embargo a PMC but |pmc-embargo-date= does not hold a single date.
| |
| − |
| |
| − | ]]
| |
| − |
| |
| − | local function is_valid_embargo_date (v)
| |
| − | if v:match ('^%d%d%d%d%-%d%d%-%d%d$') or -- ymd
| |
| − | v:match ('^%d%d?%s+%a+%s+%d%d%d%d$') or -- dmy
| |
| − | v:match ('^%a+%s+%d%d?%s*,%s*%d%d%d%d$') then -- mdy
| |
| − | return true, v;
| |
| − | end
| |
| − | return false, '9999'; -- if here not good date so return false and set embargo date to long time in future
| |
| | end | | end |
| | | | |
| Line 195: |
Line 175: |
| | Function gets current year from the server and compares it to year from a citation parameter. Years more than one | | Function gets current year from the server and compares it to year from a citation parameter. Years more than one |
| | year in the future are not acceptable. | | year in the future are not acceptable. |
| | + | |
| | + | Special case for |pmc-embargo-date=: years more than two years in the future are not acceptable |
| | | | |
| | ]] | | ]] |
| | | | |
| − | local function is_valid_year (year) | + | local function is_valid_year (year, param) |
| − | if not is_set(year_limit) then | + | if not is_set (year_limit) then |
| | year_limit = tonumber(os.date("%Y"))+1; -- global variable so we only have to fetch it once | | year_limit = tonumber(os.date("%Y"))+1; -- global variable so we only have to fetch it once |
| | end | | end |
| | | | |
| − | year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to numbers for the comparison; | + | year = tonumber (year) or lang_object:parseFormattedNumber (year); -- convert to number for the comparison; |
| | + | |
| | + | if 'pmc-embargo-date' == param then -- special case for |pmc-embargo-date= |
| | + | return year and (year <= tonumber(os.date("%Y"))+2) or false; -- years more than two years in the future are not accepted |
| | + | end |
| | return year and (year <= year_limit) or false; | | return year and (year <= year_limit) or false; |
| | end | | end |
| Line 219: |
Line 205: |
| | ]] | | ]] |
| | | | |
| − | local function is_valid_date (year, month, day) | + | local function is_valid_date (year, month, day, param) |
| | local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | | local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
| | local month_length; | | local month_length; |
| − | if not is_valid_year(year) then -- no farther into the future than next year | + | if not is_valid_year (year, param) then -- no farther into the future than next year except |pmc-embargo-date= no more than two years in the future |
| | return false; | | return false; |
| | end | | end |
| | | | |
| − | month = tonumber(month); -- required for YYYY-MM-DD dates | + | month = tonumber (month); -- required for YYYY-MM-DD dates |
| | | | |
| | if (2 == month) then -- if February | | if (2 == month) then -- if February |
| Line 253: |
Line 239: |
| | | | |
| | Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August. | | Months in a range are expected to have the same style: Jan–Mar or October–December but not February–Mar or Jul–August. |
| − | There is a special test for May because it can be either short or long form.
| + | This function looks in cfg.date_names{} to see if both month names are listed in the long subtable or both are |
| − | | + | listed in the short subtable. When both have the same style (both are listed in the same table), returns true; false else |
| − | Returns true when style for both months is the same
| |
| | | | |
| | ]] | | ]] |
| | | | |
| | local function is_valid_month_range_style (month1, month2) | | local function is_valid_month_range_style (month1, month2) |
| − | local len1 = month1:len();
| + | if (cfg.date_names.en.long[month1] and cfg.date_names.en.long[month2]) or -- are both English names listed in the long subtable? |
| − | local len2 = month2:len();
| + | (cfg.date_names.en.short[month1] and cfg.date_names.en.short[month2]) or -- are both English names listed in the short subtable? |
| − | if len1 == len2 then
| + | (cfg.date_names['local'].long[month1] and cfg.date_names['local'].long[month2]) or -- are both local names listed in the long subtable? |
| − | return true; -- both months are short form so return true
| + | (cfg.date_names['local'].short[month1] and cfg.date_names['local'].short[month2]) then -- are both local names listed in the short subtable? |
| − | elseif 'May' == month1 or 'May'== month2 then -- ToDo: I18N
| + | return true; |
| − | return true; -- both months are long form so return true
| |
| − | elseif 3 == len1 or 3 == len2 then
| |
| − | return false; -- months are mixed form so return false
| |
| − | else
| |
| − | return true; -- both months are long form so return true
| |
| | end | | end |
| | + | return false; -- names are mixed |
| | end | | end |
| | | | |
| Line 453: |
Line 434: |
| | ['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 | | ['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 |
| | ['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- year range: YYYY–YY; separated by unspaced endash | | ['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- year range: YYYY–YY; separated by unspaced endash |
| − | ['ymx'] = {'^(%d%d%d%d)%-(%d%d)%-XX$', 'y', 'm'}, -- edtf year-initial numerical year-month-XX
| |
| | ['y'] = {'^((%d%d%d%d?)%a?)$'}, -- year; here accept either YYY or YYYY | | ['y'] = {'^((%d%d%d%d?)%a?)$'}, -- year; here accept either YYY or YYYY |
| | } | | } |
| | + | |
| | + | |
| | + | --[[--------------------------< I S _ V A L I D _ E M B A R G O _ D A T E >------------------------------------ |
| | + | |
| | + | returns true and date value if that value has proper dmy, mdy, ymd format. |
| | + | |
| | + | returns false and 9999 (embargoed forever) when date value is not proper format; assumes that when |pmc-embargo-date= is |
| | + | set, the editor intended to embargo a PMC but |pmc-embargo-date= does not hold a single date. |
| | + | |
| | + | ]] |
| | + | |
| | + | local function is_valid_embargo_date (v) |
| | + | if v:match (patterns['ymd'][1]) or -- ymd |
| | + | v:match (patterns['Mdy'][1]) or -- dmy |
| | + | v:match (patterns['dMy'][1]) then -- mdy |
| | + | return true, v; |
| | + | end |
| | + | return false, '9999'; -- if here not good date so return false and set embargo date to long time in future |
| | + | end |
| | | | |
| | | | |
| Line 495: |
Line 494: |
| | anchor_year = year; | | anchor_year = year; |
| | | | |
| − | elseif date_string:match (patterns['ymx'][1]) then -- year-initial numerical year month edtf format
| |
| − | year, month = date_string:match (patterns['ymx'][1]);
| |
| − | if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or not is_valid_year(year) then return false; end -- month number not valid or not Gregorian calendar or future year
| |
| − | anchor_year = year;
| |
| − |
| |
| | elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year | | elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year |
| | month, day, anchor_year, year = mw.ustring.match(date_string, patterns['Mdy'][1]); | | month, day, anchor_year, year = mw.ustring.match(date_string, patterns['Mdy'][1]); |
| Line 627: |
Line 621: |
| | | | |
| | if in_array (param, {'date', 'publication-date', 'year'}) then | | if in_array (param, {'date', 'publication-date', 'year'}) then |
| − | add_prop_cat ('year_range_abbreviated'); | + | add_prop_cat ('year-range-abbreviated'); |
| | end | | end |
| | | | |
| Line 658: |
Line 652: |
| | local result=true; -- check whole dates for validity; assume true because not all dates will go through this test | | local result=true; -- check whole dates for validity; assume true because not all dates will go through this test |
| | if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then -- YMD (simple whole date) | | if 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 == day2 then -- YMD (simple whole date) |
| − | result = is_valid_date(year, month, day); | + | result = is_valid_date (year, month, day, param); -- <param> for |pmc-embargo-date= |
| | | | |
| | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then -- YMD-d (day range) | | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 == month2 and 0 ~= day2 then -- YMD-d (day range) |
| − | result = is_valid_date(year, month, day); | + | result = is_valid_date (year, month, day); |
| − | result = result and is_valid_date(year, month, day2); | + | result = result and is_valid_date (year, month, day2); |
| | | | |
| | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-md (day month range) | | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 == year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-md (day month range) |
| − | result = is_valid_date(year, month, day); | + | result = is_valid_date (year, month, day); |
| − | result = result and is_valid_date(year, month2, day2); | + | result = result and is_valid_date (year, month2, day2); |
| | | | |
| | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 ~= year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-ymd (day month year range) | | elseif 0 ~= year and 0 ~= month and 0 ~= day and 0 ~= year2 and 0 ~= month2 and 0 ~= day2 then -- YMD-ymd (day month year range) |
| Line 723: |
Line 717: |
| | good_date, anchor_year, COinS_date = true, v.val:match("((%d+)%a?)"); | | good_date, anchor_year, COinS_date = true, v.val:match("((%d+)%a?)"); |
| | end | | end |
| − | elseif 'pmc-embargo-date' == k then -- if the parameter is |pmc-embargo-date= | + | elseif 'pmc-embargo-date' == k then -- if the parameter is |pmc-embargo-date= |
| | good_date = check_date (v.val, k); -- go test the date | | good_date = check_date (v.val, k); -- go test the date |
| | if true == good_date then -- if the date is a valid date | | if true == good_date then -- if the date is a valid date |
| − | good_date, embargo_date = is_valid_embargo_date (v.val); -- is |pmc-embargo-date= date a single dmy, mdy, or ymd formatted date? yes: returns embargo; no: returns 9999 | + | good_date, embargo_date = is_valid_embargo_date (v.val); -- is |pmc-embargo-date= date a single dmy, mdy, or ymd formatted date? yes: returns embargo date; no: returns 9999 |
| | end | | end |
| | else -- any other date-holding parameter | | else -- any other date-holding parameter |
| Line 747: |
Line 741: |
| | 2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx) | | 2 - year value matches the year value in date when date is in the form YYYY-MM-DD and year is disambiguated (|year=YYYYx) |
| | | | |
| − | the numernic value in <result> determines the 'output' if any from this function: | + | the numeric value in <result> determines the 'output' if any from this function: |
| | 0 – adds error message to error_list sequence table | | 0 – adds error message to error_list sequence table |
| | 1 – adds maint cat | | 1 – adds maint cat |
| Line 902: |
Line 896: |
| | end | | end |
| | | | |
| − | -- yMd is not supported at en.wiki; if yMd is supported at your wiki, uncomment the next line | + | -- yMd is not supported at en.wiki; when yMd is supported at your wiki, uncomment the next line |
| | -- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- these formats not convertable; yMd not supported at en.wiki | | -- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- these formats not convertable; yMd not supported at en.wiki |
| − | -- if yMd is supported at your wiki, remove or comment-out the next line
| + | if 'yMd' == format_param then -- yMd not supported at en.wiki; when yMd is supported at your wiki, remove or comment-out this line |
| − | if 'yMd' == format_param then -- yMd not supported at en.wiki | |
| | return; -- not a reformattable date | | return; -- not a reformattable date |
| | end | | end |
| Line 934: |
Line 927: |
| | t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present | | t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present |
| | elseif 'ymd' == format_param then -- when converting to ymd | | elseif 'ymd' == format_param then -- when converting to ymd |
| − | t.y = t.y:gsub ('%a', ''); -- strip CITREF disambiguator if present; anchor year already known so process can proceed | + | t.y = t.y:gsub ('%a', ''); -- strip CITREF disambiguator if present; anchor year already known so process can proceed; TODO: maint message? |
| | if 1582 > tonumber (t.y) then -- ymd format dates not allowed before 1582 | | if 1582 > tonumber (t.y) then -- ymd format dates not allowed before 1582 |
| | return; | | return; |
| Line 1,032: |
Line 1,025: |
| | end -- if | | end -- if |
| | end -- for | | end -- for |
| − | return result; -- declare boolean result and done | + | return result; -- declare boolean result and done |
| | end | | end |
| | | | |
| Line 1,059: |
Line 1,052: |
| | end | | end |
| | return result; -- so we know if any hyphens were replaced | | return result; -- so we know if any hyphens were replaced |
| − | end
| |
| − |
| |
| − |
| |
| − | --[[--------------------------< E D T F _ T R A N S F O R M >--------------------------------------------------
| |
| − |
| |
| − | Loops through the list of date-holding parameters and converts any EDTF formatted dates to MOS compliant dates.
| |
| − | Only YYY-MM-XX supported at this time. Not called if the cs1|2 template has any date errors.
| |
| − |
| |
| − | must be done before reformat_dates() and before date_hyphen_to_dash()
| |
| − |
| |
| − | Modifies the date_parameters_list and returns true if transformation is performed, else returns false.
| |
| − |
| |
| − | ]]
| |
| − |
| |
| − | local function edtf_transform (date_parameters_list)
| |
| − | local result = false;
| |
| − | local source_date = {};
| |
| − |
| |
| − | for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list
| |
| − | if is_set(param_val.val) and param_val.val:match (patterns.ymx[1]) then -- if parameter is set and is an EDTF dates
| |
| − | source_date.year, source_date.month = param_val.val:match (patterns.ymx[1]); -- get year and month number
| |
| − | source_date.day = 1; -- required by os.time()
| |
| − | date_parameters_list[param_name].val = mw.text.trim (os.date ('%B %Y', os.time (source_date)));
| |
| − | result = true;
| |
| − | end
| |
| − | end
| |
| − | return result; -- so we know if a transform was done
| |
| | end | | end |
| | | | |
| Line 1,164: |
Line 1,130: |
| | date_hyphen_to_dash = date_hyphen_to_dash, | | date_hyphen_to_dash = date_hyphen_to_dash, |
| | date_name_xlate = date_name_xlate, | | date_name_xlate = date_name_xlate, |
| − | edtf_transform = edtf_transform,
| |
| | set_selected_modules = set_selected_modules | | set_selected_modules = set_selected_modules |
| | } | | } |