پرش به محتوا

پودمان:ناوبری مجموعه رده

پودمان به طور دائم حفاظت‌شده است
از ویکی‌پدیا، دانشنامهٔ آزاد
(تغییرمسیر از پودمان:Navseasoncats)
توضیحات پودمان[ایجاد] [پاکسازی]
require('strict')
local p = {}
local horizontal = require('Module:List').horizontal
local convertnum = require('Module:Numeral converter').convert
local yesno = require('Module:Yesno')
local setFarsiArguments = require('Module:Set Farsi argument names')

local centurysublinks, decadesublinks = false, false
local currtitle = mw.title.getCurrentTitle()
local isincatns = currtitle.nsText == 'رده'
local isinmainspace = currtitle.nsText == ''
local errors = ''
local testcasecolon = ''
local testcases = mw.ustring.match(currtitle.subpageText, '^آزمایشی')
if    testcases then testcasecolon = ':' end
local skipgaps_limit = 50
local ttrackingcats = { --when reindexing, Ctrl+H 'trackcat(13,' & 'ttrackingcats[16]'
	'', -- [1] placeholder for [[رده:ناوبری مجموعه رده با کاربرد پارامتر رده]]
	'', -- [2] placeholder for [[رده:ناوبری مجموعه رده با کاربرد پارامتر آزمایشی]]
	'', -- [3] placeholder for [[رده:ناوبری مجموعه رده با کاربرد پارامتر نامعلوم]]
	'', -- [4] placeholder for [[رده:ناوبری مجموعه رده با بازه فاقد خط فاصله ان]]
	'', -- [5] placeholder for [[رده:ناوبری مجموعه رده با بازه کوته‌نویسی‌شده (شیوه‌نامه)]]
	'', -- [6] placeholder for [[رده:ناوبری مجموعه رده با بازه تغییرمسیریافته (تغییر مبنی)]]
	'', -- [7] placeholder for [[رده:ناوبری مجموعه رده با بازه تغییرمسیریافته (تغییر متغیر)]]
	'', -- [8] placeholder for [[رده:ناوبری مجموعه رده با بازه تغییرمسیریافته (پایان)]]
	'', -- [9] placeholder for [[رده:ناوبری مجموعه رده با بازه تغییرمسیریافته (شیوه‌نامه)]]
	'', --[10] placeholder for [[رده:ناوبری مجموعه رده با بازه تغییرمسیریافته (سایر)]]
	'', --[11] placeholder for [[رده:ناوبری مجموعه رده با وقفه در بازه]]
	'', --[12] placeholder for [[رده:ناوبری مجموعه رده با بازه نامنظم]]
	'', --[13] placeholder for [[رده:ناوبری مجموعه رده با بازه نامنظم، طول ۰]]
	'', --[14] placeholder for [[رده:ناوبری مجموعه رده با پایان بازه (اکنون)]]
	'', --[15] placeholder for [[رده:ناوبری مجموعه رده با پایان بازه (خالی، شیوه‌نامه)]]
	'', --[16] placeholder for [[رده:ناوبری مجموعه رده منزوی]]
	'', --[17] placeholder for [[رده:ناوبری مجموعه رده با اندازه پیش‌فرض وقفه فصل]]
	'', --[18] placeholder for [[رده:ناوبری مجموعه رده با دهه تغییرمسیریافته]]
	'', --[19] placeholder for [[رده:ناوبری مجموعه رده با سال تغییرمسیریافته (تغییر مبنی)]]
	'', --[20] placeholder for [[رده:ناوبری مجموعه رده با سال تغییرمسیریافته (تغییر متغیر)]]
	'', --[21] placeholder for [[رده:ناوبری مجموعه رده با سال تغییرمسیریافته (سایر)]]
	'', --[22] placeholder for [[رده:ناوبری مجموعه رده با فصل تلویزیونی تغییرمسیریافته]]
	'', --[23] placeholder for [[رده:ناوبری مجموعه رده با پارامتر پرش از وقفه]]
	'', --[24] placeholder for [[رده:ناوبری مجموعه رده سال و بازه]]
	'', --[25] placeholder for [[رده:ناوبری مجموعه رده سال و دهه]]
	'', --[26] placeholder for [[رده:ناوبری مجموعه رده دهه و سده]]
	'', --[27] placeholder for [[رده:ناوبری مجموعه رده در فضای نام اصلی]]
	'', --[28] placeholder for [[رده:ناوبری مجموعه رده با خطا در تغییرمسیر]]
}
local avoidself =  (not mw.ustring.match(currtitle.text, 'ناوبری مجموعه رده با') and
					not mw.ustring.match(currtitle.text, 'ناوبری مجموعه رده.*/توضیحات') and
					not mw.ustring.match(currtitle.text, 'ناوبری مجموعه رده.*/تمرین') and
					currtitle.text ~= 'ناوبری مجموعه رده' and
					mw.ustring.gsub(currtitle.nsText, '_', ' ') ~= 'بحث کاربر' and -- [[phab:T369784]]
					mw.ustring.gsub(currtitle.nsText, '_', ' ') ~= 'بحث الگو' and
					(currtitle.nsText ~= 'الگو' or testcases)) --avoid nested transclusion errors (i.e. {{Infilmdecade}})

