local yesno = require('Modül:Evethayır') local lang = mw.language.getContentLanguage local N_YEAR_DIGITS = 12 local MAX_YEAR = 10^N_YEAR_DIGITS - 1 -------------------------------------------------------------------------------- -- Dts class -------------------------------------------------------------------------------- local Dts = {} Dts.__index = Dts Dts.months = { "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık" } Dts.monthsAbbr = { "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara" } function Dts._makeMonthSearch(t) local ret = {} for i, month in ipairs(t) do ret[month:lower] = i end return ret end Dts.monthSearch = Dts._makeMonthSearch(Dts.months) Dts.monthSearchAbbr = Dts._makeMonthSearch(Dts.monthsAbbr) -- Dts.monthSearchAbbr['sept'] = 9 -- Allow "Sept" to match September Dts.formats = { dmy = true, mdy = true, dm = true, md = true, my = true, y = true, m = true, d = true, hide = true } function Dts.new(args) local self = setmetatable({}, Dts) -- Tarih parametlerini işle. -- Bu adımda ayrıca tarihin GAY biçiminde mi yoksa YAG mi olduğunu, ve -- ay isminin kısaltılıp kısaltılmadığını işliyoruz. if args[2] or args[3] or args[4] then selfarseDateParts(args[1], args[2], args[3], args[4]) elseif args[1] then selfarseDate(args[1]) end -- Geçersiz değerlerde hata döndür if self.year then if self.year 0 then error('yıllar sıfır olamaz', 0) elseif self.year < -MAX_YEAR then error(string.format( 'yıllar %s değerinden küçük olamaz', lang:formatNum(-MAX_YEAR) ), 0) elseif self.year > MAX_YEAR then error(string.format( 'yıllar %s değerinden büyük olamaz', lang:formatNum(MAX_YEAR) ), 0) elseif math.floor(self.year) ~ self.year then error('yıllar tam sayı olmalıdır', 0) end end if self.month and ( self.month < 1 or self.month > 12 or math.floor(self.month) ~ self.month ) then error('aylar 1 ve 12 arasında (dahil) bir tam sayı olmalıdır', 0) end if self.day and ( self.day < 1 or self.day > 31 or math.floor(self.day) ~ self.day ) then error('günler 1 ve 31 arasında (dahil) bir tam sayı olmalıdır', 0) end -- Ay kısaltma davranışını ayarla, yani çıktının "January" mi yoksa "Jan" mi -- olacağını. if args.abbr then self.isAbbreviated args.abbr 'on' or yesno(args.abbr) or false else self.isAbbreviated = self.isAbbreviated or false end -- Biçim string'ini ayarla if args.format then self.format = args.format else self.format = self.format or 'mdy' end if not Dts.formats[self.format] then error(string.format( "'%s' geçerli bir biçim değil", tostring(self.format) ), 0) end -- Set addkey. This adds a value at the end of the sort key, allowing users -- to manually distinguish between identical dates. if args.addkey then self.addkey = tonumber(args.addkey) if not self.addkey or self.addkey < 0 or self.addkey > 9999 or math.floor(self.addkey) ~= self.addkey then error("'addkey' parametresi 0 ile 9999 arasında bir tam sayı olmalıdır", 0) end end -- Set whether the displayed date is allowed to wrap or not. self.isWrapping = args.nowrap 'off' or yesno(args.nowrap) false return self end function Dts:hasDate return (self.year or self.month or self.day) ~= nil end -- Find the month number for a month name, and set the isAbbreviated flag as -- appropriate. function DtsarseMonthName(s) s = s:lower local month = Dts.monthSearch if month then return month else month = Dts.monthSearchAbbr if month then self.isAbbreviated = true return month end end return nil end -- Parses separate parameters for year, month, day, and era. function DtsarseDateParts(year, month, day, bc) if year then self.year = tonumber(year) if not self.year then error(string.format( "'%s' geçerli bir yıl değil", tostring(year) ), 0) end end if month then if tonumber(month) then self.month = tonumber(month) elseif type(month) 'string' then self.month selfarseMonthName(month) end if not self.month then error(string.format( "'%s' geçerli bir ay değil", tostring(month) ), 0) end end if day then self.day tonumber(day) if not self.day then error(string.format( "'%s' geçerli bir gün değil", tostring(day) ), 0) end end if bc then local bcLower type(bc) 'string' and mw.ustring.lower(bc) if bcLower == 'mö' then if self.year and self.year > 0 then self.year = -self.year end elseif bcLower ~= 'ms' then error(string.format( "'%s' geçerli bir devir kodu değil ('MÖ' ya da 'MS' bekleniyordu)", tostring(bc) ), 0) end end end -- This method parses date strings. This is a poor man's alternative to -- mw.language:formatDate, but it ends up being easier for us to parse the date -- here than to use mw.language:formatDate and then try to figure out after the -- fact whether the month was abbreviated and whether we were DMY or MDY. function DtsarseDate(date) -- Genel hata mesajı. local function dateError error(string.format( "'%s' geçersiz bir tarih", date ), 0) end local function parseDayOrMonth(s) if s:find('^%d%d?$') then return tonumber(s) end end local function parseYear(s) if s:find('^%d%d%d%d?$') then return tonumber(s) end end -- Deal with year-only dates first, as they can have hyphens in, and later -- we need to split the string by all non-word characters, including -- hyphens. Also, we don't need to restrict years to 3 or 4 digits, as on -- their own they can't be confused as a day or a month number. self.year = tonumber(date) if self.year then return end -- Kelime olmayan karakterleri sınır olarak kullanarak string'i böl. date = tostring(date) local parts = mw.text.split(date, '%W+') local nParts = #parts if parts[1] or parts[nParts] or nParts > 3 then -- We are parsing a maximum of three elements, so raise an error if we -- have more. If the first or last elements were blank, then the start -- or end of the string was a non-word character, which we will also -- treat as an error. dateError elseif nParts < 1 then -- Eğer birden az elementimiz varsa, bir şeyler çok ama çok yanlış -- gitmiş demektir. error(string.format( "'%s' tarihini işlerken bilinmeyen bir hata oluştu", date ), 0) end if nParts 1 then -- Bu ya ay ismi ya da yıl olabilir. self.month selfarseMonthName(parts[1]) if not self.month then self.year parseYear(parts[1]) if not self.year then dateError end end elseif nParts 2 then -- Bu aşağıdaki biçimlerden herhangi biri olabilir: -- GG Ay -- Ay GG -- Ay YYYY -- YYYY-AA self.month = selfarseMonthName(parts[1]) if self.month then -- Bu ya Ay GG ya da Ay YYYY. self.year = parseYear(parts[2]) if not self.year then -- Bu Ay GG. self.format = 'mdy' self.day = parseDayOrMonth(parts[2]) if not self.day then dateError end end else self.month = selfarseMonthName(parts[2]) if self.month then -- Bu GG Ay. self.format = 'dmy' self.day = parseDayOrMonth(parts[1]) if not self.day then dateError end else -- Bu YYYY-AA. self.year = parseYear(parts[1]) self.month = parseDayOrMonth(parts[2]) if not self.year or not self.month then dateError end end end elseif nParts == 3 then -- Bu aşağıdaki biçimlerden herhangi biri olabilir: -- GG Ay YYYY -- Ay GG, YYYY -- YYYY-AA-GG -- GG-AA-YYYY self.month = selfarseMonthName(parts[1]) if self.month then -- Bu Ay GG, YYYY. self.format = 'mdy' self.day = parseDayOrMonth(parts[2]) self.year = parseYear(parts[3]) if not self.day or not self.year then dateError end else self.day = parseDayOrMonth(parts[1]) if self.day then self.month = selfarseMonthName(parts[2]) if self.month then -- Bu GG Ay YYYY. self.format = 'dmy' self.year = parseYear(parts[3]) if not self.year then dateError end else -- Bu GG-AA-YYYY. self.format = 'dmy' self.month = parseDayOrMonth(parts[2]) self.year = parseYear(parts[3]) if not self.month or not self.year then dateError end end else -- Bu YYYY-AA-GG self.year = parseYear(parts[1]) self.month = parseDayOrMonth(parts[2]) self.day = parseDayOrMonth(parts[3]) if not self.year or not self.month or not self.day then dateError end end end end end function Dts:makeSortKey local year, month, day local nYearDigits = N_YEAR_DIGITS if self:hasDate then year = self.year or os.date("*t").year if year < 0 then year = -MAX_YEAR - 1 - year nYearDigits = nYearDigits + 1 -- For the minus sign end month = self.month or 1 day = self.day or 1 else -- Boş bağlantıları en son sıralanmalı. year = MAX_YEAR month = 99 day = 99 end return string.format( '%0' .. nYearDigits .. 'd-%02d-%02d-%04d', year, month, day, self.addkey or 0 ) end function Dts:getMonthName if not self.month then return end if self.isAbbreviated then return self.monthsAbbr[self.month] else return self.months[self.month] end end function Dts:makeDisplay if self.format == 'hide' then return end local hasYear = self.year and self.format:find('y') local hasMonth = self.month and self.format:find('m') local hasDay = self.day and self.format:find('d') local isMonthFirst = self.format:find('md') local ret = {} if hasDay and hasMonth and isMonthFirst then ret[#ret + 1] = self.day ret[#ret + 1] = ' ' ret[#ret + 1] = self:getMonthName elseif hasDay and hasMonth then ret[#ret + 1] = self.day ret[#ret + 1] = ' ' ret[#ret + 1] = self:getMonthName elseif hasDay then ret[#ret + 1] = self.day elseif hasMonth then ret[#ret + 1] = self:getMonthName end if hasYear then if hasDay or hasMonth then ret[#ret + 1] = ' ' end local displayYear = math.abs(self.year) if displayYear > 9999 then displayYear = lang:formatNum(displayYear) else displayYear = tostring(displayYear) end ret[#ret + 1] = displayYear if self.year < 0 then table.insert(ret, 1, 'MÖ ') end end return table.concat(ret) end function Dts:__tostring local root = mw.html.create local span = root:tag('span') :attr('data-sort-value', self:makeSortKey) -- Display if self:hasDate and self.format ~= 'hide' then span:wikitext(self:makeDisplay) if not self.isWrapping then span:css('white-space', 'nowrap') end end return tostring(root) end -------------------------------------------------------------------------------- -- Dışa aktarımlar -------------------------------------------------------------------------------- local p = {} function p._exportClasses return { Dts = Dts } end function p._main(args) local success, ret = pcall(function local dts = Dts.new(args) return tostring(dts) end) if success then return ret else ret = string.format( '', ret ) if mw.title.getCurrentTitle.namespace == 0 then -- Yalnızca ana isim alanında kategorize et ret = ret .. 'Kategori:Hatalı sıralanabilir tablo için tarih şablonları' end return ret end end function p.main(frame) local args = require('Modül:Bağımsız değişkenler').getArgs(frame, { wrappers = 'Şablon:Sıralanabilir tablo için tarih', }) return p._main(args) end return p