پودمان:ناوبری مجموعه رده
ظاهر
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 '')..'***ناوبری مجموعه رده ناتوان در تولید جعبهٔ ناوبری***'..
'[['..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, '&#', '&#') )
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