local function extractvariable(pagename, cattype)
	local variable = ''
	if cattype then
		if cattype == 'بازه' then
			variable = mw.ustring.match(pagename, '.+(%d%d?%d?%d?%–%d%d?%d?%d?)')
		else
			variable = mw.ustring.match(pagename, '%d%d?%d?%d?')
		end
	end
	return variable
end

local function extractparts(pagename)
	local first, last = mw.ustring.match(pagename, '^(.-%s?)%d%d?%d?%d?–?%d?%d?%d?%d?(%s?.-)$')
	return first, last
end

local function trackcat(key, cat)
	if avoidself and key and cat then
		if cat ~= '' then
			ttrackingcats[key] = '[['..testcasecolon..'رده:'..cat..']]'
		else
			ttrackingcats[key] = ''
		end
	end
	return
end

local function catexists(title)
	return mw.title.new(title, 'رده').exists
end

local function rtarget(frame, cat)
	local catcontent = mw.title.new(cat or '', 'رده'):getContent()
	local hascatredirect = mw.ustring.match(catcontent or '', '{{ *رده بهتر') or
		  mw.ustring.match(catcontent or '', '{{ *[Cc]at') or
		  mw.ustring.match(catcontent or '', '{{ *تغییر')
	if hascatredirect then --prelim test
		local getRegex = require('Module:Template redirect regex').main
		local tregex = getRegex('رده بهتر')
		for _, v in pairs(tregex) do
			local rtarget = mw.ustring.match(catcontent, v..'%s*|%s*([^|}]+)')
			if rtarget then
				if mw.ustring.match(rtarget, '{{') then --{{Title year}}, etc., exists; evaluate
					local regex_ty = '%s*|%s*([^{}]*{{([^{|}]+)}}[^{}]-)%s*}}' --eval null-param templates only; expanded if/as needed
					local rtarget_orig, ty = mw.ustring.match(catcontent, v..regex_ty)
					if rtarget_orig then
						local ty_eval = frame:expandTemplate{title = ty, args = {page = cat}} --frame:newChild doesn't work, use 'page' param instead
						local rtarget_eval = mw.ustring.gsub(rtarget_orig, '{{%s*'..ty..'%s*}}', ty_eval)
						return rtarget_eval, true
					else --sub-parameters present; track & return default
						trackcat(31, 'ناوبری مجموعه رده با خطا در تغییرمسیر')
					end
				end
				rtarget = mw.ustring.gsub(rtarget, '^1%s*=%s*', '')
				rtarget = mw.ustring.gsub(rtarget, '^رده:', '')
				rtarget = mw.ustring.gsub(rtarget, '^[Cc]ategory:', '')
				return rtarget, true
			end
		end --for
	end --if
	return cat, false
end

