「モジュール:Citation/CS1/Date validation」の版間の差分
ナビゲーションに移動
検索に移動
sync from sandbox;
細 (1版 をインポートしました) |
bsd>Trappist the monk (sync from sandbox;) |
||
1行目: | 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 >-------------------------------------- | ||
]] | ]] | ||
local add_prop_cat, is_set, in_array, wrap_style; | local add_prop_cat, is_set, in_array, set_message, substitute, wrap_style; -- imported functions from selected Module:Citation/CS1/Utilities | ||
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration | local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration | ||
44行目: | 43行目: | ||
if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand | if good1 and good2 then -- lang.formatDate() returns a timestamp in the local script which which tonumber() may not understand | ||
access_ts = tonumber (access_ts) or lang_object:parseFormattedNumber (access_ts); | access_ts = tonumber (access_ts) or lang_object:parseFormattedNumber (access_ts); -- convert to numbers for the comparison; | ||
tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts); | tomorrow_ts = tonumber (tomorrow_ts) or lang_object:parseFormattedNumber (tomorrow_ts); | ||
else | else | ||
55行目: | 54行目: | ||
return false; -- accessdate out of range | return false; -- accessdate out of range | ||
end | end | ||
end | end | ||
85行目: | 65行目: | ||
local function get_month_number (month) | local function get_month_number (month) | ||
return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or | return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or -- look for local names first | ||
cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or | cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or -- failing that, look for English names | ||
0; | 0; -- not a recognized month name | ||
end | end | ||
102行目: | 82行目: | ||
which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using | which became part of ISO 8601 in 2019. See '§Sub-year groupings'. The standard defines various divisions using | ||
numbers 21-41. cs1|2 only supports generic seasons. EDTF does support the distinction between north and south | numbers 21-41. cs1|2 only supports generic seasons. EDTF does support the distinction between north and south | ||
hemisphere seasons but cs1|2 has no way to make that distinction. | |||
These additional divisions not currently supported: | These additional divisions not currently supported: | ||
195行目: | 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 | 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 | ||
219行目: | 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 | 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 (2 == month) then -- if February | ||
month_length = 28; -- then 28 days unless | month_length = 28; -- then 28 days unless | ||
if 1582 > tonumber(year) then -- Julian calendar | if 1582 > tonumber(year) then -- Julian calendar | ||
if 0 == (year%4) then | if 0 == (year%4) then -- is a leap year? | ||
month_length = 29; -- if leap year then 29 days in February | month_length = 29; -- if leap year then 29 days in February | ||
end | end | ||
else -- Gregorian calendar | else -- Gregorian calendar | ||
if (0 == (year%4) and (0 ~= (year%100) or 0 == (year%400))) then | if (0 == (year%4) and (0 ~= (year%100) or 0 == (year%400))) then -- is a leap year? | ||
month_length = 29; -- if leap year then 29 days in February | month_length = 29; -- if leap year then 29 days in February | ||
end | end | ||
253行目: | 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. | ||
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 | |||
]] | ]] | ||
local function is_valid_month_range_style (month1, month2) | local function is_valid_month_range_style (month1, month2) | ||
if (cfg.date_names.en.long[month1] and cfg.date_names.en.long[month2]) or -- are both English names listed in the long subtable? | |||
(cfg.date_names.en.short[month1] and cfg.date_names.en.short[month2]) or -- are both English names listed in the short subtable? | |||
(cfg.date_names['local'].long[month1] and cfg.date_names['local'].long[month2]) or -- are both local names listed in the long subtable? | |||
(cfg.date_names['local'].short[month1] and cfg.date_names['local'].short[month2]) then -- are both local names listed in the short subtable? | |||
return true; | |||
end | end | ||
return false; -- names are mixed | |||
end | end | ||
299行目: | 280行目: | ||
-- here when range_start is a month | -- here when range_start is a month | ||
range_end_number = get_month_number (range_end); -- get end month number | range_end_number = get_month_number (range_end); -- get end month number | ||
if range_start_number < range_end_number | if range_start_number < range_end_number and -- range_start is a month; does range_start precede range_end? | ||
is_valid_month_range_style (range_start, range_end) then -- do months have the same style? | |||
return true; -- proper order and same style | return true; -- proper order and same style | ||
end | end | ||
return false; -- range_start month number is greater than or equal to range end number; or range end isn't a month | return false; -- range_start month number is greater than or equal to range end number; or range end isn't a month | ||
429行目: | 409行目: | ||
['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'}, | ['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'}, | ||
-- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed; not supported at en.wiki | -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed; not supported at en.wiki | ||
-- ['yMd'] = {'^((%d%d%d%d?)%a?) +(%D-) +(%d%d?)$', 'a', 'y', 'm', 'd'}, | -- ['yMd'] = {'^((%d%d%d%d?)%a?) +(%D-) +(%d%d?)$', 'a', 'y', 'm', 'd'}, | ||
-- day-range-initial: day–day month year; days are separated by endash | -- day-range-initial: day–day month year; days are separated by endash | ||
['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'}, | ['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'}, | ||
456行目: | 436行目: | ||
['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 | |||
482行目: | 481行目: | ||
local function check_date (date_string, param, tCOinS_date) | local function check_date (date_string, param, tCOinS_date) | ||
local year; -- assume that year2, months, and days are not used; | local year; -- assume that year2, months, and days are not used; | ||
local year2 = 0; | local year2 = 0; -- second year in a year range | ||
local month = 0; | local month = 0; | ||
local month2 = 0; | local month2 = 0; -- second month in a month range | ||
local day = 0; | local day = 0; | ||
local day2 = 0; -- second day in a day range | local day2 = 0; -- second day in a day range | ||
562行目: | 561行目: | ||
month, year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy4-y2'][1]); | month, year, century, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy4-y2'][1]); | ||
if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | if 'Winter' ~= month and 'Summer' ~= month then return false end; -- 'month' can only be Winter or Summer | ||
anchor_year = year .. '–' .. anchor_year; | anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years | ||
year2 = century..year2; -- add the century to year2 for comparisons | year2 = century..year2; -- add the century to year2 for comparisons | ||
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
570行目: | 569行目: | ||
elseif mw.ustring.match(date_string, patterns['Sy-y'][1]) then -- special case Winter/Summer year-year; year separated with unspaced endash | elseif mw.ustring.match(date_string, patterns['Sy-y'][1]) then -- special case Winter/Summer year-year; year separated with unspaced endash | ||
month, year, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy-y'][1]); | month, year, anchor_year, year2 = mw.ustring.match(date_string, patterns['Sy-y'][1]); | ||
if 'Winter' ~= | month = get_season_number (month, param); -- <month> can only be winter or summer; also for metadata | ||
anchor_year = year .. '–' .. anchor_year; | if (month ~= cfg.date_names['en'].season['Winter']) and (month ~= cfg.date_names['en'].season['Summer']) then | ||
return false; -- not Summer or Winter; abandon | |||
end | |||
anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years | |||
if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if 1 ~= tonumber(year2) - tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
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 | ||
elseif mw.ustring.match(date_string, patterns['My-My'][1]) then -- month/season year - month/season year; separated by spaced endash | elseif mw.ustring.match(date_string, patterns['My-My'][1]) then -- month/season year - month/season year; separated by spaced endash | ||
month, year, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['My-My'][1]); | month, year, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['My-My'][1]); | ||
anchor_year = year .. '–' .. anchor_year; | anchor_year = year .. '–' .. anchor_year; -- assemble anchor_year from both years | ||
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 | ||
612行目: | 613行目: | ||
elseif mw.ustring.match(date_string, patterns['y-y'][1]) then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 | elseif mw.ustring.match(date_string, patterns['y-y'][1]) then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 | ||
year, anchor_year, year2 = mw.ustring.match(date_string, patterns['y-y'][1]); | year, anchor_year, year2 = mw.ustring.match(date_string, patterns['y-y'][1]); | ||
anchor_year = year .. '–' .. anchor_year; | anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years | ||
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 | ||
619行目: | 620行目: | ||
local century; | local century; | ||
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; | anchor_year = year .. '–' .. anchor_year; -- assemble anchor year from both years | ||
if in_array (param, {'date', 'publication-date', 'year'}) then | if in_array (param, {'date', 'publication-date', 'year'}) then | ||
add_prop_cat (' | add_prop_cat ('year-range-abbreviated'); | ||
end | 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 | ||
year2 = century .. year2; | year2 = century .. year2; -- add the century to year2 for comparisons | ||
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 | ||
elseif mw.ustring.match(date_string, patterns['y'][1]) then | elseif mw.ustring.match(date_string, patterns['y'][1]) then -- year; here accept either YYY or YYYY | ||
anchor_year, year = mw.ustring.match(date_string, patterns['y'][1]); | anchor_year, year = mw.ustring.match(date_string, patterns['y'][1]); | ||
if false == is_valid_year(year) then | if false == is_valid_year(year) then | ||
638行目: | 639行目: | ||
else | else | ||
return false; -- date format not one of the MOS:DATE approved formats | return false; -- date format not one of the MOS:DATE approved formats | ||
end | |||
if param ~= 'date' then -- CITEREF disambiguation only allowed in |date=; |year= & |publication-date= promote to date | |||
if anchor_year:match ('%l$') then | |||
return false; | |||
end | |||
end | end | ||
653行目: | 660行目: | ||
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) | ||
718行目: | 725行目: | ||
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 | 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 | ||
737行目: | 744行目: | ||
--[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------ | --[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------ | ||
Compare the value provided in |year= with the year value(s) provided in |date=. This function | Compare the value provided in |year= with the year value(s) provided in |date=. This function sets a local numeric value: | ||
0 - year value does not match the year value in date | 0 - year value does not match the year value in date | ||
1 - (default) year value matches the year value in date or one of the year values when date contains two years | 1 - (default) year value matches the year value in date or one of the year values when date contains two years | ||
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 numeric value in <result> determines the 'output' if any from this function: | |||
0 – adds error message to error_list sequence table | |||
1 – adds maint cat | |||
2 – does nothing | |||
]] | ]] | ||
local function year_date_check (year_string, date_string) | local function year_date_check (year_string, year_origin, date_string, date_origin, error_list) | ||
local year; | local year; | ||
local date1; | local date1; | ||
local date2; | local date2; | ||
local result = 1; -- result of the test; assume that the test passes | local result = 1; -- result of the test; assume that the test passes | ||
year = year_string:match ('(%d%d%d%d?)'); | year = year_string:match ('(%d%d%d%d?)'); | ||
780行目: | 792行目: | ||
result = 0; | result = 0; | ||
end | end | ||
else | else -- should never get here; this function called only when no other date errors | ||
result = 0; -- no recognizable year in date | result = 0; -- no recognizable year in date | ||
end | end | ||
if 0 == result then -- year / date mismatch | |||
table.insert (error_list, substitute (cfg.messages['mismatch'], {year_origin, date_origin})); -- add error message to error_list sequence table | |||
elseif 1 == result then -- redundant year / date | |||
set_message ('maint_date_year'); -- add a maint cat | |||
end | |||
end | end | ||
819行目: | 836行目: | ||
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ||
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ||
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | ||
}, | }, | ||
['Mdy'] = { -- date format is Mdy; reformat to: | ['Mdy'] = { -- date format is Mdy; reformat to: | ||
825行目: | 842行目: | ||
['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ||
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ||
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | ||
}, | }, | ||
['dMy'] = { -- date format is dMy; reformat to: | ['dMy'] = { -- date format is dMy; reformat to: | ||
831行目: | 848行目: | ||
['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ||
['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ||
-- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | ||
}, | }, | ||
['Md-dy'] = { -- date format is Md-dy; reformat to: | ['Md-dy'] = { -- date format is Md-dy; reformat to: | ||
866行目: | 883行目: | ||
['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic | ['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic | ||
}, | }, | ||
-- ['yMd'] = { | -- ['yMd'] = { -- not supported at en.wiki | ||
-- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, | -- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ||
-- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, | -- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ||
-- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, | -- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ||
-- }, | -- }, | ||
} | } | ||
887行目: | 904行目: | ||
end | end | ||
-- 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' == 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 | ||
908行目: | 923行目: | ||
}; | }; | ||
if t.a then -- if this date has an anchor year capture | if t.a then -- if this date has an anchor year capture (all convertable date formats except ymd) | ||
t.y = t.a; | if t.y2 then -- for year range date formats | ||
t.y2 = t.a; -- use the anchor year capture when reassembling the date | |||
else -- here for single date formats (except ymd) | |||
t.y = t.a; -- use the anchor year capture when reassembling the date | |||
end | |||
end | end | ||
if tonumber(t.m) then -- if raw month is a number (converting from ymd) | if tonumber(t.m) then -- if raw month is a number (converting from ymd) | ||
if 's' == mon_len then -- if we are to use abbreviated month names | if 's' == mon_len then -- if we are to use abbreviated month names | ||
t.m = cfg.date_names[' | t.m = cfg.date_names['inv_local_short'][tonumber(t.m)]; -- convert it to a month name | ||
else | else | ||
t.m = cfg.date_names[' | t.m = cfg.date_names['inv_local_long'][tonumber(t.m)]; -- convert it to a month name | ||
end | end | ||
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 | ||
if 1582 > tonumber(t.y) then -- ymd format dates not allowed before 1582 | 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 | |||
return; | return; | ||
end | end | ||
930行目: | 950行目: | ||
t[mon] = get_month_number (t[mon]); -- get the month number for this month (is length agnostic) | t[mon] = get_month_number (t[mon]); -- get the month number for this month (is length agnostic) | ||
if 0 == t[mon] then return; end -- seasons and named dates can't be converted | if 0 == t[mon] then return; end -- seasons and named dates can't be converted | ||
t[mon] = (('s' == mon_len) and cfg.date_names[' | t[mon] = (('s' == mon_len) and cfg.date_names['inv_local_short'][t[mon]]) or cfg.date_names['inv_local_long'][t[mon]]; -- fetch month name according to length | ||
end | end | ||
end | end | ||
1,017行目: | 1,037行目: | ||
end -- if | end -- if | ||
end -- for | end -- for | ||
return result; | return result; -- declare boolean result and done | ||
end | end | ||
1,034行目: | 1,054行目: | ||
local n; | local n; | ||
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list | 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) | if is_set (param_val.val) and | ||
not mw.ustring.match (param_val.val, patterns.ymd[1]) then -- for those that are not ymd dates (ustring because here digits may not be Western) | |||
param_val.val, n = param_val.val:gsub ('%-', '–'); -- replace any hyphen with ndash | param_val.val, n = param_val.val:gsub ('%-', '–'); -- replace any hyphen with ndash | ||
if 0 ~= n then | if 0 ~= n then | ||
1,041行目: | 1,061行目: | ||
result = true; | result = true; | ||
end | end | ||
end | end | ||
end | end | ||
1,050行目: | 1,069行目: | ||
--[[-------------------------< D A T E _ N A M E _ X L A T E >------------------------------------------------ | --[[-------------------------< D A T E _ N A M E _ X L A T E >------------------------------------------------ | ||
Attempts to translate English | Attempts to translate English date names to local-language date names using names supplied by MediaWiki's | ||
date parser function. This is simple name-for-name replacement and may not work for all languages. | date parser function. This is simple name-for-name replacement and may not work for all languages. | ||
1,064行目: | 1,083行目: | ||
local date; | local date; | ||
local sources_t = { | |||
{cfg.date_names.en.long, cfg.date_names.inv_local_long}, -- for translating long English month names to long local month names | |||
{cfg.date_names.en.short, cfg.date_names.inv_local_short}, -- short month names | |||
{cfg.date_names.en.quarter, cfg.date_names.inv_local_quarter}, -- quarter date names | |||
{cfg.date_names.en.season, cfg.date_names.inv_local_season}, -- season date nam | |||
{cfg.date_names.en.named, cfg.date_names.inv_local_named}, -- named dates | |||
} | |||
local function is_xlateable (month) -- local function to get local date name that replaces existing English-language date name | |||
for _, date_names_t in ipairs (sources_t) do -- for each sequence table in date_names_t | |||
if date_names_t[1][month] then -- if date name is English month (long or short), quarter, season or named and | |||
if date_names_t[2][date_names_t[1][month]] then -- if there is a matching local date name | |||
return date_names_t[2][date_names_t[1][month]]; -- return the local date name | |||
end | |||
end | |||
end | |||
end | |||
for param_name, param_val in pairs(date_parameters_list) do -- for each date-holding parameter in the list | 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) then -- if the parameter has a value | if is_set(param_val.val) then -- if the parameter has a value | ||
date = param_val.val; | date = param_val.val; | ||
for month in mw.ustring.gmatch (date, '%a+') do | for month in mw.ustring.gmatch (date, '[%a ]+') do -- iterate through all date names in the date (single date or date range) | ||
month = mw.text.trim (month); -- this because quarterly dates contain whitespace | |||
xlate = is_xlateable (month); -- get translate <month>; returns translation or nil | |||
if xlate then | |||
if | |||
date = mw.ustring.gsub (date, month, xlate); -- replace the English with the translation | date = mw.ustring.gsub (date, month, xlate); -- replace the English with the translation | ||
date_parameters_list[param_name].val = date; -- save the translated date | date_parameters_list[param_name].val = date; -- save the translated date | ||
1,093行目: | 1,124行目: | ||
return modified; | return modified; | ||
end | |||
1,106行目: | 1,137行目: | ||
is_set = utilities_page_ptr.is_set; | is_set = utilities_page_ptr.is_set; | ||
in_array = utilities_page_ptr.in_array; | in_array = utilities_page_ptr.in_array; | ||
set_message = utilities_page_ptr.set_message; | |||
substitute = utilities_page_ptr.substitute; | |||
wrap_style = utilities_page_ptr.wrap_style; | wrap_style = utilities_page_ptr.wrap_style; | ||