٦١
تعديل
(better;) |
ط (مراجعة واحدة) |
||
سطر ٣: | سطر ٣: | ||
]] | ]] | ||
local | local is_set, in_array; -- 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 | ||
سطر ٢٣: | سطر ٢٣: | ||
Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time) | Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time) | ||
accessdate is the date provided in | | accessdate is the date provided in |accessdate= at time 00:00:00 UTC | ||
today is the current date at time 00:00:00 UTC plus 48 hours | today is the current date at time 00:00:00 UTC plus 48 hours | ||
if today is 2015-01-01T00:00:00 then | if today is 2015-01-01T00:00:00 then | ||
سطر ٣٠: | سطر ٣٠: | ||
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser | This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser | ||
apparently doesn't understand non- | apparently doesn't understand non-Engish date month names. This function will always return false when the date | ||
contains a non-English month name because good1 is false after the call to lang.formatDate(). To get around that | contains a non-English month name because good1 is false after the call to lang.formatDate(). To get around that | ||
call this function with YYYY-MM-DD format dates. | call this function with YYYY-MM-DD format dates. | ||
سطر ٣٨: | سطر ٣٨: | ||
local function is_valid_accessdate (accessdate) | local function is_valid_accessdate (accessdate) | ||
local good1, good2; | local good1, good2; | ||
local access_ts, tomorrow_ts; -- to hold | local access_ts, tomorrow_ts; -- to hold unix time stamps representing the dates | ||
good1, access_ts = pcall (lang_object.formatDate, lang_object, 'U', accessdate ); -- convert accessdate value to | good1, access_ts = pcall (lang_object.formatDate, lang_object, 'U', accessdate ); -- convert accessdate value to unix timesatmp | ||
good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow | good2, tomorrow_ts = pcall (lang_object.formatDate, lang_object, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow | ||
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 | ||
return false; -- one or both failed to convert to | return false; -- one or both failed to convert to unix time stamp | ||
end | end | ||
سطر ٥٥: | سطر ٥٥: | ||
return false; -- accessdate out of range | return false; -- accessdate out of range | ||
end | end | ||
end | |||
--[[--------------------------< G E T _ M O N T H _ N U M B E R >---------------------------------------------- | |||
returns a number according to the month in a date: 1 for January, etc. Capitalization and spelling must be correct. If not a valid month, returns 0 | |||
]] | |||
local function get_month_number (month) | |||
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 -- failing that, look for English names | |||
0; -- not a recognized month name | |||
end | end | ||
سطر ٦٢: | سطر ٧٥: | ||
returns true and date value if that value has proper dmy, mdy, ymd format. | 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 | | returns false and 9999 (embargoed forever) when date value is not proper format; assumes that when |embargo= is | ||
set, the editor intended to embargo a | set, the editor intended to embargo a pmc but |embargo= does not hold a single date. | ||
]] | ]] | ||
سطر ٧٧: | سطر ٩٠: | ||
--[[--------------------------< G E T _ | --[[--------------------------< G E T _ S E A S O N _ N U M B E R >-------------------------------------------- | ||
returns a number according to the sequence of seasons in a year: 1 for Winter, etc. Capitalization and spelling must be correct. If not a valid season, returns 0 | |||
Uses ISO DIS 8601 2016 part 2 §4.7 Divisions of a year for hemishpere-independent seasons: | |||
21-24 = Spring, Summer, Autumn, Winter, independent of “Hemisphere” | 21-24 = Spring, Summer, Autumn, Winter, independent of “Hemisphere” | ||
These additional divisions not currently supported: | These additional divisions not currently supported: | ||
سطر ١١٣: | سطر ١٠٦: | ||
]] | ]] | ||
local function get_season_number (season | local function get_season_number (season) | ||
return cfg.date_names['local'].season[season] or -- look for local names first | return cfg.date_names['local'].season[season] or -- look for local names first | ||
cfg.date_names['en'].season[season] or -- failing that, look for English names | cfg.date_names['en'].season[season] or -- failing that, look for English names | ||
سطر ١٢٣: | سطر ١١٣: | ||
--[[--------------------------< | --[[--------------------------< I S _ P R O P E R _ N A M E >-------------------------------------------------- | ||
returns a non-zero number if date contains a recognized proper | returns a non-zero number if date contains a recognized proper name. Capitalization and spelling must be correct. | ||
]] | ]] | ||
local function | local function is_proper_name (name) | ||
return cfg.date_names['local'].named[name] or -- look for local names dates first | return cfg.date_names['local'].named[name] or -- look for local names dates first | ||
cfg.date_names['en'].named[name] or -- failing that, look for English names | cfg.date_names['en'].named[name] or -- failing that, look for English names | ||
سطر ١٧٠: | سطر ١٢٦: | ||
--[[--------------------------< | --[[--------------------------< I S _ V A L I D _ M O N T H _ O R _ S E A S O N >------------------------------ | ||
returns true if month or season | --returns true if month or season is valid (properly spelled, capitalized, abbreviated) | ||
]] | ]] | ||
local function | local function is_valid_month_or_season (month_season) | ||
if 0 == get_month_number (month_season) then -- if month text isn't one of the twelve months, might be a season | |||
if 0 == get_season_number (month_season) then -- not a month, is it a season? | |||
return false; -- return false not a month or one of the five seasons | |||
if 0 | |||
return | |||
end | end | ||
end | end | ||
return | return true; | ||
end | end | ||
سطر ١٩٣: | سطر ١٤٤: | ||
--[[--------------------------< I S _ V A L I D _ Y E A R >---------------------------------------------------- | --[[--------------------------< I S _ V A L I D _ Y E A R >---------------------------------------------------- | ||
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. | |||
]] | ]] | ||
local function is_valid_year (year) | local function is_valid_year(year) | ||
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 | ||
سطر ٢٠٩: | سطر ١٥٩: | ||
--[[--------------------------< I S _ V A L I D _ D A T E >---------------------------------------------------- | --[[--------------------------< I S _ V A L I D _ D A T E >---------------------------------------------------- | ||
Returns true if day is less than or equal to the number of days in month and year is no farther into the future | Returns true if day is less than or equal to the number of days in month and year is no farther into the future | ||
than next year; else returns false. | than next year; else returns false. | ||
سطر ٢٢٨: | سطر ١٧٧: | ||
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 -- is a leap year? | 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 | ||
end | end | ||
else | else | ||
month_length = days_in_month[month]; | month_length=days_in_month[month]; | ||
end | end | ||
سطر ٢٦٤: | سطر ٢١٣: | ||
if len1 == len2 then | if len1 == len2 then | ||
return true; -- both months are short form so return true | return true; -- both months are short form so return true | ||
elseif 'May' == month1 or 'May'== month2 then | elseif 'May' == month1 or 'May'== month2 then | ||
return true; -- both months are long form so return true | return true; -- both months are long form so return true | ||
elseif 3 == len1 or 3 == len2 then | elseif 3 == len1 or 3 == len2 then | ||
سطر ٢٨٠: | سطر ٢٢٩: | ||
Month pairs are expected to be left to right, earliest to latest in time. | Month pairs are expected to be left to right, earliest to latest in time. | ||
All season ranges are accepted as valid because there are publishers out there who have published a Summer–Spring YYYY issue | All season ranges are accepted as valid because there are publishers out there who have published a Summer–Spring YYYY issue so ... ok | ||
]] | ]] | ||
local function is_valid_month_season_range(range_start, range_end | local function is_valid_month_season_range(range_start, range_end) | ||
local range_start_number = get_month_number (range_start); | local range_start_number = get_month_number (range_start); | ||
local range_end_number; | local range_end_number; | ||
if 0 == range_start_number then -- is this a month range? | if 0 == range_start_number then -- is this a month range? | ||
range_start_number = get_season_number (range_start | range_start_number = get_season_number (range_start); -- not a month; is it a season? get start season number | ||
range_end_number = get_season_number (range_end | range_end_number = get_season_number (range_end); -- get end season number | ||
if (0 ~= range_start_number) and (0 | if (0 ~= range_start_number) and (0 ~= range_end_number) then | ||
return true; -- any season pairing is accepted | return true; -- any season pairing is accepted | ||
end | end | ||
return false; -- range_start and/or range_end is not a season | return false; -- range_start and/or range_end is not a season | ||
سطر ٢٩٩: | سطر ٢٤٨: | ||
-- 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 then -- 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? | if 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 | 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 | ||
سطر ٣٣٠: | سطر ٢٨٠: | ||
the output table receives: | the output table receives: | ||
rftdate: an | rftdate: an IS8601 formatted date | ||
rftchron: a free-form version of the date, usually without year which is in rftdate (season ranges and | rftchron: a free-form version of the date, usually without year which is in rftdate (season ranges and propername dates) | ||
rftssn: one of four season keywords: winter, spring, summer, fall (lowercase) | rftssn: one of four season keywords: winter, spring, summer, fall (lowercase) | ||
]] | ]] | ||
سطر ٣٤٥: | سطر ٢٩٤: | ||
local day = tonumber (input.day); | local day = tonumber (input.day); | ||
if (0 ~= day) and -- day must have a value for this to be a whole date | if (0 ~= day) and -- day must have a value for this to be a whole date | ||
(((1582 == year) and (10 <= month) and (12 >= month)) or -- any whole 1582 date from 1 | (((1582 == year) and (10 <= month) and (12 >= month)) or -- any whole 1582 date from 1 october to 31 December or | ||
((1926 == year) and (1 == month) and (1 == input.day)) or -- 1 January 1926 or | ((1926 == year) and (1 == month) and (1 == input.day)) or -- 1 January 1926 or | ||
((1582 < year) and (1925 >= year))) then -- any date 1 January 1583 – 31 December 1925 | ((1582 < year) and (1925 >= year))) then -- any date 1 January 1583 – 31 December 1925 | ||
tCOinS_date.inter_cal_cat = true; -- set category flag true | tCOinS_date.inter_cal_cat = true; -- set category flag true | ||
end | end | ||
-- end temporary Julian / | -- end temporary Julian / Gergorian calendar uncertainty detection | ||
if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only | if 1582 > tonumber(input.year) or 20 < tonumber(input.month) then -- Julian calendar or season so &rft.date gets year only | ||
سطر ٣٥٧: | سطر ٣٠٦: | ||
date = string.format ('%.4d/%.4d', tonumber(input.year), tonumber(input.year2)) -- assemble the date range | date = string.format ('%.4d/%.4d', tonumber(input.year), tonumber(input.year2)) -- assemble the date range | ||
end | end | ||
if 20 < tonumber(input.month) then -- if season or | if 20 < tonumber(input.month) then -- if season or propername date | ||
local season = {[24] = 'winter', [21] = 'spring', [22] = 'summer', [23] = 'fall | local season = {[24]='winter', [21]='spring', [22]='summer', [23]='fall', [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 date | ||
if | if 30 <tonumber(input.month) then | ||
tCOinS_date.rftchron = season[input.month]; -- proper | tCOinS_date.rftchron = season[input.month]; -- proper name dates | ||
else | else | ||
tCOinS_date.rftssn = season[input.month]; -- seasons | tCOinS_date.rftssn = season[input.month]; -- seasons | ||
سطر ٤٢٨: | سطر ٣٧٥: | ||
['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'}, | |||
-- 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'}, | ||
سطر ٤٤٥: | سطر ٣٩٢: | ||
-- month/season range year; months separated by endash | -- month/season range year; months separated by endash | ||
['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'}, | ['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'}, | ||
-- month/season year or proper-name year | -- month/season year or proper-name year | ||
['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, -- this way because endash is a member of %D; %D- will match January–March 2019 when it shouldn't | ['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, -- this way because endash is a member of %D; %D- will match January–March 2019 when it shouldn't | ||
-- these date formats cannot be converted | -- these date formats cannot be converted | ||
['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | ['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | ||
سطر ٤٥٣: | سطر ٣٩٩: | ||
['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 | ||
['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 | ||
} | } | ||
سطر ٤٦٦: | سطر ٤١١: | ||
If the date fails the format tests, this function returns false and does not return values for anchor_year and | If the date fails the format tests, this function returns false and does not return values for anchor_year and | ||
COinS_date. When this happens, the date parameter is | COinS_date. When this happens, the date parameter is used in the COinS metadata and the CITEREF identifier gets | ||
its year from the year parameter if present otherwise CITEREF does not get a date value. | its year from the year parameter if present otherwise CITEREF does not get a date value. | ||
Inputs: | Inputs: | ||
date_string - date string from date-holding parameters (date, year, | date_string - date string from date-holding parameters (date, year, accessdate, embargo, archivedate, etc.) | ||
Returns: | Returns: | ||
سطر ٤٨٠: | سطر ٤٢٥: | ||
]] | ]] | ||
local function check_date (date_string, | local function check_date (date_string, tCOinS_date, test_accessdate) | ||
local year; | 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; | local day2=0; -- second day in a day range | ||
local anchor_year; | local anchor_year; | ||
local coins_date; | local coins_date; | ||
if date_string:match (patterns['ymd'][1]) then -- year-initial numerical year month day format | if date_string:match (patterns['ymd'][1]) then -- year-initial numerical year month day format | ||
year, month, day = date_string:match (patterns['ymd'][1]); | year, month, day=date_string:match (patterns['ymd'][1]); | ||
if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar | if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar | ||
anchor_year = 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]); | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
elseif mw.ustring.match(date_string, patterns['Md-dy'][1]) then -- month-initial day range: month day–day, year; days are separated by endash | elseif mw.ustring.match(date_string, patterns['Md-dy'][1]) then -- month-initial day range: month day–day, year; days are separated by endash | ||
month, day, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-dy'][1]); | month, day, day2, anchor_year, year=mw.ustring.match(date_string, patterns['Md-dy'][1]); | ||
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
month2=month; -- for metadata | month2=month; -- for metadata | ||
year2 = year; | year2=year; | ||
elseif mw.ustring.match(date_string, patterns['dMy'][1]) then -- day-initial: day month year | elseif mw.ustring.match(date_string, patterns['dMy'][1]) then -- day-initial: day month year | ||
day, month, anchor_year, year = mw.ustring.match(date_string, patterns['dMy'][1]); | day, month, anchor_year, year=mw.ustring.match(date_string, patterns['dMy'][1]); | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
سطر ٥٢٠: | سطر ٤٦٠: | ||
--[[ NOT supported at en.wiki | --[[ NOT supported at en.wiki | ||
elseif mw.ustring.match(date_string, patterns['yMd'][1]) then -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed | elseif mw.ustring.match(date_string, patterns['yMd'][1]) then -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed | ||
anchor_year, year, month, day = mw.ustring.match(date_string, patterns['yMd'][1]); | anchor_year, year, month, day=mw.ustring.match(date_string, patterns['yMd'][1]); | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
سطر ٥٢٦: | سطر ٤٦٦: | ||
elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash | elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash | ||
day, day2, month, anchor_year, year = mw.ustring.match(date_string, patterns['d-dMy'][1]); | day, day2, month, anchor_year, year=mw.ustring.match(date_string, patterns['d-dMy'][1]); | ||
if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | if tonumber(day) >= tonumber(day2) then return false; end -- date range order is left to right: earlier to later; dates may not be the same; | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
month2 = month; -- for metadata | month2=month; -- for metadata | ||
year2 = year; | year2=year; | ||
elseif mw.ustring.match(date_string, patterns['dM-dMy'][1]) then -- day initial month-day-range: day month - day month year; uses spaced endash | elseif mw.ustring.match(date_string, patterns['dM-dMy'][1]) then -- day initial month-day-range: day month - day month year; uses spaced endash | ||
day, month, day2, month2, anchor_year, year = mw.ustring.match(date_string, patterns['dM-dMy'][1]); | day, month, day2, month2, anchor_year, year=mw.ustring.match(date_string, patterns['dM-dMy'][1]); | ||
if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later; | if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end -- date range order is left to right: earlier to later; | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
month2 = get_month_number (month2); | month2 = get_month_number (month2); | ||
year2 = year; | year2=year; | ||
elseif mw.ustring.match(date_string, patterns['Md-Mdy'][1]) then -- month initial month-day-range: month day – month day, year; uses spaced endash | elseif mw.ustring.match(date_string, patterns['Md-Mdy'][1]) then -- month initial month-day-range: month day – month day, year; uses spaced endash | ||
month, day, month2, day2, anchor_year, year = mw.ustring.match(date_string, patterns['Md-Mdy'][1]); | month, day, month2, day2, anchor_year, year=mw.ustring.match(date_string, patterns['Md-Mdy'][1]); | ||
if (not is_valid_month_season_range(month, month2 | if (not is_valid_month_season_range(month, month2)) or not is_valid_year(year) then return false; end | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
month2 = get_month_number (month2); | month2 = get_month_number (month2); | ||
year2 = year; | year2=year; | ||
elseif mw.ustring.match(date_string, patterns['dMy-dMy'][1]) then -- day initial month-day-year-range: day month year - day month year; uses spaced endash | elseif mw.ustring.match(date_string, patterns['dMy-dMy'][1]) then -- day initial month-day-year-range: day month year - day month year; uses spaced endash | ||
day, month, year, day2, month2, anchor_year, year2 = mw.ustring.match(date_string, patterns['dMy-dMy'][1]); | day, month, year, day2, month2, anchor_year, year2=mw.ustring.match(date_string, patterns['dMy-dMy'][1]); | ||
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
month2 = get_month_number (month2); | month2 = get_month_number (month2); | ||
elseif mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]) then -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash | elseif mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]) then -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash | ||
month, day, year, month2, day2, anchor_year, year2 = mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]); | month, day, year, month2, day2, anchor_year, year2=mw.ustring.match(date_string, patterns['Mdy-Mdy'][1]); | ||
if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | if tonumber(year2) <= tonumber(year) then return false; end -- must be sequential years, left to right, earlier to later | ||
if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | if not is_valid_year(year2) or not is_valid_month_range_style(month, month2) then return false; end -- year2 no more than one year in the future; months same style | ||
month = get_month_number (month); -- for metadata | month = get_month_number (month); -- for metadata | ||
month2 = get_month_number(month2); | month2 = get_month_number (month2); | ||
elseif mw.ustring.match(date_string, patterns['Sy4-y2'][1]) then -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | elseif mw.ustring.match(date_string, patterns['Sy4-y2'][1]) then -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | ||
local century; | local century; | ||
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 | ||
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 | ||
month = get_season_number(month | month = get_season_number (month); | ||
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 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; -- assemble anchor_year from both years | 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 | ||
month = get_season_number (month | month = get_season_number (month); -- for metadata | ||
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 | ||
سطر ٥٨٩: | سطر ٥٢٧: | ||
month = get_month_number(month); | month = get_month_number(month); | ||
month2 = get_month_number(month2); | month2 = get_month_number(month2); | ||
elseif 0 ~= get_season_number(month | elseif 0 ~= get_season_number(month) and 0 ~= get_season_number(month2) then -- both must be or season year, not mixed | ||
month = get_season_number(month | month = get_season_number(month); | ||
month2 = get_season_number(month2 | month2 = get_season_number(month2); | ||
else | else | ||
return false; | return false; | ||
سطر ٥٩٧: | سطر ٥٣٥: | ||
elseif mw.ustring.match(date_string, patterns['M-My'][1]) then -- month/season range year; months separated by endash | elseif mw.ustring.match(date_string, patterns['M-My'][1]) then -- month/season range year; months separated by endash | ||
month, month2, anchor_year, year = mw.ustring.match(date_string, patterns['M-My'][1]); | month, month2, anchor_year, year=mw.ustring.match(date_string, patterns['M-My'][1]); | ||
if (not is_valid_month_season_range(month, month2 | if (not is_valid_month_season_range(month, month2)) or (not is_valid_year(year)) then return false; end | ||
if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season | if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season | ||
month = get_month_number(month); | month = get_month_number(month); | ||
month2 = get_month_number(month2); | month2 = get_month_number(month2); | ||
else | else | ||
month = get_season_number(month | month = get_season_number(month); | ||
month2 = get_season_number(month2 | month2 = get_season_number(month2); | ||
end | end | ||
year2 = year; | year2=year; | ||
elseif mw.ustring.match(date_string, patterns['My'][1]) then -- month/season | elseif mw.ustring.match(date_string, patterns['My'][1]) then -- month/season year or proper-name year | ||
month, anchor_year, year = mw.ustring.match(date_string, patterns['My'][1]); | month, anchor_year, year=mw.ustring.match(date_string, patterns['My'][1]); | ||
if not is_valid_year(year) then return false; end | if not is_valid_year(year) then return false; end | ||
month = | if not is_valid_month_or_season (month) and 0 == is_proper_name (month) then return false; end | ||
if 0 ~= get_month_number(month) then -- determined to be a valid range so just check this one to know if month or season | |||
month = get_month_number(month); | |||
elseif 0 ~= get_season_number(month) then | |||
month = get_season_number(month); | |||
else | |||
month = is_proper_name (month); -- must be proper name; not supported in COinS | |||
end | |||
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 | ||
سطر ٦٢٣: | سطر ٥٦٦: | ||
elseif mw.ustring.match(date_string, patterns['y4-y2'][1]) then -- Year range: YYYY–YY; separated by unspaced endash | elseif mw.ustring.match(date_string, patterns['y4-y2'][1]) then -- Year range: YYYY–YY; separated by unspaced endash | ||
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 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; -- add the century to year2 for comparisons | 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 | ||
return false; | return false; | ||
سطر ٦٤٥: | سطر ٥٨٣: | ||
end | end | ||
if | if test_accessdate then -- test accessdate 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; accessdate 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 accessdate out of bounds | ||
end | end | ||
سطر ٦٥٨: | سطر ٥٩٦: | ||
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); | ||
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) | ||
result = is_valid_date(year, month, day); | result=is_valid_date(year,month,day); | ||
result = result and is_valid_date(year2, month2, day2); | result=result and is_valid_date(year2,month2,day2); | ||
end | end | ||
سطر ٦٧٦: | سطر ٦١٤: | ||
if nil ~= tCOinS_date then -- this table only passed into this function when testing |date= parameter values | if nil ~= tCOinS_date then -- this table only passed into this function when testing |date= parameter values | ||
make_COinS_date ({year = year, month = month, day = day, year2 = year2, month2 = month2, day2 = day2}, tCOinS_date); -- make an ISO 8601 date string for COinS | make_COinS_date ({year=year, month=month, day=day, year2=year2, month2=month2, day2=day2}, tCOinS_date); -- make an ISO 8601 date string for COinS | ||
end | end | ||
سطر ٦٩٠: | سطر ٦٢٨: | ||
Unlike most error messages created in this module, only one error message is created by this function. Because all of the date holding parameters are processed serially, | Unlike most error messages created in this module, only one error message is created by this function. Because all of the date holding parameters are processed serially, | ||
a single error message is created as the dates are tested. | |||
]] | ]] | ||
local function dates(date_parameters_list, tCOinS_date | local function dates(date_parameters_list, tCOinS_date) | ||
local anchor_year; | local anchor_year; -- will return as nil if the date being tested is not |date= | ||
local COinS_date; | local COinS_date; -- will return as nil if the date being tested is not |date= | ||
local embargo_date; -- if embargo date is a good dmy, mdy, ymd date then holds original value else reset to 9999 | local embargo_date; -- if embargo date is a good dmy, mdy, ymd date then holds original value else reset to 9999 | ||
local error_message = ""; | |||
local good_date = false; | local good_date = false; | ||
for k, v in pairs(date_parameters_list) do -- for each date-holding parameter in the list | for k, v in pairs(date_parameters_list) do -- for each date-holding parameter in the list | ||
if is_set(v.val) then -- if the parameter has a value | if is_set(v.val) then -- if the parameter has a value | ||
v.val = mw.ustring.gsub(v.val, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9 | v.val = mw.ustring.gsub (v.val, '%d', cfg.date_names.local_digits); -- translate 'local' digits to Western 0-9 | ||
if v.val:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year= | if v.val:match("^c%. [1-9]%d%d%d?%a?$") then -- special case for c. year or with or without CITEREF disambiguator - only |date= and |year= | ||
local year = v.val:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested | local year = v.val:match("c%. ([1-9]%d%d%d?)%a?"); -- get the year portion so it can be tested | ||
if 'date' == k then | if 'date'==k then | ||
anchor_year, COinS_date = v.val:match("((c%. [1-9]%d%d%d?)%a?)"); -- anchor year and COinS_date only from |date= parameter | anchor_year, COinS_date = v.val:match("((c%. [1-9]%d%d%d?)%a?)"); -- anchor year and COinS_date only from |date= parameter | ||
good_date = is_valid_year(year); | good_date = is_valid_year(year); | ||
elseif 'year' == k then | elseif 'year'==k then | ||
good_date = is_valid_year(year); | good_date = is_valid_year(year); | ||
end | end | ||
elseif 'date' == k then -- if the parameter is |date= | elseif 'date'==k then -- if the parameter is |date= | ||
if v.val:match("^n%.d%.%a?$") then | if v.val:match("^n%.d%.%a?$") then -- if |date=n.d. with or without a CITEREF disambiguator | ||
good_date, anchor_year, COinS_date = true, v.val:match("((n%.d%.)%a?)"); | good_date, anchor_year, COinS_date = true, v.val:match("((n%.d%.)%a?)"); --"n.d."; no error when date parameter is set to no date | ||
elseif v.val:match("^nd%a?$") then | elseif v.val:match("^nd%a?$") then -- if |date=nd with or without a CITEREF disambiguator | ||
good_date, anchor_year, COinS_date = true, v.val:match("((nd)%a?)"); | good_date, anchor_year, COinS_date = true, v.val:match("((nd)%a?)"); --"nd"; no error when date parameter is set to no date | ||
else | else | ||
good_date, anchor_year, COinS_date = check_date (v.val | good_date, anchor_year, COinS_date = check_date (v.val, tCOinS_date); -- go test the date | ||
end | end | ||
elseif 'year' == k then -- if the parameter is |year= it should hold only a year value | elseif 'year'==k then -- if the parameter is |year= it should hold only a year value | ||
if v.val:match("^[1-9]%d%d%d?%a?$") then -- if |year = 3 or 4 digits only with or without a CITEREF disambiguator | if v.val:match("^[1-9]%d%d%d?%a?$") then -- if |year= 3 or 4 digits only with or without a CITEREF disambiguator | ||
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 ' | elseif 'access-date'==k then -- if the parameter is |date= | ||
good_date = check_date (v.val | good_date = check_date (v.val, nil, true); -- go test the date; nil is a placeholder; true is the test_accessdate flag | ||
elseif 'embargo'==k then -- if the parameter is |embargo= | |||
good_date = check_date (v.val); -- 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 | | good_date, embargo_date = is_valid_embargo_date (v.val); -- is |embargo= date a single dmy, mdy, or ymd formatted date? yes:returns embargo; no: returns 9999 | ||
end | end | ||
else -- any other date-holding parameter | else -- any other date-holding parameter | ||
good_date = check_date (v.val | good_date = check_date (v.val); -- go test the date | ||
end | end | ||
if false == good_date then -- assemble one error message so we don't add the tracking category multiple times | if false==good_date then -- assemble one error message so we don't add the tracking category multiple times | ||
if is_set(error_message) then -- once we've added the first portion of the error message ... | |||
error_message=error_message .. ", "; -- ... add a comma space separator | |||
end | |||
error_message=error_message .. "|" .. v.name .. "="; -- add the failed parameter | |||
end | end | ||
end | end | ||
end | end | ||
return anchor_year, embargo_date; | return anchor_year, embargo_date, error_message; -- and done | ||
end | end | ||
سطر ٧٤٢: | سطر ٦٨٦: | ||
--[[--------------------------< 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 returns a 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) | ||
]] | ]] | ||
local function year_date_check (year_string | local function year_date_check (year_string, date_string) | ||
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?)'); | ||
سطر ٧٩٠: | سطر ٧٢٩: | ||
result = 0; | result = 0; | ||
end | end | ||
else | else | ||
result = 0; -- no recognizable year in date | result = 0; -- no recognizable year in date | ||
end | end | ||
return result; | |||
end | end | ||
سطر ٨٠٧: | سطر ٧٤١: | ||
reformatted. Does the grunt work for reformat_dates(). | reformatted. Does the grunt work for reformat_dates(). | ||
The table re_formats maps | The table re_formats maps patern_idx (current format) and format_param (desired format) to a table that holds: | ||
format string used by string.format() | format string used by string.format() | ||
identifier letters ('d', 'm', 'y', 'd2', 'm2', 'y2') that serve as indexes into a table t{} that holds captures | identifier letters ('d', 'm', 'y', 'd2', 'm2', 'y2') that serve as indexes into a table t{} that holds captures | ||
سطر ٨١٧: | سطر ٧٥١: | ||
patterns['ymd'][1] is the match pattern with captures for mw.ustring.match() | patterns['ymd'][1] is the match pattern with captures for mw.ustring.match() | ||
patterns['ymd'][2] is an indicator letter identifying the content of the first capture | patterns['ymd'][2] is an indicator letter identifying the content of the first capture | ||
patterns['ymd'][3] ... the second capture etc | patterns['ymd'][3] ... the second capture etc | ||
when a pattern matches a date, the captures are loaded into table t{} in capture order using the idemtifier | when a pattern matches a date, the captures are loaded into table t{} in capture order using the idemtifier | ||
سطر ٨٣٤: | سطر ٧٦٨: | ||
['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'}, -- |df=yMd; not supported at en.wiki | |||
}, | }, | ||
['Mdy'] = { -- date format is Mdy; reformat to: | ['Mdy'] = { -- date format is Mdy; reformat to: | ||
سطر ٨٤٠: | سطر ٧٧٤: | ||
['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'}, -- |df=yMd; not supported at en.wiki | |||
}, | }, | ||
['dMy'] = { -- date format is dMy; reformat to: | ['dMy'] = { -- date format is dMy; reformat to: | ||
سطر ٨٤٦: | سطر ٧٨٠: | ||
['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'}, -- |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: | ||
سطر ٨٨١: | سطر ٨١٥: | ||
['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic | ['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic | ||
}, | }, | ||
-- ['yMd'] = { -- not supported at en.wiki | |||
-- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | |||
-- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | |||
-- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | |||
-- }, | |||
} | } | ||
سطر ٩٠٢: | سطر ٨٣٦: | ||
end | end | ||
-- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- not supported at en.wiki | |||
if 'yMd' == format_param then -- not supported at en.wiki | |||
if 'yMd' == format_param then -- | |||
return; -- not a reformattable date | return; -- not a reformattable date | ||
end | end | ||
سطر ٩٢١: | سطر ٨٥٣: | ||
[patterns[pattern_idx][8] or 'x'] = c7; | [patterns[pattern_idx][8] or 'x'] = c7; | ||
}; | }; | ||
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) | ||
سطر ٩٣٤: | سطر ٨٦٢: | ||
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 | |||
if 1582 > tonumber (t.y) then -- ymd format dates not allowed before 1582 | |||
return; | return; | ||
end | end | ||
سطر ١٬٠٤٩: | سطر ٩٧٦: | ||
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) then | ||
not mw.ustring.match (param_val.val, | if not mw.ustring.match (param_val.val, '%d%d%d%d%-%d%d%-%d%d') 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 | ||
سطر ١٬٠٥٦: | سطر ٩٨٣: | ||
result = true; | result = true; | ||
end | end | ||
end | |||
end | end | ||
end | end | ||
return result; -- so we know if any hyphens were replaced | return result; -- so we know if any hyphens were replaced | ||
end | end | ||
سطر ١٬٠٩٤: | سطر ٩٩٥: | ||
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. | ||
if xlat_dig is true, this function will also translate | if xlat_dig is true, this function will also translate western (English) digits to the local language's digits. | ||
This will also translate ymd dates. | This will also translate ymd dates. | ||
]] | ]] | ||
local function date_name_xlate (date_parameters_list, xlt_dig) | local function date_name_xlate (date_parameters_list, xlt_dig) | ||
local xlate; | local xlate; | ||
local mode; -- long or short month names | local mode; -- long or short month names | ||
سطر ١٬١٢٦: | سطر ١٬٠٢٧: | ||
if xlt_dig then -- shall we also translate digits? | if xlt_dig then -- shall we also translate digits? | ||
date = date:gsub ('%d', cfg.date_names.xlate_digits); -- translate digits from | date = date:gsub ('%d', cfg.date_names.xlate_digits); -- translate digits from western to 'local digits' | ||
date_parameters_list[param_name].val = date; -- save the translated date | date_parameters_list[param_name].val = date; -- save the translated date | ||
modified = true; | modified = true; | ||
سطر ١٬١٣٤: | سطر ١٬٠٣٥: | ||
return modified; | return modified; | ||
end | end | ||
سطر ١٬١٤٤: | سطر ١٬٠٤٥: | ||
local function set_selected_modules (cfg_table_ptr, utilities_page_ptr) | local function set_selected_modules (cfg_table_ptr, utilities_page_ptr) | ||
is_set = utilities_page_ptr.is_set; -- import functions from selected Module:Citation/CS1/Utilities module | |||
in_array = utilities_page_ptr.in_array; -- import functions from selected Module:Citation/CS1/Utilities module | |||
in_array = utilities_page_ptr.in_array; | |||
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 | end | ||
سطر ١٬١٦٤: | سطر ١٬٠٦٠: | ||
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, | ||
set_selected_modules = set_selected_modules | set_selected_modules = set_selected_modules | ||
} | } |