local function handlecatlink(frame, firstpart, variable, lastpart, display, cattype, followRs, bold, skipgaps, issublist)
	local cat = firstpart .. variable .. lastpart
	local item
	local redirected = false
	if followRs then
		cat, redirected = rtarget(frame, cat)
	end
	local tfirstpart, tlastpart, tvariable = extractparts(cat), extractvariable(cat, cattype)
	if redirected then
		if cattype == 'دهه' and ttrackingcats[18] == '' then
			trackcat(18, 'ناوبری مجموعه رده با دهه تغییرمسیریافته')
		elseif cattype == 'سال' then
			if (tfirstpart and tlastpart) and (tfirstpart ~= firstpart or tlastpart ~= lastpart) and ttrackingcats[19] == '' then
				trackcat(19, 'ناوبری مجموعه رده با سال تغییرمسیریافته (تغییر مبنی)')
			elseif tvariable and tvariable ~= variable and ttrackingcats[20] == '' then
				trackcat(20, 'ناوبری مجموعه رده با سال تغییرمسیریافته (تغییر متغیر)')
			end
		end
	end
	if skipgaps then
		item = '[[:رده:' .. cat .. '|' .. display .. ']]'
		if bold then
			item = '<span class="catseriesnav-item-bold">' .. item .. '</span>'
		end
	elseif catexists(cat) then
		if issublist then
			if cattype == 'دهه' then decadesublinks = true end
			if cattype == 'سده' then centurysublinks = true end
		end
		item = '[[:رده:' .. cat .. '|' .. display .. ']]'
		if bold then
			item = '<span class="catseriesnav-item-bold">' .. item .. '</span>'
		end
	else
		item = '<span class="catseriesnav-item-inactive"; title="' .. cat .. '">' .. display .. '</span>'
	end
	return item
end

local function positive(int)
	int = tonumber(convertnum('en', int))
	if int < 0 then
		return -int
	end
	return int
end

local function trackisolation(firstpart, var, lastpart, skipgaps)
	local numexisting = 10
	local i = 5
	local limit = -5
	if skipgaps then
		numexisting = 100
		i = 50
		limit = -50
	end
	local condition, title, currentvar
	repeat
		currentvar = tonumber(convertnum('en', var)) + i
		title = firstpart .. convertnum('fa', positive(currentvar)) .. lastpart
		if currentvar ~= var and not catexists(title) then
			numexisting = numexisting - 1
		end
		i = i - 1
		condition = i < limit
	until condition
	if numexisting == 0 then
		return trackcat(16, 'ناوبری مجموعه رده منزوی')
	end
end

local function checkforunknownparams(tbl)
	local knownparams = { --parameter whitelist
		['min'] = 'min',
		['کمینه'] = 'کمینه',
		['max'] = 'max',
		['بیشینه'] = 'بیشینه',
		['cat'] = 'cat',
		['رده'] = 'رده',
		['show'] = 'show',
		['نمایش'] = 'نمایش',
		['testcase'] = 'testcase',
		['آزمایشی'] = 'آزمایشی',
		['testcasegap'] = 'testcasegap',
		['وقفه آزمایشی'] = 'وقفه آزمایشی',
		['skip-gaps'] = 'skip-gaps',
		['پرش از وقفه'] = 'پرش از وقفه',
		['list-all-links'] = 'list-all-links',
		['فهرست تمام پیوندها'] = 'فهرست تمام پیوندها',
		['follow-redirects'] = 'follow-redirects',
		['پیمایش تغییرمسیر'] = 'پیمایش تغییرمسیر',
	}
	for k, _ in pairs (tbl) do
		if knownparams[k] == nil then
			trackcat(3, 'ناوبری مجموعه رده با کاربرد پارامتر نامعلوم')
			break
		end
	end
end

local function detectcattype(pagename)
	local cattype
	if mw.ustring.match(pagename, 'سده %d+') then
		cattype = 'سده'
	elseif mw.ustring.match(pagename, 'دهه %d+') then
		cattype = 'دهه'
	elseif mw.ustring.match(pagename, '%d%d?%d?%d?–%d%d?%d?%d?') then
		cattype = 'بازه'
	elseif mw.ustring.match(pagename, '%d%d?%d?%d?') then
		cattype = 'سال'
	else
		cattype = nil
	end
	return cattype
end

