پودمان:IranByProvinceCatNav
پرش به ناوبری
پرش به جستجو
توضیحات این پودمان میتواند در پودمان:IranByProvinceCatNav/توضیحات قرار گیرد.
--[[
v01.18: fix handling of definite article (e.g. for 'the Northwest Territories')
each title consists of 3 parts
* prefix
* province name
* suffix
e.g. "فلان در تهران"
* prefix = "فلان در "
* province name = "تهران"
* suffix = ""
e.g. "تهران در دهه ۱۳۹۰"
* prefix = ""
* province name = "تهران"
* suffix = "در دهه ۱۳۹۰"
]]
-- config
local textSize = '90%'
local tableClass="toc"
local evenRowStyle = "vertical-align:top; background-color:#f3f3f3;"
local oddRowStyle = "vertical-align:top;"
local labelStyle = "text-align:left; font-weight: bold; padding: 0.25em 0.5em 0.25em 0.5em;"
local listStyle = "text-align:right; font-weight: normal; padding: 0.25em 0.5em 0.25em 0.5em;"
local greyLinkColor = "#888"
--[[ Note that the table styles are designed to ensure that the navbox is as wide as possible, while still leaving
enough enough space on the right for portal boxes, commons links, and GeoGroup templates.
A lot of fiddling was needed to make it work, so please test any chnages very carfully in the sandbox.
]]
local tableFallbackMaxWidth="auto"
local tableMaxWidth="calc(100% - 25em)" -- Template:GeoGroup has width: 23em<
-- local tableStyle="margin-left:0; margin-right:auto; clear:left !important; margin-top:0 !important; float:left; width:auto;"
local tableStyle="margin-right:0; margin-left:auto; clear:right !important; margin-top:0 !important; width:auto;"
-- Templates which are allowed to call this module
local callingTemplates = {
'الگو:IranByProvinceCatNav',
'الگو:ناوبری رده استانهای ایران',
}
-- globals for this module
local debugging = false
local debugmsg = ""
local tableRowNum = 0
local title_prefix = ""
local title_suffix = ""
local title_prefix
local title_suffix
local thisPageProvince
local greyLinkCount = 0
local blueLinkCount = 0
local parentname = ""
local templateName
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local p = {}
--[[
Plain text list of provinces and territories
* Each entry exactly as it appears in running text in category titles, with any prefix (e.g. "the")
* Be sure to avoid hidden characters and duplicate spaces. They break the pattern-matching on which this module relies
]]
local IranProvinces = {
'استان آذربایجان شرقی',
'استان آذربایجان غربی',
'استان اردبیل',
'استان اصفهان',
'استان البرز',
'استان ایلام',
'استان بوشهر',
'استان تهران',
'استان چهارمحال و بختیاری',
'استان خراسان جنوبی',
'استان خراسان رضوی',
'استان خراسان شمالی',
'استان خوزستان',
'استان زنجان',
'استان سمنان',
'استان سیستان و بلوچستان',
'استان فارس',
'استان قزوین',
'استان قم',
'استان کردستان',
'استان کرمان',
'استان کرمانشاه',
'استان کهگیلویه و بویراحمد',
'استان گلستان',
'استان گیلان',
'استان لرستان',
'استان مازندران',
'استان مرکزی',
'استان هرمزگان',
'استان همدان',
'استان یزد'
}
-- If the page title matches any of these Lua patterns, treat it as a false positive
local falsePositiveChecks = {
"کرج",
"استان کرج",
}
function makeTrackingCategory()
-- discount the current page, which will always be coded as a blue link, but rendered as bold un-navigable
blueLinkCount = blueLinkCount - 1
if greyLinkCount == 0 then
return "[[رده:" .. templateName .. " بدون پیوند خاکستری]]"
end
if blueLinkCount == 0 then
return "[[رده:" .. templateName .. " فقط دارای پیوند خاکستری]]"
end
if greyLinkCount <= 10 then
return "[[رده:" .. templateName .. " با کمتر از ۱۰ پیوند خاکستری]]"
end
if greyLinkCount >= 25 then
return "[[رده:" .. templateName .. " با بیش از ۲۵ پیوند خاکستری]]"
end
if greyLinkCount > 10 then
return "[[رده:" .. templateName .. " با بیش از ۱۰ پیوند خاکستری]]"
end
return ""
end
function makeTableRow(rowLabel, provinceList)
debugLog(2, "ساخت ردیف جدول, برچسب: ")
if (rowLabel == nil) then
rowLabel = "بر پایه<br/>استان"
debugLog(nil, rowLabel)
else
rowLabel = mw.text.trim(rowLabel)
debugLog(nil, " [" .. rowLabel .. "]")
end
tableRowNum = tableRowNum + 1
local thisRow
if (tableRowNum % 2) == 0 then
debugLog(3, "با شمارهٔ زوج")
thisRow = '<tr style="' .. evenRowStyle .. '">\n'
else
debugLog(3, "با شمارهٔ فرد")
thisRow = '<tr style="' .. oddRowStyle .. '">\n'
end
if not ((rowLabel == nil) or (rowLabel =="")) then
thisRow = thisRow .. '<td style="' .. labelStyle .. '">' .. rowLabel .. '</td>\n'
end
-- now begin making the row contents
thisRow = thisRow .. '<td style="' .. listStyle .. ';"><div class="hlist">\n'
local i, aProvince
debugLog(3, "پردازش فهرست استانها")
for i, aProvince in ipairs(provinceList) do
debugLog(4, "شمارهٔ " .. tostring(i) .. ": [" .. aProvince .. "]")
myCatName = makeCatName(aProvince, title_prefix, title_suffix)
thisRow = thisRow .. "* " .. makeCatLink(myCatName, aProvince) .. "\n"
end
thisRow = thisRow .. '</div></td>\n</tr>'
return thisRow
end
function makeTable()
debugLog(1, "ساخت جدول")
tableRowNum = 0
local myTable = '<table class="' .. tableClass .. '"'
myTable = myTable .. ' style="' .. tableStyle .. '; font-size:' .. textSize .. '; max-width:' .. tableFallbackMaxWidth .. '; max-width:' .. tableMaxWidth ..'">\n'
myTable = myTable .. makeTableRow(nil, IranProvinces)
myTable = myTable .. "</table>\n"
return myTable
end
-- Make a piped link to a category, if it exists
-- If it doesn't exist, just display the greyed link title without linking
function makeCatLink(catname, disp)
local displaytext
if (disp ~= "") and (disp ~= nil) then
-- use 'disp' parameter, but strip any leading word "استان"
displaytext = mw.ustring.gsub(disp, "استان%s+", "");
else
displaytext = catname
end
local fmtlink
local catPage = mw.title.new( catname, "رده" )
if (catPage.exists) then
fmtlink = "[[:رده:" .. catname .. "|" .. displaytext .. "]]"
blueLinkCount = blueLinkCount + 1
else
fmtlink = '<span style="color:' .. greyLinkColor .. '">' .. displaytext .. "</span>"
greyLinkCount = greyLinkCount + 1
end
return fmtlink
end
function makeCatName(provinceName, prefix, suffix)
local thisCatName = prefix .. provinceName .. suffix
debugLog(5, "نام این رده = [" .. thisCatName .. "]")
--[[
Now check whether the all following conditions are true
1/ the provinceName begins with "استان"
2/ the category does NOT exist if we use "استان "
3/ the category does exist if we strip "استان "
If those conditions are all true, them strip "استان"
]]
if (mw.ustring.match(provinceName, "استان ") ~= nil) then
debugLog(6, "نام استان با «استان» آغاز میشود")
local provinceNameStripped = mw.ustring.gsub(provinceName, "استان ", "", 1)
local thisCatNameStripped = prefix .. provinceNameStripped .. suffix
debugLog(6, "نام این رده بهصورت جدا جدا = [" .. thisCatNameStripped .. "]")
local testCatPage = mw.title.new(thisCatName, "رده" )
local testCatPageStripped = mw.title.new(thisCatNameStripped, "رده" )
if not testCatPage.exists then
debugLog(7, "[" .. testCatPage.fullText .. "] .. موجود نیست")
if (testCatPageStripped.exists) then
debugLog(7, "[" .. testCatPageStripped.fullText .. "] .. موجود است، پس از آن استفاده میشود")
return thisCatNameStripped
end
end
end
return thisCatName
end
function patternSearchEncode(s)
return mw.ustring.gsub(s, "([%W])", "%%%1")
end
-- Does the pagename include a province name?
function findprovinceNameInPagename(pn, provinceList, description)
local i, aProvince, testProvince
debugLog(2, "بررسی [" .. pn .."] برای نام استان در مجموعهٔ استانها: " .. description)
for i, aProvince in ipairs(provinceList) do
testProvince = aProvince
debugLog(3, "آزمایش: [" .. testProvince .. "]")
local testProvinceEncoded = patternSearchEncode(testProvince)
-- For efficiency, the first test is a simple match as a a screening test
-- If the bare county name is nowhere in the pagename, then no need for
-- more precise checks
-- This check would be one line in regex, but Lua pattern matching is cruder,
-- so we need several passes to ensure that any match is of a complete word
debugLog(4, "انطباق ساده؟ ")
if (not mw.ustring.match(pn, testProvinceEncoded)) then
debugLog(nil, "ناموفق")
else
debugLog(nil, "موفق")
-- test for false positives
local j, aFalsePositiveTest
for j, aFalsePositiveTest in ipairs(falsePositiveChecks) do
debugLog(5, "الگوی آزمایش «" .. aFalsePositiveTest .. "» مثبت کاذب است؟ ")
if (mw.ustring.match(pn, aFalsePositiveTest)) then
debugLog(nil, "منطبق است، پس ناموفق")
return nil
end
debugLog(nil, "منطبق نیست، پس درست است")
end
debugLog(4, "انطباق کل مام؟ ")
if (pn == testProvince) then
debugLog(nil, "بله")
return testProvince
end
debugLog(nil, "خیر")
debugLog(4, "انطباق در ابتدا پیش از جداکننده؟ ")
if mw.ustring.match(pn, "^" .. testProvinceEncoded .. "[^%w]") then
debugLog(nil, "بله")
return testProvince
end
debugLog(nil, "خیر")
debugLog(4, "انطباق در انتها پس از جداکننده؟ ")
if mw.ustring.match(pn, "[^%w]" .. testProvinceEncoded .. "$") then
debugLog(nil, "بله")
return testProvince
end
debugLog(nil, "خیر")
debugLog(4, "انطباق در هر جا پس یا پیش از جداکننده؟ ")
if mw.ustring.match(pn, "[^%w]" .. testProvinceEncoded .. "[^%w]") then
debugLog(nil, "بله")
return testProvince
end
debugLog(nil, "خیر")
end
-- Special case: if the province name we are testing begins with a prefixed "استان"
debugLog(4, "آزمایش استان با «استان» آغاز میشود؟ ")
if (mw.ustring.match(testProvince, "استان ") == nil) then
debugLog(nil, "خیر")
else
debugLog(nil, "بله")
end
if (mw.ustring.match(testProvince, "استان ") ~= nil) then
local testProvinceStripped = mw.ustring.gsub(testProvince, "استان ", "", 1)
local testProvinceStrippedEncoded = patternSearchEncode(testProvinceStripped)
debugLog(4, "الگوی آزمایش بدون مقالهٔ اصلی، مثلاً «" .. testProvinceStrippedEncoded .. "»؟ ")
if (mw.ustring.match(pn, "[^%w]" .. testProvinceStrippedEncoded .. "[^%w]") ~= nil)
or (mw.ustring.match(pn, "^" .. testProvinceStrippedEncoded .. "[^%w]") ~= nil)
or (mw.ustring.match(pn, "[^%w]" .. testProvinceStrippedEncoded .. "$") ~= nil)
or (mw.ustring.match(pn, "^" .. testProvinceStrippedEncoded .. "$") ~= nil) then
debugLog(nil, "بله")
return testProvinceStripped
end
debugLog(nil, "خیر")
end
end
return nil
end
-- parse the pagename to find 3 parts: prefix, province name, suffix
function parsePagename(pn)
debugLog(1, "تجزیهٔ نام صفحه: [" .. pn .. "]")
local validprovinceName
validprovinceName = findprovinceNameInPagename(pn, IranProvinces, "provincelst")
if validprovinceName == nil then
return false
end
-- if we get here, the page name "pn" includes a validprovinceName
-- so now we need to split the string
debugLog(2, "تفکیک نام صفحه پیرامون [" .. validprovinceName .. "]")
local validProvinceEncoded = mw.ustring.gsub(validprovinceName, "([%W])", "%%%1")
match_prefix, match_province, match_suffix = mw.ustring.match(pn, "^(.*)(" .. validProvinceEncoded .. ")(.*)$")
title_prefix = match_prefix
title_suffix = match_suffix
debugLog(2, "تجزیه موفق")
debugLog(3, "پیشوند عنوان = [" .. title_prefix .. "]")
debugLog(3, "استان در این صفححه = [" .. match_province .. "]")
debugLog(3, "پسوند عنوان = [" .. title_suffix .. "]")
return true
end
function publishDebugLog()
if not debugging then
return ""
end
return "== خرفسترزدایی ==\n\n" .. debugmsg .. "\n== خروجی ==\n"
end
-- debugLog builds a log which can be output if debuging is enabled
-- each log entry is given a level, so that the output is not simply a flat list
-- a debug msg may be appended to the previous msg by setting the level to nil
function debugLog(level, msg)
if (debugmsg == nil) then
debugmsg = ""
end
if (level ~= nil) then
-- not appending, so make a new line
debugmsg = debugmsg .. "\n"
-- then add the level
local i
for i = 1, level do
if (i % 2) == 1 then
debugmsg = debugmsg .. "#"
else
debugmsg = debugmsg .. "*"
end
end
end
debugmsg = debugmsg .. " " .. msg
return true
end
function getYesNoParam(args, thisParamName, defaultVal)
local paramVal = args[thisParamName]
if paramVal == nil then
paramVal = ""
end
debugLog(2, "برآورد پارامتر بله/خیر: [" .. thisParamName .. "] = [" .. paramVal .. "]")
debugLog(3, "پیشفرض = " .. ((defaultVal and "بله") or "خیر"))
debugLog(3, "برآورد بهعنوان: ")
local returnValue
if paramVal == "" then
returnValue = defaultVal
else
returnValue = yesno(args[thisParamName], defaultVal)
end
if (returnValue) then
debugLog(nil, "بله")
else
debugLog(nil, "خیر")
end
return returnValue
end
function makeErrorMsg(s)
return '<p class="error">خطای [[' .. parentname .. ']]: ' .. s .. '</p>\n'
end
function isValidParent(p)
local i, aParent
for i, aParent in ipairs(callingTemplates) do
if p == aParent then
return true
end
end
return false
end
function p.main(frame)
local parent = frame:getParent()
if parent then
parentname = parent:getTitle():gsub('/صفحه تمرین$', '')
end
if (parentname == nil) or not isValidParent(parentname) then
local errormsg = '<p class="error"> خطا: ' .. parentname .. ' دادهپوش معتبری برای [[' .. frame:getTitle() .. ']] نیست\n'
errormsg = errormsg .. '<br><br>دادهپوشهای معتبر: '
local i, aParent
for i, aParent in ipairs(callingTemplates) do
errormsg = errormsg .. '[[' .. aParent .. ']]'
end
errormsg = errormsg .. '</p>'
return errormsg
end
templateName = mw.ustring.gsub(parentname, "^الگو:", "")
debugLog(1, "بررسی پارامترها")
debugging = getYesNoParam(frame.args, "debug", false)
-- get the page title
thispage = mw.title.getCurrentTitle()
thispagename = thispage.text;
debugLog(1, "mw.title.getCurrentTitle()")
debugLog(2, "thispage.text = [" .. thispage.text .."]")
debugLog(2, "thispage.namespace = [" .. thispage.namespace .."]")
debugLog(2, "thispage.nsText = [" .. thispage.nsText .."]")
debugLog(2, "این صفحه یک رده است؟ با استفاده از (thispage:inNamespace(14)): ")
if not (thispage:inNamespace(14)) then
debugLog(nil, "خیر، رده نیست")
debugLog(1, "رده نیست، پس خروجی ارائه نمیشود")
return makeErrorMsg("تنها برای استفاده در صفحههای رده") .. publishDebugLog()
end
debugLog(nil, "بله، رده است")
if not parsePagename(thispagename) then
-- some error parsing the title, so don't proceed to output
local trackingCatInvalid = "[[رده:" .. templateName .. " در رده نامعتبر]]"
return makeErrorMsg('نام این رده شامل نام معتبر یکی از استانهای ایران نیست') .. publishDebugLog() .. trackingCatInvalid
end
debugLog(1, "تجزیه کامل شد")
debugLog(2, "پیشوند عنوان = [" .. title_prefix .. "]")
debugLog(2, "پسوند عنوان = [" .. title_suffix .. "]")
local myNavTable = makeTable()
debugLog(2, "تعداد پیوندهای آبی = [" .. blueLinkCount .. "]. (دقت کنید که صفحهٔ کنونی همواره بهعنوان پیوند آبی شمارش میشود، اما قابل ناوبری نخواهد بود)")
debugLog(2, "تعداد پیوندهای خاکستری = [" .. greyLinkCount .. "]")
if (blueLinkCount <= 1) then
-- This is a navbar to nowhere, so suppress display
myNavTable = ""
debugLog(1, "صفر پیوند آبی (بهجز صفحهٔ کنونی) باعث میشود که این ناوبری کاربردی نداشتهباشد؛ پس جعبهٔ ناوبری نمایش نخواهد یافت")
end
local myTrackingCat = makeTrackingCategory()
return publishDebugLog() .. myNavTable .. myTrackingCat
end
return p