Module:Quotations/date validation

local canonical_AD = 'AD' local canonical_BCE = 'BCE' local AD_limit = 999 -- maximum year to append CE local export = {}

local function validate_year(yearstring) local year = tonumber(yearstring) if (year == nil) then return false end if (year <= 0) then return false end return year end

local function validate_tp(tpstring) -- validates ad, bc, bce, ... local tpstring = string.upper(tpstring) local tpstring = string.gsub(tpstring, "%.", "")

local bcetable = {["BC"] = true, ["BCE"] = true} local adtable = {["AD"] = true, ["CE"] = true}

if bcetable[tpstring] then return canonical_BCE end if adtable[tpstring] then return canonical_AD end return false end

local function validate_approx(approxstring) approxstring = string.lower(approxstring) approxstring = string.gsub(approxstring, "%.", "")

local approx_table = {["a"] = true, ["c"] = true, ["circa"] = true, ["approx"] = true}

if approx_table[approxstring] then return "a" end return false end local function parse_date(datestring) local result = {} local separators = {'-', '–'} local canonical_separator = '-' for i, separator in pairs(separators) do -- replace any nonstandard separators datestring = string.gsub(datestring, separator, canonical_separator) end local datetable = mw.text.split(datestring, canonical_separator) for i, yearstring in ipairs(datetable) do		local yeartable_temp = mw.text.split(yearstring, ' ') local yeartable = {} for i, v in ipairs(yeartable_temp) do -- remove any empty strings if (v ~= '') then table.insert(yeartable, v)			end end if (#yeartable == 1) then -- only year is specified table.insert(result, {'e', validate_year(yeartable[1]), "?"}) end if (#yeartable == 2) then -- either year, BCE/AD or c, year local yt1 = validate_year(yeartable[1]) local yt2 = validate_year(yeartable[2]) if (yt1 ~= false) then -- year, BCE/AD table.insert(result, {'e', yt1, validate_tp(yeartable[2])}) end if (yt1 == false) then -- c, year table.insert(result, {validate_approx(yeartable[1]), yt2, "?"}) end end if (#yeartable == 3) then -- c, year, BCE/AD table.insert(result, {validate_approx(yeartable[1]), validate_year(yeartable[2]), validate_tp(yeartable[3])}) end end

for i, v in pairs(result) do		for i_, v_ in pairs(v) do			if (v_ == false) then return false end end end if (#result == 1) then if result[1][3] == "?" then result[1][3] = canonical_AD end return result end if (#result == 2) then -- add in missing time periods if result[1][3] == "?" then if result[2][3] == "?" then result[1][3] = canonical_AD result[2][3] = canonical_AD end if result[2][3] == canonical_AD then result[1][3] = canonical_AD end if result[2][3] == canonical_BCE then result[1][3] = canonical_BCE end end if result[1][3] == canonical_AD then if result[2][3] == "?" then result[2][3] = canonical_AD end if result[2][3] == canonical_BCE then return false end end if result[1][3] == canonical_BCE then if result[2][3] == "?" then result[2][3] = canonical_BCE end end

-- validate time ranges if result[1][3] == result[2][3] then if result[1][3] == canonical_BCE then if result[2][2] > result[1][2] then return false end else if result[2][2] < result[1][2] then return false end end else if result[1][3] == canonical_AD and result[2][3] == canonical_BCE then return false end end

return result end return false end

local function display_date(parsed_date) local separator = ' – '

local CE = "CE " local BCE = "BCE " local circa = "c." local result = {} for i, v in ipairs(parsed_date) do   	local s = "" if v[1] == 'a' then s = s..circa.." " end s = s..tostring(v[2]).." " if v[3] == canonical_BCE then s = s..BCE end if v[3] == canonical_AD then if (v[2] <= AD_limit) then s = s..CE			end end table.insert(result, mw.text.trim(s)) end return table.concat(result, separator) end

function export.main(datestring)

local parsed_date = parse_date(datestring) if (parsed_date ~= false) then return display_date(parsed_date) end return datestring end

return export