local function detectcalendar(pagename)
	local calendar
	if mw.ustring.match(pagename, '%(میلادی%)') then
		calendar = 'میلادی'
	elseif mw.ustring.match(pagename, '%(پیش از میلاد%)') then
		calendar = 'پیش از میلاد'
	elseif detectcattype(pagename) then
		calendar = 'خورشیدی'
	else
		calendar = nil
	end
	return calendar
end

local function BCornot(isBC, passed0, var, lastpart)
	var = tonumber(convertnum('en', var))
	local lastpartout = lastpart
	local BCtext = ''
	if isBC then
		if passed0 then
			lastpartout = mw.ustring.gsub(lastpart, 'پیش از میلاد', 'میلادی')
		else
			BCtext = 'پ‌م'
		end
	else
		if var < 0 then
			BCtext = 'پ‌م'
			lastpartout = mw.ustring.gsub(lastpart, 'میلادی', 'پیش از میلاد')
		else
			lastpartout = mw.ustring.gsub(lastpart, 'پیش از میلاد', 'میلادی')
			BCtext = ''
		end
	end
	return lastpartout, BCtext
end

function p.failedcat(errors, sortkey)
	if avoidself then
		return (errors or '')..'&#42;&#42;&#42;ناوبری مجموعه رده ناتوان در تولید جعبهٔ ناوبری***'..
			   '[['..testcasecolon..'رده:ناوبری مجموعه رده ناتوان در تولید جعبه ناوبری|'..(sortkey or 'س')..']]\n'
	end
	return ''
end

function p.errorclass(msg)
	return mw.text.tag( 'span', {class='error mw-ext-cite-error'}, '<b>خطا!</b> '..mw.ustring.gsub(msg, '&#', '&amp;#') )
end

function p.handleccentury(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, skipgaps, followRs)
	local condition, newlastpart
	limit = gap * 5
	if isBC then limit = -limit end
	local currgap = -limit
	local passed0 = false
	local var = 0
	repeat
		var = tonumber(convertnum('en', variable)) + currgap
		newlastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
		if var ~= 0 then
			table.insert(
				links,
				handlecatlink(
					frame,
					firstpart,
					convertnum('fa', positive(var)),
					newlastpart,
					convertnum('fa', positive(var)) .. BCtext,
					nil,
					followRs
				)
			)
		else
			passed0 = true
			if isBC then
				limit = limit - 1
			else
				limit = limit + 1
			end
		end
		if isBC then
			currgap = currgap - 1
			condition = currgap < limit
		else
			currgap = currgap + 1
			condition = currgap > limit
		end
	until condition
end
function p.handledecade(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, sublinks, skipgaps, followRs)
	local condition
	local shouldbebold = false
	local decade = tonumber(convertnum('en', variable))
	local century = math.floor(((decade-1)/100) + 1)
	if century == 0 then century = 1 end
	if mw.ustring.match(tostring(decade), '00$') then
		century = century + 1
	end
	limit = gap * 5
	if isBC then limit = -limit end
	local currgap = -limit
	if century == 1 then
		if isBC then
			currgap = currgap + 1
		else
			currgap = currgap - 1
		end
	end
	local passed0 = false
	local var
	local centurylastpart = lastpart
	repeat
		var = century + currgap
		centurylastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
		if var ~= 0 then
			shouldbebold = century + currgap == century
			table.insert(
				sublinks,
				handlecatlink(
					frame,
					mw.ustring.gsub(firstpart, 'دهه', 'سده'),
					convertnum('fa', positive(var)),
					centurylastpart,
					convertnum('fa', positive(var)) .. BCtext,
					'سده',
					followRs,
					shouldbebold,
					false,
					true
				)
			)
		else
			passed0 = true
		end
		if isBC then
			currgap = currgap - 1
			condition = currgap < limit
		else
			currgap = currgap + 1
			condition = currgap > limit
		end
	until condition
	if centurysublinks then trackcat(26, 'ناوبری مجموعه رده دهه و سده') end
	gap = 10
	condition = false
	limit = gap * 5
	if isBC then limit = -limit end
	currgap = -limit
	passed0 = false
	repeat
		var = tonumber(convertnum('en', decade + currgap))
		lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
		table.insert(
			links,
			handlecatlink(
				frame,
				firstpart,
				convertnum('fa', positive(var)),
				lastpart,
				convertnum('fa', positive(var)) .. BCtext,
				'دهه',
				followRs
			)
		)
		if var >= 0 then
			passed0 = true
		end
		if isBC then
			currgap = currgap - 10
			condition = currgap < limit
		else
			currgap = currgap + 10
			condition = currgap > limit
		end
	until condition
end
function p.handleyear(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, sublinks, skipgaps, followRs)
	trackisolation(firstpart, variable, lastpart, skipgaps)
	local condition
	local shouldbebold = false
	local year = tonumber(convertnum('en', variable))
	local decade = tonumber(tostring(math.floor(year/10)) .. '0')
	if skipgaps then
		gap = gap * 5
	end
	limit = gap * 5
	if isBC then limit = -limit end
	local currgap = -limit
	local passed0 = false
	local var, title, firstvar, lastvar
	local decadelastpart = lastpart
	local skipbaseyear = year
	if skipgaps then
		local y = -1
		while y >= -skipgaps_limit and #links <= 4 do
			var = skipbaseyear + y
			lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
			title = firstpart .. convertnum('fa', positive(var)) .. lastpart
			if catexists(title) then
				table.insert(
					links,
					1,
					handlecatlink(
						frame,
						firstpart,
						convertnum('fa', positive(var)),
						lastpart,
						convertnum('fa', positive(var)) .. BCtext,
						'سال',
						followRs,
						false,
						skipgaps
					)
				)
				skipbaseyear = var
				y = -1
			else
				y = y - 1
			end
		end
		var = skipbaseyear
		while #links < 5 do
			var = var - 1
			lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
			title = firstpart .. convertnum('fa', positive(var)) .. lastpart
			table.insert(
				links,
				1,
				'<span class="catseriesnav-item-inactive"; title="' .. title .. '">' .. convertnum('fa', positive(var)) .. BCtext .. '</span>'
			)
		end
		table.insert(
			links,
			handlecatlink(
				frame,
				firstpart,
				convertnum('fa', year),
				lastpart,
				convertnum('fa', positive(year)) .. BCtext,
				'سال',
				followRs,
				false,
				skipgaps
			)
		)
		y = 1
		skipbaseyear = year
		while y <= skipgaps_limit and #links <= 10 do
			var = skipbaseyear + y
			lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
			title = firstpart .. convertnum('fa', positive(var)) .. lastpart
			if catexists(title) then
				table.insert(
					links,
					handlecatlink(
						frame,
						firstpart,
						convertnum('fa', positive(var)),
						lastpart,
						convertnum('fa', positive(var)) .. BCtext,
						'سال',
						followRs,
						false,
						skipgaps
					)
				)
				skipbaseyear = var
				y = 1
			else
				y = y + 1
			end
		end
		var = skipbaseyear
		while #links < 11 do
			var = var + 1
			lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
			title = firstpart .. convertnum('fa', positive(var)) .. lastpart
			table.insert(
				links,
				'<span class="catseriesnav-item-inactive"; title="' .. title .. '">' .. convertnum('fa', positive(var)) .. BCtext .. '</span>'
			)
		end
	else
		repeat
			var = year + currgap
			if var == 0 then
				passed0 = true
				if isBC then
					limit = limit - 1
					currgap = currgap - 1
					var = year + currgap
				else
					limit = limit + 1
					currgap = currgap + 1
					var = year + currgap
				end
			end
			lastpart, BCtext = BCornot(isBC, passed0, var, lastpart)
			title = firstpart .. convertnum('fa', positive(var)) .. lastpart
			table.insert(
				links,
				handlecatlink(
					frame,
					firstpart,
					convertnum('fa', positive(var)),
					lastpart,
					convertnum('fa', positive(var)) .. BCtext,
					'سال',
					followRs
				)
			)
			if isBC then
				currgap = currgap - 1
				condition = currgap < limit
			else
				currgap = currgap + 1
				condition = currgap > limit
			end
		until condition
	end
	gap = 10
	condition = false
	limit = gap * 5
	if isBC then limit = -limit end
	currgap = -limit
	passed0 = false
	repeat
		shouldbebold = decade + currgap == decade
		var = decade + currgap
		table.insert(
			sublinks,
			handlecatlink(
				frame,
				firstpart .. ' دهه ',
				convertnum('fa', positive(var)),
				lastpart,
				convertnum('fa', positive(var)) .. BCtext,
				'دهه',
				followRs,
				shouldbebold,
				false,
				true
			)
		)
		if var >= 0 then
			passed0 = true
		end
		if isBC then
			currgap = currgap - 10
			condition = currgap < limit
		else
			currgap = currgap + 10
			condition = currgap > limit
		end
	until condition
	if decadesublinks then trackcat(26, 'ناوبری مجموعه رده سال و دهه') end
end

function p.main(frame)
	local args = frame:getParent().args
	checkforunknownparams(args)
	local templatestyles = require("Module:TemplateStyles")(
		"پودمان:ناوبری مجموعه رده/styles.css"
	)
	setFarsiArguments(
		args,
		{
			['cat']  = 'رده', ['skip-gaps'] = 'پرش از وقفه', ['show'] = 'نمایش',
			['follow-redirects'] = 'پیمایش تغییرمسیر', ['testcase'] = 'آزمایشی'
		}
	)
	local skipgaps = args['skip-gaps'] and yesno(args['skip-gaps']) or false
	if skipgaps then
		trackcat(23, 'ناوبری مجموعه رده با پارامتر پرش از وقفه')
	end
	local follow = true
	if args['follow-redirects'] and not yesno(args['follow-redirects']) then
		follow = false
	end
	local gap = 1
	local links = {}
	local sublinks = {}
	local pagename = args['cat'] and mw.title.new(args['cat'], 'رده').text or currtitle.text
	local cattype = detectcattype(pagename)
	local calendar = detectcalendar(pagename)
	local variable = extractvariable(pagename, cattype)
	local firstpart, lastpart = extractparts(pagename)
	local limit, currentgap = 0, 0
	local isBC = calendar == 'پیش از میلاد'
	local BCtext = ''
	local out = '<div class="toccolours catseriesnav-range">\n'
	local show = args['show']
	
	if show and show ~= '' then
		if show == 'skip-gaps' or show == 'پرش از وقفه' then return convertnum('fa', skipgaps_limit)
		elseif show == 'term-limit' or show == 'مدت محدود' then return convertnum('fa', term_limit) end
	end

	--namespace checks
	if isincatns then
		if args['cat'] and args['cat'] ~= '' then
			trackcat(1, 'ناوبری مجموعه رده با کاربرد پارامتر رده')
		end
		if args['testcase'] and args['testcase'] ~= '' then
			trackcat(2, 'ناوبری مجموعه رده با کاربرد پارامتر آزمایشی')
		end
	elseif isinmainspace then
		trackcat(27, 'ناوبری مجموعه رده در فضای نام اصلی')
	end
	
	if cattype then
		if isBC then
			BCtext = 'پ‌م'
		end
		if cattype == 'سده' then
			p.handleccentury(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, skipgaps, follow)
		elseif cattype == 'دهه' then
			p.handledecade(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, sublinks, skipgaps, follow)
		elseif cattype == 'سال' then
			p.handleyear(frame, limit, isBC, variable, firstpart, lastpart, BCtext, gap, links, sublinks, skipgaps, follow)
		else -- range
			
		end
	end
	if #links > 0 then
		out = out .. horizontal(links) .. '\n</div>'
	else
		errors = p.errorclass('ناتوان در یافتن متن متغیر در عنوان ردهٔ «' .. pagename .. '»')
		out = p.failedcat(errors, 'ع')
	end
	if decadesublinks or centurysublinks then
		out = out .. '\n<div class="toccolours catseriesnav-range catseriesnav-range-transparent">\n' ..
			  horizontal(sublinks) .. '\n</div>'
	end
	out = out .. table.concat(ttrackingcats)
	return templatestyles ..
		'<div class="catseriesnav" role="navigation" aria-label="Range">' ..
		out .. '\n</div>'
end

return p